blob: aa5d28bb8aadbd5ee8dd66c3512944a932338d71 [file] [log] [blame]
Sean Callanan6961e872010-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 Callanan6961e872010-09-01 00:58:00 +000011
Sean Callanan9e6ed532010-09-13 21:34:21 +000012#include "lldb/Core/ConstString.h"
Sean Callanan6961e872010-09-01 00:58:00 +000013#include "lldb/Core/Log.h"
Sean Callanan9e6ed532010-09-13 21:34:21 +000014#include "lldb/Expression/ClangUtilityFunction.h"
15#include "lldb/Target/ExecutionContext.h"
Sean Callanan10af7c42010-11-04 01:51:38 +000016#include "lldb/Target/ObjCLanguageRuntime.h"
17#include "lldb/Target/Process.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000018#include "lldb/Target/StackFrame.h"
Sean Callanan6961e872010-09-01 00:58:00 +000019
20#include "llvm/Support/raw_ostream.h"
Chandler Carruth1e157582013-01-02 12:20:07 +000021#include "llvm/IR/Constants.h"
Sean Callanan439dcae2013-12-20 19:55:02 +000022#include "llvm/IR/DataLayout.h"
Chandler Carruth1e157582013-01-02 12:20:07 +000023#include "llvm/IR/Function.h"
24#include "llvm/IR/Instructions.h"
25#include "llvm/IR/Module.h"
26#include "llvm/IR/Value.h"
Sean Callanan6961e872010-09-01 00:58:00 +000027
28using namespace llvm;
29using namespace lldb_private;
30
31static char ID;
32
Greg Clayton7b462cc2010-10-15 22:48:33 +000033#define VALID_POINTER_CHECK_NAME "$__lldb_valid_pointer_check"
34#define VALID_OBJC_OBJECT_CHECK_NAME "$__lldb_objc_object_check"
Sean Callanan9e6ed532010-09-13 21:34:21 +000035
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000036static const char g_valid_pointer_check_text[] =
Greg Clayton7b462cc2010-10-15 22:48:33 +000037"extern \"C\" void\n"
Greg Claytond59cea22010-10-16 21:09:32 +000038"$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n"
Greg Clayton7b462cc2010-10-15 22:48:33 +000039"{\n"
Greg Claytondd36def2010-10-17 22:03:32 +000040" unsigned char $__lldb_local_val = *$__lldb_arg_ptr;\n"
Greg Clayton7b462cc2010-10-15 22:48:33 +000041"}";
Sean Callanan9e6ed532010-09-13 21:34:21 +000042
Sean Callanan6961e872010-09-01 00:58:00 +000043DynamicCheckerFunctions::DynamicCheckerFunctions ()
44{
Sean Callanan6961e872010-09-01 00:58:00 +000045}
46
47DynamicCheckerFunctions::~DynamicCheckerFunctions ()
48{
49}
50
51bool
52DynamicCheckerFunctions::Install(Stream &error_stream,
53 ExecutionContext &exe_ctx)
54{
Greg Clayton7b462cc2010-10-15 22:48:33 +000055 m_valid_pointer_check.reset(new ClangUtilityFunction(g_valid_pointer_check_text,
56 VALID_POINTER_CHECK_NAME));
Sean Callanan6961e872010-09-01 00:58:00 +000057 if (!m_valid_pointer_check->Install(error_stream, exe_ctx))
58 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000059
Greg Claytonc14ee322011-09-22 04:58:26 +000060 Process *process = exe_ctx.GetProcessPtr();
61
62 if (process)
Sean Callanan10af7c42010-11-04 01:51:38 +000063 {
Greg Claytonc14ee322011-09-22 04:58:26 +000064 ObjCLanguageRuntime *objc_language_runtime = process->GetObjCLanguageRuntime();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000065
Sean Callanan10af7c42010-11-04 01:51:38 +000066 if (objc_language_runtime)
67 {
68 m_objc_object_check.reset(objc_language_runtime->CreateObjectChecker(VALID_OBJC_OBJECT_CHECK_NAME));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000069
Sean Callanan10af7c42010-11-04 01:51:38 +000070 if (!m_objc_object_check->Install(error_stream, exe_ctx))
71 return false;
72 }
73 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000074
Sean Callanan6961e872010-09-01 00:58:00 +000075 return true;
76}
77
Jim Inghamce553d82011-11-01 02:46:54 +000078bool
79DynamicCheckerFunctions::DoCheckersExplainStop (lldb::addr_t addr, Stream &message)
80{
81 // FIXME: We have to get the checkers to know why they scotched the call in more detail,
82 // so we can print a better message here.
83 if (m_valid_pointer_check.get() != NULL && m_valid_pointer_check->ContainsAddress(addr))
84 {
85 message.Printf ("Attempted to dereference an invalid pointer.");
86 return true;
87 }
88 else if (m_objc_object_check.get() != NULL && m_objc_object_check->ContainsAddress(addr))
89 {
90 message.Printf ("Attempted to dereference an invalid ObjC Object or send it an unrecognized selector");
91 return true;
92 }
93 return false;
94}
95
96
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000097static std::string
Sean Callanan6961e872010-09-01 00:58:00 +000098PrintValue(llvm::Value *V, bool truncate = false)
99{
100 std::string s;
101 raw_string_ostream rso(s);
102 V->print(rso);
103 rso.flush();
104 if (truncate)
105 s.resize(s.length() - 1);
106 return s;
107}
108
Sean Callanan8e999e42010-09-02 00:37:32 +0000109//----------------------------------------------------------------------
110/// @class Instrumenter IRDynamicChecks.cpp
111/// @brief Finds and instruments individual LLVM IR instructions
112///
113/// When instrumenting LLVM IR, it is frequently desirable to first search
114/// for instructions, and then later modify them. This way iterators
115/// remain intact, and multiple passes can look at the same code base without
116/// treading on each other's toes.
117///
118/// The Instrumenter class implements this functionality. A client first
119/// calls Inspect on a function, which populates a list of instructions to
120/// be instrumented. Then, later, when all passes' Inspect functions have
121/// been called, the client calls Instrument, which adds the desired
122/// instrumentation.
123///
124/// A subclass of Instrumenter must override InstrumentInstruction, which
125/// is responsible for adding whatever instrumentation is necessary.
126///
127/// A subclass of Instrumenter may override:
128///
129/// - InspectInstruction [default: does nothing]
130///
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000131/// - InspectBasicBlock [default: iterates through the instructions in a
Sean Callanan8e999e42010-09-02 00:37:32 +0000132/// basic block calling InspectInstruction]
133///
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000134/// - InspectFunction [default: iterates through the basic blocks in a
Sean Callanan8e999e42010-09-02 00:37:32 +0000135/// function calling InspectBasicBlock]
136//----------------------------------------------------------------------
137class Instrumenter {
138public:
139 //------------------------------------------------------------------
140 /// Constructor
141 ///
142 /// @param[in] module
143 /// The module being instrumented.
144 //------------------------------------------------------------------
145 Instrumenter (llvm::Module &module,
146 DynamicCheckerFunctions &checker_functions) :
147 m_module(module),
Sean Callanan9e6ed532010-09-13 21:34:21 +0000148 m_checker_functions(checker_functions),
Sean Callanan439dcae2013-12-20 19:55:02 +0000149 m_i8ptr_ty(NULL),
150 m_intptr_ty(NULL)
Sean Callanan8e999e42010-09-02 00:37:32 +0000151 {
152 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000153
Greg Clayton1a65ae12011-01-25 23:55:37 +0000154 virtual~Instrumenter ()
155 {
156 }
157
Sean Callanan8e999e42010-09-02 00:37:32 +0000158 //------------------------------------------------------------------
159 /// Inspect a function to find instructions to instrument
160 ///
161 /// @param[in] function
162 /// The function to inspect.
163 ///
164 /// @return
165 /// True on success; false on error.
166 //------------------------------------------------------------------
167 bool Inspect (llvm::Function &function)
168 {
169 return InspectFunction(function);
170 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000171
Sean Callanan8e999e42010-09-02 00:37:32 +0000172 //------------------------------------------------------------------
173 /// Instrument all the instructions found by Inspect()
174 ///
175 /// @return
176 /// True on success; false on error.
177 //------------------------------------------------------------------
178 bool Instrument ()
179 {
180 for (InstIterator ii = m_to_instrument.begin(), last_ii = m_to_instrument.end();
181 ii != last_ii;
182 ++ii)
183 {
184 if (!InstrumentInstruction(*ii))
185 return false;
186 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000187
Sean Callanan8e999e42010-09-02 00:37:32 +0000188 return true;
189 }
190protected:
191 //------------------------------------------------------------------
192 /// Add instrumentation to a single instruction
193 ///
194 /// @param[in] inst
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000195 /// The instruction to be instrumented.
Sean Callanan8e999e42010-09-02 00:37:32 +0000196 ///
197 /// @return
198 /// True on success; false otherwise.
199 //------------------------------------------------------------------
200 virtual bool InstrumentInstruction(llvm::Instruction *inst) = 0;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000201
Sean Callanan8e999e42010-09-02 00:37:32 +0000202 //------------------------------------------------------------------
203 /// Register a single instruction to be instrumented
204 ///
205 /// @param[in] inst
206 /// The instruction to be instrumented.
207 //------------------------------------------------------------------
208 void RegisterInstruction(llvm::Instruction &i)
209 {
210 m_to_instrument.push_back(&i);
211 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000212
Sean Callanan8e999e42010-09-02 00:37:32 +0000213 //------------------------------------------------------------------
214 /// Determine whether a single instruction is interesting to
215 /// instrument, and, if so, call RegisterInstruction
216 ///
217 /// @param[in] i
218 /// The instruction to be inspected.
219 ///
220 /// @return
221 /// False if there was an error scanning; true otherwise.
222 //------------------------------------------------------------------
223 virtual bool InspectInstruction(llvm::Instruction &i)
224 {
225 return true;
226 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000227
Sean Callanan8e999e42010-09-02 00:37:32 +0000228 //------------------------------------------------------------------
229 /// Scan a basic block to see if any instructions are interesting
230 ///
231 /// @param[in] bb
232 /// The basic block to be inspected.
233 ///
234 /// @return
235 /// False if there was an error scanning; true otherwise.
236 //------------------------------------------------------------------
237 virtual bool InspectBasicBlock(llvm::BasicBlock &bb)
238 {
239 for (llvm::BasicBlock::iterator ii = bb.begin(), last_ii = bb.end();
240 ii != last_ii;
241 ++ii)
242 {
243 if (!InspectInstruction(*ii))
244 return false;
245 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000246
Sean Callanan8e999e42010-09-02 00:37:32 +0000247 return true;
248 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000249
Sean Callanan8e999e42010-09-02 00:37:32 +0000250 //------------------------------------------------------------------
251 /// Scan a function to see if any instructions are interesting
252 ///
253 /// @param[in] f
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000254 /// The function to be inspected.
Sean Callanan8e999e42010-09-02 00:37:32 +0000255 ///
256 /// @return
257 /// False if there was an error scanning; true otherwise.
258 //------------------------------------------------------------------
259 virtual bool InspectFunction(llvm::Function &f)
260 {
261 for (llvm::Function::iterator bbi = f.begin(), last_bbi = f.end();
262 bbi != last_bbi;
263 ++bbi)
264 {
265 if (!InspectBasicBlock(*bbi))
266 return false;
267 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000268
Sean Callanan8e999e42010-09-02 00:37:32 +0000269 return true;
270 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000271
Sean Callanan9e6ed532010-09-13 21:34:21 +0000272 //------------------------------------------------------------------
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000273 /// Build a function pointer for a function with signature
Sean Callanan9e6ed532010-09-13 21:34:21 +0000274 /// void (*)(uint8_t*) with a given address
275 ///
276 /// @param[in] start_address
277 /// The address of the function.
278 ///
279 /// @return
280 /// The function pointer, for use in a CallInst.
281 //------------------------------------------------------------------
282 llvm::Value *BuildPointerValidatorFunc(lldb::addr_t start_address)
283 {
Sean Callanancc427fa2011-07-30 02:42:06 +0000284 llvm::Type *param_array[1];
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000285
Sean Callanancc427fa2011-07-30 02:42:06 +0000286 param_array[0] = const_cast<llvm::PointerType*>(GetI8PtrTy());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000287
Sean Callanancc427fa2011-07-30 02:42:06 +0000288 ArrayRef<llvm::Type*> params(param_array, 1);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000289
Sean Callanan9e6ed532010-09-13 21:34:21 +0000290 FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true);
291 PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
Sean Callanan439dcae2013-12-20 19:55:02 +0000292 Constant *fun_addr_int = ConstantInt::get(GetIntptrTy(), start_address, false);
Sean Callanan9e6ed532010-09-13 21:34:21 +0000293 return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
294 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000295
Sean Callanan7ba96362011-10-27 00:02:05 +0000296 //------------------------------------------------------------------
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000297 /// Build a function pointer for a function with signature
Sean Callanan7ba96362011-10-27 00:02:05 +0000298 /// void (*)(uint8_t*, uint8_t*) with a given address
299 ///
300 /// @param[in] start_address
301 /// The address of the function.
302 ///
303 /// @return
304 /// The function pointer, for use in a CallInst.
305 //------------------------------------------------------------------
306 llvm::Value *BuildObjectCheckerFunc(lldb::addr_t start_address)
307 {
Sean Callanan7ba96362011-10-27 00:02:05 +0000308 llvm::Type *param_array[2];
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000309
Sean Callanan7ba96362011-10-27 00:02:05 +0000310 param_array[0] = const_cast<llvm::PointerType*>(GetI8PtrTy());
311 param_array[1] = const_cast<llvm::PointerType*>(GetI8PtrTy());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000312
Sean Callanan7ba96362011-10-27 00:02:05 +0000313 ArrayRef<llvm::Type*> params(param_array, 2);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000314
Sean Callanan7ba96362011-10-27 00:02:05 +0000315 FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true);
316 PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
Sean Callanan439dcae2013-12-20 19:55:02 +0000317 Constant *fun_addr_int = ConstantInt::get(GetIntptrTy(), start_address, false);
Sean Callanan7ba96362011-10-27 00:02:05 +0000318 return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
319 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000320
Sean Callanancc427fa2011-07-30 02:42:06 +0000321 PointerType *GetI8PtrTy()
Sean Callanan10af7c42010-11-04 01:51:38 +0000322 {
323 if (!m_i8ptr_ty)
324 m_i8ptr_ty = llvm::Type::getInt8PtrTy(m_module.getContext());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000325
Sean Callanan10af7c42010-11-04 01:51:38 +0000326 return m_i8ptr_ty;
327 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000328
Sean Callanan439dcae2013-12-20 19:55:02 +0000329 IntegerType *GetIntptrTy()
330 {
331 if (!m_intptr_ty)
332 {
333 llvm::DataLayout data_layout(&m_module);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000334
Sean Callanan439dcae2013-12-20 19:55:02 +0000335 m_intptr_ty = llvm::Type::getIntNTy(m_module.getContext(), data_layout.getPointerSizeInBits());
336 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000337
Sean Callanan439dcae2013-12-20 19:55:02 +0000338 return m_intptr_ty;
339 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000340
Sean Callanan8e999e42010-09-02 00:37:32 +0000341 typedef std::vector <llvm::Instruction *> InstVector;
342 typedef InstVector::iterator InstIterator;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000343
Sean Callanan8e999e42010-09-02 00:37:32 +0000344 InstVector m_to_instrument; ///< List of instructions the inspector found
345 llvm::Module &m_module; ///< The module which is being instrumented
346 DynamicCheckerFunctions &m_checker_functions; ///< The dynamic checker functions for the process
Sean Callanan10af7c42010-11-04 01:51:38 +0000347private:
Sean Callanancc427fa2011-07-30 02:42:06 +0000348 PointerType *m_i8ptr_ty;
Sean Callanan439dcae2013-12-20 19:55:02 +0000349 IntegerType *m_intptr_ty;
Sean Callanan8e999e42010-09-02 00:37:32 +0000350};
351
352class ValidPointerChecker : public Instrumenter
353{
354public:
Greg Clayton1a65ae12011-01-25 23:55:37 +0000355 ValidPointerChecker (llvm::Module &module,
356 DynamicCheckerFunctions &checker_functions) :
Sean Callanan8e999e42010-09-02 00:37:32 +0000357 Instrumenter(module, checker_functions),
358 m_valid_pointer_check_func(NULL)
359 {
360 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000361
Greg Clayton1a65ae12011-01-25 23:55:37 +0000362 virtual ~ValidPointerChecker ()
363 {
364 }
Sean Callanan8e999e42010-09-02 00:37:32 +0000365private:
366 bool InstrumentInstruction(llvm::Instruction *inst)
367 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000368 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan8e999e42010-09-02 00:37:32 +0000369
Enrico Granata20edcdb2011-07-19 18:03:25 +0000370 if (log)
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000371 log->Printf("Instrumenting load/store instruction: %s\n",
Sean Callanan8e999e42010-09-02 00:37:32 +0000372 PrintValue(inst).c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000373
Sean Callanan8e999e42010-09-02 00:37:32 +0000374 if (!m_valid_pointer_check_func)
Sean Callanan9e6ed532010-09-13 21:34:21 +0000375 m_valid_pointer_check_func = BuildPointerValidatorFunc(m_checker_functions.m_valid_pointer_check->StartAddress());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000376
Sean Callanan77eaf442011-07-08 00:39:14 +0000377 llvm::Value *dereferenced_ptr = NULL;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000378
Sean Callanan8e999e42010-09-02 00:37:32 +0000379 if (llvm::LoadInst *li = dyn_cast<llvm::LoadInst> (inst))
380 dereferenced_ptr = li->getPointerOperand();
381 else if (llvm::StoreInst *si = dyn_cast<llvm::StoreInst> (inst))
382 dereferenced_ptr = si->getPointerOperand();
383 else
384 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000385
Sean Callanan8e999e42010-09-02 00:37:32 +0000386 // Insert an instruction to cast the loaded value to int8_t*
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000387
Sean Callanan8e999e42010-09-02 00:37:32 +0000388 BitCastInst *bit_cast = new BitCastInst(dereferenced_ptr,
Sean Callanan10af7c42010-11-04 01:51:38 +0000389 GetI8PtrTy(),
Sean Callanan8e999e42010-09-02 00:37:32 +0000390 "",
391 inst);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000392
Sean Callanan8e999e42010-09-02 00:37:32 +0000393 // Insert an instruction to call the helper with the result
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000394
Sean Callanancc427fa2011-07-30 02:42:06 +0000395 llvm::Value *arg_array[1];
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000396
Sean Callanancc427fa2011-07-30 02:42:06 +0000397 arg_array[0] = bit_cast;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000398
Sean Callanancc427fa2011-07-30 02:42:06 +0000399 llvm::ArrayRef<llvm::Value *> args(arg_array, 1);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000400
401 CallInst::Create(m_valid_pointer_check_func,
Sean Callanancc427fa2011-07-30 02:42:06 +0000402 args,
Sean Callanan8e999e42010-09-02 00:37:32 +0000403 "",
404 inst);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000405
Sean Callanan8e999e42010-09-02 00:37:32 +0000406 return true;
407 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000408
Sean Callanan8e999e42010-09-02 00:37:32 +0000409 bool InspectInstruction(llvm::Instruction &i)
410 {
411 if (dyn_cast<llvm::LoadInst> (&i) ||
412 dyn_cast<llvm::StoreInst> (&i))
413 RegisterInstruction(i);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000414
Sean Callanan8e999e42010-09-02 00:37:32 +0000415 return true;
416 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000417
Sean Callanan8e999e42010-09-02 00:37:32 +0000418 llvm::Value *m_valid_pointer_check_func;
Sean Callanan9e6ed532010-09-13 21:34:21 +0000419};
420
421class ObjcObjectChecker : public Instrumenter
422{
423public:
424 ObjcObjectChecker(llvm::Module &module,
425 DynamicCheckerFunctions &checker_functions) :
426 Instrumenter(module, checker_functions),
427 m_objc_object_check_func(NULL)
428 {
429 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000430
Greg Clayton1a65ae12011-01-25 23:55:37 +0000431 virtual
432 ~ObjcObjectChecker ()
433 {
434 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000435
Sean Callanana6cbf062011-11-16 00:20:50 +0000436 enum msgSend_type
437 {
438 eMsgSend = 0,
439 eMsgSendSuper,
440 eMsgSendSuper_stret,
441 eMsgSend_fpret,
442 eMsgSend_stret
443 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000444
Sean Callanana6cbf062011-11-16 00:20:50 +0000445 std::map <llvm::Instruction *, msgSend_type> msgSend_types;
Greg Clayton1a65ae12011-01-25 23:55:37 +0000446
Sean Callanan9e6ed532010-09-13 21:34:21 +0000447private:
448 bool InstrumentInstruction(llvm::Instruction *inst)
449 {
450 CallInst *call_inst = dyn_cast<CallInst>(inst);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000451
Sean Callanan9e6ed532010-09-13 21:34:21 +0000452 if (!call_inst)
Sean Callanan10af7c42010-11-04 01:51:38 +0000453 return false; // call_inst really shouldn't be NULL, because otherwise InspectInstruction wouldn't have registered it
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000454
Sean Callanan9e6ed532010-09-13 21:34:21 +0000455 if (!m_objc_object_check_func)
Sean Callanan7ba96362011-10-27 00:02:05 +0000456 m_objc_object_check_func = BuildObjectCheckerFunc(m_checker_functions.m_objc_object_check->StartAddress());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000457
Sean Callanan9e6ed532010-09-13 21:34:21 +0000458 // id objc_msgSend(id theReceiver, SEL theSelector, ...)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000459
Sean Callanana6cbf062011-11-16 00:20:50 +0000460 llvm::Value *target_object;
461 llvm::Value *selector;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000462
Sean Callanana6cbf062011-11-16 00:20:50 +0000463 switch (msgSend_types[inst])
464 {
465 case eMsgSend:
466 case eMsgSend_fpret:
467 target_object = call_inst->getArgOperand(0);
468 selector = call_inst->getArgOperand(1);
469 break;
470 case eMsgSend_stret:
471 target_object = call_inst->getArgOperand(1);
472 selector = call_inst->getArgOperand(2);
Greg Clayton23f59502012-07-17 03:23:13 +0000473 break;
Sean Callanana6cbf062011-11-16 00:20:50 +0000474 case eMsgSendSuper:
475 case eMsgSendSuper_stret:
476 return true;
477 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000478
Greg Clayton23f59502012-07-17 03:23:13 +0000479 // These objects should always be valid according to Sean Calannan
480 assert (target_object);
481 assert (selector);
482
Sean Callanan9e6ed532010-09-13 21:34:21 +0000483 // Insert an instruction to cast the receiver id to int8_t*
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000484
Sean Callanan9e6ed532010-09-13 21:34:21 +0000485 BitCastInst *bit_cast = new BitCastInst(target_object,
Sean Callanan10af7c42010-11-04 01:51:38 +0000486 GetI8PtrTy(),
Sean Callanan9e6ed532010-09-13 21:34:21 +0000487 "",
488 inst);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000489
Sean Callanan9e6ed532010-09-13 21:34:21 +0000490 // Insert an instruction to call the helper with the result
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000491
Sean Callanan7ba96362011-10-27 00:02:05 +0000492 llvm::Value *arg_array[2];
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000493
Sean Callanancc427fa2011-07-30 02:42:06 +0000494 arg_array[0] = bit_cast;
Sean Callanan7ba96362011-10-27 00:02:05 +0000495 arg_array[1] = selector;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000496
Sean Callananfc8feb82011-10-31 22:11:40 +0000497 ArrayRef<llvm::Value*> args(arg_array, 2);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000498
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000499 CallInst::Create(m_objc_object_check_func,
Sean Callanancc427fa2011-07-30 02:42:06 +0000500 args,
Sean Callanan9e6ed532010-09-13 21:34:21 +0000501 "",
502 inst);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000503
Sean Callanan9e6ed532010-09-13 21:34:21 +0000504 return true;
505 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000506
Sean Callanan9e6ed532010-09-13 21:34:21 +0000507 bool InspectInstruction(llvm::Instruction &i)
508 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000509 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan9e6ed532010-09-13 21:34:21 +0000510
511 CallInst *call_inst = dyn_cast<CallInst>(&i);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000512
Sean Callanan9e6ed532010-09-13 21:34:21 +0000513 if (call_inst)
514 {
515 // This metadata is set by IRForTarget::MaybeHandleCall().
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000516
Sean Callanan9e6ed532010-09-13 21:34:21 +0000517 MDNode *metadata = call_inst->getMetadata("lldb.call.realName");
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000518
Sean Callanan9e6ed532010-09-13 21:34:21 +0000519 if (!metadata)
520 return true;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000521
Sean Callanan9e6ed532010-09-13 21:34:21 +0000522 if (metadata->getNumOperands() != 1)
523 {
524 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000525 log->Printf("Function call metadata has %d operands for [%p] %s",
526 metadata->getNumOperands(),
527 static_cast<void*>(call_inst),
528 PrintValue(call_inst).c_str());
Sean Callanan9e6ed532010-09-13 21:34:21 +0000529 return false;
530 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000531
Daniel Maleaf051dbc2013-06-03 20:45:54 +0000532 MDString *real_name = dyn_cast<MDString>(metadata->getOperand(0));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000533
Sean Callanan9e6ed532010-09-13 21:34:21 +0000534 if (!real_name)
535 {
536 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000537 log->Printf("Function call metadata is not an MDString for [%p] %s",
538 static_cast<void*>(call_inst),
539 PrintValue(call_inst).c_str());
Sean Callanan9e6ed532010-09-13 21:34:21 +0000540 return false;
541 }
Daniel Maleaf051dbc2013-06-03 20:45:54 +0000542
543 std::string name_str = real_name->getString();
Sean Callanana6cbf062011-11-16 00:20:50 +0000544 const char* name_cstr = name_str.c_str();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000545
Sean Callanand2b465f2012-02-09 03:22:41 +0000546 if (log)
547 log->Printf("Found call to %s: %s\n", name_cstr, PrintValue(call_inst).c_str());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000548
Sean Callanana6cbf062011-11-16 00:20:50 +0000549 if (name_str.find("objc_msgSend") == std::string::npos)
550 return true;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000551
Sean Callanana6cbf062011-11-16 00:20:50 +0000552 if (!strcmp(name_cstr, "objc_msgSend"))
553 {
Sean Callanan9e6ed532010-09-13 21:34:21 +0000554 RegisterInstruction(i);
Sean Callanana6cbf062011-11-16 00:20:50 +0000555 msgSend_types[&i] = eMsgSend;
556 return true;
557 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000558
Sean Callanana6cbf062011-11-16 00:20:50 +0000559 if (!strcmp(name_cstr, "objc_msgSend_stret"))
560 {
561 RegisterInstruction(i);
562 msgSend_types[&i] = eMsgSend_stret;
563 return true;
564 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000565
Sean Callanana6cbf062011-11-16 00:20:50 +0000566 if (!strcmp(name_cstr, "objc_msgSend_fpret"))
567 {
568 RegisterInstruction(i);
569 msgSend_types[&i] = eMsgSend_fpret;
570 return true;
571 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000572
Sean Callanana6cbf062011-11-16 00:20:50 +0000573 if (!strcmp(name_cstr, "objc_msgSendSuper"))
574 {
575 RegisterInstruction(i);
576 msgSend_types[&i] = eMsgSendSuper;
577 return true;
578 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000579
Sean Callanana6cbf062011-11-16 00:20:50 +0000580 if (!strcmp(name_cstr, "objc_msgSendSuper_stret"))
581 {
582 RegisterInstruction(i);
583 msgSend_types[&i] = eMsgSendSuper_stret;
584 return true;
585 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000586
Sean Callanana6cbf062011-11-16 00:20:50 +0000587 if (log)
588 log->Printf("Function name '%s' contains 'objc_msgSend' but is not handled", name_str.c_str());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000589
Sean Callanana6cbf062011-11-16 00:20:50 +0000590 return true;
Sean Callanan9e6ed532010-09-13 21:34:21 +0000591 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000592
Sean Callanan9e6ed532010-09-13 21:34:21 +0000593 return true;
594 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000595
Sean Callanan9e6ed532010-09-13 21:34:21 +0000596 llvm::Value *m_objc_object_check_func;
Sean Callanan8e999e42010-09-02 00:37:32 +0000597};
598
599IRDynamicChecks::IRDynamicChecks(DynamicCheckerFunctions &checker_functions,
600 const char *func_name) :
Sean Callanane2ef6e32010-09-23 03:01:22 +0000601 ModulePass(ID),
Stephen Wilson71c21d12011-04-11 19:41:40 +0000602 m_func_name(func_name),
603 m_checker_functions(checker_functions)
Sean Callanan8e999e42010-09-02 00:37:32 +0000604{
605}
606
Sean Callanan6961e872010-09-01 00:58:00 +0000607IRDynamicChecks::~IRDynamicChecks()
608{
609}
610
611bool
612IRDynamicChecks::runOnModule(llvm::Module &M)
613{
Greg Clayton5160ce52013-03-27 23:08:40 +0000614 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000615
Sean Callanan6961e872010-09-01 00:58:00 +0000616 llvm::Function* function = M.getFunction(StringRef(m_func_name.c_str()));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000617
Sean Callanan6961e872010-09-01 00:58:00 +0000618 if (!function)
619 {
620 if (log)
621 log->Printf("Couldn't find %s() in the module", m_func_name.c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000622
Sean Callanan6961e872010-09-01 00:58:00 +0000623 return false;
624 }
Sean Callanan8e999e42010-09-02 00:37:32 +0000625
Sean Callanan53bacf212012-05-29 23:46:46 +0000626 if (m_checker_functions.m_valid_pointer_check.get())
627 {
628 ValidPointerChecker vpc(M, m_checker_functions);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000629
Sean Callanan53bacf212012-05-29 23:46:46 +0000630 if (!vpc.Inspect(*function))
631 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000632
Sean Callanan53bacf212012-05-29 23:46:46 +0000633 if (!vpc.Instrument())
634 return false;
635 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000636
Sean Callanan53bacf212012-05-29 23:46:46 +0000637 if (m_checker_functions.m_objc_object_check.get())
638 {
639 ObjcObjectChecker ooc(M, m_checker_functions);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000640
Sean Callanan53bacf212012-05-29 23:46:46 +0000641 if (!ooc.Inspect(*function))
642 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000643
Sean Callanan53bacf212012-05-29 23:46:46 +0000644 if (!ooc.Instrument())
645 return false;
646 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000647
Jim Inghame3be0c52011-01-22 01:25:40 +0000648 if (log && log->GetVerbose())
Sean Callananafa42372010-09-08 20:04:08 +0000649 {
650 std::string s;
651 raw_string_ostream oss(s);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000652
Sean Callananafa42372010-09-08 20:04:08 +0000653 M.print(oss, NULL);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000654
Sean Callananafa42372010-09-08 20:04:08 +0000655 oss.flush();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000656
Jim Inghame3be0c52011-01-22 01:25:40 +0000657 log->Printf ("Module after dynamic checks: \n%s", s.c_str());
Sean Callananafa42372010-09-08 20:04:08 +0000658 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000659
660 return true;
Sean Callanan6961e872010-09-01 00:58:00 +0000661}
662
663void
664IRDynamicChecks::assignPassManager(PMStack &PMS,
665 PassManagerType T)
666{
667}
668
669PassManagerType
670IRDynamicChecks::getPotentialPassManagerType() const
671{
672 return PMT_ModulePassManager;
673}