9#include "llvm/IR/Constants.h" 
   10#include "llvm/IR/DataLayout.h" 
   11#include "llvm/IR/Function.h" 
   12#include "llvm/IR/Instructions.h" 
   13#include "llvm/IR/Module.h" 
   14#include "llvm/IR/Value.h" 
   15#include "llvm/Support/raw_ostream.h" 
   36#define VALID_OBJC_OBJECT_CHECK_NAME "$__lldb_objc_object_check" 
   53        lang = frame->GetLanguage();
 
   55    if (objc_language_runtime &&
 
   57      Expected<std::unique_ptr<UtilityFunction>> checker_fn =
 
   60        return checker_fn.takeError();
 
   65  return Error::success();
 
 
   74    message.
Printf(
"Attempted to dereference an invalid ObjC Object or send it " 
   75                   "an unrecognized selector");
 
 
   81static std::string 
PrintValue(llvm::Value *V, 
bool truncate = 
false) {
 
   83  raw_string_ostream rso(s);
 
   86    s.resize(s.length() - 1);
 
 
  123               std::shared_ptr<UtilityFunction> checker_function)
 
 
  144         ii != last_ii; ++ii) {
 
 
  188    for (llvm::BasicBlock::iterator ii = bb.begin(), last_ii = bb.end();
 
  189         ii != last_ii; ++ii) {
 
 
  205    for (llvm::Function::iterator bbi = f.begin(), last_bbi = f.end();
 
  206         bbi != last_bbi; ++bbi) {
 
 
  223    llvm::Type *param_array[2];
 
  225    param_array[0] = 
const_cast<llvm::PointerType *
>(
GetI8PtrTy());
 
  226    param_array[1] = 
const_cast<llvm::PointerType *
>(
GetI8PtrTy());
 
  228    ArrayRef<llvm::Type *> params(param_array, 2);
 
  230    FunctionType *fun_ty = FunctionType::get(
 
  231        llvm::Type::getVoidTy(
m_module.getContext()), params, 
true);
 
  232    PointerType *fun_ptr_ty = PointerType::getUnqual(
m_module.getContext());
 
  233    Constant *fun_addr_int =
 
  234        ConstantInt::get(
GetIntptrTy(), start_address, 
false);
 
  235    return {fun_ty, ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty)};
 
 
  249          m_module.getDataLayout().getPointerSizeInBits());
 
 
  260  std::shared_ptr<UtilityFunction>
 
 
  271                    std::shared_ptr<UtilityFunction> checker_function)
 
 
  289    CallInst *call_inst = dyn_cast<CallInst>(inst);
 
  301    llvm::Value *target_object;
 
  302    llvm::Value *selector;
 
  309      if (call_inst->hasStructRetAttr()) {
 
  310        target_object = call_inst->getArgOperand(1);
 
  311        selector = call_inst->getArgOperand(2);
 
  313        target_object = call_inst->getArgOperand(0);
 
  314        selector = call_inst->getArgOperand(1);
 
  318      target_object = call_inst->getArgOperand(1);
 
  319      selector = call_inst->getArgOperand(2);
 
  327    assert(target_object);
 
  332    llvm::Value *arg_array[2];
 
  334    arg_array[0] = target_object;
 
  335    arg_array[1] = selector;
 
  337    ArrayRef<llvm::Value *> args(arg_array, 2);
 
 
  345    if (llvm::Function *function = llvm::dyn_cast<llvm::Function>(value)) {
 
  349    if (llvm::ConstantExpr *const_expr =
 
  350            llvm::dyn_cast<llvm::ConstantExpr>(value)) {
 
  351      switch (const_expr->getOpcode()) {
 
  354      case llvm::Instruction::BitCast:
 
 
  369    CallInst *call_inst = dyn_cast<CallInst>(&i);
 
  374      if (!called_function)
 
  377      std::string name_str = called_function->getName().str();
 
  378      const char *name_cstr = name_str.c_str();
 
  380      LLDB_LOGF(log, 
"Found call to %s: %s\n", name_cstr,
 
  383      if (name_str.find(
"objc_msgSend") == std::string::npos)
 
  386      if (!strcmp(name_cstr, 
"objc_msgSend")) {
 
  392      if (!strcmp(name_cstr, 
"objc_msgSend_stret")) {
 
  398      if (!strcmp(name_cstr, 
"objc_msgSend_fpret")) {
 
  404      if (!strcmp(name_cstr, 
"objc_msgSendSuper")) {
 
  410      if (!strcmp(name_cstr, 
"objc_msgSendSuper_stret")) {
 
  417                "Function name '%s' contains 'objc_msgSend' but is not handled",
 
 
 
  440  llvm::Function *function = M.getFunction(StringRef(
m_func_name));
 
  460    raw_string_ostream oss(s);
 
  462    M.print(oss, 
nullptr);
 
  464    LLDB_LOGF(log, 
"Module after dynamic checks: \n%s", s.c_str());
 
 
  473  return PMT_ModulePassManager;
 
 
#define VALID_OBJC_OBJECT_CHECK_NAME
static std::string PrintValue(const Value *value, bool truncate=false)
#define LLDB_LOGF(log,...)
llvm::Module & m_module
The module which is being instrumented.
virtual bool InspectInstruction(llvm::Instruction &i)
Determine whether a single instruction is interesting to instrument, and, if so, call RegisterInstruc...
IntegerType * GetIntptrTy()
virtual bool InstrumentInstruction(llvm::Instruction *inst)=0
Add instrumentation to a single instruction.
std::shared_ptr< UtilityFunction > m_checker_function
The dynamic checker function for the process.
Instrumenter(llvm::Module &module, std::shared_ptr< UtilityFunction > checker_function)
Constructor.
InstVector m_to_instrument
List of instructions the inspector found.
PointerType * GetI8PtrTy()
bool Inspect(llvm::Function &function)
Inspect a function to find instructions to instrument.
virtual ~Instrumenter()=default
std::vector< llvm::Instruction * > InstVector
bool Instrument()
Instrument all the instructions found by Inspect()
virtual bool InspectBasicBlock(llvm::BasicBlock &bb)
Scan a basic block to see if any instructions are interesting.
virtual bool InspectFunction(llvm::Function &f)
Scan a function to see if any instructions are interesting.
void RegisterInstruction(llvm::Instruction &inst)
Register a single instruction to be instrumented.
llvm::FunctionCallee BuildObjectCheckerFunc(lldb::addr_t start_address)
Build a function pointer for a function with signature void (*)(uint8_t*, uint8_t*) with a given addr...
IntegerType * m_intptr_ty
InstVector::iterator InstIterator
std::map< llvm::Instruction *, msgSend_type > msgSend_types
bool InspectInstruction(llvm::Instruction &i) override
Determine whether a single instruction is interesting to instrument, and, if so, call RegisterInstruc...
static llvm::Function * GetCalledFunction(llvm::CallInst *inst)
~ObjcObjectChecker() override=default
llvm::FunctionCallee m_objc_object_check_func
bool InstrumentInstruction(llvm::Instruction *inst) override
Add instrumentation to a single instruction.
static llvm::Function * GetFunction(llvm::Value *value)
ObjcObjectChecker(llvm::Module &module, std::shared_ptr< UtilityFunction > checker_function)
bool DoCheckersExplainStop(lldb::addr_t addr, Stream &message) override
std::shared_ptr< UtilityFunction > m_objc_object_check
llvm::Error Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) override
Install the utility functions into a process.
ClangDynamicCheckerFunctions()
Constructor.
~ClangDynamicCheckerFunctions() override
Destructor.
DynamicCheckerFunctions(DynamicCheckerFunctionsKind kind)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
StackFrame * GetFramePtr() const
Returns a pointer to the frame object.
Process * GetProcessPtr() const
Returns a pointer to the process object.
~IRDynamicChecks() override
Destructor.
ClangDynamicCheckerFunctions & m_checker_functions
The checker functions for the process.
bool runOnModule(llvm::Module &M) override
Run this IR transformer on a single module.
std::string m_func_name
The name of the function to add checks to.
IRDynamicChecks(ClangDynamicCheckerFunctions &checker_functions, const char *func_name="$__lldb_expr")
Constructor.
llvm::PassManagerType getPotentialPassManagerType() const override
Returns PMT_ModulePassManager.
void assignPassManager(llvm::PMStack &PMS, llvm::PassManagerType T=llvm::PMT_ModulePassManager) override
Interface stub.
static bool LanguageIsObjC(lldb::LanguageType language)
static ObjCLanguageRuntime * Get(Process &process)
virtual llvm::Expected< std::unique_ptr< UtilityFunction > > CreateObjectChecker(std::string name, ExecutionContext &exe_ctx)=0
A plug-in interface definition class for debugging a process.
A stream class that can stream formatted output to a file.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
A type-erased pair of llvm::dwarf::SourceLanguageName and version.
lldb::LanguageType AsLanguageType() const