1*061da546Spatrick //===-- IRDynamicChecks.cpp -------------------------------------*- C++ -*-===// 2*061da546Spatrick // 3*061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5*061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*061da546Spatrick // 7*061da546Spatrick //===----------------------------------------------------------------------===// 8*061da546Spatrick 9*061da546Spatrick #include "llvm/IR/Constants.h" 10*061da546Spatrick #include "llvm/IR/DataLayout.h" 11*061da546Spatrick #include "llvm/IR/Function.h" 12*061da546Spatrick #include "llvm/IR/Instructions.h" 13*061da546Spatrick #include "llvm/IR/Module.h" 14*061da546Spatrick #include "llvm/IR/Value.h" 15*061da546Spatrick #include "llvm/Support/raw_ostream.h" 16*061da546Spatrick 17*061da546Spatrick #include "IRDynamicChecks.h" 18*061da546Spatrick 19*061da546Spatrick #include "lldb/Expression/UtilityFunction.h" 20*061da546Spatrick #include "lldb/Target/ExecutionContext.h" 21*061da546Spatrick #include "lldb/Target/Process.h" 22*061da546Spatrick #include "lldb/Target/StackFrame.h" 23*061da546Spatrick #include "lldb/Target/Target.h" 24*061da546Spatrick #include "lldb/Utility/ConstString.h" 25*061da546Spatrick #include "lldb/Utility/Log.h" 26*061da546Spatrick 27*061da546Spatrick #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" 28*061da546Spatrick 29*061da546Spatrick using namespace llvm; 30*061da546Spatrick using namespace lldb_private; 31*061da546Spatrick 32*061da546Spatrick static char ID; 33*061da546Spatrick 34*061da546Spatrick #define VALID_POINTER_CHECK_NAME "_$__lldb_valid_pointer_check" 35*061da546Spatrick #define VALID_OBJC_OBJECT_CHECK_NAME "$__lldb_objc_object_check" 36*061da546Spatrick 37*061da546Spatrick static const char g_valid_pointer_check_text[] = 38*061da546Spatrick "extern \"C\" void\n" 39*061da546Spatrick "_$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n" 40*061da546Spatrick "{\n" 41*061da546Spatrick " unsigned char $__lldb_local_val = *$__lldb_arg_ptr;\n" 42*061da546Spatrick "}"; 43*061da546Spatrick 44*061da546Spatrick ClangDynamicCheckerFunctions::ClangDynamicCheckerFunctions() 45*061da546Spatrick : DynamicCheckerFunctions(DCF_Clang) {} 46*061da546Spatrick 47*061da546Spatrick ClangDynamicCheckerFunctions::~ClangDynamicCheckerFunctions() = default; 48*061da546Spatrick 49*061da546Spatrick bool ClangDynamicCheckerFunctions::Install( 50*061da546Spatrick DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) { 51*061da546Spatrick Status error; 52*061da546Spatrick m_valid_pointer_check.reset( 53*061da546Spatrick exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage( 54*061da546Spatrick g_valid_pointer_check_text, lldb::eLanguageTypeC, 55*061da546Spatrick VALID_POINTER_CHECK_NAME, error)); 56*061da546Spatrick if (error.Fail()) 57*061da546Spatrick return false; 58*061da546Spatrick 59*061da546Spatrick if (!m_valid_pointer_check->Install(diagnostic_manager, exe_ctx)) 60*061da546Spatrick return false; 61*061da546Spatrick 62*061da546Spatrick Process *process = exe_ctx.GetProcessPtr(); 63*061da546Spatrick 64*061da546Spatrick if (process) { 65*061da546Spatrick ObjCLanguageRuntime *objc_language_runtime = 66*061da546Spatrick ObjCLanguageRuntime::Get(*process); 67*061da546Spatrick 68*061da546Spatrick if (objc_language_runtime) { 69*061da546Spatrick m_objc_object_check.reset(objc_language_runtime->CreateObjectChecker( 70*061da546Spatrick VALID_OBJC_OBJECT_CHECK_NAME)); 71*061da546Spatrick 72*061da546Spatrick if (!m_objc_object_check->Install(diagnostic_manager, exe_ctx)) 73*061da546Spatrick return false; 74*061da546Spatrick } 75*061da546Spatrick } 76*061da546Spatrick 77*061da546Spatrick return true; 78*061da546Spatrick } 79*061da546Spatrick 80*061da546Spatrick bool ClangDynamicCheckerFunctions::DoCheckersExplainStop(lldb::addr_t addr, 81*061da546Spatrick Stream &message) { 82*061da546Spatrick // FIXME: We have to get the checkers to know why they scotched the call in 83*061da546Spatrick // more detail, 84*061da546Spatrick // so we can print a better message here. 85*061da546Spatrick if (m_valid_pointer_check && m_valid_pointer_check->ContainsAddress(addr)) { 86*061da546Spatrick message.Printf("Attempted to dereference an invalid pointer."); 87*061da546Spatrick return true; 88*061da546Spatrick } else if (m_objc_object_check && 89*061da546Spatrick m_objc_object_check->ContainsAddress(addr)) { 90*061da546Spatrick message.Printf("Attempted to dereference an invalid ObjC Object or send it " 91*061da546Spatrick "an unrecognized selector"); 92*061da546Spatrick return true; 93*061da546Spatrick } 94*061da546Spatrick return false; 95*061da546Spatrick } 96*061da546Spatrick 97*061da546Spatrick static std::string PrintValue(llvm::Value *V, bool truncate = false) { 98*061da546Spatrick std::string s; 99*061da546Spatrick raw_string_ostream rso(s); 100*061da546Spatrick V->print(rso); 101*061da546Spatrick rso.flush(); 102*061da546Spatrick if (truncate) 103*061da546Spatrick s.resize(s.length() - 1); 104*061da546Spatrick return s; 105*061da546Spatrick } 106*061da546Spatrick 107*061da546Spatrick /// \class Instrumenter IRDynamicChecks.cpp 108*061da546Spatrick /// Finds and instruments individual LLVM IR instructions 109*061da546Spatrick /// 110*061da546Spatrick /// When instrumenting LLVM IR, it is frequently desirable to first search for 111*061da546Spatrick /// instructions, and then later modify them. This way iterators remain 112*061da546Spatrick /// intact, and multiple passes can look at the same code base without 113*061da546Spatrick /// treading on each other's toes. 114*061da546Spatrick /// 115*061da546Spatrick /// The Instrumenter class implements this functionality. A client first 116*061da546Spatrick /// calls Inspect on a function, which populates a list of instructions to be 117*061da546Spatrick /// instrumented. Then, later, when all passes' Inspect functions have been 118*061da546Spatrick /// called, the client calls Instrument, which adds the desired 119*061da546Spatrick /// instrumentation. 120*061da546Spatrick /// 121*061da546Spatrick /// A subclass of Instrumenter must override InstrumentInstruction, which 122*061da546Spatrick /// is responsible for adding whatever instrumentation is necessary. 123*061da546Spatrick /// 124*061da546Spatrick /// A subclass of Instrumenter may override: 125*061da546Spatrick /// 126*061da546Spatrick /// - InspectInstruction [default: does nothing] 127*061da546Spatrick /// 128*061da546Spatrick /// - InspectBasicBlock [default: iterates through the instructions in a 129*061da546Spatrick /// basic block calling InspectInstruction] 130*061da546Spatrick /// 131*061da546Spatrick /// - InspectFunction [default: iterates through the basic blocks in a 132*061da546Spatrick /// function calling InspectBasicBlock] 133*061da546Spatrick class Instrumenter { 134*061da546Spatrick public: 135*061da546Spatrick /// Constructor 136*061da546Spatrick /// 137*061da546Spatrick /// \param[in] module 138*061da546Spatrick /// The module being instrumented. 139*061da546Spatrick Instrumenter(llvm::Module &module, 140*061da546Spatrick std::shared_ptr<UtilityFunction> checker_function) 141*061da546Spatrick : m_module(module), m_checker_function(checker_function), 142*061da546Spatrick m_i8ptr_ty(nullptr), m_intptr_ty(nullptr) {} 143*061da546Spatrick 144*061da546Spatrick virtual ~Instrumenter() = default; 145*061da546Spatrick 146*061da546Spatrick /// Inspect a function to find instructions to instrument 147*061da546Spatrick /// 148*061da546Spatrick /// \param[in] function 149*061da546Spatrick /// The function to inspect. 150*061da546Spatrick /// 151*061da546Spatrick /// \return 152*061da546Spatrick /// True on success; false on error. 153*061da546Spatrick bool Inspect(llvm::Function &function) { return InspectFunction(function); } 154*061da546Spatrick 155*061da546Spatrick /// Instrument all the instructions found by Inspect() 156*061da546Spatrick /// 157*061da546Spatrick /// \return 158*061da546Spatrick /// True on success; false on error. 159*061da546Spatrick bool Instrument() { 160*061da546Spatrick for (InstIterator ii = m_to_instrument.begin(), 161*061da546Spatrick last_ii = m_to_instrument.end(); 162*061da546Spatrick ii != last_ii; ++ii) { 163*061da546Spatrick if (!InstrumentInstruction(*ii)) 164*061da546Spatrick return false; 165*061da546Spatrick } 166*061da546Spatrick 167*061da546Spatrick return true; 168*061da546Spatrick } 169*061da546Spatrick 170*061da546Spatrick protected: 171*061da546Spatrick /// Add instrumentation to a single instruction 172*061da546Spatrick /// 173*061da546Spatrick /// \param[in] inst 174*061da546Spatrick /// The instruction to be instrumented. 175*061da546Spatrick /// 176*061da546Spatrick /// \return 177*061da546Spatrick /// True on success; false otherwise. 178*061da546Spatrick virtual bool InstrumentInstruction(llvm::Instruction *inst) = 0; 179*061da546Spatrick 180*061da546Spatrick /// Register a single instruction to be instrumented 181*061da546Spatrick /// 182*061da546Spatrick /// \param[in] inst 183*061da546Spatrick /// The instruction to be instrumented. 184*061da546Spatrick void RegisterInstruction(llvm::Instruction &i) { 185*061da546Spatrick m_to_instrument.push_back(&i); 186*061da546Spatrick } 187*061da546Spatrick 188*061da546Spatrick /// Determine whether a single instruction is interesting to instrument, 189*061da546Spatrick /// and, if so, call RegisterInstruction 190*061da546Spatrick /// 191*061da546Spatrick /// \param[in] i 192*061da546Spatrick /// The instruction to be inspected. 193*061da546Spatrick /// 194*061da546Spatrick /// \return 195*061da546Spatrick /// False if there was an error scanning; true otherwise. 196*061da546Spatrick virtual bool InspectInstruction(llvm::Instruction &i) { return true; } 197*061da546Spatrick 198*061da546Spatrick /// Scan a basic block to see if any instructions are interesting 199*061da546Spatrick /// 200*061da546Spatrick /// \param[in] bb 201*061da546Spatrick /// The basic block to be inspected. 202*061da546Spatrick /// 203*061da546Spatrick /// \return 204*061da546Spatrick /// False if there was an error scanning; true otherwise. 205*061da546Spatrick virtual bool InspectBasicBlock(llvm::BasicBlock &bb) { 206*061da546Spatrick for (llvm::BasicBlock::iterator ii = bb.begin(), last_ii = bb.end(); 207*061da546Spatrick ii != last_ii; ++ii) { 208*061da546Spatrick if (!InspectInstruction(*ii)) 209*061da546Spatrick return false; 210*061da546Spatrick } 211*061da546Spatrick 212*061da546Spatrick return true; 213*061da546Spatrick } 214*061da546Spatrick 215*061da546Spatrick /// Scan a function to see if any instructions are interesting 216*061da546Spatrick /// 217*061da546Spatrick /// \param[in] f 218*061da546Spatrick /// The function to be inspected. 219*061da546Spatrick /// 220*061da546Spatrick /// \return 221*061da546Spatrick /// False if there was an error scanning; true otherwise. 222*061da546Spatrick virtual bool InspectFunction(llvm::Function &f) { 223*061da546Spatrick for (llvm::Function::iterator bbi = f.begin(), last_bbi = f.end(); 224*061da546Spatrick bbi != last_bbi; ++bbi) { 225*061da546Spatrick if (!InspectBasicBlock(*bbi)) 226*061da546Spatrick return false; 227*061da546Spatrick } 228*061da546Spatrick 229*061da546Spatrick return true; 230*061da546Spatrick } 231*061da546Spatrick 232*061da546Spatrick /// Build a function pointer for a function with signature void 233*061da546Spatrick /// (*)(uint8_t*) with a given address 234*061da546Spatrick /// 235*061da546Spatrick /// \param[in] start_address 236*061da546Spatrick /// The address of the function. 237*061da546Spatrick /// 238*061da546Spatrick /// \return 239*061da546Spatrick /// The function pointer, for use in a CallInst. 240*061da546Spatrick llvm::FunctionCallee BuildPointerValidatorFunc(lldb::addr_t start_address) { 241*061da546Spatrick llvm::Type *param_array[1]; 242*061da546Spatrick 243*061da546Spatrick param_array[0] = const_cast<llvm::PointerType *>(GetI8PtrTy()); 244*061da546Spatrick 245*061da546Spatrick ArrayRef<llvm::Type *> params(param_array, 1); 246*061da546Spatrick 247*061da546Spatrick FunctionType *fun_ty = FunctionType::get( 248*061da546Spatrick llvm::Type::getVoidTy(m_module.getContext()), params, true); 249*061da546Spatrick PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty); 250*061da546Spatrick Constant *fun_addr_int = 251*061da546Spatrick ConstantInt::get(GetIntptrTy(), start_address, false); 252*061da546Spatrick return {fun_ty, ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty)}; 253*061da546Spatrick } 254*061da546Spatrick 255*061da546Spatrick /// Build a function pointer for a function with signature void 256*061da546Spatrick /// (*)(uint8_t*, uint8_t*) with a given address 257*061da546Spatrick /// 258*061da546Spatrick /// \param[in] start_address 259*061da546Spatrick /// The address of the function. 260*061da546Spatrick /// 261*061da546Spatrick /// \return 262*061da546Spatrick /// The function pointer, for use in a CallInst. 263*061da546Spatrick llvm::FunctionCallee BuildObjectCheckerFunc(lldb::addr_t start_address) { 264*061da546Spatrick llvm::Type *param_array[2]; 265*061da546Spatrick 266*061da546Spatrick param_array[0] = const_cast<llvm::PointerType *>(GetI8PtrTy()); 267*061da546Spatrick param_array[1] = const_cast<llvm::PointerType *>(GetI8PtrTy()); 268*061da546Spatrick 269*061da546Spatrick ArrayRef<llvm::Type *> params(param_array, 2); 270*061da546Spatrick 271*061da546Spatrick FunctionType *fun_ty = FunctionType::get( 272*061da546Spatrick llvm::Type::getVoidTy(m_module.getContext()), params, true); 273*061da546Spatrick PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty); 274*061da546Spatrick Constant *fun_addr_int = 275*061da546Spatrick ConstantInt::get(GetIntptrTy(), start_address, false); 276*061da546Spatrick return {fun_ty, ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty)}; 277*061da546Spatrick } 278*061da546Spatrick 279*061da546Spatrick PointerType *GetI8PtrTy() { 280*061da546Spatrick if (!m_i8ptr_ty) 281*061da546Spatrick m_i8ptr_ty = llvm::Type::getInt8PtrTy(m_module.getContext()); 282*061da546Spatrick 283*061da546Spatrick return m_i8ptr_ty; 284*061da546Spatrick } 285*061da546Spatrick 286*061da546Spatrick IntegerType *GetIntptrTy() { 287*061da546Spatrick if (!m_intptr_ty) { 288*061da546Spatrick llvm::DataLayout data_layout(&m_module); 289*061da546Spatrick 290*061da546Spatrick m_intptr_ty = llvm::Type::getIntNTy(m_module.getContext(), 291*061da546Spatrick data_layout.getPointerSizeInBits()); 292*061da546Spatrick } 293*061da546Spatrick 294*061da546Spatrick return m_intptr_ty; 295*061da546Spatrick } 296*061da546Spatrick 297*061da546Spatrick typedef std::vector<llvm::Instruction *> InstVector; 298*061da546Spatrick typedef InstVector::iterator InstIterator; 299*061da546Spatrick 300*061da546Spatrick InstVector m_to_instrument; ///< List of instructions the inspector found 301*061da546Spatrick llvm::Module &m_module; ///< The module which is being instrumented 302*061da546Spatrick std::shared_ptr<UtilityFunction> 303*061da546Spatrick m_checker_function; ///< The dynamic checker function for the process 304*061da546Spatrick 305*061da546Spatrick private: 306*061da546Spatrick PointerType *m_i8ptr_ty; 307*061da546Spatrick IntegerType *m_intptr_ty; 308*061da546Spatrick }; 309*061da546Spatrick 310*061da546Spatrick class ValidPointerChecker : public Instrumenter { 311*061da546Spatrick public: 312*061da546Spatrick ValidPointerChecker(llvm::Module &module, 313*061da546Spatrick std::shared_ptr<UtilityFunction> checker_function) 314*061da546Spatrick : Instrumenter(module, checker_function), 315*061da546Spatrick m_valid_pointer_check_func(nullptr) {} 316*061da546Spatrick 317*061da546Spatrick ~ValidPointerChecker() override = default; 318*061da546Spatrick 319*061da546Spatrick protected: 320*061da546Spatrick bool InstrumentInstruction(llvm::Instruction *inst) override { 321*061da546Spatrick Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 322*061da546Spatrick 323*061da546Spatrick LLDB_LOGF(log, "Instrumenting load/store instruction: %s\n", 324*061da546Spatrick PrintValue(inst).c_str()); 325*061da546Spatrick 326*061da546Spatrick if (!m_valid_pointer_check_func) 327*061da546Spatrick m_valid_pointer_check_func = 328*061da546Spatrick BuildPointerValidatorFunc(m_checker_function->StartAddress()); 329*061da546Spatrick 330*061da546Spatrick llvm::Value *dereferenced_ptr = nullptr; 331*061da546Spatrick 332*061da546Spatrick if (llvm::LoadInst *li = dyn_cast<llvm::LoadInst>(inst)) 333*061da546Spatrick dereferenced_ptr = li->getPointerOperand(); 334*061da546Spatrick else if (llvm::StoreInst *si = dyn_cast<llvm::StoreInst>(inst)) 335*061da546Spatrick dereferenced_ptr = si->getPointerOperand(); 336*061da546Spatrick else 337*061da546Spatrick return false; 338*061da546Spatrick 339*061da546Spatrick // Insert an instruction to cast the loaded value to int8_t* 340*061da546Spatrick 341*061da546Spatrick BitCastInst *bit_cast = 342*061da546Spatrick new BitCastInst(dereferenced_ptr, GetI8PtrTy(), "", inst); 343*061da546Spatrick 344*061da546Spatrick // Insert an instruction to call the helper with the result 345*061da546Spatrick 346*061da546Spatrick llvm::Value *arg_array[1]; 347*061da546Spatrick 348*061da546Spatrick arg_array[0] = bit_cast; 349*061da546Spatrick 350*061da546Spatrick llvm::ArrayRef<llvm::Value *> args(arg_array, 1); 351*061da546Spatrick 352*061da546Spatrick CallInst::Create(m_valid_pointer_check_func, args, "", inst); 353*061da546Spatrick 354*061da546Spatrick return true; 355*061da546Spatrick } 356*061da546Spatrick 357*061da546Spatrick bool InspectInstruction(llvm::Instruction &i) override { 358*061da546Spatrick if (dyn_cast<llvm::LoadInst>(&i) || dyn_cast<llvm::StoreInst>(&i)) 359*061da546Spatrick RegisterInstruction(i); 360*061da546Spatrick 361*061da546Spatrick return true; 362*061da546Spatrick } 363*061da546Spatrick 364*061da546Spatrick private: 365*061da546Spatrick llvm::FunctionCallee m_valid_pointer_check_func; 366*061da546Spatrick }; 367*061da546Spatrick 368*061da546Spatrick class ObjcObjectChecker : public Instrumenter { 369*061da546Spatrick public: 370*061da546Spatrick ObjcObjectChecker(llvm::Module &module, 371*061da546Spatrick std::shared_ptr<UtilityFunction> checker_function) 372*061da546Spatrick : Instrumenter(module, checker_function), 373*061da546Spatrick m_objc_object_check_func(nullptr) {} 374*061da546Spatrick 375*061da546Spatrick ~ObjcObjectChecker() override = default; 376*061da546Spatrick 377*061da546Spatrick enum msgSend_type { 378*061da546Spatrick eMsgSend = 0, 379*061da546Spatrick eMsgSendSuper, 380*061da546Spatrick eMsgSendSuper_stret, 381*061da546Spatrick eMsgSend_fpret, 382*061da546Spatrick eMsgSend_stret 383*061da546Spatrick }; 384*061da546Spatrick 385*061da546Spatrick std::map<llvm::Instruction *, msgSend_type> msgSend_types; 386*061da546Spatrick 387*061da546Spatrick protected: 388*061da546Spatrick bool InstrumentInstruction(llvm::Instruction *inst) override { 389*061da546Spatrick CallInst *call_inst = dyn_cast<CallInst>(inst); 390*061da546Spatrick 391*061da546Spatrick if (!call_inst) 392*061da546Spatrick return false; // call_inst really shouldn't be nullptr, because otherwise 393*061da546Spatrick // InspectInstruction wouldn't have registered it 394*061da546Spatrick 395*061da546Spatrick if (!m_objc_object_check_func) 396*061da546Spatrick m_objc_object_check_func = 397*061da546Spatrick BuildObjectCheckerFunc(m_checker_function->StartAddress()); 398*061da546Spatrick 399*061da546Spatrick // id objc_msgSend(id theReceiver, SEL theSelector, ...) 400*061da546Spatrick 401*061da546Spatrick llvm::Value *target_object; 402*061da546Spatrick llvm::Value *selector; 403*061da546Spatrick 404*061da546Spatrick switch (msgSend_types[inst]) { 405*061da546Spatrick case eMsgSend: 406*061da546Spatrick case eMsgSend_fpret: 407*061da546Spatrick // On arm64, clang uses objc_msgSend for scalar and struct return 408*061da546Spatrick // calls. The call instruction will record which was used. 409*061da546Spatrick if (call_inst->hasStructRetAttr()) { 410*061da546Spatrick target_object = call_inst->getArgOperand(1); 411*061da546Spatrick selector = call_inst->getArgOperand(2); 412*061da546Spatrick } else { 413*061da546Spatrick target_object = call_inst->getArgOperand(0); 414*061da546Spatrick selector = call_inst->getArgOperand(1); 415*061da546Spatrick } 416*061da546Spatrick break; 417*061da546Spatrick case eMsgSend_stret: 418*061da546Spatrick target_object = call_inst->getArgOperand(1); 419*061da546Spatrick selector = call_inst->getArgOperand(2); 420*061da546Spatrick break; 421*061da546Spatrick case eMsgSendSuper: 422*061da546Spatrick case eMsgSendSuper_stret: 423*061da546Spatrick return true; 424*061da546Spatrick } 425*061da546Spatrick 426*061da546Spatrick // These objects should always be valid according to Sean Calannan 427*061da546Spatrick assert(target_object); 428*061da546Spatrick assert(selector); 429*061da546Spatrick 430*061da546Spatrick // Insert an instruction to cast the receiver id to int8_t* 431*061da546Spatrick 432*061da546Spatrick BitCastInst *bit_cast = 433*061da546Spatrick new BitCastInst(target_object, GetI8PtrTy(), "", inst); 434*061da546Spatrick 435*061da546Spatrick // Insert an instruction to call the helper with the result 436*061da546Spatrick 437*061da546Spatrick llvm::Value *arg_array[2]; 438*061da546Spatrick 439*061da546Spatrick arg_array[0] = bit_cast; 440*061da546Spatrick arg_array[1] = selector; 441*061da546Spatrick 442*061da546Spatrick ArrayRef<llvm::Value *> args(arg_array, 2); 443*061da546Spatrick 444*061da546Spatrick CallInst::Create(m_objc_object_check_func, args, "", inst); 445*061da546Spatrick 446*061da546Spatrick return true; 447*061da546Spatrick } 448*061da546Spatrick 449*061da546Spatrick static llvm::Function *GetFunction(llvm::Value *value) { 450*061da546Spatrick if (llvm::Function *function = llvm::dyn_cast<llvm::Function>(value)) { 451*061da546Spatrick return function; 452*061da546Spatrick } 453*061da546Spatrick 454*061da546Spatrick if (llvm::ConstantExpr *const_expr = 455*061da546Spatrick llvm::dyn_cast<llvm::ConstantExpr>(value)) { 456*061da546Spatrick switch (const_expr->getOpcode()) { 457*061da546Spatrick default: 458*061da546Spatrick return nullptr; 459*061da546Spatrick case llvm::Instruction::BitCast: 460*061da546Spatrick return GetFunction(const_expr->getOperand(0)); 461*061da546Spatrick } 462*061da546Spatrick } 463*061da546Spatrick 464*061da546Spatrick return nullptr; 465*061da546Spatrick } 466*061da546Spatrick 467*061da546Spatrick static llvm::Function *GetCalledFunction(llvm::CallInst *inst) { 468*061da546Spatrick return GetFunction(inst->getCalledValue()); 469*061da546Spatrick } 470*061da546Spatrick 471*061da546Spatrick bool InspectInstruction(llvm::Instruction &i) override { 472*061da546Spatrick Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 473*061da546Spatrick 474*061da546Spatrick CallInst *call_inst = dyn_cast<CallInst>(&i); 475*061da546Spatrick 476*061da546Spatrick if (call_inst) { 477*061da546Spatrick const llvm::Function *called_function = GetCalledFunction(call_inst); 478*061da546Spatrick 479*061da546Spatrick if (!called_function) 480*061da546Spatrick return true; 481*061da546Spatrick 482*061da546Spatrick std::string name_str = called_function->getName().str(); 483*061da546Spatrick const char *name_cstr = name_str.c_str(); 484*061da546Spatrick 485*061da546Spatrick LLDB_LOGF(log, "Found call to %s: %s\n", name_cstr, 486*061da546Spatrick PrintValue(call_inst).c_str()); 487*061da546Spatrick 488*061da546Spatrick if (name_str.find("objc_msgSend") == std::string::npos) 489*061da546Spatrick return true; 490*061da546Spatrick 491*061da546Spatrick if (!strcmp(name_cstr, "objc_msgSend")) { 492*061da546Spatrick RegisterInstruction(i); 493*061da546Spatrick msgSend_types[&i] = eMsgSend; 494*061da546Spatrick return true; 495*061da546Spatrick } 496*061da546Spatrick 497*061da546Spatrick if (!strcmp(name_cstr, "objc_msgSend_stret")) { 498*061da546Spatrick RegisterInstruction(i); 499*061da546Spatrick msgSend_types[&i] = eMsgSend_stret; 500*061da546Spatrick return true; 501*061da546Spatrick } 502*061da546Spatrick 503*061da546Spatrick if (!strcmp(name_cstr, "objc_msgSend_fpret")) { 504*061da546Spatrick RegisterInstruction(i); 505*061da546Spatrick msgSend_types[&i] = eMsgSend_fpret; 506*061da546Spatrick return true; 507*061da546Spatrick } 508*061da546Spatrick 509*061da546Spatrick if (!strcmp(name_cstr, "objc_msgSendSuper")) { 510*061da546Spatrick RegisterInstruction(i); 511*061da546Spatrick msgSend_types[&i] = eMsgSendSuper; 512*061da546Spatrick return true; 513*061da546Spatrick } 514*061da546Spatrick 515*061da546Spatrick if (!strcmp(name_cstr, "objc_msgSendSuper_stret")) { 516*061da546Spatrick RegisterInstruction(i); 517*061da546Spatrick msgSend_types[&i] = eMsgSendSuper_stret; 518*061da546Spatrick return true; 519*061da546Spatrick } 520*061da546Spatrick 521*061da546Spatrick LLDB_LOGF(log, 522*061da546Spatrick "Function name '%s' contains 'objc_msgSend' but is not handled", 523*061da546Spatrick name_str.c_str()); 524*061da546Spatrick 525*061da546Spatrick return true; 526*061da546Spatrick } 527*061da546Spatrick 528*061da546Spatrick return true; 529*061da546Spatrick } 530*061da546Spatrick 531*061da546Spatrick private: 532*061da546Spatrick llvm::FunctionCallee m_objc_object_check_func; 533*061da546Spatrick }; 534*061da546Spatrick 535*061da546Spatrick IRDynamicChecks::IRDynamicChecks( 536*061da546Spatrick ClangDynamicCheckerFunctions &checker_functions, const char *func_name) 537*061da546Spatrick : ModulePass(ID), m_func_name(func_name), 538*061da546Spatrick m_checker_functions(checker_functions) {} 539*061da546Spatrick 540*061da546Spatrick IRDynamicChecks::~IRDynamicChecks() = default; 541*061da546Spatrick 542*061da546Spatrick bool IRDynamicChecks::runOnModule(llvm::Module &M) { 543*061da546Spatrick Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 544*061da546Spatrick 545*061da546Spatrick llvm::Function *function = M.getFunction(StringRef(m_func_name)); 546*061da546Spatrick 547*061da546Spatrick if (!function) { 548*061da546Spatrick LLDB_LOGF(log, "Couldn't find %s() in the module", m_func_name.c_str()); 549*061da546Spatrick 550*061da546Spatrick return false; 551*061da546Spatrick } 552*061da546Spatrick 553*061da546Spatrick if (m_checker_functions.m_valid_pointer_check) { 554*061da546Spatrick ValidPointerChecker vpc(M, m_checker_functions.m_valid_pointer_check); 555*061da546Spatrick 556*061da546Spatrick if (!vpc.Inspect(*function)) 557*061da546Spatrick return false; 558*061da546Spatrick 559*061da546Spatrick if (!vpc.Instrument()) 560*061da546Spatrick return false; 561*061da546Spatrick } 562*061da546Spatrick 563*061da546Spatrick if (m_checker_functions.m_objc_object_check) { 564*061da546Spatrick ObjcObjectChecker ooc(M, m_checker_functions.m_objc_object_check); 565*061da546Spatrick 566*061da546Spatrick if (!ooc.Inspect(*function)) 567*061da546Spatrick return false; 568*061da546Spatrick 569*061da546Spatrick if (!ooc.Instrument()) 570*061da546Spatrick return false; 571*061da546Spatrick } 572*061da546Spatrick 573*061da546Spatrick if (log && log->GetVerbose()) { 574*061da546Spatrick std::string s; 575*061da546Spatrick raw_string_ostream oss(s); 576*061da546Spatrick 577*061da546Spatrick M.print(oss, nullptr); 578*061da546Spatrick 579*061da546Spatrick oss.flush(); 580*061da546Spatrick 581*061da546Spatrick LLDB_LOGF(log, "Module after dynamic checks: \n%s", s.c_str()); 582*061da546Spatrick } 583*061da546Spatrick 584*061da546Spatrick return true; 585*061da546Spatrick } 586*061da546Spatrick 587*061da546Spatrick void IRDynamicChecks::assignPassManager(PMStack &PMS, PassManagerType T) {} 588*061da546Spatrick 589*061da546Spatrick PassManagerType IRDynamicChecks::getPotentialPassManagerType() const { 590*061da546Spatrick return PMT_ModulePassManager; 591*061da546Spatrick } 592