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