blob: 22624eaf6137e8dfcfdf39ec3c6b7368f03a411a [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 {
Sean Callanan9b6898f2011-07-30 02:42:06 +0000261 IntegerType *intptr_ty = llvm::Type::getIntNTy(m_module.getContext(),
Sean Callanane8a59a82010-09-13 21:34:21 +0000262 (m_module.getPointerSize() == llvm::Module::Pointer64) ? 64 : 32);
263
Sean Callanan9b6898f2011-07-30 02:42:06 +0000264 llvm::Type *param_array[1];
265
266 param_array[0] = const_cast<llvm::PointerType*>(GetI8PtrTy());
267
268 ArrayRef<llvm::Type*> params(param_array, 1);
Sean Callanane8a59a82010-09-13 21:34:21 +0000269
270 FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true);
271 PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
272 Constant *fun_addr_int = ConstantInt::get(intptr_ty, start_address, false);
273 return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
274 }
275
Sean Callanan9b6898f2011-07-30 02:42:06 +0000276 PointerType *GetI8PtrTy()
Sean Callanan14a97ff2010-11-04 01:51:38 +0000277 {
278 if (!m_i8ptr_ty)
279 m_i8ptr_ty = llvm::Type::getInt8PtrTy(m_module.getContext());
280
281 return m_i8ptr_ty;
282 }
283
Sean Callanan05262332010-09-02 00:37:32 +0000284 typedef std::vector <llvm::Instruction *> InstVector;
285 typedef InstVector::iterator InstIterator;
286
287 InstVector m_to_instrument; ///< List of instructions the inspector found
288 llvm::Module &m_module; ///< The module which is being instrumented
289 DynamicCheckerFunctions &m_checker_functions; ///< The dynamic checker functions for the process
Sean Callanan14a97ff2010-11-04 01:51:38 +0000290private:
Sean Callanan9b6898f2011-07-30 02:42:06 +0000291 PointerType *m_i8ptr_ty;
Sean Callanan05262332010-09-02 00:37:32 +0000292};
293
294class ValidPointerChecker : public Instrumenter
295{
296public:
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000297 ValidPointerChecker (llvm::Module &module,
298 DynamicCheckerFunctions &checker_functions) :
Sean Callanan05262332010-09-02 00:37:32 +0000299 Instrumenter(module, checker_functions),
300 m_valid_pointer_check_func(NULL)
301 {
302 }
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000303
304 virtual ~ValidPointerChecker ()
305 {
306 }
Sean Callanan05262332010-09-02 00:37:32 +0000307private:
308 bool InstrumentInstruction(llvm::Instruction *inst)
309 {
Greg Claytone005f2c2010-11-06 01:53:30 +0000310 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan05262332010-09-02 00:37:32 +0000311
Enrico Granata4c3fb4b2011-07-19 18:03:25 +0000312 if (log)
Sean Callanan05262332010-09-02 00:37:32 +0000313 log->Printf("Instrumenting load/store instruction: %s\n",
314 PrintValue(inst).c_str());
315
316 if (!m_valid_pointer_check_func)
Sean Callanane8a59a82010-09-13 21:34:21 +0000317 m_valid_pointer_check_func = BuildPointerValidatorFunc(m_checker_functions.m_valid_pointer_check->StartAddress());
Sean Callanan05262332010-09-02 00:37:32 +0000318
Sean Callanan58baaad2011-07-08 00:39:14 +0000319 llvm::Value *dereferenced_ptr = NULL;
Sean Callanan05262332010-09-02 00:37:32 +0000320
321 if (llvm::LoadInst *li = dyn_cast<llvm::LoadInst> (inst))
322 dereferenced_ptr = li->getPointerOperand();
323 else if (llvm::StoreInst *si = dyn_cast<llvm::StoreInst> (inst))
324 dereferenced_ptr = si->getPointerOperand();
325 else
326 return false;
327
328 // Insert an instruction to cast the loaded value to int8_t*
329
330 BitCastInst *bit_cast = new BitCastInst(dereferenced_ptr,
Sean Callanan14a97ff2010-11-04 01:51:38 +0000331 GetI8PtrTy(),
Sean Callanan05262332010-09-02 00:37:32 +0000332 "",
333 inst);
334
335 // Insert an instruction to call the helper with the result
336
Sean Callanan9b6898f2011-07-30 02:42:06 +0000337 llvm::Value *arg_array[1];
338
339 arg_array[0] = bit_cast;
340
341 llvm::ArrayRef<llvm::Value *> args(arg_array, 1);
Sean Callanan05262332010-09-02 00:37:32 +0000342
343 CallInst::Create(m_valid_pointer_check_func,
Sean Callanan9b6898f2011-07-30 02:42:06 +0000344 args,
Sean Callanan05262332010-09-02 00:37:32 +0000345 "",
346 inst);
347
348 return true;
349 }
350
351 bool InspectInstruction(llvm::Instruction &i)
352 {
353 if (dyn_cast<llvm::LoadInst> (&i) ||
354 dyn_cast<llvm::StoreInst> (&i))
355 RegisterInstruction(i);
356
357 return true;
358 }
359
360 llvm::Value *m_valid_pointer_check_func;
Sean Callanane8a59a82010-09-13 21:34:21 +0000361};
362
363class ObjcObjectChecker : public Instrumenter
364{
365public:
366 ObjcObjectChecker(llvm::Module &module,
367 DynamicCheckerFunctions &checker_functions) :
368 Instrumenter(module, checker_functions),
369 m_objc_object_check_func(NULL)
370 {
371 }
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000372
373 virtual
374 ~ObjcObjectChecker ()
375 {
376 }
377
Sean Callanane8a59a82010-09-13 21:34:21 +0000378private:
379 bool InstrumentInstruction(llvm::Instruction *inst)
380 {
381 CallInst *call_inst = dyn_cast<CallInst>(inst);
382
383 if (!call_inst)
Sean Callanan14a97ff2010-11-04 01:51:38 +0000384 return false; // call_inst really shouldn't be NULL, because otherwise InspectInstruction wouldn't have registered it
Sean Callanane8a59a82010-09-13 21:34:21 +0000385
386 if (!m_objc_object_check_func)
387 m_objc_object_check_func = BuildPointerValidatorFunc(m_checker_functions.m_objc_object_check->StartAddress());
388
Sean Callanan58baaad2011-07-08 00:39:14 +0000389 llvm::Value *target_object = NULL;
Sean Callanane8a59a82010-09-13 21:34:21 +0000390
391 // id objc_msgSend(id theReceiver, SEL theSelector, ...)
392
393 target_object = call_inst->getArgOperand(0);
394
395 // Insert an instruction to cast the receiver id to int8_t*
396
397 BitCastInst *bit_cast = new BitCastInst(target_object,
Sean Callanan14a97ff2010-11-04 01:51:38 +0000398 GetI8PtrTy(),
Sean Callanane8a59a82010-09-13 21:34:21 +0000399 "",
400 inst);
401
402 // Insert an instruction to call the helper with the result
403
Sean Callanan9b6898f2011-07-30 02:42:06 +0000404 llvm::Value *arg_array[1];
405
406 arg_array[0] = bit_cast;
407
408 ArrayRef<llvm::Value*> args(arg_array, 1);
Sean Callanane8a59a82010-09-13 21:34:21 +0000409
410 CallInst::Create(m_objc_object_check_func,
Sean Callanan9b6898f2011-07-30 02:42:06 +0000411 args,
Sean Callanane8a59a82010-09-13 21:34:21 +0000412 "",
413 inst);
414
415 return true;
416 }
417
418 bool InspectInstruction(llvm::Instruction &i)
419 {
Greg Claytone005f2c2010-11-06 01:53:30 +0000420 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanane8a59a82010-09-13 21:34:21 +0000421
422 CallInst *call_inst = dyn_cast<CallInst>(&i);
423
424 if (call_inst)
425 {
426 // This metadata is set by IRForTarget::MaybeHandleCall().
427
428 MDNode *metadata = call_inst->getMetadata("lldb.call.realName");
429
430 if (!metadata)
431 return true;
432
433 if (metadata->getNumOperands() != 1)
434 {
435 if (log)
436 log->Printf("Function call metadata has %d operands for [%p] %s", metadata->getNumOperands(), call_inst, PrintValue(call_inst).c_str());
437 return false;
438 }
439
440 ConstantArray *real_name = dyn_cast<ConstantArray>(metadata->getOperand(0));
441
442 if (!real_name)
443 {
444 if (log)
445 log->Printf("Function call metadata is not a ConstantArray for [%p] %s", call_inst, PrintValue(call_inst).c_str());
446 return false;
447 }
448
449 if (!real_name->isString())
450 {
451 if (log)
452 log->Printf("Function call metadata is not a string for [%p] %s", call_inst, PrintValue(call_inst).c_str());
453 return false;
454 }
455
456 if (log)
457 log->Printf("Found call to %s: %s\n", real_name->getAsString().c_str(), PrintValue(call_inst).c_str());
458
459 if (real_name->getAsString().find("objc_msgSend") != std::string::npos)
460 RegisterInstruction(i);
461 }
462
463 return true;
464 }
465
466 llvm::Value *m_objc_object_check_func;
Sean Callanan05262332010-09-02 00:37:32 +0000467};
468
469IRDynamicChecks::IRDynamicChecks(DynamicCheckerFunctions &checker_functions,
470 const char *func_name) :
Sean Callanan47a5c4c2010-09-23 03:01:22 +0000471 ModulePass(ID),
Stephen Wilsondbeb3e12011-04-11 19:41:40 +0000472 m_func_name(func_name),
473 m_checker_functions(checker_functions)
Sean Callanan05262332010-09-02 00:37:32 +0000474{
475}
476
Sean Callananf18d91c2010-09-01 00:58:00 +0000477IRDynamicChecks::~IRDynamicChecks()
478{
479}
480
481bool
482IRDynamicChecks::runOnModule(llvm::Module &M)
483{
Greg Claytone005f2c2010-11-06 01:53:30 +0000484 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callananf18d91c2010-09-01 00:58:00 +0000485
486 llvm::Function* function = M.getFunction(StringRef(m_func_name.c_str()));
487
488 if (!function)
489 {
490 if (log)
491 log->Printf("Couldn't find %s() in the module", m_func_name.c_str());
492
493 return false;
494 }
Sean Callanan05262332010-09-02 00:37:32 +0000495
496 ValidPointerChecker vpc(M, m_checker_functions);
Sean Callananf18d91c2010-09-01 00:58:00 +0000497
Sean Callanan05262332010-09-02 00:37:32 +0000498 if (!vpc.Inspect(*function))
499 return false;
Sean Callananf18d91c2010-09-01 00:58:00 +0000500
Sean Callanan05262332010-09-02 00:37:32 +0000501 if (!vpc.Instrument())
502 return false;
Sean Callananf18d91c2010-09-01 00:58:00 +0000503
Sean Callanane8a59a82010-09-13 21:34:21 +0000504 ObjcObjectChecker ooc(M, m_checker_functions);
505
506 if (!ooc.Inspect(*function))
507 return false;
508
509 if (!ooc.Instrument())
510 return false;
Jim Inghambbce7122011-01-22 01:25:40 +0000511
512 if (log && log->GetVerbose())
Sean Callanan65af7342010-09-08 20:04:08 +0000513 {
514 std::string s;
515 raw_string_ostream oss(s);
516
517 M.print(oss, NULL);
518
519 oss.flush();
520
Jim Inghambbce7122011-01-22 01:25:40 +0000521 log->Printf ("Module after dynamic checks: \n%s", s.c_str());
Sean Callanan65af7342010-09-08 20:04:08 +0000522 }
523
Sean Callananf18d91c2010-09-01 00:58:00 +0000524 return true;
525}
526
527void
528IRDynamicChecks::assignPassManager(PMStack &PMS,
529 PassManagerType T)
530{
531}
532
533PassManagerType
534IRDynamicChecks::getPotentialPassManagerType() const
535{
536 return PMT_ModulePassManager;
537}