blob: 09f520c731c17b246d71ed72f4982d859cc301d7 [file] [log] [blame]
Sean Callananf18d91c2010-09-01 00:58:00 +00001//===-- 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"
Sean Callananf18d91c2010-09-01 00:58:00 +000011
Sean Callanane8a59a82010-09-13 21:34:21 +000012#include "lldb/Core/ConstString.h"
Sean Callananf18d91c2010-09-01 00:58:00 +000013#include "lldb/Core/Log.h"
Sean Callanane8a59a82010-09-13 21:34:21 +000014#include "lldb/Expression/ClangUtilityFunction.h"
15#include "lldb/Target/ExecutionContext.h"
Sean Callanan14a97ff2010-11-04 01:51:38 +000016#include "lldb/Target/ObjCLanguageRuntime.h"
17#include "lldb/Target/Process.h"
Sean Callanane8a59a82010-09-13 21:34:21 +000018#include "lldb/Target/StackFrame.h"
Sean Callananf18d91c2010-09-01 00:58:00 +000019
20#include "llvm/Support/raw_ostream.h"
Sean Callanan2a8c3382011-04-14 02:01:31 +000021#include "llvm/Constants.h"
Sean Callananf18d91c2010-09-01 00:58:00 +000022#include "llvm/Function.h"
Sean Callanan05262332010-09-02 00:37:32 +000023#include "llvm/Instructions.h"
Sean Callananf18d91c2010-09-01 00:58:00 +000024#include "llvm/Module.h"
25#include "llvm/Value.h"
26
27using namespace llvm;
28using namespace lldb_private;
29
30static char ID;
31
Greg Clayton8de27c72010-10-15 22:48:33 +000032#define VALID_POINTER_CHECK_NAME "$__lldb_valid_pointer_check"
33#define VALID_OBJC_OBJECT_CHECK_NAME "$__lldb_objc_object_check"
Sean Callanane8a59a82010-09-13 21:34:21 +000034
Greg Clayton8de27c72010-10-15 22:48:33 +000035static const char g_valid_pointer_check_text[] =
36"extern \"C\" void\n"
Greg Clayton21f5fe12010-10-16 21:09:32 +000037"$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n"
Greg Clayton8de27c72010-10-15 22:48:33 +000038"{\n"
Greg Clayton24b48ff2010-10-17 22:03:32 +000039" unsigned char $__lldb_local_val = *$__lldb_arg_ptr;\n"
Greg Clayton8de27c72010-10-15 22:48:33 +000040"}";
Sean Callanane8a59a82010-09-13 21:34:21 +000041
Sean Callananf18d91c2010-09-01 00:58:00 +000042DynamicCheckerFunctions::DynamicCheckerFunctions ()
43{
Sean Callananf18d91c2010-09-01 00:58:00 +000044}
45
46DynamicCheckerFunctions::~DynamicCheckerFunctions ()
47{
48}
49
50bool
51DynamicCheckerFunctions::Install(Stream &error_stream,
52 ExecutionContext &exe_ctx)
53{
Greg Clayton8de27c72010-10-15 22:48:33 +000054 m_valid_pointer_check.reset(new ClangUtilityFunction(g_valid_pointer_check_text,
55 VALID_POINTER_CHECK_NAME));
Sean Callananf18d91c2010-09-01 00:58:00 +000056 if (!m_valid_pointer_check->Install(error_stream, exe_ctx))
57 return false;
Sean Callanan14a97ff2010-11-04 01:51:38 +000058
59 if (exe_ctx.process)
60 {
61 ObjCLanguageRuntime *objc_language_runtime = exe_ctx.process->GetObjCLanguageRuntime();
62
63 if (objc_language_runtime)
64 {
65 m_objc_object_check.reset(objc_language_runtime->CreateObjectChecker(VALID_OBJC_OBJECT_CHECK_NAME));
66
67 if (!m_objc_object_check->Install(error_stream, exe_ctx))
68 return false;
69 }
70 }
Sean Callananf18d91c2010-09-01 00:58:00 +000071
72 return true;
73}
74
Sean Callananf18d91c2010-09-01 00:58:00 +000075static std::string
76PrintValue(llvm::Value *V, bool truncate = false)
77{
78 std::string s;
79 raw_string_ostream rso(s);
80 V->print(rso);
81 rso.flush();
82 if (truncate)
83 s.resize(s.length() - 1);
84 return s;
85}
86
Sean Callanan05262332010-09-02 00:37:32 +000087//----------------------------------------------------------------------
88/// @class Instrumenter IRDynamicChecks.cpp
89/// @brief Finds and instruments individual LLVM IR instructions
90///
91/// When instrumenting LLVM IR, it is frequently desirable to first search
92/// for instructions, and then later modify them. This way iterators
93/// remain intact, and multiple passes can look at the same code base without
94/// treading on each other's toes.
95///
96/// The Instrumenter class implements this functionality. A client first
97/// calls Inspect on a function, which populates a list of instructions to
98/// be instrumented. Then, later, when all passes' Inspect functions have
99/// been called, the client calls Instrument, which adds the desired
100/// instrumentation.
101///
102/// A subclass of Instrumenter must override InstrumentInstruction, which
103/// is responsible for adding whatever instrumentation is necessary.
104///
105/// A subclass of Instrumenter may override:
106///
107/// - InspectInstruction [default: does nothing]
108///
109/// - InspectBasicBlock [default: iterates through the instructions in a
110/// basic block calling InspectInstruction]
111///
112/// - InspectFunction [default: iterates through the basic blocks in a
113/// function calling InspectBasicBlock]
114//----------------------------------------------------------------------
115class Instrumenter {
116public:
117 //------------------------------------------------------------------
118 /// Constructor
119 ///
120 /// @param[in] module
121 /// The module being instrumented.
122 //------------------------------------------------------------------
123 Instrumenter (llvm::Module &module,
124 DynamicCheckerFunctions &checker_functions) :
125 m_module(module),
Sean Callanane8a59a82010-09-13 21:34:21 +0000126 m_checker_functions(checker_functions),
127 m_i8ptr_ty(NULL)
Sean Callanan05262332010-09-02 00:37:32 +0000128 {
129 }
130
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000131 virtual~Instrumenter ()
132 {
133 }
134
Sean Callanan05262332010-09-02 00:37:32 +0000135 //------------------------------------------------------------------
136 /// Inspect a function to find instructions to instrument
137 ///
138 /// @param[in] function
139 /// The function to inspect.
140 ///
141 /// @return
142 /// True on success; false on error.
143 //------------------------------------------------------------------
144 bool Inspect (llvm::Function &function)
145 {
146 return InspectFunction(function);
147 }
148
149 //------------------------------------------------------------------
150 /// Instrument all the instructions found by Inspect()
151 ///
152 /// @return
153 /// True on success; false on error.
154 //------------------------------------------------------------------
155 bool Instrument ()
156 {
157 for (InstIterator ii = m_to_instrument.begin(), last_ii = m_to_instrument.end();
158 ii != last_ii;
159 ++ii)
160 {
161 if (!InstrumentInstruction(*ii))
162 return false;
163 }
164
165 return true;
166 }
167protected:
168 //------------------------------------------------------------------
169 /// Add instrumentation to a single instruction
170 ///
171 /// @param[in] inst
172 /// The instruction to be instrumented.
173 ///
174 /// @return
175 /// True on success; false otherwise.
176 //------------------------------------------------------------------
177 virtual bool InstrumentInstruction(llvm::Instruction *inst) = 0;
178
179 //------------------------------------------------------------------
180 /// Register a single instruction to be instrumented
181 ///
182 /// @param[in] inst
183 /// The instruction to be instrumented.
184 //------------------------------------------------------------------
185 void RegisterInstruction(llvm::Instruction &i)
186 {
187 m_to_instrument.push_back(&i);
188 }
189
190 //------------------------------------------------------------------
191 /// Determine whether a single instruction is interesting to
192 /// instrument, and, if so, call RegisterInstruction
193 ///
194 /// @param[in] i
195 /// The instruction to be inspected.
196 ///
197 /// @return
198 /// False if there was an error scanning; true otherwise.
199 //------------------------------------------------------------------
200 virtual bool InspectInstruction(llvm::Instruction &i)
201 {
202 return true;
203 }
204
205 //------------------------------------------------------------------
206 /// Scan a basic block to see if any instructions are interesting
207 ///
208 /// @param[in] bb
209 /// The basic block to be inspected.
210 ///
211 /// @return
212 /// False if there was an error scanning; true otherwise.
213 //------------------------------------------------------------------
214 virtual bool InspectBasicBlock(llvm::BasicBlock &bb)
215 {
216 for (llvm::BasicBlock::iterator ii = bb.begin(), last_ii = bb.end();
217 ii != last_ii;
218 ++ii)
219 {
220 if (!InspectInstruction(*ii))
221 return false;
222 }
223
224 return true;
225 }
226
227 //------------------------------------------------------------------
228 /// Scan a function to see if any instructions are interesting
229 ///
230 /// @param[in] f
231 /// The function to be inspected.
232 ///
233 /// @return
234 /// False if there was an error scanning; true otherwise.
235 //------------------------------------------------------------------
236 virtual bool InspectFunction(llvm::Function &f)
237 {
238 for (llvm::Function::iterator bbi = f.begin(), last_bbi = f.end();
239 bbi != last_bbi;
240 ++bbi)
241 {
242 if (!InspectBasicBlock(*bbi))
243 return false;
244 }
245
246 return true;
247 }
248
Sean Callanane8a59a82010-09-13 21:34:21 +0000249 //------------------------------------------------------------------
250 /// Build a function pointer for a function with signature
251 /// void (*)(uint8_t*) with a given address
252 ///
253 /// @param[in] start_address
254 /// The address of the function.
255 ///
256 /// @return
257 /// The function pointer, for use in a CallInst.
258 //------------------------------------------------------------------
259 llvm::Value *BuildPointerValidatorFunc(lldb::addr_t start_address)
260 {
261 std::vector<const llvm::Type*> params;
262
263 const IntegerType *intptr_ty = llvm::Type::getIntNTy(m_module.getContext(),
264 (m_module.getPointerSize() == llvm::Module::Pointer64) ? 64 : 32);
265
Sean Callanan14a97ff2010-11-04 01:51:38 +0000266 params.push_back(GetI8PtrTy());
Sean Callanane8a59a82010-09-13 21:34:21 +0000267
268 FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true);
269 PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
270 Constant *fun_addr_int = ConstantInt::get(intptr_ty, start_address, false);
271 return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
272 }
273
Sean Callanan14a97ff2010-11-04 01:51:38 +0000274 const PointerType *GetI8PtrTy()
275 {
276 if (!m_i8ptr_ty)
277 m_i8ptr_ty = llvm::Type::getInt8PtrTy(m_module.getContext());
278
279 return m_i8ptr_ty;
280 }
281
Sean Callanan05262332010-09-02 00:37:32 +0000282 typedef std::vector <llvm::Instruction *> InstVector;
283 typedef InstVector::iterator InstIterator;
284
285 InstVector m_to_instrument; ///< List of instructions the inspector found
286 llvm::Module &m_module; ///< The module which is being instrumented
287 DynamicCheckerFunctions &m_checker_functions; ///< The dynamic checker functions for the process
Sean Callanan14a97ff2010-11-04 01:51:38 +0000288private:
Sean Callanane8a59a82010-09-13 21:34:21 +0000289 const PointerType *m_i8ptr_ty;
Sean Callanan05262332010-09-02 00:37:32 +0000290};
291
292class ValidPointerChecker : public Instrumenter
293{
294public:
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000295 ValidPointerChecker (llvm::Module &module,
296 DynamicCheckerFunctions &checker_functions) :
Sean Callanan05262332010-09-02 00:37:32 +0000297 Instrumenter(module, checker_functions),
298 m_valid_pointer_check_func(NULL)
299 {
300 }
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000301
302 virtual ~ValidPointerChecker ()
303 {
304 }
Sean Callanan05262332010-09-02 00:37:32 +0000305private:
306 bool InstrumentInstruction(llvm::Instruction *inst)
307 {
Greg Claytone005f2c2010-11-06 01:53:30 +0000308 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan05262332010-09-02 00:37:32 +0000309
310 if(log)
311 log->Printf("Instrumenting load/store instruction: %s\n",
312 PrintValue(inst).c_str());
313
314 if (!m_valid_pointer_check_func)
Sean Callanane8a59a82010-09-13 21:34:21 +0000315 m_valid_pointer_check_func = BuildPointerValidatorFunc(m_checker_functions.m_valid_pointer_check->StartAddress());
Sean Callanan05262332010-09-02 00:37:32 +0000316
Sean Callanan58baaad2011-07-08 00:39:14 +0000317 llvm::Value *dereferenced_ptr = NULL;
Sean Callanan05262332010-09-02 00:37:32 +0000318
319 if (llvm::LoadInst *li = dyn_cast<llvm::LoadInst> (inst))
320 dereferenced_ptr = li->getPointerOperand();
321 else if (llvm::StoreInst *si = dyn_cast<llvm::StoreInst> (inst))
322 dereferenced_ptr = si->getPointerOperand();
323 else
324 return false;
325
326 // Insert an instruction to cast the loaded value to int8_t*
327
328 BitCastInst *bit_cast = new BitCastInst(dereferenced_ptr,
Sean Callanan14a97ff2010-11-04 01:51:38 +0000329 GetI8PtrTy(),
Sean Callanan05262332010-09-02 00:37:32 +0000330 "",
331 inst);
332
333 // Insert an instruction to call the helper with the result
334
335 SmallVector <llvm::Value*, 1> args;
336 args.push_back(bit_cast);
337
338 CallInst::Create(m_valid_pointer_check_func,
339 args.begin(),
340 args.end(),
341 "",
342 inst);
343
344 return true;
345 }
346
347 bool InspectInstruction(llvm::Instruction &i)
348 {
349 if (dyn_cast<llvm::LoadInst> (&i) ||
350 dyn_cast<llvm::StoreInst> (&i))
351 RegisterInstruction(i);
352
353 return true;
354 }
355
356 llvm::Value *m_valid_pointer_check_func;
Sean Callanane8a59a82010-09-13 21:34:21 +0000357};
358
359class ObjcObjectChecker : public Instrumenter
360{
361public:
362 ObjcObjectChecker(llvm::Module &module,
363 DynamicCheckerFunctions &checker_functions) :
364 Instrumenter(module, checker_functions),
365 m_objc_object_check_func(NULL)
366 {
367 }
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000368
369 virtual
370 ~ObjcObjectChecker ()
371 {
372 }
373
Sean Callanane8a59a82010-09-13 21:34:21 +0000374private:
375 bool InstrumentInstruction(llvm::Instruction *inst)
376 {
377 CallInst *call_inst = dyn_cast<CallInst>(inst);
378
379 if (!call_inst)
Sean Callanan14a97ff2010-11-04 01:51:38 +0000380 return false; // call_inst really shouldn't be NULL, because otherwise InspectInstruction wouldn't have registered it
Sean Callanane8a59a82010-09-13 21:34:21 +0000381
382 if (!m_objc_object_check_func)
383 m_objc_object_check_func = BuildPointerValidatorFunc(m_checker_functions.m_objc_object_check->StartAddress());
384
Sean Callanan58baaad2011-07-08 00:39:14 +0000385 llvm::Value *target_object = NULL;
Sean Callanane8a59a82010-09-13 21:34:21 +0000386
387 // id objc_msgSend(id theReceiver, SEL theSelector, ...)
388
389 target_object = call_inst->getArgOperand(0);
390
391 // Insert an instruction to cast the receiver id to int8_t*
392
393 BitCastInst *bit_cast = new BitCastInst(target_object,
Sean Callanan14a97ff2010-11-04 01:51:38 +0000394 GetI8PtrTy(),
Sean Callanane8a59a82010-09-13 21:34:21 +0000395 "",
396 inst);
397
398 // Insert an instruction to call the helper with the result
399
400 SmallVector <llvm::Value*, 1> args;
401 args.push_back(bit_cast);
402
403 CallInst::Create(m_objc_object_check_func,
404 args.begin(),
405 args.end(),
406 "",
407 inst);
408
409 return true;
410 }
411
412 bool InspectInstruction(llvm::Instruction &i)
413 {
Greg Claytone005f2c2010-11-06 01:53:30 +0000414 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanane8a59a82010-09-13 21:34:21 +0000415
416 CallInst *call_inst = dyn_cast<CallInst>(&i);
417
418 if (call_inst)
419 {
420 // This metadata is set by IRForTarget::MaybeHandleCall().
421
422 MDNode *metadata = call_inst->getMetadata("lldb.call.realName");
423
424 if (!metadata)
425 return true;
426
427 if (metadata->getNumOperands() != 1)
428 {
429 if (log)
430 log->Printf("Function call metadata has %d operands for [%p] %s", metadata->getNumOperands(), call_inst, PrintValue(call_inst).c_str());
431 return false;
432 }
433
434 ConstantArray *real_name = dyn_cast<ConstantArray>(metadata->getOperand(0));
435
436 if (!real_name)
437 {
438 if (log)
439 log->Printf("Function call metadata is not a ConstantArray for [%p] %s", call_inst, PrintValue(call_inst).c_str());
440 return false;
441 }
442
443 if (!real_name->isString())
444 {
445 if (log)
446 log->Printf("Function call metadata is not a string for [%p] %s", call_inst, PrintValue(call_inst).c_str());
447 return false;
448 }
449
450 if (log)
451 log->Printf("Found call to %s: %s\n", real_name->getAsString().c_str(), PrintValue(call_inst).c_str());
452
453 if (real_name->getAsString().find("objc_msgSend") != std::string::npos)
454 RegisterInstruction(i);
455 }
456
457 return true;
458 }
459
460 llvm::Value *m_objc_object_check_func;
Sean Callanan05262332010-09-02 00:37:32 +0000461};
462
463IRDynamicChecks::IRDynamicChecks(DynamicCheckerFunctions &checker_functions,
464 const char *func_name) :
Sean Callanan47a5c4c2010-09-23 03:01:22 +0000465 ModulePass(ID),
Stephen Wilsondbeb3e12011-04-11 19:41:40 +0000466 m_func_name(func_name),
467 m_checker_functions(checker_functions)
Sean Callanan05262332010-09-02 00:37:32 +0000468{
469}
470
Sean Callananf18d91c2010-09-01 00:58:00 +0000471IRDynamicChecks::~IRDynamicChecks()
472{
473}
474
475bool
476IRDynamicChecks::runOnModule(llvm::Module &M)
477{
Greg Claytone005f2c2010-11-06 01:53:30 +0000478 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callananf18d91c2010-09-01 00:58:00 +0000479
480 llvm::Function* function = M.getFunction(StringRef(m_func_name.c_str()));
481
482 if (!function)
483 {
484 if (log)
485 log->Printf("Couldn't find %s() in the module", m_func_name.c_str());
486
487 return false;
488 }
Sean Callanan05262332010-09-02 00:37:32 +0000489
490 ValidPointerChecker vpc(M, m_checker_functions);
Sean Callananf18d91c2010-09-01 00:58:00 +0000491
Sean Callanan05262332010-09-02 00:37:32 +0000492 if (!vpc.Inspect(*function))
493 return false;
Sean Callananf18d91c2010-09-01 00:58:00 +0000494
Sean Callanan05262332010-09-02 00:37:32 +0000495 if (!vpc.Instrument())
496 return false;
Sean Callananf18d91c2010-09-01 00:58:00 +0000497
Sean Callanane8a59a82010-09-13 21:34:21 +0000498 ObjcObjectChecker ooc(M, m_checker_functions);
499
500 if (!ooc.Inspect(*function))
501 return false;
502
503 if (!ooc.Instrument())
504 return false;
Jim Inghambbce7122011-01-22 01:25:40 +0000505
506 if (log && log->GetVerbose())
Sean Callanan65af7342010-09-08 20:04:08 +0000507 {
508 std::string s;
509 raw_string_ostream oss(s);
510
511 M.print(oss, NULL);
512
513 oss.flush();
514
Jim Inghambbce7122011-01-22 01:25:40 +0000515 log->Printf ("Module after dynamic checks: \n%s", s.c_str());
Sean Callanan65af7342010-09-08 20:04:08 +0000516 }
517
Sean Callananf18d91c2010-09-01 00:58:00 +0000518 return true;
519}
520
521void
522IRDynamicChecks::assignPassManager(PMStack &PMS,
523 PassManagerType T)
524{
525}
526
527PassManagerType
528IRDynamicChecks::getPotentialPassManagerType() const
529{
530 return PMT_ModulePassManager;
531}