blob: 2a21db523a6cade71f4a4ebebfd341a78539009b [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"
16#include "lldb/Target/StackFrame.h"
Sean Callananf18d91c2010-09-01 00:58:00 +000017
18#include "llvm/Support/raw_ostream.h"
19#include "llvm/Function.h"
Sean Callanan05262332010-09-02 00:37:32 +000020#include "llvm/Instructions.h"
Sean Callananf18d91c2010-09-01 00:58:00 +000021#include "llvm/Module.h"
22#include "llvm/Value.h"
23
24using namespace llvm;
25using namespace lldb_private;
26
27static char ID;
28
Greg Clayton8de27c72010-10-15 22:48:33 +000029#define VALID_POINTER_CHECK_NAME "$__lldb_valid_pointer_check"
30#define VALID_OBJC_OBJECT_CHECK_NAME "$__lldb_objc_object_check"
Sean Callanane8a59a82010-09-13 21:34:21 +000031
Greg Clayton8de27c72010-10-15 22:48:33 +000032static const char g_valid_pointer_check_text[] =
33"extern \"C\" void\n"
34VALID_POINTER_CHECK_NAME " (unsigned char *ptr)\n"
35"{\n"
36" unsigned char val = *ptr;\n"
37"}";
Sean Callanane8a59a82010-09-13 21:34:21 +000038
39static bool FunctionExists(const SymbolContext &sym_ctx, const char *name)
40{
41 ConstString name_cs(name);
42
43 SymbolContextList sym_ctxs;
44
45 sym_ctx.FindFunctionsByName(name_cs, false, sym_ctxs);
46
47 return (sym_ctxs.GetSize() != 0);
48}
49
50static const char *objc_object_check_text(ExecutionContext &exe_ctx)
51{
52 std::string ret;
53
54 if (!exe_ctx.frame)
Greg Clayton8de27c72010-10-15 22:48:33 +000055 return "extern \"C\" void $__lldb_objc_object_check (unsigned char *obj) { }";
Sean Callanane8a59a82010-09-13 21:34:21 +000056
57 const SymbolContext &sym_ctx(exe_ctx.frame->GetSymbolContext(lldb::eSymbolContextEverything));
58
59 if (FunctionExists(sym_ctx, "gdb_object_getClass"))
60 {
61 return "extern \"C\" void "
Greg Clayton8de27c72010-10-15 22:48:33 +000062 "$__lldb_objc_object_check(uint8_t *obj)"
Sean Callanane8a59a82010-09-13 21:34:21 +000063 "{"
64 ""
65 "}";
66 }
67 else if (FunctionExists(sym_ctx, "gdb_class_getClass"))
68 {
69 return "extern \"C\" void "
Greg Clayton8de27c72010-10-15 22:48:33 +000070 "$__lldb_objc_object_check(uint8_t *obj)"
Sean Callanane8a59a82010-09-13 21:34:21 +000071 "{"
72 ""
73 "}";
74 }
75 else
76 {
77 return "extern \"C\" void "
Greg Clayton8de27c72010-10-15 22:48:33 +000078 "$__lldb_objc_object_check(uint8_t *obj)"
Sean Callanane8a59a82010-09-13 21:34:21 +000079 "{"
80 ""
81 "}";
82 }
83}
Sean Callananf18d91c2010-09-01 00:58:00 +000084
85DynamicCheckerFunctions::DynamicCheckerFunctions ()
86{
Sean Callananf18d91c2010-09-01 00:58:00 +000087}
88
89DynamicCheckerFunctions::~DynamicCheckerFunctions ()
90{
91}
92
93bool
94DynamicCheckerFunctions::Install(Stream &error_stream,
95 ExecutionContext &exe_ctx)
96{
Greg Clayton8de27c72010-10-15 22:48:33 +000097 m_valid_pointer_check.reset(new ClangUtilityFunction(g_valid_pointer_check_text,
98 VALID_POINTER_CHECK_NAME));
Sean Callanane8a59a82010-09-13 21:34:21 +000099
Sean Callananf18d91c2010-09-01 00:58:00 +0000100 if (!m_valid_pointer_check->Install(error_stream, exe_ctx))
101 return false;
102
103 return true;
104}
105
Sean Callananf18d91c2010-09-01 00:58:00 +0000106static std::string
107PrintValue(llvm::Value *V, bool truncate = false)
108{
109 std::string s;
110 raw_string_ostream rso(s);
111 V->print(rso);
112 rso.flush();
113 if (truncate)
114 s.resize(s.length() - 1);
115 return s;
116}
117
Sean Callanan05262332010-09-02 00:37:32 +0000118//----------------------------------------------------------------------
119/// @class Instrumenter IRDynamicChecks.cpp
120/// @brief Finds and instruments individual LLVM IR instructions
121///
122/// When instrumenting LLVM IR, it is frequently desirable to first search
123/// for instructions, and then later modify them. This way iterators
124/// remain intact, and multiple passes can look at the same code base without
125/// treading on each other's toes.
126///
127/// The Instrumenter class implements this functionality. A client first
128/// calls Inspect on a function, which populates a list of instructions to
129/// be instrumented. Then, later, when all passes' Inspect functions have
130/// been called, the client calls Instrument, which adds the desired
131/// instrumentation.
132///
133/// A subclass of Instrumenter must override InstrumentInstruction, which
134/// is responsible for adding whatever instrumentation is necessary.
135///
136/// A subclass of Instrumenter may override:
137///
138/// - InspectInstruction [default: does nothing]
139///
140/// - InspectBasicBlock [default: iterates through the instructions in a
141/// basic block calling InspectInstruction]
142///
143/// - InspectFunction [default: iterates through the basic blocks in a
144/// function calling InspectBasicBlock]
145//----------------------------------------------------------------------
146class Instrumenter {
147public:
148 //------------------------------------------------------------------
149 /// Constructor
150 ///
151 /// @param[in] module
152 /// The module being instrumented.
153 //------------------------------------------------------------------
154 Instrumenter (llvm::Module &module,
155 DynamicCheckerFunctions &checker_functions) :
156 m_module(module),
Sean Callanane8a59a82010-09-13 21:34:21 +0000157 m_checker_functions(checker_functions),
158 m_i8ptr_ty(NULL)
Sean Callanan05262332010-09-02 00:37:32 +0000159 {
160 }
161
162 //------------------------------------------------------------------
163 /// Inspect a function to find instructions to instrument
164 ///
165 /// @param[in] function
166 /// The function to inspect.
167 ///
168 /// @return
169 /// True on success; false on error.
170 //------------------------------------------------------------------
171 bool Inspect (llvm::Function &function)
172 {
173 return InspectFunction(function);
174 }
175
176 //------------------------------------------------------------------
177 /// Instrument all the instructions found by Inspect()
178 ///
179 /// @return
180 /// True on success; false on error.
181 //------------------------------------------------------------------
182 bool Instrument ()
183 {
184 for (InstIterator ii = m_to_instrument.begin(), last_ii = m_to_instrument.end();
185 ii != last_ii;
186 ++ii)
187 {
188 if (!InstrumentInstruction(*ii))
189 return false;
190 }
191
192 return true;
193 }
194protected:
195 //------------------------------------------------------------------
196 /// Add instrumentation to a single instruction
197 ///
198 /// @param[in] inst
199 /// The instruction to be instrumented.
200 ///
201 /// @return
202 /// True on success; false otherwise.
203 //------------------------------------------------------------------
204 virtual bool InstrumentInstruction(llvm::Instruction *inst) = 0;
205
206 //------------------------------------------------------------------
207 /// Register a single instruction to be instrumented
208 ///
209 /// @param[in] inst
210 /// The instruction to be instrumented.
211 //------------------------------------------------------------------
212 void RegisterInstruction(llvm::Instruction &i)
213 {
214 m_to_instrument.push_back(&i);
215 }
216
217 //------------------------------------------------------------------
218 /// Determine whether a single instruction is interesting to
219 /// instrument, and, if so, call RegisterInstruction
220 ///
221 /// @param[in] i
222 /// The instruction to be inspected.
223 ///
224 /// @return
225 /// False if there was an error scanning; true otherwise.
226 //------------------------------------------------------------------
227 virtual bool InspectInstruction(llvm::Instruction &i)
228 {
229 return true;
230 }
231
232 //------------------------------------------------------------------
233 /// Scan a basic block to see if any instructions are interesting
234 ///
235 /// @param[in] bb
236 /// The basic block to be inspected.
237 ///
238 /// @return
239 /// False if there was an error scanning; true otherwise.
240 //------------------------------------------------------------------
241 virtual bool InspectBasicBlock(llvm::BasicBlock &bb)
242 {
243 for (llvm::BasicBlock::iterator ii = bb.begin(), last_ii = bb.end();
244 ii != last_ii;
245 ++ii)
246 {
247 if (!InspectInstruction(*ii))
248 return false;
249 }
250
251 return true;
252 }
253
254 //------------------------------------------------------------------
255 /// Scan a function to see if any instructions are interesting
256 ///
257 /// @param[in] f
258 /// The function to be inspected.
259 ///
260 /// @return
261 /// False if there was an error scanning; true otherwise.
262 //------------------------------------------------------------------
263 virtual bool InspectFunction(llvm::Function &f)
264 {
265 for (llvm::Function::iterator bbi = f.begin(), last_bbi = f.end();
266 bbi != last_bbi;
267 ++bbi)
268 {
269 if (!InspectBasicBlock(*bbi))
270 return false;
271 }
272
273 return true;
274 }
275
Sean Callanane8a59a82010-09-13 21:34:21 +0000276 //------------------------------------------------------------------
277 /// Build a function pointer for a function with signature
278 /// void (*)(uint8_t*) with a given address
279 ///
280 /// @param[in] start_address
281 /// The address of the function.
282 ///
283 /// @return
284 /// The function pointer, for use in a CallInst.
285 //------------------------------------------------------------------
286 llvm::Value *BuildPointerValidatorFunc(lldb::addr_t start_address)
287 {
288 std::vector<const llvm::Type*> params;
289
290 const IntegerType *intptr_ty = llvm::Type::getIntNTy(m_module.getContext(),
291 (m_module.getPointerSize() == llvm::Module::Pointer64) ? 64 : 32);
292
293 if (!m_i8ptr_ty)
294 m_i8ptr_ty = llvm::Type::getInt8PtrTy(m_module.getContext());
295
296 params.push_back(m_i8ptr_ty);
297
298 FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true);
299 PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
300 Constant *fun_addr_int = ConstantInt::get(intptr_ty, start_address, false);
301 return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
302 }
303
Sean Callanan05262332010-09-02 00:37:32 +0000304 typedef std::vector <llvm::Instruction *> InstVector;
305 typedef InstVector::iterator InstIterator;
306
307 InstVector m_to_instrument; ///< List of instructions the inspector found
308 llvm::Module &m_module; ///< The module which is being instrumented
309 DynamicCheckerFunctions &m_checker_functions; ///< The dynamic checker functions for the process
Sean Callanane8a59a82010-09-13 21:34:21 +0000310
311 const PointerType *m_i8ptr_ty;
Sean Callanan05262332010-09-02 00:37:32 +0000312};
313
314class ValidPointerChecker : public Instrumenter
315{
316public:
317 ValidPointerChecker(llvm::Module &module,
318 DynamicCheckerFunctions &checker_functions) :
319 Instrumenter(module, checker_functions),
320 m_valid_pointer_check_func(NULL)
321 {
322 }
323private:
324 bool InstrumentInstruction(llvm::Instruction *inst)
325 {
326 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
327
328 if(log)
329 log->Printf("Instrumenting load/store instruction: %s\n",
330 PrintValue(inst).c_str());
331
332 if (!m_valid_pointer_check_func)
Sean Callanane8a59a82010-09-13 21:34:21 +0000333 m_valid_pointer_check_func = BuildPointerValidatorFunc(m_checker_functions.m_valid_pointer_check->StartAddress());
Sean Callanan05262332010-09-02 00:37:32 +0000334
335 llvm::Value *dereferenced_ptr;
336
337 if (llvm::LoadInst *li = dyn_cast<llvm::LoadInst> (inst))
338 dereferenced_ptr = li->getPointerOperand();
339 else if (llvm::StoreInst *si = dyn_cast<llvm::StoreInst> (inst))
340 dereferenced_ptr = si->getPointerOperand();
341 else
342 return false;
343
344 // Insert an instruction to cast the loaded value to int8_t*
345
346 BitCastInst *bit_cast = new BitCastInst(dereferenced_ptr,
347 m_i8ptr_ty,
348 "",
349 inst);
350
351 // Insert an instruction to call the helper with the result
352
353 SmallVector <llvm::Value*, 1> args;
354 args.push_back(bit_cast);
355
356 CallInst::Create(m_valid_pointer_check_func,
357 args.begin(),
358 args.end(),
359 "",
360 inst);
361
362 return true;
363 }
364
365 bool InspectInstruction(llvm::Instruction &i)
366 {
367 if (dyn_cast<llvm::LoadInst> (&i) ||
368 dyn_cast<llvm::StoreInst> (&i))
369 RegisterInstruction(i);
370
371 return true;
372 }
373
374 llvm::Value *m_valid_pointer_check_func;
Sean Callanane8a59a82010-09-13 21:34:21 +0000375};
376
377class ObjcObjectChecker : public Instrumenter
378{
379public:
380 ObjcObjectChecker(llvm::Module &module,
381 DynamicCheckerFunctions &checker_functions) :
382 Instrumenter(module, checker_functions),
383 m_objc_object_check_func(NULL)
384 {
385 }
386private:
387 bool InstrumentInstruction(llvm::Instruction *inst)
388 {
389 CallInst *call_inst = dyn_cast<CallInst>(inst);
390
391 if (!call_inst)
392 return false; // this really should be true, because otherwise InspectInstruction wouldn't have registered it
393
394 if (!m_objc_object_check_func)
395 m_objc_object_check_func = BuildPointerValidatorFunc(m_checker_functions.m_objc_object_check->StartAddress());
396
397 llvm::Value *target_object;
398
399 // id objc_msgSend(id theReceiver, SEL theSelector, ...)
400
401 target_object = call_inst->getArgOperand(0);
402
403 // Insert an instruction to cast the receiver id to int8_t*
404
405 BitCastInst *bit_cast = new BitCastInst(target_object,
406 m_i8ptr_ty,
407 "",
408 inst);
409
410 // Insert an instruction to call the helper with the result
411
412 SmallVector <llvm::Value*, 1> args;
413 args.push_back(bit_cast);
414
415 CallInst::Create(m_objc_object_check_func,
416 args.begin(),
417 args.end(),
418 "",
419 inst);
420
421 return true;
422 }
423
424 bool InspectInstruction(llvm::Instruction &i)
425 {
426 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
427
428 CallInst *call_inst = dyn_cast<CallInst>(&i);
429
430 if (call_inst)
431 {
432 // This metadata is set by IRForTarget::MaybeHandleCall().
433
434 MDNode *metadata = call_inst->getMetadata("lldb.call.realName");
435
436 if (!metadata)
437 return true;
438
439 if (metadata->getNumOperands() != 1)
440 {
441 if (log)
442 log->Printf("Function call metadata has %d operands for [%p] %s", metadata->getNumOperands(), call_inst, PrintValue(call_inst).c_str());
443 return false;
444 }
445
446 ConstantArray *real_name = dyn_cast<ConstantArray>(metadata->getOperand(0));
447
448 if (!real_name)
449 {
450 if (log)
451 log->Printf("Function call metadata is not a ConstantArray for [%p] %s", call_inst, PrintValue(call_inst).c_str());
452 return false;
453 }
454
455 if (!real_name->isString())
456 {
457 if (log)
458 log->Printf("Function call metadata is not a string for [%p] %s", call_inst, PrintValue(call_inst).c_str());
459 return false;
460 }
461
462 if (log)
463 log->Printf("Found call to %s: %s\n", real_name->getAsString().c_str(), PrintValue(call_inst).c_str());
464
465 if (real_name->getAsString().find("objc_msgSend") != std::string::npos)
466 RegisterInstruction(i);
467 }
468
469 return true;
470 }
471
472 llvm::Value *m_objc_object_check_func;
Sean Callanan05262332010-09-02 00:37:32 +0000473 const PointerType *m_i8ptr_ty;
474};
475
476IRDynamicChecks::IRDynamicChecks(DynamicCheckerFunctions &checker_functions,
477 const char *func_name) :
Sean Callanan47a5c4c2010-09-23 03:01:22 +0000478 ModulePass(ID),
Sean Callanan05262332010-09-02 00:37:32 +0000479 m_checker_functions(checker_functions),
480 m_func_name(func_name)
481{
482}
483
Sean Callananf18d91c2010-09-01 00:58:00 +0000484IRDynamicChecks::~IRDynamicChecks()
485{
486}
487
488bool
489IRDynamicChecks::runOnModule(llvm::Module &M)
490{
491 lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
492
493 llvm::Function* function = M.getFunction(StringRef(m_func_name.c_str()));
494
495 if (!function)
496 {
497 if (log)
498 log->Printf("Couldn't find %s() in the module", m_func_name.c_str());
499
500 return false;
501 }
Sean Callanan05262332010-09-02 00:37:32 +0000502
503 ValidPointerChecker vpc(M, m_checker_functions);
Sean Callananf18d91c2010-09-01 00:58:00 +0000504
Sean Callanan05262332010-09-02 00:37:32 +0000505 if (!vpc.Inspect(*function))
506 return false;
Sean Callananf18d91c2010-09-01 00:58:00 +0000507
Sean Callanan05262332010-09-02 00:37:32 +0000508 if (!vpc.Instrument())
509 return false;
Sean Callananf18d91c2010-09-01 00:58:00 +0000510
Sean Callanane8a59a82010-09-13 21:34:21 +0000511 /*
512 ObjcObjectChecker ooc(M, m_checker_functions);
513
514 if (!ooc.Inspect(*function))
515 return false;
516
517 if (!ooc.Instrument())
518 return false;
519 */
520
Sean Callanan65af7342010-09-08 20:04:08 +0000521 if (log)
522 {
523 std::string s;
524 raw_string_ostream oss(s);
525
526 M.print(oss, NULL);
527
528 oss.flush();
529
530 log->Printf("Module after dynamic checks: \n%s", s.c_str());
531 }
532
Sean Callananf18d91c2010-09-01 00:58:00 +0000533 return true;
534}
535
536void
537IRDynamicChecks::assignPassManager(PMStack &PMS,
538 PassManagerType T)
539{
540}
541
542PassManagerType
543IRDynamicChecks::getPotentialPassManagerType() const
544{
545 return PMT_ModulePassManager;
546}