blob: 30d7f6330f65252e0b65da83c62327a435469b25 [file] [log] [blame]
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +00001//===-- IRDynamicChecks.cpp -------------------------------------*- C++ -*-===//
Sean Callanan6961e872010-09-01 00:58:00 +00002//
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
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +000010// C Includes
11// C++ Includes
12// Other libraries and framework includes
13#include "llvm/Support/raw_ostream.h"
14#include "llvm/IR/Constants.h"
15#include "llvm/IR/DataLayout.h"
16#include "llvm/IR/Function.h"
17#include "llvm/IR/Instructions.h"
18#include "llvm/IR/Module.h"
19#include "llvm/IR/Value.h"
20
21// Project includes
Sean Callanan6961e872010-09-01 00:58:00 +000022#include "lldb/Expression/IRDynamicChecks.h"
Sean Callanan6961e872010-09-01 00:58:00 +000023
Sean Callanan9e6ed532010-09-13 21:34:21 +000024#include "lldb/Core/ConstString.h"
Sean Callanan6961e872010-09-01 00:58:00 +000025#include "lldb/Core/Log.h"
Jim Ingham151c0322015-09-15 21:13:50 +000026#include "lldb/Expression/UtilityFunction.h"
Sean Callanan9e6ed532010-09-13 21:34:21 +000027#include "lldb/Target/ExecutionContext.h"
Sean Callanan10af7c42010-11-04 01:51:38 +000028#include "lldb/Target/ObjCLanguageRuntime.h"
29#include "lldb/Target/Process.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000030#include "lldb/Target/StackFrame.h"
Jim Ingham151c0322015-09-15 21:13:50 +000031#include "lldb/Target/Target.h"
Sean Callanan6961e872010-09-01 00:58:00 +000032
Sean Callanan6961e872010-09-01 00:58:00 +000033using namespace llvm;
34using namespace lldb_private;
35
36static char ID;
37
Greg Clayton7b462cc2010-10-15 22:48:33 +000038#define VALID_POINTER_CHECK_NAME "$__lldb_valid_pointer_check"
39#define VALID_OBJC_OBJECT_CHECK_NAME "$__lldb_objc_object_check"
Sean Callanan9e6ed532010-09-13 21:34:21 +000040
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000041static const char g_valid_pointer_check_text[] =
Greg Clayton7b462cc2010-10-15 22:48:33 +000042"extern \"C\" void\n"
Greg Claytond59cea22010-10-16 21:09:32 +000043"$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n"
Greg Clayton7b462cc2010-10-15 22:48:33 +000044"{\n"
Greg Claytondd36def2010-10-17 22:03:32 +000045" unsigned char $__lldb_local_val = *$__lldb_arg_ptr;\n"
Greg Clayton7b462cc2010-10-15 22:48:33 +000046"}";
Sean Callanan9e6ed532010-09-13 21:34:21 +000047
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +000048DynamicCheckerFunctions::DynamicCheckerFunctions() = default;
Sean Callanan6961e872010-09-01 00:58:00 +000049
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +000050DynamicCheckerFunctions::~DynamicCheckerFunctions() = default;
Sean Callanan6961e872010-09-01 00:58:00 +000051
52bool
53DynamicCheckerFunctions::Install(Stream &error_stream,
54 ExecutionContext &exe_ctx)
55{
Jim Ingham151c0322015-09-15 21:13:50 +000056 Error error;
57 m_valid_pointer_check.reset(exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(g_valid_pointer_check_text,
58 lldb::eLanguageTypeC,
59 VALID_POINTER_CHECK_NAME,
60 error));
61 if (error.Fail())
62 return false;
63
Sean Callanan6961e872010-09-01 00:58:00 +000064 if (!m_valid_pointer_check->Install(error_stream, exe_ctx))
65 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000066
Greg Claytonc14ee322011-09-22 04:58:26 +000067 Process *process = exe_ctx.GetProcessPtr();
68
69 if (process)
Sean Callanan10af7c42010-11-04 01:51:38 +000070 {
Greg Claytonc14ee322011-09-22 04:58:26 +000071 ObjCLanguageRuntime *objc_language_runtime = process->GetObjCLanguageRuntime();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000072
Sean Callanan10af7c42010-11-04 01:51:38 +000073 if (objc_language_runtime)
74 {
75 m_objc_object_check.reset(objc_language_runtime->CreateObjectChecker(VALID_OBJC_OBJECT_CHECK_NAME));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000076
Sean Callanan10af7c42010-11-04 01:51:38 +000077 if (!m_objc_object_check->Install(error_stream, exe_ctx))
78 return false;
79 }
80 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000081
Sean Callanan6961e872010-09-01 00:58:00 +000082 return true;
83}
84
Jim Inghamce553d82011-11-01 02:46:54 +000085bool
86DynamicCheckerFunctions::DoCheckersExplainStop (lldb::addr_t addr, Stream &message)
87{
88 // FIXME: We have to get the checkers to know why they scotched the call in more detail,
89 // so we can print a better message here.
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +000090 if (m_valid_pointer_check && m_valid_pointer_check->ContainsAddress(addr))
Jim Inghamce553d82011-11-01 02:46:54 +000091 {
92 message.Printf ("Attempted to dereference an invalid pointer.");
93 return true;
94 }
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +000095 else if (m_objc_object_check && m_objc_object_check->ContainsAddress(addr))
Jim Inghamce553d82011-11-01 02:46:54 +000096 {
97 message.Printf ("Attempted to dereference an invalid ObjC Object or send it an unrecognized selector");
98 return true;
99 }
100 return false;
101}
102
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000103static std::string
Sean Callanan6961e872010-09-01 00:58:00 +0000104PrintValue(llvm::Value *V, bool truncate = false)
105{
106 std::string s;
107 raw_string_ostream rso(s);
108 V->print(rso);
109 rso.flush();
110 if (truncate)
111 s.resize(s.length() - 1);
112 return s;
113}
114
Sean Callanan8e999e42010-09-02 00:37:32 +0000115//----------------------------------------------------------------------
116/// @class Instrumenter IRDynamicChecks.cpp
117/// @brief Finds and instruments individual LLVM IR instructions
118///
119/// When instrumenting LLVM IR, it is frequently desirable to first search
120/// for instructions, and then later modify them. This way iterators
121/// remain intact, and multiple passes can look at the same code base without
122/// treading on each other's toes.
123///
124/// The Instrumenter class implements this functionality. A client first
125/// calls Inspect on a function, which populates a list of instructions to
126/// be instrumented. Then, later, when all passes' Inspect functions have
127/// been called, the client calls Instrument, which adds the desired
128/// instrumentation.
129///
130/// A subclass of Instrumenter must override InstrumentInstruction, which
131/// is responsible for adding whatever instrumentation is necessary.
132///
133/// A subclass of Instrumenter may override:
134///
135/// - InspectInstruction [default: does nothing]
136///
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000137/// - InspectBasicBlock [default: iterates through the instructions in a
Sean Callanan8e999e42010-09-02 00:37:32 +0000138/// basic block calling InspectInstruction]
139///
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000140/// - InspectFunction [default: iterates through the basic blocks in a
Sean Callanan8e999e42010-09-02 00:37:32 +0000141/// function calling InspectBasicBlock]
142//----------------------------------------------------------------------
143class Instrumenter {
144public:
145 //------------------------------------------------------------------
146 /// Constructor
147 ///
148 /// @param[in] module
149 /// The module being instrumented.
150 //------------------------------------------------------------------
151 Instrumenter (llvm::Module &module,
152 DynamicCheckerFunctions &checker_functions) :
153 m_module(module),
Sean Callanan9e6ed532010-09-13 21:34:21 +0000154 m_checker_functions(checker_functions),
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000155 m_i8ptr_ty(nullptr),
156 m_intptr_ty(nullptr)
Sean Callanan8e999e42010-09-02 00:37:32 +0000157 {
158 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000159
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000160 virtual ~Instrumenter() = default;
Greg Clayton1a65ae12011-01-25 23:55:37 +0000161
Sean Callanan8e999e42010-09-02 00:37:32 +0000162 //------------------------------------------------------------------
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 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000175
Sean Callanan8e999e42010-09-02 00:37:32 +0000176 //------------------------------------------------------------------
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 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000191
Sean Callanan8e999e42010-09-02 00:37:32 +0000192 return true;
193 }
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000194
Sean Callanan8e999e42010-09-02 00:37:32 +0000195protected:
196 //------------------------------------------------------------------
197 /// Add instrumentation to a single instruction
198 ///
199 /// @param[in] inst
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000200 /// The instruction to be instrumented.
Sean Callanan8e999e42010-09-02 00:37:32 +0000201 ///
202 /// @return
203 /// True on success; false otherwise.
204 //------------------------------------------------------------------
205 virtual bool InstrumentInstruction(llvm::Instruction *inst) = 0;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000206
Sean Callanan8e999e42010-09-02 00:37:32 +0000207 //------------------------------------------------------------------
208 /// Register a single instruction to be instrumented
209 ///
210 /// @param[in] inst
211 /// The instruction to be instrumented.
212 //------------------------------------------------------------------
213 void RegisterInstruction(llvm::Instruction &i)
214 {
215 m_to_instrument.push_back(&i);
216 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000217
Sean Callanan8e999e42010-09-02 00:37:32 +0000218 //------------------------------------------------------------------
219 /// Determine whether a single instruction is interesting to
220 /// instrument, and, if so, call RegisterInstruction
221 ///
222 /// @param[in] i
223 /// The instruction to be inspected.
224 ///
225 /// @return
226 /// False if there was an error scanning; true otherwise.
227 //------------------------------------------------------------------
228 virtual bool InspectInstruction(llvm::Instruction &i)
229 {
230 return true;
231 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000232
Sean Callanan8e999e42010-09-02 00:37:32 +0000233 //------------------------------------------------------------------
234 /// Scan a basic block to see if any instructions are interesting
235 ///
236 /// @param[in] bb
237 /// The basic block to be inspected.
238 ///
239 /// @return
240 /// False if there was an error scanning; true otherwise.
241 //------------------------------------------------------------------
242 virtual bool InspectBasicBlock(llvm::BasicBlock &bb)
243 {
244 for (llvm::BasicBlock::iterator ii = bb.begin(), last_ii = bb.end();
245 ii != last_ii;
246 ++ii)
247 {
248 if (!InspectInstruction(*ii))
249 return false;
250 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000251
Sean Callanan8e999e42010-09-02 00:37:32 +0000252 return true;
253 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000254
Sean Callanan8e999e42010-09-02 00:37:32 +0000255 //------------------------------------------------------------------
256 /// Scan a function to see if any instructions are interesting
257 ///
258 /// @param[in] f
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000259 /// The function to be inspected.
Sean Callanan8e999e42010-09-02 00:37:32 +0000260 ///
261 /// @return
262 /// False if there was an error scanning; true otherwise.
263 //------------------------------------------------------------------
264 virtual bool InspectFunction(llvm::Function &f)
265 {
266 for (llvm::Function::iterator bbi = f.begin(), last_bbi = f.end();
267 bbi != last_bbi;
268 ++bbi)
269 {
270 if (!InspectBasicBlock(*bbi))
271 return false;
272 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000273
Sean Callanan8e999e42010-09-02 00:37:32 +0000274 return true;
275 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000276
Sean Callanan9e6ed532010-09-13 21:34:21 +0000277 //------------------------------------------------------------------
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000278 /// Build a function pointer for a function with signature
Sean Callanan9e6ed532010-09-13 21:34:21 +0000279 /// void (*)(uint8_t*) with a given address
280 ///
281 /// @param[in] start_address
282 /// The address of the function.
283 ///
284 /// @return
285 /// The function pointer, for use in a CallInst.
286 //------------------------------------------------------------------
287 llvm::Value *BuildPointerValidatorFunc(lldb::addr_t start_address)
288 {
Sean Callanancc427fa2011-07-30 02:42:06 +0000289 llvm::Type *param_array[1];
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000290
Sean Callanancc427fa2011-07-30 02:42:06 +0000291 param_array[0] = const_cast<llvm::PointerType*>(GetI8PtrTy());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000292
Sean Callanancc427fa2011-07-30 02:42:06 +0000293 ArrayRef<llvm::Type*> params(param_array, 1);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000294
Sean Callanan9e6ed532010-09-13 21:34:21 +0000295 FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true);
296 PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
Sean Callanan439dcae2013-12-20 19:55:02 +0000297 Constant *fun_addr_int = ConstantInt::get(GetIntptrTy(), start_address, false);
Sean Callanan9e6ed532010-09-13 21:34:21 +0000298 return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
299 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000300
Sean Callanan7ba96362011-10-27 00:02:05 +0000301 //------------------------------------------------------------------
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000302 /// Build a function pointer for a function with signature
Sean Callanan7ba96362011-10-27 00:02:05 +0000303 /// void (*)(uint8_t*, uint8_t*) with a given address
304 ///
305 /// @param[in] start_address
306 /// The address of the function.
307 ///
308 /// @return
309 /// The function pointer, for use in a CallInst.
310 //------------------------------------------------------------------
311 llvm::Value *BuildObjectCheckerFunc(lldb::addr_t start_address)
312 {
Sean Callanan7ba96362011-10-27 00:02:05 +0000313 llvm::Type *param_array[2];
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000314
Sean Callanan7ba96362011-10-27 00:02:05 +0000315 param_array[0] = const_cast<llvm::PointerType*>(GetI8PtrTy());
316 param_array[1] = const_cast<llvm::PointerType*>(GetI8PtrTy());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000317
Sean Callanan7ba96362011-10-27 00:02:05 +0000318 ArrayRef<llvm::Type*> params(param_array, 2);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000319
Sean Callanan7ba96362011-10-27 00:02:05 +0000320 FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true);
321 PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
Sean Callanan439dcae2013-12-20 19:55:02 +0000322 Constant *fun_addr_int = ConstantInt::get(GetIntptrTy(), start_address, false);
Sean Callanan7ba96362011-10-27 00:02:05 +0000323 return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
324 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000325
Sean Callanancc427fa2011-07-30 02:42:06 +0000326 PointerType *GetI8PtrTy()
Sean Callanan10af7c42010-11-04 01:51:38 +0000327 {
328 if (!m_i8ptr_ty)
329 m_i8ptr_ty = llvm::Type::getInt8PtrTy(m_module.getContext());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000330
Sean Callanan10af7c42010-11-04 01:51:38 +0000331 return m_i8ptr_ty;
332 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000333
Sean Callanan439dcae2013-12-20 19:55:02 +0000334 IntegerType *GetIntptrTy()
335 {
336 if (!m_intptr_ty)
337 {
338 llvm::DataLayout data_layout(&m_module);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000339
Sean Callanan439dcae2013-12-20 19:55:02 +0000340 m_intptr_ty = llvm::Type::getIntNTy(m_module.getContext(), data_layout.getPointerSizeInBits());
341 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000342
Sean Callanan439dcae2013-12-20 19:55:02 +0000343 return m_intptr_ty;
344 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000345
Sean Callanan8e999e42010-09-02 00:37:32 +0000346 typedef std::vector <llvm::Instruction *> InstVector;
347 typedef InstVector::iterator InstIterator;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000348
Sean Callanan8e999e42010-09-02 00:37:32 +0000349 InstVector m_to_instrument; ///< List of instructions the inspector found
350 llvm::Module &m_module; ///< The module which is being instrumented
351 DynamicCheckerFunctions &m_checker_functions; ///< The dynamic checker functions for the process
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000352
Sean Callanan10af7c42010-11-04 01:51:38 +0000353private:
Sean Callanancc427fa2011-07-30 02:42:06 +0000354 PointerType *m_i8ptr_ty;
Sean Callanan439dcae2013-12-20 19:55:02 +0000355 IntegerType *m_intptr_ty;
Sean Callanan8e999e42010-09-02 00:37:32 +0000356};
357
358class ValidPointerChecker : public Instrumenter
359{
360public:
Greg Clayton1a65ae12011-01-25 23:55:37 +0000361 ValidPointerChecker (llvm::Module &module,
362 DynamicCheckerFunctions &checker_functions) :
Sean Callanan8e999e42010-09-02 00:37:32 +0000363 Instrumenter(module, checker_functions),
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000364 m_valid_pointer_check_func(nullptr)
Sean Callanan8e999e42010-09-02 00:37:32 +0000365 {
366 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000367
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000368 ~ValidPointerChecker() override = default;
369
370protected:
371 bool InstrumentInstruction(llvm::Instruction *inst) override
Sean Callanan8e999e42010-09-02 00:37:32 +0000372 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000373 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan8e999e42010-09-02 00:37:32 +0000374
Enrico Granata20edcdb2011-07-19 18:03:25 +0000375 if (log)
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000376 log->Printf("Instrumenting load/store instruction: %s\n",
Sean Callanan8e999e42010-09-02 00:37:32 +0000377 PrintValue(inst).c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000378
Sean Callanan8e999e42010-09-02 00:37:32 +0000379 if (!m_valid_pointer_check_func)
Sean Callanan9e6ed532010-09-13 21:34:21 +0000380 m_valid_pointer_check_func = BuildPointerValidatorFunc(m_checker_functions.m_valid_pointer_check->StartAddress());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000381
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000382 llvm::Value *dereferenced_ptr = nullptr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000383
Sean Callanan8e999e42010-09-02 00:37:32 +0000384 if (llvm::LoadInst *li = dyn_cast<llvm::LoadInst> (inst))
385 dereferenced_ptr = li->getPointerOperand();
386 else if (llvm::StoreInst *si = dyn_cast<llvm::StoreInst> (inst))
387 dereferenced_ptr = si->getPointerOperand();
388 else
389 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000390
Sean Callanan8e999e42010-09-02 00:37:32 +0000391 // Insert an instruction to cast the loaded value to int8_t*
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000392
Sean Callanan8e999e42010-09-02 00:37:32 +0000393 BitCastInst *bit_cast = new BitCastInst(dereferenced_ptr,
Sean Callanan10af7c42010-11-04 01:51:38 +0000394 GetI8PtrTy(),
Sean Callanan8e999e42010-09-02 00:37:32 +0000395 "",
396 inst);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000397
Sean Callanan8e999e42010-09-02 00:37:32 +0000398 // Insert an instruction to call the helper with the result
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000399
Sean Callanancc427fa2011-07-30 02:42:06 +0000400 llvm::Value *arg_array[1];
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000401
Sean Callanancc427fa2011-07-30 02:42:06 +0000402 arg_array[0] = bit_cast;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000403
Sean Callanancc427fa2011-07-30 02:42:06 +0000404 llvm::ArrayRef<llvm::Value *> args(arg_array, 1);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000405
406 CallInst::Create(m_valid_pointer_check_func,
Sean Callanancc427fa2011-07-30 02:42:06 +0000407 args,
Sean Callanan8e999e42010-09-02 00:37:32 +0000408 "",
409 inst);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000410
Sean Callanan8e999e42010-09-02 00:37:32 +0000411 return true;
412 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000413
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000414 bool InspectInstruction(llvm::Instruction &i) override
Sean Callanan8e999e42010-09-02 00:37:32 +0000415 {
416 if (dyn_cast<llvm::LoadInst> (&i) ||
417 dyn_cast<llvm::StoreInst> (&i))
418 RegisterInstruction(i);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000419
Sean Callanan8e999e42010-09-02 00:37:32 +0000420 return true;
421 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000422
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000423private:
Sean Callanan8e999e42010-09-02 00:37:32 +0000424 llvm::Value *m_valid_pointer_check_func;
Sean Callanan9e6ed532010-09-13 21:34:21 +0000425};
426
427class ObjcObjectChecker : public Instrumenter
428{
429public:
430 ObjcObjectChecker(llvm::Module &module,
431 DynamicCheckerFunctions &checker_functions) :
432 Instrumenter(module, checker_functions),
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000433 m_objc_object_check_func(nullptr)
Sean Callanan9e6ed532010-09-13 21:34:21 +0000434 {
435 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000436
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000437 ~ObjcObjectChecker() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000438
Sean Callanana6cbf062011-11-16 00:20:50 +0000439 enum msgSend_type
440 {
441 eMsgSend = 0,
442 eMsgSendSuper,
443 eMsgSendSuper_stret,
444 eMsgSend_fpret,
445 eMsgSend_stret
446 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000447
Sean Callanana6cbf062011-11-16 00:20:50 +0000448 std::map <llvm::Instruction *, msgSend_type> msgSend_types;
Greg Clayton1a65ae12011-01-25 23:55:37 +0000449
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000450protected:
451 bool InstrumentInstruction(llvm::Instruction *inst) override
Sean Callanan9e6ed532010-09-13 21:34:21 +0000452 {
453 CallInst *call_inst = dyn_cast<CallInst>(inst);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000454
Sean Callanan9e6ed532010-09-13 21:34:21 +0000455 if (!call_inst)
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000456 return false; // call_inst really shouldn't be nullptr, because otherwise InspectInstruction wouldn't have registered it
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000457
Sean Callanan9e6ed532010-09-13 21:34:21 +0000458 if (!m_objc_object_check_func)
Sean Callanan7ba96362011-10-27 00:02:05 +0000459 m_objc_object_check_func = BuildObjectCheckerFunc(m_checker_functions.m_objc_object_check->StartAddress());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000460
Sean Callanan9e6ed532010-09-13 21:34:21 +0000461 // id objc_msgSend(id theReceiver, SEL theSelector, ...)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000462
Sean Callanana6cbf062011-11-16 00:20:50 +0000463 llvm::Value *target_object;
464 llvm::Value *selector;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000465
Sean Callanana6cbf062011-11-16 00:20:50 +0000466 switch (msgSend_types[inst])
467 {
468 case eMsgSend:
469 case eMsgSend_fpret:
470 target_object = call_inst->getArgOperand(0);
471 selector = call_inst->getArgOperand(1);
472 break;
473 case eMsgSend_stret:
474 target_object = call_inst->getArgOperand(1);
475 selector = call_inst->getArgOperand(2);
Greg Clayton23f59502012-07-17 03:23:13 +0000476 break;
Sean Callanana6cbf062011-11-16 00:20:50 +0000477 case eMsgSendSuper:
478 case eMsgSendSuper_stret:
479 return true;
480 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000481
Greg Clayton23f59502012-07-17 03:23:13 +0000482 // These objects should always be valid according to Sean Calannan
483 assert (target_object);
484 assert (selector);
485
Sean Callanan9e6ed532010-09-13 21:34:21 +0000486 // Insert an instruction to cast the receiver id to int8_t*
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000487
Sean Callanan9e6ed532010-09-13 21:34:21 +0000488 BitCastInst *bit_cast = new BitCastInst(target_object,
Sean Callanan10af7c42010-11-04 01:51:38 +0000489 GetI8PtrTy(),
Sean Callanan9e6ed532010-09-13 21:34:21 +0000490 "",
491 inst);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000492
Sean Callanan9e6ed532010-09-13 21:34:21 +0000493 // Insert an instruction to call the helper with the result
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000494
Sean Callanan7ba96362011-10-27 00:02:05 +0000495 llvm::Value *arg_array[2];
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000496
Sean Callanancc427fa2011-07-30 02:42:06 +0000497 arg_array[0] = bit_cast;
Sean Callanan7ba96362011-10-27 00:02:05 +0000498 arg_array[1] = selector;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000499
Sean Callananfc8feb82011-10-31 22:11:40 +0000500 ArrayRef<llvm::Value*> args(arg_array, 2);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000501
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000502 CallInst::Create(m_objc_object_check_func,
Sean Callanancc427fa2011-07-30 02:42:06 +0000503 args,
Sean Callanan9e6ed532010-09-13 21:34:21 +0000504 "",
505 inst);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000506
Sean Callanan9e6ed532010-09-13 21:34:21 +0000507 return true;
508 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000509
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000510 bool InspectInstruction(llvm::Instruction &i) override
Sean Callanan9e6ed532010-09-13 21:34:21 +0000511 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000512 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan9e6ed532010-09-13 21:34:21 +0000513
514 CallInst *call_inst = dyn_cast<CallInst>(&i);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000515
Sean Callanan9e6ed532010-09-13 21:34:21 +0000516 if (call_inst)
517 {
518 // This metadata is set by IRForTarget::MaybeHandleCall().
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000519
Duncan P. N. Exon Smith68caa7d2014-11-12 01:59:53 +0000520 MDNode *metadata = call_inst->getMetadata("lldb.call.realName");
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000521
Sean Callanan9e6ed532010-09-13 21:34:21 +0000522 if (!metadata)
523 return true;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000524
Sean Callanan9e6ed532010-09-13 21:34:21 +0000525 if (metadata->getNumOperands() != 1)
526 {
527 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000528 log->Printf("Function call metadata has %d operands for [%p] %s",
529 metadata->getNumOperands(),
530 static_cast<void*>(call_inst),
531 PrintValue(call_inst).c_str());
Sean Callanan9e6ed532010-09-13 21:34:21 +0000532 return false;
533 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000534
Daniel Maleaf051dbc2013-06-03 20:45:54 +0000535 MDString *real_name = dyn_cast<MDString>(metadata->getOperand(0));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000536
Sean Callanan9e6ed532010-09-13 21:34:21 +0000537 if (!real_name)
538 {
539 if (log)
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000540 log->Printf("Function call metadata is not an MDString for [%p] %s",
541 static_cast<void*>(call_inst),
542 PrintValue(call_inst).c_str());
Sean Callanan9e6ed532010-09-13 21:34:21 +0000543 return false;
544 }
Daniel Maleaf051dbc2013-06-03 20:45:54 +0000545
546 std::string name_str = real_name->getString();
Sean Callanana6cbf062011-11-16 00:20:50 +0000547 const char* name_cstr = name_str.c_str();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000548
Sean Callanand2b465f2012-02-09 03:22:41 +0000549 if (log)
550 log->Printf("Found call to %s: %s\n", name_cstr, PrintValue(call_inst).c_str());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000551
Sean Callanana6cbf062011-11-16 00:20:50 +0000552 if (name_str.find("objc_msgSend") == std::string::npos)
553 return true;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000554
Sean Callanana6cbf062011-11-16 00:20:50 +0000555 if (!strcmp(name_cstr, "objc_msgSend"))
556 {
Sean Callanan9e6ed532010-09-13 21:34:21 +0000557 RegisterInstruction(i);
Sean Callanana6cbf062011-11-16 00:20:50 +0000558 msgSend_types[&i] = eMsgSend;
559 return true;
560 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000561
Sean Callanana6cbf062011-11-16 00:20:50 +0000562 if (!strcmp(name_cstr, "objc_msgSend_stret"))
563 {
564 RegisterInstruction(i);
565 msgSend_types[&i] = eMsgSend_stret;
566 return true;
567 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000568
Sean Callanana6cbf062011-11-16 00:20:50 +0000569 if (!strcmp(name_cstr, "objc_msgSend_fpret"))
570 {
571 RegisterInstruction(i);
572 msgSend_types[&i] = eMsgSend_fpret;
573 return true;
574 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000575
Sean Callanana6cbf062011-11-16 00:20:50 +0000576 if (!strcmp(name_cstr, "objc_msgSendSuper"))
577 {
578 RegisterInstruction(i);
579 msgSend_types[&i] = eMsgSendSuper;
580 return true;
581 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000582
Sean Callanana6cbf062011-11-16 00:20:50 +0000583 if (!strcmp(name_cstr, "objc_msgSendSuper_stret"))
584 {
585 RegisterInstruction(i);
586 msgSend_types[&i] = eMsgSendSuper_stret;
587 return true;
588 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000589
Sean Callanana6cbf062011-11-16 00:20:50 +0000590 if (log)
591 log->Printf("Function name '%s' contains 'objc_msgSend' but is not handled", name_str.c_str());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000592
Sean Callanana6cbf062011-11-16 00:20:50 +0000593 return true;
Sean Callanan9e6ed532010-09-13 21:34:21 +0000594 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000595
Sean Callanan9e6ed532010-09-13 21:34:21 +0000596 return true;
597 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000598
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000599private:
Sean Callanan9e6ed532010-09-13 21:34:21 +0000600 llvm::Value *m_objc_object_check_func;
Sean Callanan8e999e42010-09-02 00:37:32 +0000601};
602
603IRDynamicChecks::IRDynamicChecks(DynamicCheckerFunctions &checker_functions,
604 const char *func_name) :
Sean Callanane2ef6e32010-09-23 03:01:22 +0000605 ModulePass(ID),
Stephen Wilson71c21d12011-04-11 19:41:40 +0000606 m_func_name(func_name),
607 m_checker_functions(checker_functions)
Sean Callanan8e999e42010-09-02 00:37:32 +0000608{
609}
610
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000611IRDynamicChecks::~IRDynamicChecks() = default;
Sean Callanan6961e872010-09-01 00:58:00 +0000612
613bool
614IRDynamicChecks::runOnModule(llvm::Module &M)
615{
Greg Clayton5160ce52013-03-27 23:08:40 +0000616 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000617
Sean Callanan6961e872010-09-01 00:58:00 +0000618 llvm::Function* function = M.getFunction(StringRef(m_func_name.c_str()));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000619
Sean Callanan6961e872010-09-01 00:58:00 +0000620 if (!function)
621 {
622 if (log)
623 log->Printf("Couldn't find %s() in the module", m_func_name.c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000624
Sean Callanan6961e872010-09-01 00:58:00 +0000625 return false;
626 }
Sean Callanan8e999e42010-09-02 00:37:32 +0000627
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000628 if (m_checker_functions.m_valid_pointer_check)
Sean Callanan53bacf212012-05-29 23:46:46 +0000629 {
630 ValidPointerChecker vpc(M, m_checker_functions);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000631
Sean Callanan53bacf212012-05-29 23:46:46 +0000632 if (!vpc.Inspect(*function))
633 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000634
Sean Callanan53bacf212012-05-29 23:46:46 +0000635 if (!vpc.Instrument())
636 return false;
637 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000638
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000639 if (m_checker_functions.m_objc_object_check)
Sean Callanan53bacf212012-05-29 23:46:46 +0000640 {
641 ObjcObjectChecker ooc(M, m_checker_functions);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000642
Sean Callanan53bacf212012-05-29 23:46:46 +0000643 if (!ooc.Inspect(*function))
644 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000645
Sean Callanan53bacf212012-05-29 23:46:46 +0000646 if (!ooc.Instrument())
647 return false;
648 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000649
Jim Inghame3be0c52011-01-22 01:25:40 +0000650 if (log && log->GetVerbose())
Sean Callananafa42372010-09-08 20:04:08 +0000651 {
652 std::string s;
653 raw_string_ostream oss(s);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000654
Eugene Zelenkoadb5b1d2015-10-31 00:43:59 +0000655 M.print(oss, nullptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000656
Sean Callananafa42372010-09-08 20:04:08 +0000657 oss.flush();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000658
Jim Inghame3be0c52011-01-22 01:25:40 +0000659 log->Printf ("Module after dynamic checks: \n%s", s.c_str());
Sean Callananafa42372010-09-08 20:04:08 +0000660 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000661
662 return true;
Sean Callanan6961e872010-09-01 00:58:00 +0000663}
664
665void
666IRDynamicChecks::assignPassManager(PMStack &PMS,
667 PassManagerType T)
668{
669}
670
671PassManagerType
672IRDynamicChecks::getPotentialPassManagerType() const
673{
674 return PMT_ModulePassManager;
675}