• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- IRDynamicChecks.cpp -------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Expression/IRDynamicChecks.h"
11 
12 #include "lldb/Core/ConstString.h"
13 #include "lldb/Core/Log.h"
14 #include "lldb/Expression/ClangUtilityFunction.h"
15 #include "lldb/Target/ExecutionContext.h"
16 #include "lldb/Target/ObjCLanguageRuntime.h"
17 #include "lldb/Target/Process.h"
18 #include "lldb/Target/StackFrame.h"
19 
20 #include "llvm/Support/raw_ostream.h"
21 #include "llvm/IR/Constants.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/IR/Instructions.h"
24 #include "llvm/IR/Module.h"
25 #include "llvm/IR/Value.h"
26 
27 using namespace llvm;
28 using namespace lldb_private;
29 
30 static char ID;
31 
32 #define VALID_POINTER_CHECK_NAME "$__lldb_valid_pointer_check"
33 #define VALID_OBJC_OBJECT_CHECK_NAME "$__lldb_objc_object_check"
34 
35 static const char g_valid_pointer_check_text[] =
36 "extern \"C\" void\n"
37 "$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n"
38 "{\n"
39 "    unsigned char $__lldb_local_val = *$__lldb_arg_ptr;\n"
40 "}";
41 
DynamicCheckerFunctions()42 DynamicCheckerFunctions::DynamicCheckerFunctions ()
43 {
44 }
45 
~DynamicCheckerFunctions()46 DynamicCheckerFunctions::~DynamicCheckerFunctions ()
47 {
48 }
49 
50 bool
Install(Stream & error_stream,ExecutionContext & exe_ctx)51 DynamicCheckerFunctions::Install(Stream &error_stream,
52                                  ExecutionContext &exe_ctx)
53 {
54     m_valid_pointer_check.reset(new ClangUtilityFunction(g_valid_pointer_check_text,
55                                                          VALID_POINTER_CHECK_NAME));
56     if (!m_valid_pointer_check->Install(error_stream, exe_ctx))
57         return false;
58 
59     Process *process = exe_ctx.GetProcessPtr();
60 
61     if (process)
62     {
63         ObjCLanguageRuntime *objc_language_runtime = process->GetObjCLanguageRuntime();
64 
65         if (objc_language_runtime)
66         {
67             m_objc_object_check.reset(objc_language_runtime->CreateObjectChecker(VALID_OBJC_OBJECT_CHECK_NAME));
68 
69             if (!m_objc_object_check->Install(error_stream, exe_ctx))
70                 return false;
71         }
72     }
73 
74     return true;
75 }
76 
77 bool
DoCheckersExplainStop(lldb::addr_t addr,Stream & message)78 DynamicCheckerFunctions::DoCheckersExplainStop (lldb::addr_t addr, Stream &message)
79 {
80     // FIXME: We have to get the checkers to know why they scotched the call in more detail,
81     // so we can print a better message here.
82     if (m_valid_pointer_check.get() != NULL && m_valid_pointer_check->ContainsAddress(addr))
83     {
84         message.Printf ("Attempted to dereference an invalid pointer.");
85         return true;
86     }
87     else if (m_objc_object_check.get() != NULL && m_objc_object_check->ContainsAddress(addr))
88     {
89         message.Printf ("Attempted to dereference an invalid ObjC Object or send it an unrecognized selector");
90         return true;
91     }
92     return false;
93 }
94 
95 
96 static std::string
PrintValue(llvm::Value * V,bool truncate=false)97 PrintValue(llvm::Value *V, bool truncate = false)
98 {
99     std::string s;
100     raw_string_ostream rso(s);
101     V->print(rso);
102     rso.flush();
103     if (truncate)
104         s.resize(s.length() - 1);
105     return s;
106 }
107 
108 //----------------------------------------------------------------------
109 /// @class Instrumenter IRDynamicChecks.cpp
110 /// @brief Finds and instruments individual LLVM IR instructions
111 ///
112 /// When instrumenting LLVM IR, it is frequently desirable to first search
113 /// for instructions, and then later modify them.  This way iterators
114 /// remain intact, and multiple passes can look at the same code base without
115 /// treading on each other's toes.
116 ///
117 /// The Instrumenter class implements this functionality.  A client first
118 /// calls Inspect on a function, which populates a list of instructions to
119 /// be instrumented.  Then, later, when all passes' Inspect functions have
120 /// been called, the client calls Instrument, which adds the desired
121 /// instrumentation.
122 ///
123 /// A subclass of Instrumenter must override InstrumentInstruction, which
124 /// is responsible for adding whatever instrumentation is necessary.
125 ///
126 /// A subclass of Instrumenter may override:
127 ///
128 /// - InspectInstruction [default: does nothing]
129 ///
130 /// - InspectBasicBlock [default: iterates through the instructions in a
131 ///   basic block calling InspectInstruction]
132 ///
133 /// - InspectFunction [default: iterates through the basic blocks in a
134 ///   function calling InspectBasicBlock]
135 //----------------------------------------------------------------------
136 class Instrumenter {
137 public:
138     //------------------------------------------------------------------
139     /// Constructor
140     ///
141     /// @param[in] module
142     ///     The module being instrumented.
143     //------------------------------------------------------------------
Instrumenter(llvm::Module & module,DynamicCheckerFunctions & checker_functions)144     Instrumenter (llvm::Module &module,
145                   DynamicCheckerFunctions &checker_functions) :
146         m_module(module),
147         m_checker_functions(checker_functions),
148         m_i8ptr_ty(NULL)
149     {
150     }
151 
~Instrumenter()152     virtual~Instrumenter ()
153     {
154     }
155 
156     //------------------------------------------------------------------
157     /// Inspect a function to find instructions to instrument
158     ///
159     /// @param[in] function
160     ///     The function to inspect.
161     ///
162     /// @return
163     ///     True on success; false on error.
164     //------------------------------------------------------------------
Inspect(llvm::Function & function)165     bool Inspect (llvm::Function &function)
166     {
167         return InspectFunction(function);
168     }
169 
170     //------------------------------------------------------------------
171     /// Instrument all the instructions found by Inspect()
172     ///
173     /// @return
174     ///     True on success; false on error.
175     //------------------------------------------------------------------
Instrument()176     bool Instrument ()
177     {
178         for (InstIterator ii = m_to_instrument.begin(), last_ii = m_to_instrument.end();
179              ii != last_ii;
180              ++ii)
181         {
182             if (!InstrumentInstruction(*ii))
183                 return false;
184         }
185 
186         return true;
187     }
188 protected:
189     //------------------------------------------------------------------
190     /// Add instrumentation to a single instruction
191     ///
192     /// @param[in] inst
193     ///     The instruction to be instrumented.
194     ///
195     /// @return
196     ///     True on success; false otherwise.
197     //------------------------------------------------------------------
198     virtual bool InstrumentInstruction(llvm::Instruction *inst) = 0;
199 
200     //------------------------------------------------------------------
201     /// Register a single instruction to be instrumented
202     ///
203     /// @param[in] inst
204     ///     The instruction to be instrumented.
205     //------------------------------------------------------------------
RegisterInstruction(llvm::Instruction & i)206     void RegisterInstruction(llvm::Instruction &i)
207     {
208         m_to_instrument.push_back(&i);
209     }
210 
211     //------------------------------------------------------------------
212     /// Determine whether a single instruction is interesting to
213     /// instrument, and, if so, call RegisterInstruction
214     ///
215     /// @param[in] i
216     ///     The instruction to be inspected.
217     ///
218     /// @return
219     ///     False if there was an error scanning; true otherwise.
220     //------------------------------------------------------------------
InspectInstruction(llvm::Instruction & i)221     virtual bool InspectInstruction(llvm::Instruction &i)
222     {
223         return true;
224     }
225 
226     //------------------------------------------------------------------
227     /// Scan a basic block to see if any instructions are interesting
228     ///
229     /// @param[in] bb
230     ///     The basic block to be inspected.
231     ///
232     /// @return
233     ///     False if there was an error scanning; true otherwise.
234     //------------------------------------------------------------------
InspectBasicBlock(llvm::BasicBlock & bb)235     virtual bool InspectBasicBlock(llvm::BasicBlock &bb)
236     {
237         for (llvm::BasicBlock::iterator ii = bb.begin(), last_ii = bb.end();
238              ii != last_ii;
239              ++ii)
240         {
241             if (!InspectInstruction(*ii))
242                 return false;
243         }
244 
245         return true;
246     }
247 
248     //------------------------------------------------------------------
249     /// Scan a function to see if any instructions are interesting
250     ///
251     /// @param[in] f
252     ///     The function to be inspected.
253     ///
254     /// @return
255     ///     False if there was an error scanning; true otherwise.
256     //------------------------------------------------------------------
InspectFunction(llvm::Function & f)257     virtual bool InspectFunction(llvm::Function &f)
258     {
259         for (llvm::Function::iterator bbi = f.begin(), last_bbi = f.end();
260              bbi != last_bbi;
261              ++bbi)
262         {
263             if (!InspectBasicBlock(*bbi))
264                 return false;
265         }
266 
267         return true;
268     }
269 
270     //------------------------------------------------------------------
271     /// Build a function pointer for a function with signature
272     /// void (*)(uint8_t*) with a given address
273     ///
274     /// @param[in] start_address
275     ///     The address of the function.
276     ///
277     /// @return
278     ///     The function pointer, for use in a CallInst.
279     //------------------------------------------------------------------
BuildPointerValidatorFunc(lldb::addr_t start_address)280     llvm::Value *BuildPointerValidatorFunc(lldb::addr_t start_address)
281     {
282         IntegerType *intptr_ty = llvm::Type::getIntNTy(m_module.getContext(),
283                                                              (m_module.getPointerSize() == llvm::Module::Pointer64) ? 64 : 32);
284 
285         llvm::Type *param_array[1];
286 
287         param_array[0] = const_cast<llvm::PointerType*>(GetI8PtrTy());
288 
289         ArrayRef<llvm::Type*> params(param_array, 1);
290 
291         FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true);
292         PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
293         Constant *fun_addr_int = ConstantInt::get(intptr_ty, start_address, false);
294         return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
295     }
296 
297     //------------------------------------------------------------------
298     /// Build a function pointer for a function with signature
299     /// void (*)(uint8_t*, uint8_t*) with a given address
300     ///
301     /// @param[in] start_address
302     ///     The address of the function.
303     ///
304     /// @return
305     ///     The function pointer, for use in a CallInst.
306     //------------------------------------------------------------------
BuildObjectCheckerFunc(lldb::addr_t start_address)307     llvm::Value *BuildObjectCheckerFunc(lldb::addr_t start_address)
308     {
309         IntegerType *intptr_ty = llvm::Type::getIntNTy(m_module.getContext(),
310                                                        (m_module.getPointerSize() == llvm::Module::Pointer64) ? 64 : 32);
311 
312         llvm::Type *param_array[2];
313 
314         param_array[0] = const_cast<llvm::PointerType*>(GetI8PtrTy());
315         param_array[1] = const_cast<llvm::PointerType*>(GetI8PtrTy());
316 
317         ArrayRef<llvm::Type*> params(param_array, 2);
318 
319         FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true);
320         PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
321         Constant *fun_addr_int = ConstantInt::get(intptr_ty, start_address, false);
322         return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
323     }
324 
GetI8PtrTy()325     PointerType *GetI8PtrTy()
326     {
327         if (!m_i8ptr_ty)
328             m_i8ptr_ty = llvm::Type::getInt8PtrTy(m_module.getContext());
329 
330         return m_i8ptr_ty;
331     }
332 
333     typedef std::vector <llvm::Instruction *>   InstVector;
334     typedef InstVector::iterator                InstIterator;
335 
336     InstVector                  m_to_instrument;        ///< List of instructions the inspector found
337     llvm::Module               &m_module;               ///< The module which is being instrumented
338     DynamicCheckerFunctions    &m_checker_functions;    ///< The dynamic checker functions for the process
339 private:
340     PointerType                *m_i8ptr_ty;
341 };
342 
343 class ValidPointerChecker : public Instrumenter
344 {
345 public:
ValidPointerChecker(llvm::Module & module,DynamicCheckerFunctions & checker_functions)346     ValidPointerChecker (llvm::Module &module,
347                          DynamicCheckerFunctions &checker_functions) :
348         Instrumenter(module, checker_functions),
349         m_valid_pointer_check_func(NULL)
350     {
351     }
352 
~ValidPointerChecker()353     virtual ~ValidPointerChecker ()
354     {
355     }
356 private:
InstrumentInstruction(llvm::Instruction * inst)357     bool InstrumentInstruction(llvm::Instruction *inst)
358     {
359         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
360 
361         if (log)
362             log->Printf("Instrumenting load/store instruction: %s\n",
363                         PrintValue(inst).c_str());
364 
365         if (!m_valid_pointer_check_func)
366             m_valid_pointer_check_func = BuildPointerValidatorFunc(m_checker_functions.m_valid_pointer_check->StartAddress());
367 
368         llvm::Value *dereferenced_ptr = NULL;
369 
370         if (llvm::LoadInst *li = dyn_cast<llvm::LoadInst> (inst))
371             dereferenced_ptr = li->getPointerOperand();
372         else if (llvm::StoreInst *si = dyn_cast<llvm::StoreInst> (inst))
373             dereferenced_ptr = si->getPointerOperand();
374         else
375             return false;
376 
377         // Insert an instruction to cast the loaded value to int8_t*
378 
379         BitCastInst *bit_cast = new BitCastInst(dereferenced_ptr,
380                                                 GetI8PtrTy(),
381                                                 "",
382                                                 inst);
383 
384         // Insert an instruction to call the helper with the result
385 
386         llvm::Value *arg_array[1];
387 
388         arg_array[0] = bit_cast;
389 
390         llvm::ArrayRef<llvm::Value *> args(arg_array, 1);
391 
392         CallInst::Create(m_valid_pointer_check_func,
393                          args,
394                          "",
395                          inst);
396 
397         return true;
398     }
399 
InspectInstruction(llvm::Instruction & i)400     bool InspectInstruction(llvm::Instruction &i)
401     {
402         if (dyn_cast<llvm::LoadInst> (&i) ||
403             dyn_cast<llvm::StoreInst> (&i))
404             RegisterInstruction(i);
405 
406         return true;
407     }
408 
409     llvm::Value         *m_valid_pointer_check_func;
410 };
411 
412 class ObjcObjectChecker : public Instrumenter
413 {
414 public:
ObjcObjectChecker(llvm::Module & module,DynamicCheckerFunctions & checker_functions)415     ObjcObjectChecker(llvm::Module &module,
416                         DynamicCheckerFunctions &checker_functions) :
417         Instrumenter(module, checker_functions),
418         m_objc_object_check_func(NULL)
419     {
420     }
421 
422     virtual
~ObjcObjectChecker()423     ~ObjcObjectChecker ()
424     {
425     }
426 
427     enum msgSend_type
428     {
429         eMsgSend = 0,
430         eMsgSendSuper,
431         eMsgSendSuper_stret,
432         eMsgSend_fpret,
433         eMsgSend_stret
434     };
435 
436     std::map <llvm::Instruction *, msgSend_type> msgSend_types;
437 
438 private:
InstrumentInstruction(llvm::Instruction * inst)439     bool InstrumentInstruction(llvm::Instruction *inst)
440     {
441         CallInst *call_inst = dyn_cast<CallInst>(inst);
442 
443         if (!call_inst)
444             return false; // call_inst really shouldn't be NULL, because otherwise InspectInstruction wouldn't have registered it
445 
446         if (!m_objc_object_check_func)
447             m_objc_object_check_func = BuildObjectCheckerFunc(m_checker_functions.m_objc_object_check->StartAddress());
448 
449         // id objc_msgSend(id theReceiver, SEL theSelector, ...)
450 
451         llvm::Value *target_object;
452         llvm::Value *selector;
453 
454         switch (msgSend_types[inst])
455         {
456         case eMsgSend:
457         case eMsgSend_fpret:
458             target_object = call_inst->getArgOperand(0);
459             selector = call_inst->getArgOperand(1);
460             break;
461         case eMsgSend_stret:
462             target_object = call_inst->getArgOperand(1);
463             selector = call_inst->getArgOperand(2);
464             break;
465         case eMsgSendSuper:
466         case eMsgSendSuper_stret:
467             return true;
468         }
469 
470         // These objects should always be valid according to Sean Calannan
471         assert (target_object);
472         assert (selector);
473 
474         // Insert an instruction to cast the receiver id to int8_t*
475 
476         BitCastInst *bit_cast = new BitCastInst(target_object,
477                                                 GetI8PtrTy(),
478                                                 "",
479                                                 inst);
480 
481         // Insert an instruction to call the helper with the result
482 
483         llvm::Value *arg_array[2];
484 
485         arg_array[0] = bit_cast;
486         arg_array[1] = selector;
487 
488         ArrayRef<llvm::Value*> args(arg_array, 2);
489 
490         CallInst::Create(m_objc_object_check_func,
491                          args,
492                          "",
493                          inst);
494 
495         return true;
496     }
497 
InspectInstruction(llvm::Instruction & i)498     bool InspectInstruction(llvm::Instruction &i)
499     {
500         Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
501 
502         CallInst *call_inst = dyn_cast<CallInst>(&i);
503 
504         if (call_inst)
505         {
506             // This metadata is set by IRForTarget::MaybeHandleCall().
507 
508             MDNode *metadata = call_inst->getMetadata("lldb.call.realName");
509 
510             if (!metadata)
511                 return true;
512 
513             if (metadata->getNumOperands() != 1)
514             {
515                 if (log)
516                     log->Printf("Function call metadata has %d operands for [%p] %s", metadata->getNumOperands(), call_inst, PrintValue(call_inst).c_str());
517                 return false;
518             }
519 
520             MDString *real_name = dyn_cast<MDString>(metadata->getOperand(0));
521 
522             if (!real_name)
523             {
524                 if (log)
525                     log->Printf("Function call metadata is not an MDString for [%p] %s", call_inst, PrintValue(call_inst).c_str());
526                 return false;
527             }
528 
529             std::string name_str = real_name->getString();
530             const char* name_cstr = name_str.c_str();
531 
532             if (log)
533                 log->Printf("Found call to %s: %s\n", name_cstr, PrintValue(call_inst).c_str());
534 
535             if (name_str.find("objc_msgSend") == std::string::npos)
536                 return true;
537 
538             if (!strcmp(name_cstr, "objc_msgSend"))
539             {
540                 RegisterInstruction(i);
541                 msgSend_types[&i] = eMsgSend;
542                 return true;
543             }
544 
545             if (!strcmp(name_cstr, "objc_msgSend_stret"))
546             {
547                 RegisterInstruction(i);
548                 msgSend_types[&i] = eMsgSend_stret;
549                 return true;
550             }
551 
552             if (!strcmp(name_cstr, "objc_msgSend_fpret"))
553             {
554                 RegisterInstruction(i);
555                 msgSend_types[&i] = eMsgSend_fpret;
556                 return true;
557             }
558 
559             if (!strcmp(name_cstr, "objc_msgSendSuper"))
560             {
561                 RegisterInstruction(i);
562                 msgSend_types[&i] = eMsgSendSuper;
563                 return true;
564             }
565 
566             if (!strcmp(name_cstr, "objc_msgSendSuper_stret"))
567             {
568                 RegisterInstruction(i);
569                 msgSend_types[&i] = eMsgSendSuper_stret;
570                 return true;
571             }
572 
573             if (log)
574                 log->Printf("Function name '%s' contains 'objc_msgSend' but is not handled", name_str.c_str());
575 
576             return true;
577         }
578 
579         return true;
580     }
581 
582     llvm::Value         *m_objc_object_check_func;
583 };
584 
IRDynamicChecks(DynamicCheckerFunctions & checker_functions,const char * func_name)585 IRDynamicChecks::IRDynamicChecks(DynamicCheckerFunctions &checker_functions,
586                                  const char *func_name) :
587     ModulePass(ID),
588     m_func_name(func_name),
589     m_checker_functions(checker_functions)
590 {
591 }
592 
~IRDynamicChecks()593 IRDynamicChecks::~IRDynamicChecks()
594 {
595 }
596 
597 bool
runOnModule(llvm::Module & M)598 IRDynamicChecks::runOnModule(llvm::Module &M)
599 {
600     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
601 
602     llvm::Function* function = M.getFunction(StringRef(m_func_name.c_str()));
603 
604     if (!function)
605     {
606         if (log)
607             log->Printf("Couldn't find %s() in the module", m_func_name.c_str());
608 
609         return false;
610     }
611 
612     if (m_checker_functions.m_valid_pointer_check.get())
613     {
614         ValidPointerChecker vpc(M, m_checker_functions);
615 
616         if (!vpc.Inspect(*function))
617             return false;
618 
619         if (!vpc.Instrument())
620             return false;
621     }
622 
623     if (m_checker_functions.m_objc_object_check.get())
624     {
625         ObjcObjectChecker ooc(M, m_checker_functions);
626 
627         if (!ooc.Inspect(*function))
628             return false;
629 
630         if (!ooc.Instrument())
631             return false;
632     }
633 
634     if (log && log->GetVerbose())
635     {
636         std::string s;
637         raw_string_ostream oss(s);
638 
639         M.print(oss, NULL);
640 
641         oss.flush();
642 
643         log->Printf ("Module after dynamic checks: \n%s", s.c_str());
644     }
645 
646     return true;
647 }
648 
649 void
assignPassManager(PMStack & PMS,PassManagerType T)650 IRDynamicChecks::assignPassManager(PMStack &PMS,
651                                    PassManagerType T)
652 {
653 }
654 
655 PassManagerType
getPotentialPassManagerType() const656 IRDynamicChecks::getPotentialPassManagerType() const
657 {
658     return PMT_ModulePassManager;
659 }
660