blob: f68be96541dc3232f197359c72dc77af473a2658 [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"
21#include "llvm/Function.h"
Sean Callanan05262332010-09-02 00:37:32 +000022#include "llvm/Instructions.h"
Sean Callananf18d91c2010-09-01 00:58:00 +000023#include "llvm/Module.h"
24#include "llvm/Value.h"
25
26using namespace llvm;
27using namespace lldb_private;
28
29static char ID;
30
Greg Clayton8de27c72010-10-15 22:48:33 +000031#define VALID_POINTER_CHECK_NAME "$__lldb_valid_pointer_check"
32#define VALID_OBJC_OBJECT_CHECK_NAME "$__lldb_objc_object_check"
Sean Callanane8a59a82010-09-13 21:34:21 +000033
Greg Clayton8de27c72010-10-15 22:48:33 +000034static const char g_valid_pointer_check_text[] =
35"extern \"C\" void\n"
Greg Clayton21f5fe12010-10-16 21:09:32 +000036"$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n"
Greg Clayton8de27c72010-10-15 22:48:33 +000037"{\n"
Greg Clayton24b48ff2010-10-17 22:03:32 +000038" unsigned char $__lldb_local_val = *$__lldb_arg_ptr;\n"
Greg Clayton8de27c72010-10-15 22:48:33 +000039"}";
Sean Callanane8a59a82010-09-13 21:34:21 +000040
Sean Callananf18d91c2010-09-01 00:58:00 +000041DynamicCheckerFunctions::DynamicCheckerFunctions ()
42{
Sean Callananf18d91c2010-09-01 00:58:00 +000043}
44
45DynamicCheckerFunctions::~DynamicCheckerFunctions ()
46{
47}
48
49bool
50DynamicCheckerFunctions::Install(Stream &error_stream,
51 ExecutionContext &exe_ctx)
52{
Greg Clayton8de27c72010-10-15 22:48:33 +000053 m_valid_pointer_check.reset(new ClangUtilityFunction(g_valid_pointer_check_text,
54 VALID_POINTER_CHECK_NAME));
Sean Callananf18d91c2010-09-01 00:58:00 +000055 if (!m_valid_pointer_check->Install(error_stream, exe_ctx))
56 return false;
Sean Callanan14a97ff2010-11-04 01:51:38 +000057
58 if (exe_ctx.process)
59 {
60 ObjCLanguageRuntime *objc_language_runtime = exe_ctx.process->GetObjCLanguageRuntime();
61
62 if (objc_language_runtime)
63 {
64 m_objc_object_check.reset(objc_language_runtime->CreateObjectChecker(VALID_OBJC_OBJECT_CHECK_NAME));
65
66 if (!m_objc_object_check->Install(error_stream, exe_ctx))
67 return false;
68 }
69 }
Sean Callananf18d91c2010-09-01 00:58:00 +000070
71 return true;
72}
73
Sean Callananf18d91c2010-09-01 00:58:00 +000074static std::string
75PrintValue(llvm::Value *V, bool truncate = false)
76{
77 std::string s;
78 raw_string_ostream rso(s);
79 V->print(rso);
80 rso.flush();
81 if (truncate)
82 s.resize(s.length() - 1);
83 return s;
84}
85
Sean Callanan05262332010-09-02 00:37:32 +000086//----------------------------------------------------------------------
87/// @class Instrumenter IRDynamicChecks.cpp
88/// @brief Finds and instruments individual LLVM IR instructions
89///
90/// When instrumenting LLVM IR, it is frequently desirable to first search
91/// for instructions, and then later modify them. This way iterators
92/// remain intact, and multiple passes can look at the same code base without
93/// treading on each other's toes.
94///
95/// The Instrumenter class implements this functionality. A client first
96/// calls Inspect on a function, which populates a list of instructions to
97/// be instrumented. Then, later, when all passes' Inspect functions have
98/// been called, the client calls Instrument, which adds the desired
99/// instrumentation.
100///
101/// A subclass of Instrumenter must override InstrumentInstruction, which
102/// is responsible for adding whatever instrumentation is necessary.
103///
104/// A subclass of Instrumenter may override:
105///
106/// - InspectInstruction [default: does nothing]
107///
108/// - InspectBasicBlock [default: iterates through the instructions in a
109/// basic block calling InspectInstruction]
110///
111/// - InspectFunction [default: iterates through the basic blocks in a
112/// function calling InspectBasicBlock]
113//----------------------------------------------------------------------
114class Instrumenter {
115public:
116 //------------------------------------------------------------------
117 /// Constructor
118 ///
119 /// @param[in] module
120 /// The module being instrumented.
121 //------------------------------------------------------------------
122 Instrumenter (llvm::Module &module,
123 DynamicCheckerFunctions &checker_functions) :
124 m_module(module),
Sean Callanane8a59a82010-09-13 21:34:21 +0000125 m_checker_functions(checker_functions),
126 m_i8ptr_ty(NULL)
Sean Callanan05262332010-09-02 00:37:32 +0000127 {
128 }
129
130 //------------------------------------------------------------------
131 /// Inspect a function to find instructions to instrument
132 ///
133 /// @param[in] function
134 /// The function to inspect.
135 ///
136 /// @return
137 /// True on success; false on error.
138 //------------------------------------------------------------------
139 bool Inspect (llvm::Function &function)
140 {
141 return InspectFunction(function);
142 }
143
144 //------------------------------------------------------------------
145 /// Instrument all the instructions found by Inspect()
146 ///
147 /// @return
148 /// True on success; false on error.
149 //------------------------------------------------------------------
150 bool Instrument ()
151 {
152 for (InstIterator ii = m_to_instrument.begin(), last_ii = m_to_instrument.end();
153 ii != last_ii;
154 ++ii)
155 {
156 if (!InstrumentInstruction(*ii))
157 return false;
158 }
159
160 return true;
161 }
162protected:
163 //------------------------------------------------------------------
164 /// Add instrumentation to a single instruction
165 ///
166 /// @param[in] inst
167 /// The instruction to be instrumented.
168 ///
169 /// @return
170 /// True on success; false otherwise.
171 //------------------------------------------------------------------
172 virtual bool InstrumentInstruction(llvm::Instruction *inst) = 0;
173
174 //------------------------------------------------------------------
175 /// Register a single instruction to be instrumented
176 ///
177 /// @param[in] inst
178 /// The instruction to be instrumented.
179 //------------------------------------------------------------------
180 void RegisterInstruction(llvm::Instruction &i)
181 {
182 m_to_instrument.push_back(&i);
183 }
184
185 //------------------------------------------------------------------
186 /// Determine whether a single instruction is interesting to
187 /// instrument, and, if so, call RegisterInstruction
188 ///
189 /// @param[in] i
190 /// The instruction to be inspected.
191 ///
192 /// @return
193 /// False if there was an error scanning; true otherwise.
194 //------------------------------------------------------------------
195 virtual bool InspectInstruction(llvm::Instruction &i)
196 {
197 return true;
198 }
199
200 //------------------------------------------------------------------
201 /// Scan a basic block to see if any instructions are interesting
202 ///
203 /// @param[in] bb
204 /// The basic block to be inspected.
205 ///
206 /// @return
207 /// False if there was an error scanning; true otherwise.
208 //------------------------------------------------------------------
209 virtual bool InspectBasicBlock(llvm::BasicBlock &bb)
210 {
211 for (llvm::BasicBlock::iterator ii = bb.begin(), last_ii = bb.end();
212 ii != last_ii;
213 ++ii)
214 {
215 if (!InspectInstruction(*ii))
216 return false;
217 }
218
219 return true;
220 }
221
222 //------------------------------------------------------------------
223 /// Scan a function to see if any instructions are interesting
224 ///
225 /// @param[in] f
226 /// The function to be inspected.
227 ///
228 /// @return
229 /// False if there was an error scanning; true otherwise.
230 //------------------------------------------------------------------
231 virtual bool InspectFunction(llvm::Function &f)
232 {
233 for (llvm::Function::iterator bbi = f.begin(), last_bbi = f.end();
234 bbi != last_bbi;
235 ++bbi)
236 {
237 if (!InspectBasicBlock(*bbi))
238 return false;
239 }
240
241 return true;
242 }
243
Sean Callanane8a59a82010-09-13 21:34:21 +0000244 //------------------------------------------------------------------
245 /// Build a function pointer for a function with signature
246 /// void (*)(uint8_t*) with a given address
247 ///
248 /// @param[in] start_address
249 /// The address of the function.
250 ///
251 /// @return
252 /// The function pointer, for use in a CallInst.
253 //------------------------------------------------------------------
254 llvm::Value *BuildPointerValidatorFunc(lldb::addr_t start_address)
255 {
256 std::vector<const llvm::Type*> params;
257
258 const IntegerType *intptr_ty = llvm::Type::getIntNTy(m_module.getContext(),
259 (m_module.getPointerSize() == llvm::Module::Pointer64) ? 64 : 32);
260
Sean Callanan14a97ff2010-11-04 01:51:38 +0000261 params.push_back(GetI8PtrTy());
Sean Callanane8a59a82010-09-13 21:34:21 +0000262
263 FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true);
264 PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
265 Constant *fun_addr_int = ConstantInt::get(intptr_ty, start_address, false);
266 return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
267 }
268
Sean Callanan14a97ff2010-11-04 01:51:38 +0000269 const PointerType *GetI8PtrTy()
270 {
271 if (!m_i8ptr_ty)
272 m_i8ptr_ty = llvm::Type::getInt8PtrTy(m_module.getContext());
273
274 return m_i8ptr_ty;
275 }
276
Sean Callanan05262332010-09-02 00:37:32 +0000277 typedef std::vector <llvm::Instruction *> InstVector;
278 typedef InstVector::iterator InstIterator;
279
280 InstVector m_to_instrument; ///< List of instructions the inspector found
281 llvm::Module &m_module; ///< The module which is being instrumented
282 DynamicCheckerFunctions &m_checker_functions; ///< The dynamic checker functions for the process
Sean Callanan14a97ff2010-11-04 01:51:38 +0000283private:
Sean Callanane8a59a82010-09-13 21:34:21 +0000284 const PointerType *m_i8ptr_ty;
Sean Callanan05262332010-09-02 00:37:32 +0000285};
286
287class ValidPointerChecker : public Instrumenter
288{
289public:
290 ValidPointerChecker(llvm::Module &module,
291 DynamicCheckerFunctions &checker_functions) :
292 Instrumenter(module, checker_functions),
293 m_valid_pointer_check_func(NULL)
294 {
295 }
296private:
297 bool InstrumentInstruction(llvm::Instruction *inst)
298 {
299 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
300
301 if(log)
302 log->Printf("Instrumenting load/store instruction: %s\n",
303 PrintValue(inst).c_str());
304
305 if (!m_valid_pointer_check_func)
Sean Callanane8a59a82010-09-13 21:34:21 +0000306 m_valid_pointer_check_func = BuildPointerValidatorFunc(m_checker_functions.m_valid_pointer_check->StartAddress());
Sean Callanan05262332010-09-02 00:37:32 +0000307
308 llvm::Value *dereferenced_ptr;
309
310 if (llvm::LoadInst *li = dyn_cast<llvm::LoadInst> (inst))
311 dereferenced_ptr = li->getPointerOperand();
312 else if (llvm::StoreInst *si = dyn_cast<llvm::StoreInst> (inst))
313 dereferenced_ptr = si->getPointerOperand();
314 else
315 return false;
316
317 // Insert an instruction to cast the loaded value to int8_t*
318
319 BitCastInst *bit_cast = new BitCastInst(dereferenced_ptr,
Sean Callanan14a97ff2010-11-04 01:51:38 +0000320 GetI8PtrTy(),
Sean Callanan05262332010-09-02 00:37:32 +0000321 "",
322 inst);
323
324 // Insert an instruction to call the helper with the result
325
326 SmallVector <llvm::Value*, 1> args;
327 args.push_back(bit_cast);
328
329 CallInst::Create(m_valid_pointer_check_func,
330 args.begin(),
331 args.end(),
332 "",
333 inst);
334
335 return true;
336 }
337
338 bool InspectInstruction(llvm::Instruction &i)
339 {
340 if (dyn_cast<llvm::LoadInst> (&i) ||
341 dyn_cast<llvm::StoreInst> (&i))
342 RegisterInstruction(i);
343
344 return true;
345 }
346
347 llvm::Value *m_valid_pointer_check_func;
Sean Callanane8a59a82010-09-13 21:34:21 +0000348};
349
350class ObjcObjectChecker : public Instrumenter
351{
352public:
353 ObjcObjectChecker(llvm::Module &module,
354 DynamicCheckerFunctions &checker_functions) :
355 Instrumenter(module, checker_functions),
356 m_objc_object_check_func(NULL)
357 {
358 }
359private:
360 bool InstrumentInstruction(llvm::Instruction *inst)
361 {
362 CallInst *call_inst = dyn_cast<CallInst>(inst);
363
364 if (!call_inst)
Sean Callanan14a97ff2010-11-04 01:51:38 +0000365 return false; // call_inst really shouldn't be NULL, because otherwise InspectInstruction wouldn't have registered it
Sean Callanane8a59a82010-09-13 21:34:21 +0000366
367 if (!m_objc_object_check_func)
368 m_objc_object_check_func = BuildPointerValidatorFunc(m_checker_functions.m_objc_object_check->StartAddress());
369
370 llvm::Value *target_object;
371
372 // id objc_msgSend(id theReceiver, SEL theSelector, ...)
373
374 target_object = call_inst->getArgOperand(0);
375
376 // Insert an instruction to cast the receiver id to int8_t*
377
378 BitCastInst *bit_cast = new BitCastInst(target_object,
Sean Callanan14a97ff2010-11-04 01:51:38 +0000379 GetI8PtrTy(),
Sean Callanane8a59a82010-09-13 21:34:21 +0000380 "",
381 inst);
382
383 // Insert an instruction to call the helper with the result
384
385 SmallVector <llvm::Value*, 1> args;
386 args.push_back(bit_cast);
387
388 CallInst::Create(m_objc_object_check_func,
389 args.begin(),
390 args.end(),
391 "",
392 inst);
393
394 return true;
395 }
396
397 bool InspectInstruction(llvm::Instruction &i)
398 {
399 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
400
401 CallInst *call_inst = dyn_cast<CallInst>(&i);
402
403 if (call_inst)
404 {
405 // This metadata is set by IRForTarget::MaybeHandleCall().
406
407 MDNode *metadata = call_inst->getMetadata("lldb.call.realName");
408
409 if (!metadata)
410 return true;
411
412 if (metadata->getNumOperands() != 1)
413 {
414 if (log)
415 log->Printf("Function call metadata has %d operands for [%p] %s", metadata->getNumOperands(), call_inst, PrintValue(call_inst).c_str());
416 return false;
417 }
418
419 ConstantArray *real_name = dyn_cast<ConstantArray>(metadata->getOperand(0));
420
421 if (!real_name)
422 {
423 if (log)
424 log->Printf("Function call metadata is not a ConstantArray for [%p] %s", call_inst, PrintValue(call_inst).c_str());
425 return false;
426 }
427
428 if (!real_name->isString())
429 {
430 if (log)
431 log->Printf("Function call metadata is not a string for [%p] %s", call_inst, PrintValue(call_inst).c_str());
432 return false;
433 }
434
435 if (log)
436 log->Printf("Found call to %s: %s\n", real_name->getAsString().c_str(), PrintValue(call_inst).c_str());
437
438 if (real_name->getAsString().find("objc_msgSend") != std::string::npos)
439 RegisterInstruction(i);
440 }
441
442 return true;
443 }
444
445 llvm::Value *m_objc_object_check_func;
Sean Callanan05262332010-09-02 00:37:32 +0000446};
447
448IRDynamicChecks::IRDynamicChecks(DynamicCheckerFunctions &checker_functions,
449 const char *func_name) :
Sean Callanan47a5c4c2010-09-23 03:01:22 +0000450 ModulePass(ID),
Sean Callanan05262332010-09-02 00:37:32 +0000451 m_checker_functions(checker_functions),
452 m_func_name(func_name)
453{
454}
455
Sean Callananf18d91c2010-09-01 00:58:00 +0000456IRDynamicChecks::~IRDynamicChecks()
457{
458}
459
460bool
461IRDynamicChecks::runOnModule(llvm::Module &M)
462{
463 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
464
465 llvm::Function* function = M.getFunction(StringRef(m_func_name.c_str()));
466
467 if (!function)
468 {
469 if (log)
470 log->Printf("Couldn't find %s() in the module", m_func_name.c_str());
471
472 return false;
473 }
Sean Callanan05262332010-09-02 00:37:32 +0000474
475 ValidPointerChecker vpc(M, m_checker_functions);
Sean Callananf18d91c2010-09-01 00:58:00 +0000476
Sean Callanan05262332010-09-02 00:37:32 +0000477 if (!vpc.Inspect(*function))
478 return false;
Sean Callananf18d91c2010-09-01 00:58:00 +0000479
Sean Callanan05262332010-09-02 00:37:32 +0000480 if (!vpc.Instrument())
481 return false;
Sean Callananf18d91c2010-09-01 00:58:00 +0000482
Sean Callanane8a59a82010-09-13 21:34:21 +0000483 ObjcObjectChecker ooc(M, m_checker_functions);
484
485 if (!ooc.Inspect(*function))
486 return false;
487
488 if (!ooc.Instrument())
489 return false;
Sean Callanane8a59a82010-09-13 21:34:21 +0000490
Sean Callanan65af7342010-09-08 20:04:08 +0000491 if (log)
492 {
493 std::string s;
494 raw_string_ostream oss(s);
495
496 M.print(oss, NULL);
497
498 oss.flush();
499
500 log->Printf("Module after dynamic checks: \n%s", s.c_str());
501 }
502
Sean Callananf18d91c2010-09-01 00:58:00 +0000503 return true;
504}
505
506void
507IRDynamicChecks::assignPassManager(PMStack &PMS,
508 PassManagerType T)
509{
510}
511
512PassManagerType
513IRDynamicChecks::getPotentialPassManagerType() const
514{
515 return PMT_ModulePassManager;
516}