1296417Sdim//===-- IRDynamicChecks.cpp -------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10296417Sdim// C Includes 11296417Sdim// C++ Includes 12296417Sdim// Other libraries and framework includes 13296417Sdim#include "llvm/Support/raw_ostream.h" 14296417Sdim#include "llvm/IR/Constants.h" 15296417Sdim#include "llvm/IR/DataLayout.h" 16296417Sdim#include "llvm/IR/Function.h" 17296417Sdim#include "llvm/IR/Instructions.h" 18296417Sdim#include "llvm/IR/Module.h" 19296417Sdim#include "llvm/IR/Value.h" 20296417Sdim 21296417Sdim// Project includes 22254721Semaste#include "lldb/Expression/IRDynamicChecks.h" 23254721Semaste 24254721Semaste#include "lldb/Core/ConstString.h" 25254721Semaste#include "lldb/Core/Log.h" 26296417Sdim#include "lldb/Expression/UtilityFunction.h" 27254721Semaste#include "lldb/Target/ExecutionContext.h" 28254721Semaste#include "lldb/Target/ObjCLanguageRuntime.h" 29254721Semaste#include "lldb/Target/Process.h" 30254721Semaste#include "lldb/Target/StackFrame.h" 31296417Sdim#include "lldb/Target/Target.h" 32254721Semaste 33254721Semasteusing namespace llvm; 34254721Semasteusing namespace lldb_private; 35254721Semaste 36254721Semastestatic char ID; 37254721Semaste 38296417Sdim#define VALID_POINTER_CHECK_NAME "_$__lldb_valid_pointer_check" 39254721Semaste#define VALID_OBJC_OBJECT_CHECK_NAME "$__lldb_objc_object_check" 40254721Semaste 41276479Sdimstatic const char g_valid_pointer_check_text[] = 42254721Semaste"extern \"C\" void\n" 43296417Sdim"_$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n" 44254721Semaste"{\n" 45254721Semaste" unsigned char $__lldb_local_val = *$__lldb_arg_ptr;\n" 46254721Semaste"}"; 47254721Semaste 48296417SdimDynamicCheckerFunctions::DynamicCheckerFunctions() = default; 49254721Semaste 50296417SdimDynamicCheckerFunctions::~DynamicCheckerFunctions() = default; 51254721Semaste 52254721Semastebool 53254721SemasteDynamicCheckerFunctions::Install(Stream &error_stream, 54254721Semaste ExecutionContext &exe_ctx) 55254721Semaste{ 56296417Sdim Error error; 57296417Sdim m_valid_pointer_check.reset(exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage(g_valid_pointer_check_text, 58296417Sdim lldb::eLanguageTypeC, 59296417Sdim VALID_POINTER_CHECK_NAME, 60296417Sdim error)); 61296417Sdim if (error.Fail()) 62296417Sdim return false; 63296417Sdim 64254721Semaste if (!m_valid_pointer_check->Install(error_stream, exe_ctx)) 65254721Semaste return false; 66276479Sdim 67254721Semaste Process *process = exe_ctx.GetProcessPtr(); 68254721Semaste 69254721Semaste if (process) 70254721Semaste { 71254721Semaste ObjCLanguageRuntime *objc_language_runtime = process->GetObjCLanguageRuntime(); 72276479Sdim 73254721Semaste if (objc_language_runtime) 74254721Semaste { 75254721Semaste m_objc_object_check.reset(objc_language_runtime->CreateObjectChecker(VALID_OBJC_OBJECT_CHECK_NAME)); 76276479Sdim 77254721Semaste if (!m_objc_object_check->Install(error_stream, exe_ctx)) 78254721Semaste return false; 79254721Semaste } 80254721Semaste } 81276479Sdim 82254721Semaste return true; 83254721Semaste} 84254721Semaste 85254721Semastebool 86254721SemasteDynamicCheckerFunctions::DoCheckersExplainStop (lldb::addr_t addr, Stream &message) 87254721Semaste{ 88254721Semaste // FIXME: We have to get the checkers to know why they scotched the call in more detail, 89254721Semaste // so we can print a better message here. 90296417Sdim if (m_valid_pointer_check && m_valid_pointer_check->ContainsAddress(addr)) 91254721Semaste { 92254721Semaste message.Printf ("Attempted to dereference an invalid pointer."); 93254721Semaste return true; 94254721Semaste } 95296417Sdim else if (m_objc_object_check && m_objc_object_check->ContainsAddress(addr)) 96254721Semaste { 97254721Semaste message.Printf ("Attempted to dereference an invalid ObjC Object or send it an unrecognized selector"); 98254721Semaste return true; 99254721Semaste } 100254721Semaste return false; 101254721Semaste} 102254721Semaste 103276479Sdimstatic std::string 104254721SemastePrintValue(llvm::Value *V, bool truncate = false) 105254721Semaste{ 106254721Semaste std::string s; 107254721Semaste raw_string_ostream rso(s); 108254721Semaste V->print(rso); 109254721Semaste rso.flush(); 110254721Semaste if (truncate) 111254721Semaste s.resize(s.length() - 1); 112254721Semaste return s; 113254721Semaste} 114254721Semaste 115254721Semaste//---------------------------------------------------------------------- 116254721Semaste/// @class Instrumenter IRDynamicChecks.cpp 117254721Semaste/// @brief Finds and instruments individual LLVM IR instructions 118254721Semaste/// 119254721Semaste/// When instrumenting LLVM IR, it is frequently desirable to first search 120254721Semaste/// for instructions, and then later modify them. This way iterators 121254721Semaste/// remain intact, and multiple passes can look at the same code base without 122254721Semaste/// treading on each other's toes. 123254721Semaste/// 124254721Semaste/// The Instrumenter class implements this functionality. A client first 125254721Semaste/// calls Inspect on a function, which populates a list of instructions to 126254721Semaste/// be instrumented. Then, later, when all passes' Inspect functions have 127254721Semaste/// been called, the client calls Instrument, which adds the desired 128254721Semaste/// instrumentation. 129254721Semaste/// 130254721Semaste/// A subclass of Instrumenter must override InstrumentInstruction, which 131254721Semaste/// is responsible for adding whatever instrumentation is necessary. 132254721Semaste/// 133254721Semaste/// A subclass of Instrumenter may override: 134254721Semaste/// 135254721Semaste/// - InspectInstruction [default: does nothing] 136254721Semaste/// 137276479Sdim/// - InspectBasicBlock [default: iterates through the instructions in a 138254721Semaste/// basic block calling InspectInstruction] 139254721Semaste/// 140276479Sdim/// - InspectFunction [default: iterates through the basic blocks in a 141254721Semaste/// function calling InspectBasicBlock] 142254721Semaste//---------------------------------------------------------------------- 143254721Semasteclass Instrumenter { 144254721Semastepublic: 145254721Semaste //------------------------------------------------------------------ 146254721Semaste /// Constructor 147254721Semaste /// 148254721Semaste /// @param[in] module 149254721Semaste /// The module being instrumented. 150254721Semaste //------------------------------------------------------------------ 151254721Semaste Instrumenter (llvm::Module &module, 152254721Semaste DynamicCheckerFunctions &checker_functions) : 153254721Semaste m_module(module), 154254721Semaste m_checker_functions(checker_functions), 155296417Sdim m_i8ptr_ty(nullptr), 156296417Sdim m_intptr_ty(nullptr) 157254721Semaste { 158254721Semaste } 159276479Sdim 160296417Sdim virtual ~Instrumenter() = default; 161254721Semaste 162254721Semaste //------------------------------------------------------------------ 163254721Semaste /// Inspect a function to find instructions to instrument 164254721Semaste /// 165254721Semaste /// @param[in] function 166254721Semaste /// The function to inspect. 167254721Semaste /// 168254721Semaste /// @return 169254721Semaste /// True on success; false on error. 170254721Semaste //------------------------------------------------------------------ 171254721Semaste bool Inspect (llvm::Function &function) 172254721Semaste { 173254721Semaste return InspectFunction(function); 174254721Semaste } 175276479Sdim 176254721Semaste //------------------------------------------------------------------ 177254721Semaste /// Instrument all the instructions found by Inspect() 178254721Semaste /// 179254721Semaste /// @return 180254721Semaste /// True on success; false on error. 181254721Semaste //------------------------------------------------------------------ 182254721Semaste bool Instrument () 183254721Semaste { 184254721Semaste for (InstIterator ii = m_to_instrument.begin(), last_ii = m_to_instrument.end(); 185254721Semaste ii != last_ii; 186254721Semaste ++ii) 187254721Semaste { 188254721Semaste if (!InstrumentInstruction(*ii)) 189254721Semaste return false; 190254721Semaste } 191276479Sdim 192254721Semaste return true; 193254721Semaste } 194296417Sdim 195254721Semasteprotected: 196254721Semaste //------------------------------------------------------------------ 197254721Semaste /// Add instrumentation to a single instruction 198254721Semaste /// 199254721Semaste /// @param[in] inst 200276479Sdim /// The instruction to be instrumented. 201254721Semaste /// 202254721Semaste /// @return 203254721Semaste /// True on success; false otherwise. 204254721Semaste //------------------------------------------------------------------ 205254721Semaste virtual bool InstrumentInstruction(llvm::Instruction *inst) = 0; 206276479Sdim 207254721Semaste //------------------------------------------------------------------ 208254721Semaste /// Register a single instruction to be instrumented 209254721Semaste /// 210254721Semaste /// @param[in] inst 211254721Semaste /// The instruction to be instrumented. 212254721Semaste //------------------------------------------------------------------ 213254721Semaste void RegisterInstruction(llvm::Instruction &i) 214254721Semaste { 215254721Semaste m_to_instrument.push_back(&i); 216254721Semaste } 217276479Sdim 218254721Semaste //------------------------------------------------------------------ 219254721Semaste /// Determine whether a single instruction is interesting to 220254721Semaste /// instrument, and, if so, call RegisterInstruction 221254721Semaste /// 222254721Semaste /// @param[in] i 223254721Semaste /// The instruction to be inspected. 224254721Semaste /// 225254721Semaste /// @return 226254721Semaste /// False if there was an error scanning; true otherwise. 227254721Semaste //------------------------------------------------------------------ 228254721Semaste virtual bool InspectInstruction(llvm::Instruction &i) 229254721Semaste { 230254721Semaste return true; 231254721Semaste } 232276479Sdim 233254721Semaste //------------------------------------------------------------------ 234254721Semaste /// Scan a basic block to see if any instructions are interesting 235254721Semaste /// 236254721Semaste /// @param[in] bb 237254721Semaste /// The basic block to be inspected. 238254721Semaste /// 239254721Semaste /// @return 240254721Semaste /// False if there was an error scanning; true otherwise. 241254721Semaste //------------------------------------------------------------------ 242254721Semaste virtual bool InspectBasicBlock(llvm::BasicBlock &bb) 243254721Semaste { 244254721Semaste for (llvm::BasicBlock::iterator ii = bb.begin(), last_ii = bb.end(); 245254721Semaste ii != last_ii; 246254721Semaste ++ii) 247254721Semaste { 248254721Semaste if (!InspectInstruction(*ii)) 249254721Semaste return false; 250254721Semaste } 251276479Sdim 252254721Semaste return true; 253254721Semaste } 254276479Sdim 255254721Semaste //------------------------------------------------------------------ 256254721Semaste /// Scan a function to see if any instructions are interesting 257254721Semaste /// 258254721Semaste /// @param[in] f 259276479Sdim /// The function to be inspected. 260254721Semaste /// 261254721Semaste /// @return 262254721Semaste /// False if there was an error scanning; true otherwise. 263254721Semaste //------------------------------------------------------------------ 264254721Semaste virtual bool InspectFunction(llvm::Function &f) 265254721Semaste { 266254721Semaste for (llvm::Function::iterator bbi = f.begin(), last_bbi = f.end(); 267254721Semaste bbi != last_bbi; 268254721Semaste ++bbi) 269254721Semaste { 270254721Semaste if (!InspectBasicBlock(*bbi)) 271254721Semaste return false; 272254721Semaste } 273276479Sdim 274254721Semaste return true; 275254721Semaste } 276276479Sdim 277254721Semaste //------------------------------------------------------------------ 278276479Sdim /// Build a function pointer for a function with signature 279254721Semaste /// void (*)(uint8_t*) with a given address 280254721Semaste /// 281254721Semaste /// @param[in] start_address 282254721Semaste /// The address of the function. 283254721Semaste /// 284254721Semaste /// @return 285254721Semaste /// The function pointer, for use in a CallInst. 286254721Semaste //------------------------------------------------------------------ 287254721Semaste llvm::Value *BuildPointerValidatorFunc(lldb::addr_t start_address) 288254721Semaste { 289254721Semaste llvm::Type *param_array[1]; 290276479Sdim 291254721Semaste param_array[0] = const_cast<llvm::PointerType*>(GetI8PtrTy()); 292276479Sdim 293254721Semaste ArrayRef<llvm::Type*> params(param_array, 1); 294276479Sdim 295254721Semaste FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true); 296254721Semaste PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty); 297262528Semaste Constant *fun_addr_int = ConstantInt::get(GetIntptrTy(), start_address, false); 298254721Semaste return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty); 299254721Semaste } 300276479Sdim 301254721Semaste //------------------------------------------------------------------ 302276479Sdim /// Build a function pointer for a function with signature 303254721Semaste /// void (*)(uint8_t*, uint8_t*) with a given address 304254721Semaste /// 305254721Semaste /// @param[in] start_address 306254721Semaste /// The address of the function. 307254721Semaste /// 308254721Semaste /// @return 309254721Semaste /// The function pointer, for use in a CallInst. 310254721Semaste //------------------------------------------------------------------ 311254721Semaste llvm::Value *BuildObjectCheckerFunc(lldb::addr_t start_address) 312254721Semaste { 313254721Semaste llvm::Type *param_array[2]; 314276479Sdim 315254721Semaste param_array[0] = const_cast<llvm::PointerType*>(GetI8PtrTy()); 316254721Semaste param_array[1] = const_cast<llvm::PointerType*>(GetI8PtrTy()); 317276479Sdim 318254721Semaste ArrayRef<llvm::Type*> params(param_array, 2); 319276479Sdim 320254721Semaste FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true); 321254721Semaste PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty); 322262528Semaste Constant *fun_addr_int = ConstantInt::get(GetIntptrTy(), start_address, false); 323254721Semaste return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty); 324254721Semaste } 325276479Sdim 326254721Semaste PointerType *GetI8PtrTy() 327254721Semaste { 328254721Semaste if (!m_i8ptr_ty) 329254721Semaste m_i8ptr_ty = llvm::Type::getInt8PtrTy(m_module.getContext()); 330276479Sdim 331254721Semaste return m_i8ptr_ty; 332254721Semaste } 333276479Sdim 334262528Semaste IntegerType *GetIntptrTy() 335262528Semaste { 336262528Semaste if (!m_intptr_ty) 337262528Semaste { 338262528Semaste llvm::DataLayout data_layout(&m_module); 339276479Sdim 340262528Semaste m_intptr_ty = llvm::Type::getIntNTy(m_module.getContext(), data_layout.getPointerSizeInBits()); 341262528Semaste } 342276479Sdim 343262528Semaste return m_intptr_ty; 344262528Semaste } 345276479Sdim 346254721Semaste typedef std::vector <llvm::Instruction *> InstVector; 347254721Semaste typedef InstVector::iterator InstIterator; 348276479Sdim 349254721Semaste InstVector m_to_instrument; ///< List of instructions the inspector found 350254721Semaste llvm::Module &m_module; ///< The module which is being instrumented 351254721Semaste DynamicCheckerFunctions &m_checker_functions; ///< The dynamic checker functions for the process 352296417Sdim 353254721Semasteprivate: 354254721Semaste PointerType *m_i8ptr_ty; 355262528Semaste IntegerType *m_intptr_ty; 356254721Semaste}; 357254721Semaste 358254721Semasteclass ValidPointerChecker : public Instrumenter 359254721Semaste{ 360254721Semastepublic: 361254721Semaste ValidPointerChecker (llvm::Module &module, 362254721Semaste DynamicCheckerFunctions &checker_functions) : 363254721Semaste Instrumenter(module, checker_functions), 364296417Sdim m_valid_pointer_check_func(nullptr) 365254721Semaste { 366254721Semaste } 367276479Sdim 368296417Sdim ~ValidPointerChecker() override = default; 369296417Sdim 370296417Sdimprotected: 371296417Sdim bool InstrumentInstruction(llvm::Instruction *inst) override 372254721Semaste { 373254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 374254721Semaste 375254721Semaste if (log) 376276479Sdim log->Printf("Instrumenting load/store instruction: %s\n", 377254721Semaste PrintValue(inst).c_str()); 378276479Sdim 379254721Semaste if (!m_valid_pointer_check_func) 380254721Semaste m_valid_pointer_check_func = BuildPointerValidatorFunc(m_checker_functions.m_valid_pointer_check->StartAddress()); 381276479Sdim 382296417Sdim llvm::Value *dereferenced_ptr = nullptr; 383276479Sdim 384254721Semaste if (llvm::LoadInst *li = dyn_cast<llvm::LoadInst> (inst)) 385254721Semaste dereferenced_ptr = li->getPointerOperand(); 386254721Semaste else if (llvm::StoreInst *si = dyn_cast<llvm::StoreInst> (inst)) 387254721Semaste dereferenced_ptr = si->getPointerOperand(); 388254721Semaste else 389254721Semaste return false; 390276479Sdim 391254721Semaste // Insert an instruction to cast the loaded value to int8_t* 392276479Sdim 393254721Semaste BitCastInst *bit_cast = new BitCastInst(dereferenced_ptr, 394254721Semaste GetI8PtrTy(), 395254721Semaste "", 396254721Semaste inst); 397276479Sdim 398254721Semaste // Insert an instruction to call the helper with the result 399276479Sdim 400254721Semaste llvm::Value *arg_array[1]; 401276479Sdim 402254721Semaste arg_array[0] = bit_cast; 403276479Sdim 404254721Semaste llvm::ArrayRef<llvm::Value *> args(arg_array, 1); 405276479Sdim 406276479Sdim CallInst::Create(m_valid_pointer_check_func, 407254721Semaste args, 408254721Semaste "", 409254721Semaste inst); 410276479Sdim 411254721Semaste return true; 412254721Semaste } 413276479Sdim 414296417Sdim bool InspectInstruction(llvm::Instruction &i) override 415254721Semaste { 416254721Semaste if (dyn_cast<llvm::LoadInst> (&i) || 417254721Semaste dyn_cast<llvm::StoreInst> (&i)) 418254721Semaste RegisterInstruction(i); 419276479Sdim 420254721Semaste return true; 421254721Semaste } 422276479Sdim 423296417Sdimprivate: 424254721Semaste llvm::Value *m_valid_pointer_check_func; 425254721Semaste}; 426254721Semaste 427254721Semasteclass ObjcObjectChecker : public Instrumenter 428254721Semaste{ 429254721Semastepublic: 430254721Semaste ObjcObjectChecker(llvm::Module &module, 431254721Semaste DynamicCheckerFunctions &checker_functions) : 432254721Semaste Instrumenter(module, checker_functions), 433296417Sdim m_objc_object_check_func(nullptr) 434254721Semaste { 435254721Semaste } 436276479Sdim 437296417Sdim ~ObjcObjectChecker() override = default; 438276479Sdim 439254721Semaste enum msgSend_type 440254721Semaste { 441254721Semaste eMsgSend = 0, 442254721Semaste eMsgSendSuper, 443254721Semaste eMsgSendSuper_stret, 444254721Semaste eMsgSend_fpret, 445254721Semaste eMsgSend_stret 446254721Semaste }; 447276479Sdim 448254721Semaste std::map <llvm::Instruction *, msgSend_type> msgSend_types; 449254721Semaste 450296417Sdimprotected: 451296417Sdim bool InstrumentInstruction(llvm::Instruction *inst) override 452254721Semaste { 453254721Semaste CallInst *call_inst = dyn_cast<CallInst>(inst); 454276479Sdim 455254721Semaste if (!call_inst) 456296417Sdim return false; // call_inst really shouldn't be nullptr, because otherwise InspectInstruction wouldn't have registered it 457276479Sdim 458254721Semaste if (!m_objc_object_check_func) 459254721Semaste m_objc_object_check_func = BuildObjectCheckerFunc(m_checker_functions.m_objc_object_check->StartAddress()); 460276479Sdim 461254721Semaste // id objc_msgSend(id theReceiver, SEL theSelector, ...) 462276479Sdim 463254721Semaste llvm::Value *target_object; 464254721Semaste llvm::Value *selector; 465276479Sdim 466254721Semaste switch (msgSend_types[inst]) 467254721Semaste { 468254721Semaste case eMsgSend: 469254721Semaste case eMsgSend_fpret: 470254721Semaste target_object = call_inst->getArgOperand(0); 471254721Semaste selector = call_inst->getArgOperand(1); 472254721Semaste break; 473254721Semaste case eMsgSend_stret: 474254721Semaste target_object = call_inst->getArgOperand(1); 475254721Semaste selector = call_inst->getArgOperand(2); 476254721Semaste break; 477254721Semaste case eMsgSendSuper: 478254721Semaste case eMsgSendSuper_stret: 479254721Semaste return true; 480254721Semaste } 481276479Sdim 482254721Semaste // These objects should always be valid according to Sean Calannan 483254721Semaste assert (target_object); 484254721Semaste assert (selector); 485254721Semaste 486254721Semaste // Insert an instruction to cast the receiver id to int8_t* 487276479Sdim 488254721Semaste BitCastInst *bit_cast = new BitCastInst(target_object, 489254721Semaste GetI8PtrTy(), 490254721Semaste "", 491254721Semaste inst); 492276479Sdim 493254721Semaste // Insert an instruction to call the helper with the result 494276479Sdim 495254721Semaste llvm::Value *arg_array[2]; 496276479Sdim 497254721Semaste arg_array[0] = bit_cast; 498254721Semaste arg_array[1] = selector; 499276479Sdim 500254721Semaste ArrayRef<llvm::Value*> args(arg_array, 2); 501276479Sdim 502276479Sdim CallInst::Create(m_objc_object_check_func, 503254721Semaste args, 504254721Semaste "", 505254721Semaste inst); 506276479Sdim 507254721Semaste return true; 508254721Semaste } 509276479Sdim 510296417Sdim bool InspectInstruction(llvm::Instruction &i) override 511254721Semaste { 512254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 513254721Semaste 514254721Semaste CallInst *call_inst = dyn_cast<CallInst>(&i); 515276479Sdim 516254721Semaste if (call_inst) 517254721Semaste { 518254721Semaste // This metadata is set by IRForTarget::MaybeHandleCall(). 519276479Sdim 520254721Semaste MDNode *metadata = call_inst->getMetadata("lldb.call.realName"); 521276479Sdim 522254721Semaste if (!metadata) 523254721Semaste return true; 524276479Sdim 525254721Semaste if (metadata->getNumOperands() != 1) 526254721Semaste { 527254721Semaste if (log) 528276479Sdim log->Printf("Function call metadata has %d operands for [%p] %s", 529276479Sdim metadata->getNumOperands(), 530276479Sdim static_cast<void*>(call_inst), 531276479Sdim PrintValue(call_inst).c_str()); 532254721Semaste return false; 533254721Semaste } 534276479Sdim 535254721Semaste MDString *real_name = dyn_cast<MDString>(metadata->getOperand(0)); 536276479Sdim 537254721Semaste if (!real_name) 538254721Semaste { 539254721Semaste if (log) 540276479Sdim log->Printf("Function call metadata is not an MDString for [%p] %s", 541276479Sdim static_cast<void*>(call_inst), 542276479Sdim PrintValue(call_inst).c_str()); 543254721Semaste return false; 544254721Semaste } 545254721Semaste 546254721Semaste std::string name_str = real_name->getString(); 547254721Semaste const char* name_cstr = name_str.c_str(); 548276479Sdim 549254721Semaste if (log) 550254721Semaste log->Printf("Found call to %s: %s\n", name_cstr, PrintValue(call_inst).c_str()); 551276479Sdim 552254721Semaste if (name_str.find("objc_msgSend") == std::string::npos) 553254721Semaste return true; 554276479Sdim 555254721Semaste if (!strcmp(name_cstr, "objc_msgSend")) 556254721Semaste { 557254721Semaste RegisterInstruction(i); 558254721Semaste msgSend_types[&i] = eMsgSend; 559254721Semaste return true; 560254721Semaste } 561276479Sdim 562254721Semaste if (!strcmp(name_cstr, "objc_msgSend_stret")) 563254721Semaste { 564254721Semaste RegisterInstruction(i); 565254721Semaste msgSend_types[&i] = eMsgSend_stret; 566254721Semaste return true; 567254721Semaste } 568276479Sdim 569254721Semaste if (!strcmp(name_cstr, "objc_msgSend_fpret")) 570254721Semaste { 571254721Semaste RegisterInstruction(i); 572254721Semaste msgSend_types[&i] = eMsgSend_fpret; 573254721Semaste return true; 574254721Semaste } 575276479Sdim 576254721Semaste if (!strcmp(name_cstr, "objc_msgSendSuper")) 577254721Semaste { 578254721Semaste RegisterInstruction(i); 579254721Semaste msgSend_types[&i] = eMsgSendSuper; 580254721Semaste return true; 581254721Semaste } 582276479Sdim 583254721Semaste if (!strcmp(name_cstr, "objc_msgSendSuper_stret")) 584254721Semaste { 585254721Semaste RegisterInstruction(i); 586254721Semaste msgSend_types[&i] = eMsgSendSuper_stret; 587254721Semaste return true; 588254721Semaste } 589276479Sdim 590254721Semaste if (log) 591254721Semaste log->Printf("Function name '%s' contains 'objc_msgSend' but is not handled", name_str.c_str()); 592276479Sdim 593254721Semaste return true; 594254721Semaste } 595276479Sdim 596254721Semaste return true; 597254721Semaste } 598276479Sdim 599296417Sdimprivate: 600254721Semaste llvm::Value *m_objc_object_check_func; 601254721Semaste}; 602254721Semaste 603254721SemasteIRDynamicChecks::IRDynamicChecks(DynamicCheckerFunctions &checker_functions, 604254721Semaste const char *func_name) : 605254721Semaste ModulePass(ID), 606254721Semaste m_func_name(func_name), 607254721Semaste m_checker_functions(checker_functions) 608254721Semaste{ 609254721Semaste} 610254721Semaste 611296417SdimIRDynamicChecks::~IRDynamicChecks() = default; 612254721Semaste 613254721Semastebool 614254721SemasteIRDynamicChecks::runOnModule(llvm::Module &M) 615254721Semaste{ 616254721Semaste Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 617276479Sdim 618254721Semaste llvm::Function* function = M.getFunction(StringRef(m_func_name.c_str())); 619276479Sdim 620254721Semaste if (!function) 621254721Semaste { 622254721Semaste if (log) 623254721Semaste log->Printf("Couldn't find %s() in the module", m_func_name.c_str()); 624276479Sdim 625254721Semaste return false; 626254721Semaste } 627254721Semaste 628296417Sdim if (m_checker_functions.m_valid_pointer_check) 629254721Semaste { 630254721Semaste ValidPointerChecker vpc(M, m_checker_functions); 631276479Sdim 632254721Semaste if (!vpc.Inspect(*function)) 633254721Semaste return false; 634276479Sdim 635254721Semaste if (!vpc.Instrument()) 636254721Semaste return false; 637254721Semaste } 638276479Sdim 639296417Sdim if (m_checker_functions.m_objc_object_check) 640254721Semaste { 641254721Semaste ObjcObjectChecker ooc(M, m_checker_functions); 642276479Sdim 643254721Semaste if (!ooc.Inspect(*function)) 644254721Semaste return false; 645276479Sdim 646254721Semaste if (!ooc.Instrument()) 647254721Semaste return false; 648254721Semaste } 649276479Sdim 650254721Semaste if (log && log->GetVerbose()) 651254721Semaste { 652254721Semaste std::string s; 653254721Semaste raw_string_ostream oss(s); 654276479Sdim 655296417Sdim M.print(oss, nullptr); 656276479Sdim 657254721Semaste oss.flush(); 658276479Sdim 659254721Semaste log->Printf ("Module after dynamic checks: \n%s", s.c_str()); 660254721Semaste } 661276479Sdim 662276479Sdim return true; 663254721Semaste} 664254721Semaste 665254721Semastevoid 666254721SemasteIRDynamicChecks::assignPassManager(PMStack &PMS, 667254721Semaste PassManagerType T) 668254721Semaste{ 669254721Semaste} 670254721Semaste 671254721SemastePassManagerType 672254721SemasteIRDynamicChecks::getPotentialPassManagerType() const 673254721Semaste{ 674254721Semaste return PMT_ModulePassManager; 675254721Semaste} 676