1f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan//===-- IRDynamicChecks.cpp -------------------------------------------*- C++ -*-===// 2f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan// 3f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan// The LLVM Compiler Infrastructure 4f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan// 5f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan// This file is distributed under the University of Illinois Open Source 6f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan// License. See LICENSE.TXT for details. 7f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan// 8f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan//===----------------------------------------------------------------------===// 9f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 10f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan#include "lldb/Expression/IRDynamicChecks.h" 11f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 12e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan#include "lldb/Core/ConstString.h" 13f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan#include "lldb/Core/Log.h" 14e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan#include "lldb/Expression/ClangUtilityFunction.h" 15e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan#include "lldb/Target/ExecutionContext.h" 1614a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan#include "lldb/Target/ObjCLanguageRuntime.h" 1714a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan#include "lldb/Target/Process.h" 18e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan#include "lldb/Target/StackFrame.h" 19f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 20f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan#include "llvm/Support/raw_ostream.h" 21a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Constants.h" 22a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Function.h" 23a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Instructions.h" 24a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Module.h" 25a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Value.h" 26f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 27f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callananusing namespace llvm; 28f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callananusing namespace lldb_private; 29f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 30f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callananstatic char ID; 31f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 328de27c761a22187ef63fb60000894be163e7285fGreg Clayton#define VALID_POINTER_CHECK_NAME "$__lldb_valid_pointer_check" 338de27c761a22187ef63fb60000894be163e7285fGreg Clayton#define VALID_OBJC_OBJECT_CHECK_NAME "$__lldb_objc_object_check" 34e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 358de27c761a22187ef63fb60000894be163e7285fGreg Claytonstatic const char g_valid_pointer_check_text[] = 368de27c761a22187ef63fb60000894be163e7285fGreg Clayton"extern \"C\" void\n" 3721f5fe13a24510b9e77946b49873fdc60979bb1eGreg Clayton"$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n" 388de27c761a22187ef63fb60000894be163e7285fGreg Clayton"{\n" 3924b48ff28b7c60dd4598212c3e77935a0fc1142dGreg Clayton" unsigned char $__lldb_local_val = *$__lldb_arg_ptr;\n" 408de27c761a22187ef63fb60000894be163e7285fGreg Clayton"}"; 41e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 42f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean CallananDynamicCheckerFunctions::DynamicCheckerFunctions () 43f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan{ 44f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan} 45f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 46f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean CallananDynamicCheckerFunctions::~DynamicCheckerFunctions () 47f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan{ 48f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan} 49f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 50f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callananbool 51f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean CallananDynamicCheckerFunctions::Install(Stream &error_stream, 52f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan ExecutionContext &exe_ctx) 53f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan{ 548de27c761a22187ef63fb60000894be163e7285fGreg Clayton m_valid_pointer_check.reset(new ClangUtilityFunction(g_valid_pointer_check_text, 558de27c761a22187ef63fb60000894be163e7285fGreg Clayton VALID_POINTER_CHECK_NAME)); 56f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan if (!m_valid_pointer_check->Install(error_stream, exe_ctx)) 57f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan return false; 5814a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan 59567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 60567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton 61567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton if (process) 6214a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan { 63567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton ObjCLanguageRuntime *objc_language_runtime = process->GetObjCLanguageRuntime(); 6414a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan 6514a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan if (objc_language_runtime) 6614a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan { 6714a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan m_objc_object_check.reset(objc_language_runtime->CreateObjectChecker(VALID_OBJC_OBJECT_CHECK_NAME)); 6814a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan 6914a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan if (!m_objc_object_check->Install(error_stream, exe_ctx)) 7014a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan return false; 7114a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan } 7214a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan } 73f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 74f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan return true; 75f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan} 76f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 77ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Inghambool 78ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim InghamDynamicCheckerFunctions::DoCheckersExplainStop (lldb::addr_t addr, Stream &message) 79ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham{ 80ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham // FIXME: We have to get the checkers to know why they scotched the call in more detail, 81ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham // so we can print a better message here. 82ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham if (m_valid_pointer_check.get() != NULL && m_valid_pointer_check->ContainsAddress(addr)) 83ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham { 84ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham message.Printf ("Attempted to dereference an invalid pointer."); 85ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham return true; 86ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham } 87ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham else if (m_objc_object_check.get() != NULL && m_objc_object_check->ContainsAddress(addr)) 88ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham { 89ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham message.Printf ("Attempted to dereference an invalid ObjC Object or send it an unrecognized selector"); 90ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham return true; 91ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham } 92ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham return false; 93ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham} 94ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham 95ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham 96f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callananstatic std::string 97f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean CallananPrintValue(llvm::Value *V, bool truncate = false) 98f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan{ 99f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan std::string s; 100f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan raw_string_ostream rso(s); 101f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan V->print(rso); 102f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan rso.flush(); 103f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan if (truncate) 104f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan s.resize(s.length() - 1); 105f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan return s; 106f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan} 107f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 1080526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan//---------------------------------------------------------------------- 1090526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// @class Instrumenter IRDynamicChecks.cpp 1100526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// @brief Finds and instruments individual LLVM IR instructions 1110526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// 1120526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// When instrumenting LLVM IR, it is frequently desirable to first search 1130526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// for instructions, and then later modify them. This way iterators 1140526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// remain intact, and multiple passes can look at the same code base without 1150526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// treading on each other's toes. 1160526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// 1170526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// The Instrumenter class implements this functionality. A client first 1180526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// calls Inspect on a function, which populates a list of instructions to 1190526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// be instrumented. Then, later, when all passes' Inspect functions have 1200526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// been called, the client calls Instrument, which adds the desired 1210526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// instrumentation. 1220526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// 1230526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// A subclass of Instrumenter must override InstrumentInstruction, which 1240526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// is responsible for adding whatever instrumentation is necessary. 1250526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// 1260526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// A subclass of Instrumenter may override: 1270526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// 1280526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// - InspectInstruction [default: does nothing] 1290526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// 1300526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// - InspectBasicBlock [default: iterates through the instructions in a 1310526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// basic block calling InspectInstruction] 1320526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// 1330526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// - InspectFunction [default: iterates through the basic blocks in a 1340526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan/// function calling InspectBasicBlock] 1350526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan//---------------------------------------------------------------------- 1360526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callananclass Instrumenter { 1370526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callananpublic: 1380526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan //------------------------------------------------------------------ 1390526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// Constructor 1400526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// 1410526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// @param[in] module 1420526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// The module being instrumented. 1430526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan //------------------------------------------------------------------ 1440526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan Instrumenter (llvm::Module &module, 1450526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan DynamicCheckerFunctions &checker_functions) : 1460526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan m_module(module), 147e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan m_checker_functions(checker_functions), 148e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan m_i8ptr_ty(NULL) 1490526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan { 1500526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan } 1510526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 152bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton virtual~Instrumenter () 153bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton { 154bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton } 155bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton 1560526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan //------------------------------------------------------------------ 1570526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// Inspect a function to find instructions to instrument 1580526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// 1590526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// @param[in] function 1600526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// The function to inspect. 1610526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// 1620526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// @return 1630526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// True on success; false on error. 1640526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan //------------------------------------------------------------------ 1650526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan bool Inspect (llvm::Function &function) 1660526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan { 1670526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan return InspectFunction(function); 1680526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan } 1690526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 1700526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan //------------------------------------------------------------------ 1710526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// Instrument all the instructions found by Inspect() 1720526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// 1730526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// @return 1740526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// True on success; false on error. 1750526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan //------------------------------------------------------------------ 1760526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan bool Instrument () 1770526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan { 1780526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan for (InstIterator ii = m_to_instrument.begin(), last_ii = m_to_instrument.end(); 1790526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan ii != last_ii; 1800526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan ++ii) 1810526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan { 1820526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan if (!InstrumentInstruction(*ii)) 1830526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan return false; 1840526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan } 1850526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 1860526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan return true; 1870526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan } 1880526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callananprotected: 1890526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan //------------------------------------------------------------------ 1900526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// Add instrumentation to a single instruction 1910526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// 1920526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// @param[in] inst 1930526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// The instruction to be instrumented. 1940526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// 1950526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// @return 1960526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// True on success; false otherwise. 1970526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan //------------------------------------------------------------------ 1980526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan virtual bool InstrumentInstruction(llvm::Instruction *inst) = 0; 1990526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 2000526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan //------------------------------------------------------------------ 2010526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// Register a single instruction to be instrumented 2020526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// 2030526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// @param[in] inst 2040526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// The instruction to be instrumented. 2050526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan //------------------------------------------------------------------ 2060526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan void RegisterInstruction(llvm::Instruction &i) 2070526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan { 2080526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan m_to_instrument.push_back(&i); 2090526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan } 2100526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 2110526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan //------------------------------------------------------------------ 2120526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// Determine whether a single instruction is interesting to 2130526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// instrument, and, if so, call RegisterInstruction 2140526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// 2150526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// @param[in] i 2160526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// The instruction to be inspected. 2170526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// 2180526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// @return 2190526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// False if there was an error scanning; true otherwise. 2200526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan //------------------------------------------------------------------ 2210526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan virtual bool InspectInstruction(llvm::Instruction &i) 2220526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan { 2230526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan return true; 2240526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan } 2250526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 2260526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan //------------------------------------------------------------------ 2270526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// Scan a basic block to see if any instructions are interesting 2280526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// 2290526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// @param[in] bb 2300526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// The basic block to be inspected. 2310526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// 2320526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// @return 2330526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// False if there was an error scanning; true otherwise. 2340526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan //------------------------------------------------------------------ 2350526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan virtual bool InspectBasicBlock(llvm::BasicBlock &bb) 2360526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan { 2370526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan for (llvm::BasicBlock::iterator ii = bb.begin(), last_ii = bb.end(); 2380526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan ii != last_ii; 2390526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan ++ii) 2400526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan { 2410526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan if (!InspectInstruction(*ii)) 2420526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan return false; 2430526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan } 2440526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 2450526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan return true; 2460526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan } 2470526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 2480526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan //------------------------------------------------------------------ 2490526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// Scan a function to see if any instructions are interesting 2500526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// 2510526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// @param[in] f 2520526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// The function to be inspected. 2530526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// 2540526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// @return 2550526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan /// False if there was an error scanning; true otherwise. 2560526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan //------------------------------------------------------------------ 2570526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan virtual bool InspectFunction(llvm::Function &f) 2580526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan { 2590526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan for (llvm::Function::iterator bbi = f.begin(), last_bbi = f.end(); 2600526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan bbi != last_bbi; 2610526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan ++bbi) 2620526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan { 2630526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan if (!InspectBasicBlock(*bbi)) 2640526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan return false; 2650526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan } 2660526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 2670526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan return true; 2680526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan } 2690526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 270e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan //------------------------------------------------------------------ 271e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan /// Build a function pointer for a function with signature 272e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan /// void (*)(uint8_t*) with a given address 273e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan /// 274e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan /// @param[in] start_address 275e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan /// The address of the function. 276e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan /// 277e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan /// @return 278e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan /// The function pointer, for use in a CallInst. 279e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan //------------------------------------------------------------------ 280e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan llvm::Value *BuildPointerValidatorFunc(lldb::addr_t start_address) 281e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan { 2829b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan IntegerType *intptr_ty = llvm::Type::getIntNTy(m_module.getContext(), 2834fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan (m_module.getPointerSize() == llvm::Module::Pointer64) ? 64 : 32); 284e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 2859b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan llvm::Type *param_array[1]; 2869b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 2879b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan param_array[0] = const_cast<llvm::PointerType*>(GetI8PtrTy()); 2889b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 2899b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan ArrayRef<llvm::Type*> params(param_array, 1); 290e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 291e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true); 292e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty); 293e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan Constant *fun_addr_int = ConstantInt::get(intptr_ty, start_address, false); 294e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty); 295e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan } 296e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 29720b8a9643335e959d8822d720618be13c363f28eSean Callanan //------------------------------------------------------------------ 29820b8a9643335e959d8822d720618be13c363f28eSean Callanan /// Build a function pointer for a function with signature 29920b8a9643335e959d8822d720618be13c363f28eSean Callanan /// void (*)(uint8_t*, uint8_t*) with a given address 30020b8a9643335e959d8822d720618be13c363f28eSean Callanan /// 30120b8a9643335e959d8822d720618be13c363f28eSean Callanan /// @param[in] start_address 30220b8a9643335e959d8822d720618be13c363f28eSean Callanan /// The address of the function. 30320b8a9643335e959d8822d720618be13c363f28eSean Callanan /// 30420b8a9643335e959d8822d720618be13c363f28eSean Callanan /// @return 30520b8a9643335e959d8822d720618be13c363f28eSean Callanan /// The function pointer, for use in a CallInst. 30620b8a9643335e959d8822d720618be13c363f28eSean Callanan //------------------------------------------------------------------ 30720b8a9643335e959d8822d720618be13c363f28eSean Callanan llvm::Value *BuildObjectCheckerFunc(lldb::addr_t start_address) 30820b8a9643335e959d8822d720618be13c363f28eSean Callanan { 30920b8a9643335e959d8822d720618be13c363f28eSean Callanan IntegerType *intptr_ty = llvm::Type::getIntNTy(m_module.getContext(), 3104fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan (m_module.getPointerSize() == llvm::Module::Pointer64) ? 64 : 32); 31120b8a9643335e959d8822d720618be13c363f28eSean Callanan 31220b8a9643335e959d8822d720618be13c363f28eSean Callanan llvm::Type *param_array[2]; 31320b8a9643335e959d8822d720618be13c363f28eSean Callanan 31420b8a9643335e959d8822d720618be13c363f28eSean Callanan param_array[0] = const_cast<llvm::PointerType*>(GetI8PtrTy()); 31520b8a9643335e959d8822d720618be13c363f28eSean Callanan param_array[1] = const_cast<llvm::PointerType*>(GetI8PtrTy()); 31620b8a9643335e959d8822d720618be13c363f28eSean Callanan 31720b8a9643335e959d8822d720618be13c363f28eSean Callanan ArrayRef<llvm::Type*> params(param_array, 2); 31820b8a9643335e959d8822d720618be13c363f28eSean Callanan 31920b8a9643335e959d8822d720618be13c363f28eSean Callanan FunctionType *fun_ty = FunctionType::get(llvm::Type::getVoidTy(m_module.getContext()), params, true); 32020b8a9643335e959d8822d720618be13c363f28eSean Callanan PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty); 32120b8a9643335e959d8822d720618be13c363f28eSean Callanan Constant *fun_addr_int = ConstantInt::get(intptr_ty, start_address, false); 32220b8a9643335e959d8822d720618be13c363f28eSean Callanan return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty); 32320b8a9643335e959d8822d720618be13c363f28eSean Callanan } 32420b8a9643335e959d8822d720618be13c363f28eSean Callanan 3259b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan PointerType *GetI8PtrTy() 32614a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan { 32714a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan if (!m_i8ptr_ty) 32814a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan m_i8ptr_ty = llvm::Type::getInt8PtrTy(m_module.getContext()); 32914a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan 33014a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan return m_i8ptr_ty; 33114a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan } 33214a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan 3330526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan typedef std::vector <llvm::Instruction *> InstVector; 3340526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan typedef InstVector::iterator InstIterator; 3350526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 3360526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan InstVector m_to_instrument; ///< List of instructions the inspector found 3370526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan llvm::Module &m_module; ///< The module which is being instrumented 3380526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan DynamicCheckerFunctions &m_checker_functions; ///< The dynamic checker functions for the process 33914a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callananprivate: 3409b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan PointerType *m_i8ptr_ty; 3410526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan}; 3420526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 3430526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callananclass ValidPointerChecker : public Instrumenter 3440526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan{ 3450526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callananpublic: 346bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton ValidPointerChecker (llvm::Module &module, 347bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton DynamicCheckerFunctions &checker_functions) : 3480526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan Instrumenter(module, checker_functions), 3490526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan m_valid_pointer_check_func(NULL) 3500526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan { 3510526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan } 352bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton 353bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton virtual ~ValidPointerChecker () 354bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton { 355bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton } 3560526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callananprivate: 3570526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan bool InstrumentInstruction(llvm::Instruction *inst) 3580526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan { 359952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 3600526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 3614c3fb4b50a87e6e08987096d7edacc26545f58dcEnrico Granata if (log) 3620526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan log->Printf("Instrumenting load/store instruction: %s\n", 3630526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan PrintValue(inst).c_str()); 3640526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 3650526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan if (!m_valid_pointer_check_func) 366e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan m_valid_pointer_check_func = BuildPointerValidatorFunc(m_checker_functions.m_valid_pointer_check->StartAddress()); 3670526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 36858baaada202ea16e928f0c76e9124d42fd3655cdSean Callanan llvm::Value *dereferenced_ptr = NULL; 3690526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 3700526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan if (llvm::LoadInst *li = dyn_cast<llvm::LoadInst> (inst)) 3710526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan dereferenced_ptr = li->getPointerOperand(); 3720526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan else if (llvm::StoreInst *si = dyn_cast<llvm::StoreInst> (inst)) 3730526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan dereferenced_ptr = si->getPointerOperand(); 3740526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan else 3750526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan return false; 3760526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 3770526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan // Insert an instruction to cast the loaded value to int8_t* 3780526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 3790526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan BitCastInst *bit_cast = new BitCastInst(dereferenced_ptr, 38014a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan GetI8PtrTy(), 3810526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan "", 3820526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan inst); 3830526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 3840526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan // Insert an instruction to call the helper with the result 3850526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 3869b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan llvm::Value *arg_array[1]; 3879b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 3889b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan arg_array[0] = bit_cast; 3899b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 3909b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan llvm::ArrayRef<llvm::Value *> args(arg_array, 1); 3910526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 3920526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan CallInst::Create(m_valid_pointer_check_func, 3939b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan args, 3940526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan "", 3950526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan inst); 3960526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 3970526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan return true; 3980526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan } 3990526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 4000526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan bool InspectInstruction(llvm::Instruction &i) 4010526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan { 4020526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan if (dyn_cast<llvm::LoadInst> (&i) || 4030526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan dyn_cast<llvm::StoreInst> (&i)) 4040526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan RegisterInstruction(i); 4050526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 4060526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan return true; 4070526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan } 4080526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 4090526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan llvm::Value *m_valid_pointer_check_func; 410e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan}; 411e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 412e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callananclass ObjcObjectChecker : public Instrumenter 413e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan{ 414e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callananpublic: 415e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan ObjcObjectChecker(llvm::Module &module, 416e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan DynamicCheckerFunctions &checker_functions) : 417e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan Instrumenter(module, checker_functions), 418e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan m_objc_object_check_func(NULL) 419e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan { 420e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan } 421bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton 422bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton virtual 423bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton ~ObjcObjectChecker () 424bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton { 425bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton } 4267befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan 4277befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan enum msgSend_type 4287befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan { 4297befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan eMsgSend = 0, 4307befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan eMsgSendSuper, 4317befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan eMsgSendSuper_stret, 4327befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan eMsgSend_fpret, 4337befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan eMsgSend_stret 4347befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan }; 4357befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan 4367befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan std::map <llvm::Instruction *, msgSend_type> msgSend_types; 437bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton 438e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callananprivate: 439e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan bool InstrumentInstruction(llvm::Instruction *inst) 440e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan { 441e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan CallInst *call_inst = dyn_cast<CallInst>(inst); 442e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 443e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan if (!call_inst) 44414a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan return false; // call_inst really shouldn't be NULL, because otherwise InspectInstruction wouldn't have registered it 445e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 446e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan if (!m_objc_object_check_func) 44720b8a9643335e959d8822d720618be13c363f28eSean Callanan m_objc_object_check_func = BuildObjectCheckerFunc(m_checker_functions.m_objc_object_check->StartAddress()); 448e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 449e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan // id objc_msgSend(id theReceiver, SEL theSelector, ...) 450e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 4517befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan llvm::Value *target_object; 4527befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan llvm::Value *selector; 4537befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan 4547befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan switch (msgSend_types[inst]) 4557befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan { 4567befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan case eMsgSend: 4577befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan case eMsgSend_fpret: 4587befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan target_object = call_inst->getArgOperand(0); 4597befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan selector = call_inst->getArgOperand(1); 4607befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan break; 4617befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan case eMsgSend_stret: 4627befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan target_object = call_inst->getArgOperand(1); 4637befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan selector = call_inst->getArgOperand(2); 4644a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton break; 4657befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan case eMsgSendSuper: 4667befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan case eMsgSendSuper_stret: 4677befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan return true; 4687befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan } 4694a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton 4704a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton // These objects should always be valid according to Sean Calannan 4714a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton assert (target_object); 4724a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton assert (selector); 4734a379b1194f3e6b308cd6e80b45d6ca5dd0aafd7Greg Clayton 474e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan // Insert an instruction to cast the receiver id to int8_t* 475e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 476e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan BitCastInst *bit_cast = new BitCastInst(target_object, 47714a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan GetI8PtrTy(), 478e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan "", 479e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan inst); 480e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 481e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan // Insert an instruction to call the helper with the result 482e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 48320b8a9643335e959d8822d720618be13c363f28eSean Callanan llvm::Value *arg_array[2]; 4849b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 4859b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan arg_array[0] = bit_cast; 48620b8a9643335e959d8822d720618be13c363f28eSean Callanan arg_array[1] = selector; 4879b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 488715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan ArrayRef<llvm::Value*> args(arg_array, 2); 489e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 490e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan CallInst::Create(m_objc_object_check_func, 4919b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan args, 492e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan "", 493e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan inst); 494e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 495e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan return true; 496e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan } 497e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 498e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan bool InspectInstruction(llvm::Instruction &i) 499e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan { 500952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 501e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 502e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan CallInst *call_inst = dyn_cast<CallInst>(&i); 503e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 504e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan if (call_inst) 505e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan { 506e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan // This metadata is set by IRForTarget::MaybeHandleCall(). 507e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 508e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan MDNode *metadata = call_inst->getMetadata("lldb.call.realName"); 509e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 510e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan if (!metadata) 511e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan return true; 512e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 513e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan if (metadata->getNumOperands() != 1) 514e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan { 515e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan if (log) 516e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan log->Printf("Function call metadata has %d operands for [%p] %s", metadata->getNumOperands(), call_inst, PrintValue(call_inst).c_str()); 517e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan return false; 518e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan } 519e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 520804930f1d6f0b79f837acadf76b9d7b75cd412cdDaniel Malea MDString *real_name = dyn_cast<MDString>(metadata->getOperand(0)); 521e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 522e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan if (!real_name) 523e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan { 524e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan if (log) 525804930f1d6f0b79f837acadf76b9d7b75cd412cdDaniel Malea log->Printf("Function call metadata is not an MDString for [%p] %s", call_inst, PrintValue(call_inst).c_str()); 526e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan return false; 527e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan } 528804930f1d6f0b79f837acadf76b9d7b75cd412cdDaniel Malea 529804930f1d6f0b79f837acadf76b9d7b75cd412cdDaniel Malea std::string name_str = real_name->getString(); 5307befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan const char* name_cstr = name_str.c_str(); 5317befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan 53239a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan if (log) 53339a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan log->Printf("Found call to %s: %s\n", name_cstr, PrintValue(call_inst).c_str()); 53439a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan 5357befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan if (name_str.find("objc_msgSend") == std::string::npos) 5367befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan return true; 5377befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan 5387befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan if (!strcmp(name_cstr, "objc_msgSend")) 5397befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan { 540e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan RegisterInstruction(i); 5417befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan msgSend_types[&i] = eMsgSend; 5427befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan return true; 5437befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan } 5447befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan 5457befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan if (!strcmp(name_cstr, "objc_msgSend_stret")) 5467befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan { 5477befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan RegisterInstruction(i); 5487befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan msgSend_types[&i] = eMsgSend_stret; 5497befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan return true; 5507befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan } 5517befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan 5527befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan if (!strcmp(name_cstr, "objc_msgSend_fpret")) 5537befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan { 5547befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan RegisterInstruction(i); 5557befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan msgSend_types[&i] = eMsgSend_fpret; 5567befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan return true; 5577befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan } 5587befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan 5597befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan if (!strcmp(name_cstr, "objc_msgSendSuper")) 5607befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan { 5617befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan RegisterInstruction(i); 5627befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan msgSend_types[&i] = eMsgSendSuper; 5637befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan return true; 5647befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan } 5657befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan 5667befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan if (!strcmp(name_cstr, "objc_msgSendSuper_stret")) 5677befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan { 5687befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan RegisterInstruction(i); 5697befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan msgSend_types[&i] = eMsgSendSuper_stret; 5707befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan return true; 5717befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan } 5727befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan 5737befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan if (log) 5747befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan log->Printf("Function name '%s' contains 'objc_msgSend' but is not handled", name_str.c_str()); 5757befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan 5767befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan return true; 577e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan } 578e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 579e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan return true; 580e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan } 581e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 582e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan llvm::Value *m_objc_object_check_func; 5830526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan}; 5840526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 5850526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean CallananIRDynamicChecks::IRDynamicChecks(DynamicCheckerFunctions &checker_functions, 5860526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan const char *func_name) : 58747a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan ModulePass(ID), 588dbeb3e1e038a75f00fd565203839020e1d00a7c6Stephen Wilson m_func_name(func_name), 589dbeb3e1e038a75f00fd565203839020e1d00a7c6Stephen Wilson m_checker_functions(checker_functions) 5900526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan{ 5910526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan} 5920526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 593f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean CallananIRDynamicChecks::~IRDynamicChecks() 594f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan{ 595f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan} 596f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 597f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callananbool 598f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean CallananIRDynamicChecks::runOnModule(llvm::Module &M) 599f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan{ 600952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 601f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 602f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan llvm::Function* function = M.getFunction(StringRef(m_func_name.c_str())); 603f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 604f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan if (!function) 605f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan { 606f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan if (log) 607f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan log->Printf("Couldn't find %s() in the module", m_func_name.c_str()); 608f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 609f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan return false; 610f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan } 6110526233d38d2b5b957bc3c1fc5e26c2d8e30904fSean Callanan 612153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan if (m_checker_functions.m_valid_pointer_check.get()) 613153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan { 614153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan ValidPointerChecker vpc(M, m_checker_functions); 615153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan 616153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan if (!vpc.Inspect(*function)) 617153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan return false; 618153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan 619153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan if (!vpc.Instrument()) 620153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan return false; 621153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan } 622e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 623153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan if (m_checker_functions.m_objc_object_check.get()) 624153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan { 625153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan ObjcObjectChecker ooc(M, m_checker_functions); 626153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan 627153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan if (!ooc.Inspect(*function)) 628153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan return false; 629153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan 630153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan if (!ooc.Instrument()) 631153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan return false; 632153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan } 633153bcca3f1e2c61780218f31c6515e698eb8f8a1Sean Callanan 634bbce7124afdd5fb30742da08a195d33bbbba8fcfJim Ingham if (log && log->GetVerbose()) 63565af734ce9ebc0597c9c3ccdd270023546ffaef3Sean Callanan { 63665af734ce9ebc0597c9c3ccdd270023546ffaef3Sean Callanan std::string s; 63765af734ce9ebc0597c9c3ccdd270023546ffaef3Sean Callanan raw_string_ostream oss(s); 63865af734ce9ebc0597c9c3ccdd270023546ffaef3Sean Callanan 63965af734ce9ebc0597c9c3ccdd270023546ffaef3Sean Callanan M.print(oss, NULL); 64065af734ce9ebc0597c9c3ccdd270023546ffaef3Sean Callanan 64165af734ce9ebc0597c9c3ccdd270023546ffaef3Sean Callanan oss.flush(); 64265af734ce9ebc0597c9c3ccdd270023546ffaef3Sean Callanan 643bbce7124afdd5fb30742da08a195d33bbbba8fcfJim Ingham log->Printf ("Module after dynamic checks: \n%s", s.c_str()); 64465af734ce9ebc0597c9c3ccdd270023546ffaef3Sean Callanan } 64565af734ce9ebc0597c9c3ccdd270023546ffaef3Sean Callanan 646f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan return true; 647f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan} 648f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 649f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callananvoid 650f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean CallananIRDynamicChecks::assignPassManager(PMStack &PMS, 651f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan PassManagerType T) 652f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan{ 653f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan} 654f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 655f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean CallananPassManagerType 656f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean CallananIRDynamicChecks::getPotentialPassManagerType() const 657f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan{ 658f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan return PMT_ModulePassManager; 659f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan} 660