blob: a84fe8e7b5232bf7691026d93a5a67d74c41fdbd [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
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000130 virtual~Instrumenter ()
131 {
132 }
133
Sean Callanan05262332010-09-02 00:37:32 +0000134 //------------------------------------------------------------------
135 /// Inspect a function to find instructions to instrument
136 ///
137 /// @param[in] function
138 /// The function to inspect.
139 ///
140 /// @return
141 /// True on success; false on error.
142 //------------------------------------------------------------------
143 bool Inspect (llvm::Function &function)
144 {
145 return InspectFunction(function);
146 }
147
148 //------------------------------------------------------------------
149 /// Instrument all the instructions found by Inspect()
150 ///
151 /// @return
152 /// True on success; false on error.
153 //------------------------------------------------------------------
154 bool Instrument ()
155 {
156 for (InstIterator ii = m_to_instrument.begin(), last_ii = m_to_instrument.end();
157 ii != last_ii;
158 ++ii)
159 {
160 if (!InstrumentInstruction(*ii))
161 return false;
162 }
163
164 return true;
165 }
166protected:
167 //------------------------------------------------------------------
168 /// Add instrumentation to a single instruction
169 ///
170 /// @param[in] inst
171 /// The instruction to be instrumented.
172 ///
173 /// @return
174 /// True on success; false otherwise.
175 //------------------------------------------------------------------
176 virtual bool InstrumentInstruction(llvm::Instruction *inst) = 0;
177
178 //------------------------------------------------------------------
179 /// Register a single instruction to be instrumented
180 ///
181 /// @param[in] inst
182 /// The instruction to be instrumented.
183 //------------------------------------------------------------------
184 void RegisterInstruction(llvm::Instruction &i)
185 {
186 m_to_instrument.push_back(&i);
187 }
188
189 //------------------------------------------------------------------
190 /// Determine whether a single instruction is interesting to
191 /// instrument, and, if so, call RegisterInstruction
192 ///
193 /// @param[in] i
194 /// The instruction to be inspected.
195 ///
196 /// @return
197 /// False if there was an error scanning; true otherwise.
198 //------------------------------------------------------------------
199 virtual bool InspectInstruction(llvm::Instruction &i)
200 {
201 return true;
202 }
203
204 //------------------------------------------------------------------
205 /// Scan a basic block to see if any instructions are interesting
206 ///
207 /// @param[in] bb
208 /// The basic block to be inspected.
209 ///
210 /// @return
211 /// False if there was an error scanning; true otherwise.
212 //------------------------------------------------------------------
213 virtual bool InspectBasicBlock(llvm::BasicBlock &bb)
214 {
215 for (llvm::BasicBlock::iterator ii = bb.begin(), last_ii = bb.end();
216 ii != last_ii;
217 ++ii)
218 {
219 if (!InspectInstruction(*ii))
220 return false;
221 }
222
223 return true;
224 }
225
226 //------------------------------------------------------------------
227 /// Scan a function to see if any instructions are interesting
228 ///
229 /// @param[in] f
230 /// The function to be inspected.
231 ///
232 /// @return
233 /// False if there was an error scanning; true otherwise.
234 //------------------------------------------------------------------
235 virtual bool InspectFunction(llvm::Function &f)
236 {
237 for (llvm::Function::iterator bbi = f.begin(), last_bbi = f.end();
238 bbi != last_bbi;
239 ++bbi)
240 {
241 if (!InspectBasicBlock(*bbi))
242 return false;
243 }
244
245 return true;
246 }
247
Sean Callanane8a59a82010-09-13 21:34:21 +0000248 //------------------------------------------------------------------
249 /// Build a function pointer for a function with signature
250 /// void (*)(uint8_t*) with a given address
251 ///
252 /// @param[in] start_address
253 /// The address of the function.
254 ///
255 /// @return
256 /// The function pointer, for use in a CallInst.
257 //------------------------------------------------------------------
258 llvm::Value *BuildPointerValidatorFunc(lldb::addr_t start_address)
259 {
260 std::vector<const llvm::Type*> params;
261
262 const IntegerType *intptr_ty = llvm::Type::getIntNTy(m_module.getContext(),
263 (m_module.getPointerSize() == llvm::Module::Pointer64) ? 64 : 32);
264
Sean Callanan14a97ff2010-11-04 01:51:38 +0000265 params.push_back(GetI8PtrTy());
Sean Callanane8a59a82010-09-13 21:34:21 +0000266
267 FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true);
268 PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
269 Constant *fun_addr_int = ConstantInt::get(intptr_ty, start_address, false);
270 return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
271 }
272
Sean Callanan14a97ff2010-11-04 01:51:38 +0000273 const PointerType *GetI8PtrTy()
274 {
275 if (!m_i8ptr_ty)
276 m_i8ptr_ty = llvm::Type::getInt8PtrTy(m_module.getContext());
277
278 return m_i8ptr_ty;
279 }
280
Sean Callanan05262332010-09-02 00:37:32 +0000281 typedef std::vector <llvm::Instruction *> InstVector;
282 typedef InstVector::iterator InstIterator;
283
284 InstVector m_to_instrument; ///< List of instructions the inspector found
285 llvm::Module &m_module; ///< The module which is being instrumented
286 DynamicCheckerFunctions &m_checker_functions; ///< The dynamic checker functions for the process
Sean Callanan14a97ff2010-11-04 01:51:38 +0000287private:
Sean Callanane8a59a82010-09-13 21:34:21 +0000288 const PointerType *m_i8ptr_ty;
Sean Callanan05262332010-09-02 00:37:32 +0000289};
290
291class ValidPointerChecker : public Instrumenter
292{
293public:
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000294 ValidPointerChecker (llvm::Module &module,
295 DynamicCheckerFunctions &checker_functions) :
Sean Callanan05262332010-09-02 00:37:32 +0000296 Instrumenter(module, checker_functions),
297 m_valid_pointer_check_func(NULL)
298 {
299 }
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000300
301 virtual ~ValidPointerChecker ()
302 {
303 }
Sean Callanan05262332010-09-02 00:37:32 +0000304private:
305 bool InstrumentInstruction(llvm::Instruction *inst)
306 {
Greg Claytone005f2c2010-11-06 01:53:30 +0000307 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan05262332010-09-02 00:37:32 +0000308
309 if(log)
310 log->Printf("Instrumenting load/store instruction: %s\n",
311 PrintValue(inst).c_str());
312
313 if (!m_valid_pointer_check_func)
Sean Callanane8a59a82010-09-13 21:34:21 +0000314 m_valid_pointer_check_func = BuildPointerValidatorFunc(m_checker_functions.m_valid_pointer_check->StartAddress());
Sean Callanan05262332010-09-02 00:37:32 +0000315
316 llvm::Value *dereferenced_ptr;
317
318 if (llvm::LoadInst *li = dyn_cast<llvm::LoadInst> (inst))
319 dereferenced_ptr = li->getPointerOperand();
320 else if (llvm::StoreInst *si = dyn_cast<llvm::StoreInst> (inst))
321 dereferenced_ptr = si->getPointerOperand();
322 else
323 return false;
324
325 // Insert an instruction to cast the loaded value to int8_t*
326
327 BitCastInst *bit_cast = new BitCastInst(dereferenced_ptr,
Sean Callanan14a97ff2010-11-04 01:51:38 +0000328 GetI8PtrTy(),
Sean Callanan05262332010-09-02 00:37:32 +0000329 "",
330 inst);
331
332 // Insert an instruction to call the helper with the result
333
334 SmallVector <llvm::Value*, 1> args;
335 args.push_back(bit_cast);
336
337 CallInst::Create(m_valid_pointer_check_func,
338 args.begin(),
339 args.end(),
340 "",
341 inst);
342
343 return true;
344 }
345
346 bool InspectInstruction(llvm::Instruction &i)
347 {
348 if (dyn_cast<llvm::LoadInst> (&i) ||
349 dyn_cast<llvm::StoreInst> (&i))
350 RegisterInstruction(i);
351
352 return true;
353 }
354
355 llvm::Value *m_valid_pointer_check_func;
Sean Callanane8a59a82010-09-13 21:34:21 +0000356};
357
358class ObjcObjectChecker : public Instrumenter
359{
360public:
361 ObjcObjectChecker(llvm::Module &module,
362 DynamicCheckerFunctions &checker_functions) :
363 Instrumenter(module, checker_functions),
364 m_objc_object_check_func(NULL)
365 {
366 }
Greg Claytonbdcb6ab2011-01-25 23:55:37 +0000367
368 virtual
369 ~ObjcObjectChecker ()
370 {
371 }
372
Sean Callanane8a59a82010-09-13 21:34:21 +0000373private:
374 bool InstrumentInstruction(llvm::Instruction *inst)
375 {
376 CallInst *call_inst = dyn_cast<CallInst>(inst);
377
378 if (!call_inst)
Sean Callanan14a97ff2010-11-04 01:51:38 +0000379 return false; // call_inst really shouldn't be NULL, because otherwise InspectInstruction wouldn't have registered it
Sean Callanane8a59a82010-09-13 21:34:21 +0000380
381 if (!m_objc_object_check_func)
382 m_objc_object_check_func = BuildPointerValidatorFunc(m_checker_functions.m_objc_object_check->StartAddress());
383
384 llvm::Value *target_object;
385
386 // id objc_msgSend(id theReceiver, SEL theSelector, ...)
387
388 target_object = call_inst->getArgOperand(0);
389
390 // Insert an instruction to cast the receiver id to int8_t*
391
392 BitCastInst *bit_cast = new BitCastInst(target_object,
Sean Callanan14a97ff2010-11-04 01:51:38 +0000393 GetI8PtrTy(),
Sean Callanane8a59a82010-09-13 21:34:21 +0000394 "",
395 inst);
396
397 // Insert an instruction to call the helper with the result
398
399 SmallVector <llvm::Value*, 1> args;
400 args.push_back(bit_cast);
401
402 CallInst::Create(m_objc_object_check_func,
403 args.begin(),
404 args.end(),
405 "",
406 inst);
407
408 return true;
409 }
410
411 bool InspectInstruction(llvm::Instruction &i)
412 {
Greg Claytone005f2c2010-11-06 01:53:30 +0000413 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanane8a59a82010-09-13 21:34:21 +0000414
415 CallInst *call_inst = dyn_cast<CallInst>(&i);
416
417 if (call_inst)
418 {
419 // This metadata is set by IRForTarget::MaybeHandleCall().
420
421 MDNode *metadata = call_inst->getMetadata("lldb.call.realName");
422
423 if (!metadata)
424 return true;
425
426 if (metadata->getNumOperands() != 1)
427 {
428 if (log)
429 log->Printf("Function call metadata has %d operands for [%p] %s", metadata->getNumOperands(), call_inst, PrintValue(call_inst).c_str());
430 return false;
431 }
432
433 ConstantArray *real_name = dyn_cast<ConstantArray>(metadata->getOperand(0));
434
435 if (!real_name)
436 {
437 if (log)
438 log->Printf("Function call metadata is not a ConstantArray for [%p] %s", call_inst, PrintValue(call_inst).c_str());
439 return false;
440 }
441
442 if (!real_name->isString())
443 {
444 if (log)
445 log->Printf("Function call metadata is not a string for [%p] %s", call_inst, PrintValue(call_inst).c_str());
446 return false;
447 }
448
449 if (log)
450 log->Printf("Found call to %s: %s\n", real_name->getAsString().c_str(), PrintValue(call_inst).c_str());
451
452 if (real_name->getAsString().find("objc_msgSend") != std::string::npos)
453 RegisterInstruction(i);
454 }
455
456 return true;
457 }
458
459 llvm::Value *m_objc_object_check_func;
Sean Callanan05262332010-09-02 00:37:32 +0000460};
461
462IRDynamicChecks::IRDynamicChecks(DynamicCheckerFunctions &checker_functions,
463 const char *func_name) :
Sean Callanan47a5c4c2010-09-23 03:01:22 +0000464 ModulePass(ID),
Stephen Wilsondbeb3e12011-04-11 19:41:40 +0000465 m_func_name(func_name),
466 m_checker_functions(checker_functions)
Sean Callanan05262332010-09-02 00:37:32 +0000467{
468}
469
Sean Callananf18d91c2010-09-01 00:58:00 +0000470IRDynamicChecks::~IRDynamicChecks()
471{
472}
473
474bool
475IRDynamicChecks::runOnModule(llvm::Module &M)
476{
Greg Claytone005f2c2010-11-06 01:53:30 +0000477 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callananf18d91c2010-09-01 00:58:00 +0000478
479 llvm::Function* function = M.getFunction(StringRef(m_func_name.c_str()));
480
481 if (!function)
482 {
483 if (log)
484 log->Printf("Couldn't find %s() in the module", m_func_name.c_str());
485
486 return false;
487 }
Sean Callanan05262332010-09-02 00:37:32 +0000488
489 ValidPointerChecker vpc(M, m_checker_functions);
Sean Callananf18d91c2010-09-01 00:58:00 +0000490
Sean Callanan05262332010-09-02 00:37:32 +0000491 if (!vpc.Inspect(*function))
492 return false;
Sean Callananf18d91c2010-09-01 00:58:00 +0000493
Sean Callanan05262332010-09-02 00:37:32 +0000494 if (!vpc.Instrument())
495 return false;
Sean Callananf18d91c2010-09-01 00:58:00 +0000496
Sean Callanane8a59a82010-09-13 21:34:21 +0000497 ObjcObjectChecker ooc(M, m_checker_functions);
498
499 if (!ooc.Inspect(*function))
500 return false;
501
502 if (!ooc.Instrument())
503 return false;
Jim Inghambbce7122011-01-22 01:25:40 +0000504
505 if (log && log->GetVerbose())
Sean Callanan65af7342010-09-08 20:04:08 +0000506 {
507 std::string s;
508 raw_string_ostream oss(s);
509
510 M.print(oss, NULL);
511
512 oss.flush();
513
Jim Inghambbce7122011-01-22 01:25:40 +0000514 log->Printf ("Module after dynamic checks: \n%s", s.c_str());
Sean Callanan65af7342010-09-08 20:04:08 +0000515 }
516
Sean Callananf18d91c2010-09-01 00:58:00 +0000517 return true;
518}
519
520void
521IRDynamicChecks::assignPassManager(PMStack &PMS,
522 PassManagerType T)
523{
524}
525
526PassManagerType
527IRDynamicChecks::getPotentialPassManagerType() const
528{
529 return PMT_ModulePassManager;
530}