brintos

brintos / llvm-project-archived public Read only

0
0
Text · 55.6 KiB · a343766 Raw
1772 lines · cpp
1//===-- IRForTarget.cpp ---------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "IRForTarget.h"10 11#include "ClangExpressionDeclMap.h"12#include "ClangUtil.h"13 14#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"15#include "llvm/IR/Constants.h"16#include "llvm/IR/DataLayout.h"17#include "llvm/IR/Operator.h"18#include "llvm/IR/InstrTypes.h"19#include "llvm/IR/Instructions.h"20#include "llvm/IR/Intrinsics.h"21#include "llvm/IR/LegacyPassManager.h"22#include "llvm/IR/Metadata.h"23#include "llvm/IR/Module.h"24#include "llvm/IR/ValueSymbolTable.h"25#include "llvm/Support/raw_ostream.h"26#include "llvm/Transforms/IPO.h"27 28#include "clang/AST/ASTContext.h"29 30#include "lldb/Core/dwarf.h"31#include "lldb/Expression/IRExecutionUnit.h"32#include "lldb/Expression/IRInterpreter.h"33#include "lldb/Symbol/CompilerType.h"34#include "lldb/Utility/ConstString.h"35#include "lldb/Utility/DataBufferHeap.h"36#include "lldb/Utility/Endian.h"37#include "lldb/Utility/LLDBLog.h"38#include "lldb/Utility/Log.h"39#include "lldb/Utility/Scalar.h"40#include "lldb/Utility/StreamString.h"41 42#include <map>43#include <optional>44 45using namespace llvm;46using lldb_private::LLDBLog;47 48typedef SmallVector<Instruction *, 2> InstrList;49 50IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker)51    : m_maker(maker), m_values() {}52 53IRForTarget::FunctionValueCache::~FunctionValueCache() = default;54 55llvm::Value *56IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) {57  if (!m_values.count(function)) {58    llvm::Value *ret = m_maker(function);59    m_values[function] = ret;60    return ret;61  }62  return m_values[function];63}64 65static llvm::Value *FindEntryInstruction(llvm::Function *function) {66  if (function->empty())67    return nullptr;68 69  return &*function->getEntryBlock().getFirstNonPHIOrDbg();70}71 72IRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,73                         bool resolve_vars,74                         lldb_private::IRExecutionUnit &execution_unit,75                         lldb_private::Stream &error_stream,76                         const char *func_name)77    : m_resolve_vars(resolve_vars), m_func_name(func_name),78      m_decl_map(decl_map), m_error_stream(error_stream),79      m_execution_unit(execution_unit),80      m_entry_instruction_finder(FindEntryInstruction) {}81 82/* Handy utility functions used at several places in the code */83 84static std::string PrintValue(const Value *value, bool truncate = false) {85  std::string s;86  if (value) {87    raw_string_ostream rso(s);88    value->print(rso);89    if (truncate)90      s.resize(s.length() - 1);91  }92  return s;93}94 95static std::string PrintType(const llvm::Type *type, bool truncate = false) {96  std::string s;97  raw_string_ostream rso(s);98  type->print(rso);99  if (truncate)100    s.resize(s.length() - 1);101  return s;102}103 104bool IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) {105  llvm_function.setLinkage(GlobalValue::ExternalLinkage);106 107  return true;108}109 110clang::NamedDecl *IRForTarget::DeclForGlobal(const GlobalValue *global_val,111                                             Module *module) {112  NamedMDNode *named_metadata =113      module->getNamedMetadata("clang.global.decl.ptrs");114 115  if (!named_metadata)116    return nullptr;117 118  unsigned num_nodes = named_metadata->getNumOperands();119  unsigned node_index;120 121  for (node_index = 0; node_index < num_nodes; ++node_index) {122    llvm::MDNode *metadata_node =123        dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index));124    if (!metadata_node)125      return nullptr;126 127    if (metadata_node->getNumOperands() != 2)128      continue;129 130    if (mdconst::dyn_extract_or_null<GlobalValue>(131            metadata_node->getOperand(0)) != global_val)132      continue;133 134    ConstantInt *constant_int =135        mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1));136 137    if (!constant_int)138      return nullptr;139 140    uintptr_t ptr = constant_int->getZExtValue();141 142    return reinterpret_cast<clang::NamedDecl *>(ptr);143  }144 145  return nullptr;146}147 148clang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) {149  return DeclForGlobal(global_val, m_module);150}151 152/// Returns true iff the mangled symbol is for a static guard variable.153static bool isGuardVariableSymbol(llvm::StringRef mangled_symbol,154                                  bool check_ms_abi = true) {155  bool result =156      mangled_symbol.starts_with("_ZGV"); // Itanium ABI guard variable157  if (check_ms_abi)158    result |= mangled_symbol.ends_with("@4IA"); // Microsoft ABI159  return result;160}161 162bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {163  lldb_private::Log *log(GetLog(LLDBLog::Expressions));164 165  if (!m_resolve_vars)166    return true;167 168  // Find the result variable.  If it doesn't exist, we can give up right here.169 170  ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();171 172  llvm::StringRef result_name;173  bool found_result = false;174 175  for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {176    result_name = value_symbol.first();177 178    // Check if this is a guard variable. It seems this causes some hiccups179    // on Windows, so let's only check for Itanium guard variables.180    bool is_guard_var = isGuardVariableSymbol(result_name, /*MS ABI*/ false);181 182    if (result_name.contains("$__lldb_expr_result_ptr") && !is_guard_var) {183      found_result = true;184      m_result_is_pointer = true;185      break;186    }187 188    if (result_name.contains("$__lldb_expr_result") && !is_guard_var) {189      found_result = true;190      m_result_is_pointer = false;191      break;192    }193  }194 195  if (!found_result) {196    LLDB_LOG(log, "Couldn't find result variable");197 198    return true;199  }200 201  LLDB_LOG(log, "Result name: \"{0}\"", result_name);202 203  Value *result_value = m_module->getNamedValue(result_name);204 205  if (!result_value) {206    LLDB_LOG(log, "Result variable had no data");207 208    m_error_stream.Format("Internal error [IRForTarget]: Result variable's "209                          "name ({0}) exists, but not its definition\n",210                          result_name);211 212    return false;213  }214 215  LLDB_LOG(log, "Found result in the IR: \"{0}\"",216           PrintValue(result_value, false));217 218  GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);219 220  if (!result_global) {221    LLDB_LOG(log, "Result variable isn't a GlobalVariable");222 223    m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "224                          "is defined, but is not a global variable\n",225                          result_name);226 227    return false;228  }229 230  clang::NamedDecl *result_decl = DeclForGlobal(result_global);231  if (!result_decl) {232    LLDB_LOG(log, "Result variable doesn't have a corresponding Decl");233 234    m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "235                          "does not have a corresponding Clang entity\n",236                          result_name);237 238    return false;239  }240 241  if (log) {242    std::string decl_desc_str;243    raw_string_ostream decl_desc_stream(decl_desc_str);244    result_decl->print(decl_desc_stream);245 246    LLDB_LOG(log, "Found result decl: \"{0}\"", decl_desc_str);247  }248 249  clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);250  if (!result_var) {251    LLDB_LOG(log, "Result variable Decl isn't a VarDecl");252 253    m_error_stream.Format("Internal error [IRForTarget]: Result variable "254                          "({0})'s corresponding Clang entity isn't a "255                          "variable\n",256                          result_name);257 258    return false;259  }260 261  // Get the next available result name from m_decl_map and create the262  // persistent variable for it263 264  // If the result is an Lvalue, it is emitted as a pointer; see265  // ASTResultSynthesizer::SynthesizeBodyResult.266  if (m_result_is_pointer) {267    clang::QualType pointer_qual_type = result_var->getType();268    const clang::Type *pointer_type = pointer_qual_type.getTypePtr();269 270    const clang::PointerType *pointer_pointertype =271        pointer_type->getAs<clang::PointerType>();272    const clang::ObjCObjectPointerType *pointer_objcobjpointertype =273        pointer_type->getAs<clang::ObjCObjectPointerType>();274 275    if (pointer_pointertype) {276      clang::QualType element_qual_type = pointer_pointertype->getPointeeType();277 278      m_result_type = lldb_private::TypeFromParser(279          m_decl_map->GetTypeSystem()->GetType(element_qual_type));280    } else if (pointer_objcobjpointertype) {281      clang::QualType element_qual_type =282          clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);283 284      m_result_type = lldb_private::TypeFromParser(285          m_decl_map->GetTypeSystem()->GetType(element_qual_type));286    } else {287      LLDB_LOG(log, "Expected result to have pointer type, but it did not");288 289      m_error_stream.Format("Internal error [IRForTarget]: Lvalue result ({0}) "290                            "is not a pointer variable\n",291                            result_name);292 293      return false;294    }295  } else {296    m_result_type = lldb_private::TypeFromParser(297        m_decl_map->GetTypeSystem()->GetType(result_var->getType()));298  }299 300  lldb::TargetSP target_sp(m_execution_unit.GetTarget());301  auto bit_size_or_err = m_result_type.GetBitSize(target_sp.get());302  if (!bit_size_or_err) {303    lldb_private::StreamString type_desc_stream;304    m_result_type.DumpTypeDescription(&type_desc_stream);305 306    LLDB_LOG(log, "Result type has unknown size");307 308    m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' "309                          "couldn't be determined\n%s",310                          type_desc_stream.GetData(),311                          llvm::toString(bit_size_or_err.takeError()).c_str());312    return false;313  }314 315  if (log) {316    lldb_private::StreamString type_desc_stream;317    m_result_type.DumpTypeDescription(&type_desc_stream);318 319    LLDB_LOG(log, "Result decl type: \"{0}\"", type_desc_stream.GetData());320  }321 322  m_result_name = lldb_private::ConstString("$RESULT_NAME");323 324  LLDB_LOG(log, "Creating a new result global: \"{0}\" with size {1}",325           m_result_name,326           llvm::expectedToOptional(m_result_type.GetByteSize(target_sp.get()))327               .value_or(0));328 329  // Construct a new result global and set up its metadata330 331  GlobalVariable *new_result_global = new GlobalVariable(332      (*m_module), result_global->getValueType(), false, /* not constant */333      GlobalValue::ExternalLinkage, nullptr,             /* no initializer */334      m_result_name.GetCString());335 336  // It's too late in compilation to create a new VarDecl for this, but we337  // don't need to.  We point the metadata at the old VarDecl.  This creates an338  // odd anomaly: a variable with a Value whose name is something like $0 and a339  // Decl whose name is $__lldb_expr_result.  This condition is handled in340  // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is341  // fixed up.342 343  ConstantInt *new_constant_int =344      ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),345                       reinterpret_cast<uintptr_t>(result_decl), false);346 347  llvm::Metadata *values[2];348  values[0] = ConstantAsMetadata::get(new_result_global);349  values[1] = ConstantAsMetadata::get(new_constant_int);350 351  ArrayRef<Metadata *> value_ref(values, 2);352 353  MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);354  NamedMDNode *named_metadata =355      m_module->getNamedMetadata("clang.global.decl.ptrs");356  named_metadata->addOperand(persistent_global_md);357 358  LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(result_global),359           PrintValue(new_result_global));360 361  if (result_global->use_empty()) {362    // We need to synthesize a store for this variable, because otherwise363    // there's nothing to put into its equivalent persistent variable.364 365    BasicBlock &entry_block(llvm_function.getEntryBlock());366    Instruction *first_entry_instruction(&*entry_block.getFirstNonPHIOrDbg());367 368    if (!first_entry_instruction)369      return false;370 371    if (!result_global->hasInitializer()) {372      LLDB_LOG(log, "Couldn't find initializer for unused variable");373 374      m_error_stream.Format("Internal error [IRForTarget]: Result variable "375                            "({0}) has no writes and no initializer\n",376                            result_name);377 378      return false;379    }380 381    Constant *initializer = result_global->getInitializer();382 383    StoreInst *synthesized_store = new StoreInst(384        initializer, new_result_global, first_entry_instruction->getIterator());385 386    LLDB_LOG(log, "Synthesized result store \"{0}\"\n",387             PrintValue(synthesized_store));388  } else {389    result_global->replaceAllUsesWith(new_result_global);390  }391 392  if (!m_decl_map->AddPersistentVariable(393          result_decl, m_result_name, m_result_type, true, m_result_is_pointer))394    return false;395 396  result_global->eraseFromParent();397 398  return true;399}400 401bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,402                                         llvm::GlobalVariable *cstr) {403  lldb_private::Log *log(GetLog(LLDBLog::Expressions));404 405  Type *ns_str_ty = ns_str->getType();406 407  Type *i8_ptr_ty = PointerType::getUnqual(m_module->getContext());408  Type *i32_ty = Type::getInt32Ty(m_module->getContext());409  Type *i8_ty = Type::getInt8Ty(m_module->getContext());410 411  if (!m_CFStringCreateWithBytes) {412    lldb::addr_t CFStringCreateWithBytes_addr;413 414    static lldb_private::ConstString g_CFStringCreateWithBytes_str(415        "CFStringCreateWithBytes");416 417    bool missing_weak = false;418    CFStringCreateWithBytes_addr = m_execution_unit.FindSymbol(419        g_CFStringCreateWithBytes_str, missing_weak);420    if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS || missing_weak) {421      LLDB_LOG(log, "Couldn't find CFStringCreateWithBytes in the target");422 423      m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C "424                            "constant string requires "425                            "CFStringCreateWithBytes\n");426 427      return false;428    }429 430    LLDB_LOG(log, "Found CFStringCreateWithBytes at {0}",431             CFStringCreateWithBytes_addr);432 433    // Build the function type:434    //435    // CFStringRef CFStringCreateWithBytes (436    //   CFAllocatorRef alloc,437    //   const UInt8 *bytes,438    //   CFIndex numBytes,439    //   CFStringEncoding encoding,440    //   Boolean isExternalRepresentation441    // );442    //443    // We make the following substitutions:444    //445    // CFStringRef -> i8*446    // CFAllocatorRef -> i8*447    // UInt8 * -> i8*448    // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its449    // pointer size for now) CFStringEncoding -> i32 Boolean -> i8450 451    Type *arg_type_array[5];452 453    arg_type_array[0] = i8_ptr_ty;454    arg_type_array[1] = i8_ptr_ty;455    arg_type_array[2] = m_intptr_ty;456    arg_type_array[3] = i32_ty;457    arg_type_array[4] = i8_ty;458 459    ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);460 461    llvm::FunctionType *CFSCWB_ty =462        FunctionType::get(ns_str_ty, CFSCWB_arg_types, false);463 464    // Build the constant containing the pointer to the function465    PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(m_module->getContext());466    Constant *CFSCWB_addr_int =467        ConstantInt::get(m_intptr_ty, CFStringCreateWithBytes_addr, false);468    m_CFStringCreateWithBytes = {469        CFSCWB_ty, ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty)};470  }471 472  ConstantDataSequential *string_array = nullptr;473 474  if (cstr)475    string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());476 477  Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty);478  Constant *bytes_arg = cstr ? cstr : Constant::getNullValue(i8_ptr_ty);479  Constant *numBytes_arg = ConstantInt::get(480      m_intptr_ty, cstr ? (string_array->getNumElements() - 1) * string_array->getElementByteSize() : 0, false);481 int encoding_flags = 0;482 switch (cstr ? string_array->getElementByteSize() : 1) {483 case 1:484   encoding_flags = 0x08000100; /* 0x08000100 is kCFStringEncodingUTF8 */485   break;486 case 2:487   encoding_flags = 0x0100; /* 0x0100 is kCFStringEncodingUTF16 */488   break;489 case 4:490   encoding_flags = 0x0c000100; /* 0x0c000100 is kCFStringEncodingUTF32 */491   break;492 default:493   encoding_flags = 0x0600; /* fall back to 0x0600, kCFStringEncodingASCII */494   LLDB_LOG(log, "Encountered an Objective-C constant string with unusual "495                 "element size {0}",496            string_array->getElementByteSize());497 }498 Constant *encoding_arg = ConstantInt::get(i32_ty, encoding_flags, false);499 Constant *isExternal_arg =500     ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */501 502 Value *argument_array[5];503 504 argument_array[0] = alloc_arg;505 argument_array[1] = bytes_arg;506 argument_array[2] = numBytes_arg;507 argument_array[3] = encoding_arg;508 argument_array[4] = isExternal_arg;509 510 ArrayRef<Value *> CFSCWB_arguments(argument_array, 5);511 512 FunctionValueCache CFSCWB_Caller(513     [this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * {514       return CallInst::Create(515           m_CFStringCreateWithBytes, CFSCWB_arguments,516           "CFStringCreateWithBytes",517           llvm::cast<Instruction>(518               m_entry_instruction_finder.GetValue(function))519               ->getIterator());520     });521 522 if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder,523                     m_error_stream)) {524   LLDB_LOG(log, "Couldn't replace the NSString with the result of the call");525 526   m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an "527                         "Objective-C constant string with a dynamic "528                         "string\n");529 530   return false;531  }532 533  ns_str->eraseFromParent();534 535  return true;536}537 538bool IRForTarget::RewriteObjCConstStrings() {539  lldb_private::Log *log(GetLog(LLDBLog::Expressions));540 541  ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();542 543  for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {544    llvm::StringRef value_name = value_symbol.first();545 546    if (value_name.contains("_unnamed_cfstring_")) {547      Value *nsstring_value = value_symbol.second;548 549      GlobalVariable *nsstring_global =550          dyn_cast<GlobalVariable>(nsstring_value);551 552      if (!nsstring_global) {553        LLDB_LOG(log, "NSString variable is not a GlobalVariable");554 555        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "556                              "constant string is not a global variable\n");557 558        return false;559      }560 561      if (!nsstring_global->hasInitializer()) {562        LLDB_LOG(log, "NSString variable does not have an initializer");563 564        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "565                              "constant string does not have an initializer\n");566 567        return false;568      }569 570      ConstantStruct *nsstring_struct =571          dyn_cast<ConstantStruct>(nsstring_global->getInitializer());572 573      if (!nsstring_struct) {574        LLDB_LOG(log,575                 "NSString variable's initializer is not a ConstantStruct");576 577        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "578                              "constant string is not a structure constant\n");579 580        return false;581      }582 583      // We expect the following structure:584      //585      // struct {586      //   int *isa;587      //   int flags;588      //   char *str;589      //   long length;590      // };591 592      if (nsstring_struct->getNumOperands() != 4) {593 594        LLDB_LOG(log,595                 "NSString variable's initializer structure has an "596                 "unexpected number of members.  Should be 4, is {0}",597                 nsstring_struct->getNumOperands());598 599        m_error_stream.Printf("Internal error [IRForTarget]: The struct for an "600                              "Objective-C constant string is not as "601                              "expected\n");602 603        return false;604      }605 606      Constant *nsstring_member = nsstring_struct->getOperand(2);607 608      if (!nsstring_member) {609        LLDB_LOG(log, "NSString initializer's str element was empty");610 611        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "612                              "constant string does not have a string "613                              "initializer\n");614 615        return false;616      }617 618      auto *cstr_global = dyn_cast<GlobalVariable>(nsstring_member);619      if (!cstr_global) {620        LLDB_LOG(log,621                 "NSString initializer's str element is not a GlobalVariable");622 623        m_error_stream.Printf("Internal error [IRForTarget]: Unhandled"624                              "constant string initializer\n");625 626        return false;627      }628 629      if (!cstr_global->hasInitializer()) {630        LLDB_LOG(log, "NSString initializer's str element does not have an "631                      "initializer");632 633        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "634                              "constant string's string initializer doesn't "635                              "point to initialized data\n");636 637        return false;638      }639 640      /*641      if (!cstr_array)642      {643          if (log)644              log->PutCString("NSString initializer's str element is not a645      ConstantArray");646 647          if (m_error_stream)648              m_error_stream.Printf("Internal error [IRForTarget]: An649      Objective-C constant string's string initializer doesn't point to an650      array\n");651 652          return false;653      }654 655      if (!cstr_array->isCString())656      {657          if (log)658              log->PutCString("NSString initializer's str element is not a C659      string array");660 661          if (m_error_stream)662              m_error_stream.Printf("Internal error [IRForTarget]: An663      Objective-C constant string's string initializer doesn't point to a C664      string\n");665 666          return false;667      }668      */669 670      ConstantDataArray *cstr_array =671          dyn_cast<ConstantDataArray>(cstr_global->getInitializer());672 673      if (cstr_array)674        LLDB_LOG(log, "Found NSString constant {0}, which contains \"{1}\"",675                 value_name, cstr_array->getAsString());676      else677        LLDB_LOG(log, "Found NSString constant {0}, which contains \"\"",678                 value_name);679 680      if (!cstr_array)681        cstr_global = nullptr;682 683      if (!RewriteObjCConstString(nsstring_global, cstr_global)) {684        LLDB_LOG(log, "Error rewriting the constant string");685 686        // We don't print an error message here because RewriteObjCConstString687        // has done so for us.688 689        return false;690      }691    }692  }693 694  for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {695    llvm::StringRef value_name = value_symbol.first();696 697    if (value_name == "__CFConstantStringClassReference") {698      GlobalVariable *gv = dyn_cast<GlobalVariable>(value_symbol.second);699 700      if (!gv) {701        LLDB_LOG(log,702                 "__CFConstantStringClassReference is not a global variable");703 704        m_error_stream.Printf("Internal error [IRForTarget]: Found a "705                              "CFConstantStringClassReference, but it is not a "706                              "global object\n");707 708        return false;709      }710 711      gv->eraseFromParent();712 713      break;714    }715  }716 717  return true;718}719 720static bool IsObjCSelectorRef(Value *value) {721  GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);722 723  return !(724      !global_variable || !global_variable->hasName() ||725      !global_variable->getName().starts_with("OBJC_SELECTOR_REFERENCES_"));726}727 728// This function does not report errors; its callers are responsible.729bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {730  lldb_private::Log *log(GetLog(LLDBLog::Expressions));731 732  LoadInst *load = dyn_cast<LoadInst>(selector_load);733 734  if (!load)735    return false;736 737  // Unpack the message name from the selector.  In LLVM IR, an objc_msgSend738  // gets represented as739  //740  //   %sel = load ptr, ptr @OBJC_SELECTOR_REFERENCES_, align 8741  //   call i8 @objc_msgSend(ptr %obj, ptr %sel, ...)742  //743  // where %obj is the object pointer and %sel is the selector.744  //745  // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called746  // @"\01L_OBJC_METH_VAR_NAME_".747  // @"\01L_OBJC_METH_VAR_NAME_" contains the string.748 749  // Find the pointer's initializer and get the string from its target.750 751  GlobalVariable *_objc_selector_references_ =752      dyn_cast<GlobalVariable>(load->getPointerOperand());753 754  if (!_objc_selector_references_ ||755      !_objc_selector_references_->hasInitializer())756    return false;757 758  Constant *osr_initializer = _objc_selector_references_->getInitializer();759  if (!osr_initializer)760    return false;761 762  // Find the string's initializer (a ConstantArray) and get the string from it763 764  GlobalVariable *_objc_meth_var_name_ =765      dyn_cast<GlobalVariable>(osr_initializer);766 767  if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())768    return false;769 770  Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();771 772  ConstantDataArray *omvn_initializer_array =773      dyn_cast<ConstantDataArray>(omvn_initializer);774 775  if (!omvn_initializer_array->isString())776    return false;777 778  std::string omvn_initializer_string =779      std::string(omvn_initializer_array->getAsString());780 781  LLDB_LOG(log, "Found Objective-C selector reference \"{0}\"",782           omvn_initializer_string);783 784  // Construct a call to sel_registerName785 786  if (!m_sel_registerName) {787    lldb::addr_t sel_registerName_addr;788 789    bool missing_weak = false;790    static lldb_private::ConstString g_sel_registerName_str("sel_registerName");791    sel_registerName_addr = m_execution_unit.FindSymbol(g_sel_registerName_str,792                                                        missing_weak);793    if (sel_registerName_addr == LLDB_INVALID_ADDRESS || missing_weak)794      return false;795 796    LLDB_LOG(log, "Found sel_registerName at {0}", sel_registerName_addr);797 798    // Build the function type: struct objc_selector799    // *sel_registerName(uint8_t*)800 801    // The below code would be "more correct," but in actuality what's required802    // is uint8_t*803    // Type *sel_type = StructType::get(m_module->getContext());804    // Type *sel_ptr_type = PointerType::getUnqual(sel_type);805    Type *sel_ptr_type = PointerType::getUnqual(m_module->getContext());806 807    Type *type_array[1];808 809    type_array[0] = llvm::PointerType::getUnqual(m_module->getContext());810 811    ArrayRef<Type *> srN_arg_types(type_array, 1);812 813    llvm::FunctionType *srN_type =814        FunctionType::get(sel_ptr_type, srN_arg_types, false);815 816    // Build the constant containing the pointer to the function817    PointerType *srN_ptr_ty = PointerType::getUnqual(m_module->getContext());818    Constant *srN_addr_int =819        ConstantInt::get(m_intptr_ty, sel_registerName_addr, false);820    m_sel_registerName = {srN_type,821                          ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty)};822  }823 824  CallInst *srN_call =825      CallInst::Create(m_sel_registerName, _objc_meth_var_name_,826                       "sel_registerName", selector_load->getIterator());827 828  // Replace the load with the call in all users829 830  selector_load->replaceAllUsesWith(srN_call);831 832  selector_load->eraseFromParent();833 834  return true;835}836 837bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) {838  lldb_private::Log *log(GetLog(LLDBLog::Expressions));839 840  InstrList selector_loads;841 842  for (Instruction &inst : basic_block) {843    if (LoadInst *load = dyn_cast<LoadInst>(&inst))844      if (IsObjCSelectorRef(load->getPointerOperand()))845        selector_loads.push_back(&inst);846  }847 848  for (Instruction *inst : selector_loads) {849    if (!RewriteObjCSelector(inst)) {850      m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "851                            "static reference to an Objective-C selector to a "852                            "dynamic reference\n");853 854      LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C selector");855 856      return false;857    }858  }859 860  return true;861}862 863// This function does not report errors; its callers are responsible.864bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {865  lldb_private::Log *log(GetLog(LLDBLog::Expressions));866 867  AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);868 869  MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");870 871  if (!alloc_md || !alloc_md->getNumOperands())872    return false;873 874  ConstantInt *constant_int =875      mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));876 877  if (!constant_int)878    return false;879 880  // We attempt to register this as a new persistent variable with the DeclMap.881 882  uintptr_t ptr = constant_int->getZExtValue();883 884  clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);885 886  lldb_private::TypeFromParser result_decl_type(887      m_decl_map->GetTypeSystem()->GetType(decl->getType()));888 889  StringRef decl_name(decl->getName());890  lldb_private::ConstString persistent_variable_name(decl_name.data(),891                                                     decl_name.size());892  if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name,893                                         result_decl_type, false, false))894    return false;895 896  GlobalVariable *persistent_global = new GlobalVariable(897      (*m_module), alloc->getType(), false,  /* not constant */898      GlobalValue::ExternalLinkage, nullptr, /* no initializer */899      alloc->getName().str());900 901  // What we're going to do here is make believe this was a regular old902  // external variable.  That means we need to make the metadata valid.903 904  NamedMDNode *named_metadata =905      m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");906 907  llvm::Metadata *values[2];908  values[0] = ConstantAsMetadata::get(persistent_global);909  values[1] = ConstantAsMetadata::get(constant_int);910 911  ArrayRef<llvm::Metadata *> value_ref(values, 2);912 913  MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);914  named_metadata->addOperand(persistent_global_md);915 916  // Now, since the variable is a pointer variable, we will drop in a load of917  // that pointer variable.918 919  LoadInst *persistent_load =920      new LoadInst(persistent_global->getValueType(), persistent_global, "",921                   alloc->getIterator());922 923  LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(alloc),924           PrintValue(persistent_load));925 926  alloc->replaceAllUsesWith(persistent_load);927  alloc->eraseFromParent();928 929  return true;930}931 932bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {933  if (!m_resolve_vars)934    return true;935 936  lldb_private::Log *log(GetLog(LLDBLog::Expressions));937 938  InstrList pvar_allocs;939 940  for (Instruction &inst : basic_block) {941 942    if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) {943      llvm::StringRef alloc_name = alloc->getName();944 945      if (alloc_name.starts_with("$") && !alloc_name.starts_with("$__lldb")) {946        if (alloc_name.find_first_of("0123456789") == 1) {947          LLDB_LOG(log, "Rejecting a numeric persistent variable.");948 949          m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, "950                                "$1, ... are reserved for use as result "951                                "names\n");952 953          return false;954        }955 956        pvar_allocs.push_back(alloc);957      }958    }959  }960 961  for (Instruction *inst : pvar_allocs) {962    if (!RewritePersistentAlloc(inst)) {963      m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "964                            "the creation of a persistent variable\n");965 966      LLDB_LOG(log, "Couldn't rewrite the creation of a persistent variable");967 968      return false;969    }970  }971 972  return true;973}974 975// This function does not report errors; its callers are responsible.976bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {977  lldb_private::Log *log(GetLog(LLDBLog::Expressions));978 979  LLDB_LOG(log, "MaybeHandleVariable ({0})", PrintValue(llvm_value_ptr));980 981  if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) {982    switch (constant_expr->getOpcode()) {983    default:984      break;985    case Instruction::GetElementPtr:986    case Instruction::BitCast:987      Value *s = constant_expr->getOperand(0);988      if (!MaybeHandleVariable(s))989        return false;990    }991  } else if (GlobalVariable *global_variable =992                 dyn_cast<GlobalVariable>(llvm_value_ptr)) {993    if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))994      return true;995 996    clang::NamedDecl *named_decl = DeclForGlobal(global_variable);997 998    if (!named_decl) {999      if (IsObjCSelectorRef(llvm_value_ptr))1000        return true;1001 1002      if (!global_variable->hasExternalLinkage())1003        return true;1004 1005      LLDB_LOG(log, "Found global variable \"{0}\" without metadata",1006               global_variable->getName());1007 1008      return false;1009    }1010 1011    llvm::StringRef name(named_decl->getName());1012 1013    clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);1014    if (value_decl == nullptr)1015      return false;1016 1017    lldb_private::CompilerType compiler_type =1018        m_decl_map->GetTypeSystem()->GetType(value_decl->getType());1019 1020    const Type *value_type = nullptr;1021 1022    if (name.starts_with("$")) {1023      // The $__lldb_expr_result name indicates the return value has allocated1024      // as a static variable.  Per the comment at1025      // ASTResultSynthesizer::SynthesizeBodyResult, accesses to this static1026      // variable need to be redirected to the result of dereferencing a1027      // pointer that is passed in as one of the arguments.1028      //1029      // Consequently, when reporting the size of the type, we report a pointer1030      // type pointing to the type of $__lldb_expr_result, not the type itself.1031      //1032      // We also do this for any user-declared persistent variables.1033      compiler_type = compiler_type.GetPointerType();1034      value_type = PointerType::getUnqual(global_variable->getContext());1035    } else {1036      value_type = global_variable->getType();1037    }1038 1039    auto *target = m_execution_unit.GetTarget().get();1040    std::optional<uint64_t> value_size =1041        llvm::expectedToOptional(compiler_type.GetByteSize(target));1042    if (!value_size)1043      return false;1044    std::optional<size_t> opt_alignment = compiler_type.GetTypeBitAlign(target);1045    if (!opt_alignment)1046      return false;1047    lldb::offset_t value_alignment = (*opt_alignment + 7ull) / 8ull;1048 1049    LLDB_LOG(log,1050             "Type of \"{0}\" is [clang \"{1}\", llvm \"{2}\"] [size {3}, "1051             "align {4}]",1052             name,1053             lldb_private::ClangUtil::GetQualType(compiler_type).getAsString(),1054             PrintType(value_type), *value_size, value_alignment);1055 1056    if (named_decl)1057      m_decl_map->AddValueToStruct(named_decl, lldb_private::ConstString(name),1058                                   llvm_value_ptr, *value_size,1059                                   value_alignment);1060  } else if (isa<llvm::Function>(llvm_value_ptr)) {1061    LLDB_LOG(log, "Function pointers aren't handled right now");1062 1063    return false;1064  }1065 1066  return true;1067}1068 1069// This function does not report errors; its callers are responsible.1070bool IRForTarget::HandleSymbol(Value *symbol) {1071  lldb_private::Log *log(GetLog(LLDBLog::Expressions));1072 1073  lldb_private::ConstString name(symbol->getName().str().c_str());1074 1075  lldb::addr_t symbol_addr =1076      m_decl_map->GetSymbolAddress(name, lldb::eSymbolTypeAny);1077 1078  if (symbol_addr == LLDB_INVALID_ADDRESS) {1079    LLDB_LOG(log, "Symbol \"{0}\" had no address", name);1080 1081    return false;1082  }1083 1084  LLDB_LOG(log, "Found \"{0}\" at {1}", name, symbol_addr);1085 1086  Type *symbol_type = symbol->getType();1087 1088  Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);1089 1090  Value *symbol_addr_ptr =1091      ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);1092 1093  LLDB_LOG(log, "Replacing {0} with {1}", PrintValue(symbol),1094           PrintValue(symbol_addr_ptr));1095 1096  symbol->replaceAllUsesWith(symbol_addr_ptr);1097 1098  return true;1099}1100 1101bool IRForTarget::MaybeHandleCallArguments(CallInst *Old) {1102  lldb_private::Log *log(GetLog(LLDBLog::Expressions));1103 1104  LLDB_LOG(log, "MaybeHandleCallArguments({0})", PrintValue(Old));1105 1106  for (unsigned op_index = 0, num_ops = Old->arg_size();1107       op_index < num_ops; ++op_index)1108    // conservatively believe that this is a store1109    if (!MaybeHandleVariable(Old->getArgOperand(op_index))) {1110      m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "1111                            "one of the arguments of a function call.\n");1112 1113      return false;1114    }1115 1116  return true;1117}1118 1119bool IRForTarget::HandleObjCClass(Value *classlist_reference) {1120  lldb_private::Log *log(GetLog(LLDBLog::Expressions));1121 1122  GlobalVariable *global_variable =1123      dyn_cast<GlobalVariable>(classlist_reference);1124 1125  if (!global_variable)1126    return false;1127 1128  Constant *initializer = global_variable->getInitializer();1129 1130  if (!initializer)1131    return false;1132 1133  if (!initializer->hasName())1134    return false;1135 1136  StringRef name(initializer->getName());1137  lldb_private::ConstString name_cstr(name.str().c_str());1138  lldb::addr_t class_ptr =1139      m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);1140 1141  LLDB_LOG(log, "Found reference to Objective-C class {0} ({1})", name,1142           (unsigned long long)class_ptr);1143 1144  if (class_ptr == LLDB_INVALID_ADDRESS)1145    return false;1146 1147  if (global_variable->use_empty())1148    return false;1149 1150  SmallVector<LoadInst *, 2> load_instructions;1151 1152  for (llvm::User *u : global_variable->users()) {1153    if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))1154      load_instructions.push_back(load_instruction);1155  }1156 1157  if (load_instructions.empty())1158    return false;1159 1160  Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr);1161 1162  for (LoadInst *load_instruction : load_instructions) {1163    Constant *class_bitcast =1164        ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());1165 1166    load_instruction->replaceAllUsesWith(class_bitcast);1167 1168    load_instruction->eraseFromParent();1169  }1170 1171  return true;1172}1173 1174bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {1175  std::vector<CallInst *> calls_to_remove;1176 1177  for (Instruction &inst : basic_block) {1178    CallInst *call = dyn_cast<CallInst>(&inst);1179 1180    // MaybeHandleCallArguments handles error reporting; we are silent here1181    if (!call)1182      continue;1183 1184    bool remove = false;1185 1186    llvm::Function *func = call->getCalledFunction();1187 1188    if (func && func->getName() == "__cxa_atexit")1189      remove = true;1190 1191    llvm::Value *val = call->getCalledOperand();1192 1193    if (val && val->getName() == "__cxa_atexit")1194      remove = true;1195 1196    if (remove)1197      calls_to_remove.push_back(call);1198  }1199 1200  for (CallInst *ci : calls_to_remove)1201    ci->eraseFromParent();1202 1203  return true;1204}1205 1206bool IRForTarget::ResolveCalls(BasicBlock &basic_block) {1207  // Prepare the current basic block for execution in the remote process1208 1209  for (Instruction &inst : basic_block) {1210    CallInst *call = dyn_cast<CallInst>(&inst);1211 1212    // MaybeHandleCallArguments handles error reporting; we are silent here1213    if (call && !MaybeHandleCallArguments(call))1214      return false;1215  }1216 1217  return true;1218}1219 1220bool IRForTarget::ResolveExternals(Function &llvm_function) {1221  lldb_private::Log *log(GetLog(LLDBLog::Expressions));1222 1223  for (GlobalVariable &global_var : m_module->globals()) {1224    llvm::StringRef global_name = global_var.getName();1225 1226    LLDB_LOG(log, "Examining {0}, DeclForGlobalValue returns {1}", global_name,1227             static_cast<void *>(DeclForGlobal(&global_var)));1228 1229    if (global_name.starts_with("OBJC_IVAR")) {1230      if (!HandleSymbol(&global_var)) {1231        m_error_stream.Format("Error [IRForTarget]: Couldn't find Objective-C "1232                              "indirect ivar symbol {0}\n",1233                              global_name);1234 1235        return false;1236      }1237    } else if (global_name.contains("OBJC_CLASSLIST_REFERENCES_$")) {1238      if (!HandleObjCClass(&global_var)) {1239        m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "1240                              "for an Objective-C static method call\n");1241 1242        return false;1243      }1244    } else if (global_name.contains("OBJC_CLASSLIST_SUP_REFS_$")) {1245      if (!HandleObjCClass(&global_var)) {1246        m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "1247                              "for an Objective-C static method call\n");1248 1249        return false;1250      }1251    } else if (DeclForGlobal(&global_var)) {1252      if (!MaybeHandleVariable(&global_var)) {1253        m_error_stream.Format("Internal error [IRForTarget]: Couldn't rewrite "1254                              "external variable {0}\n",1255                              global_name);1256 1257        return false;1258      }1259    }1260  }1261 1262  return true;1263}1264 1265static bool isGuardVariableRef(Value *V) {1266  GlobalVariable *GV = dyn_cast<GlobalVariable>(V);1267 1268  if (!GV || !GV->hasName() || !isGuardVariableSymbol(GV->getName()))1269    return false;1270 1271  return true;1272}1273 1274void IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction *guard_load) {1275  Constant *zero(Constant::getNullValue(guard_load->getType()));1276  guard_load->replaceAllUsesWith(zero);1277  guard_load->eraseFromParent();1278}1279 1280static void ExciseGuardStore(Instruction *guard_store) {1281  guard_store->eraseFromParent();1282}1283 1284bool IRForTarget::RemoveGuards(BasicBlock &basic_block) {1285  // Eliminate any reference to guard variables found.1286 1287  InstrList guard_loads;1288  InstrList guard_stores;1289 1290  for (Instruction &inst : basic_block) {1291 1292    if (LoadInst *load = dyn_cast<LoadInst>(&inst))1293      if (isGuardVariableRef(load->getPointerOperand()))1294        guard_loads.push_back(&inst);1295 1296    if (StoreInst *store = dyn_cast<StoreInst>(&inst))1297      if (isGuardVariableRef(store->getPointerOperand()))1298        guard_stores.push_back(&inst);1299  }1300 1301  for (Instruction *inst : guard_loads)1302    TurnGuardLoadIntoZero(inst);1303 1304  for (Instruction *inst : guard_stores)1305    ExciseGuardStore(inst);1306 1307  return true;1308}1309 1310// This function does not report errors; its callers are responsible.1311bool IRForTarget::UnfoldConstant(Constant *old_constant,1312                                 llvm::Function *llvm_function,1313                                 FunctionValueCache &value_maker,1314                                 FunctionValueCache &entry_instruction_finder,1315                                 lldb_private::Stream &error_stream) {1316  SmallVector<User *, 16> users;1317 1318  // We do this because the use list might change, invalidating our iterator.1319  // Much better to keep a work list ourselves.1320  for (llvm::User *u : old_constant->users())1321    users.push_back(u);1322 1323  for (size_t i = 0; i < users.size(); ++i) {1324    User *user = users[i];1325 1326    if (Constant *constant = dyn_cast<Constant>(user)) {1327      // synthesize a new non-constant equivalent of the constant1328 1329      if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {1330        switch (constant_expr->getOpcode()) {1331        default:1332          error_stream.Printf("error [IRForTarget internal]: Unhandled "1333                              "constant expression type: \"%s\"",1334                              PrintValue(constant_expr).c_str());1335          return false;1336        case Instruction::BitCast: {1337          FunctionValueCache bit_cast_maker(1338              [&value_maker, &entry_instruction_finder, old_constant,1339               constant_expr](llvm::Function *function) -> llvm::Value * {1340                // UnaryExpr1341                //   OperandList[0] is value1342 1343                if (constant_expr->getOperand(0) != old_constant)1344                  return constant_expr;1345 1346                return new BitCastInst(1347                    value_maker.GetValue(function), constant_expr->getType(),1348                    "",1349                    llvm::cast<Instruction>(1350                        entry_instruction_finder.GetValue(function))1351                        ->getIterator());1352              });1353 1354          if (!UnfoldConstant(constant_expr, llvm_function, bit_cast_maker,1355                              entry_instruction_finder, error_stream))1356            return false;1357        } break;1358        case Instruction::GetElementPtr: {1359          // GetElementPtrConstantExpr1360          //   OperandList[0] is base1361          //   OperandList[1]... are indices1362 1363          FunctionValueCache get_element_pointer_maker(1364              [&value_maker, &entry_instruction_finder, old_constant,1365               constant_expr](llvm::Function *function) -> llvm::Value * {1366                auto *gep = cast<llvm::GEPOperator>(constant_expr);1367                Value *ptr = gep->getPointerOperand();1368 1369                if (ptr == old_constant)1370                  ptr = value_maker.GetValue(function);1371 1372                std::vector<Value *> index_vector;1373                for (Value *operand : gep->indices()) {1374                  if (operand == old_constant)1375                    operand = value_maker.GetValue(function);1376 1377                  index_vector.push_back(operand);1378                }1379 1380                ArrayRef<Value *> indices(index_vector);1381 1382                return GetElementPtrInst::Create(1383                    gep->getSourceElementType(), ptr, indices, "",1384                    llvm::cast<Instruction>(1385                        entry_instruction_finder.GetValue(function))1386                        ->getIterator());1387              });1388 1389          if (!UnfoldConstant(constant_expr, llvm_function,1390                              get_element_pointer_maker,1391                              entry_instruction_finder, error_stream))1392            return false;1393        } break;1394        }1395      } else {1396        error_stream.Printf(1397            "error [IRForTarget internal]: Unhandled constant type: \"%s\"",1398            PrintValue(constant).c_str());1399        return false;1400      }1401    } else {1402      if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) {1403        if (llvm_function && inst->getParent()->getParent() != llvm_function) {1404          error_stream.PutCString("error: Capturing non-local variables in "1405                                  "expressions is unsupported.\n");1406          return false;1407        }1408        inst->replaceUsesOfWith(1409            old_constant, value_maker.GetValue(inst->getParent()->getParent()));1410      } else {1411        error_stream.Printf(1412            "error [IRForTarget internal]: Unhandled non-constant type: \"%s\"",1413            PrintValue(user).c_str());1414        return false;1415      }1416    }1417  }1418 1419  if (!isa<GlobalValue>(old_constant)) {1420    old_constant->destroyConstant();1421  }1422 1423  return true;1424}1425 1426bool IRForTarget::ReplaceVariables(Function &llvm_function) {1427  if (!m_resolve_vars)1428    return true;1429 1430  lldb_private::Log *log(GetLog(LLDBLog::Expressions));1431 1432  m_decl_map->DoStructLayout();1433 1434  LLDB_LOG(log, "Element arrangement:");1435 1436  uint32_t num_elements;1437  uint32_t element_index;1438 1439  size_t size;1440  lldb::offset_t alignment;1441 1442  if (!m_decl_map->GetStructInfo(num_elements, size, alignment))1443    return false;1444 1445  Function::arg_iterator iter(llvm_function.arg_begin());1446 1447  if (iter == llvm_function.arg_end()) {1448    m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes no "1449                          "arguments (should take at least a struct pointer)");1450 1451    return false;1452  }1453 1454  Argument *argument = &*iter;1455 1456  if (argument->getName() == "this") {1457    ++iter;1458 1459    if (iter == llvm_function.arg_end()) {1460      m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "1461                            "'this' argument (should take a struct pointer "1462                            "too)");1463 1464      return false;1465    }1466 1467    argument = &*iter;1468  } else if (argument->getName() == "self") {1469    ++iter;1470 1471    if (iter == llvm_function.arg_end()) {1472      m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "1473                            "'self' argument (should take '_cmd' and a struct "1474                            "pointer too)");1475 1476      return false;1477    }1478 1479    if (iter->getName() != "_cmd") {1480      m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes '{0}' "1481                            "after 'self' argument (should take '_cmd')",1482                            iter->getName());1483 1484      return false;1485    }1486 1487    ++iter;1488 1489    if (iter == llvm_function.arg_end()) {1490      m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "1491                            "'self' and '_cmd' arguments (should take a struct "1492                            "pointer too)");1493 1494      return false;1495    }1496 1497    argument = &*iter;1498  }1499 1500  if (argument->getName() != "$__lldb_arg") {1501    m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes an "1502                          "argument named '{0}' instead of the struct pointer",1503                          argument->getName());1504 1505    return false;1506  }1507 1508  LLDB_LOG(log, "Arg: \"{0}\"", PrintValue(argument));1509 1510  BasicBlock &entry_block(llvm_function.getEntryBlock());1511  Instruction *FirstEntryInstruction(&*entry_block.getFirstNonPHIOrDbg());1512 1513  if (!FirstEntryInstruction) {1514    m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find the "1515                          "first instruction in the wrapper for use in "1516                          "rewriting");1517 1518    return false;1519  }1520 1521  LLVMContext &context(m_module->getContext());1522  IntegerType *offset_type(Type::getInt32Ty(context));1523 1524  if (!offset_type) {1525    m_error_stream.Printf(1526        "Internal error [IRForTarget]: Couldn't produce an offset type");1527 1528    return false;1529  }1530 1531  for (element_index = 0; element_index < num_elements; ++element_index) {1532    const clang::NamedDecl *decl = nullptr;1533    Value *value = nullptr;1534    lldb::offset_t offset;1535    lldb_private::ConstString name;1536 1537    if (!m_decl_map->GetStructElement(decl, value, offset, name,1538                                      element_index)) {1539      m_error_stream.Printf(1540          "Internal error [IRForTarget]: Structure information is incomplete");1541 1542      return false;1543    }1544 1545    LLDB_LOG(log, "  \"{0}\" (\"{1}\") placed at {2}", name,1546             decl->getNameAsString(), offset);1547 1548    if (value) {1549      LLDB_LOG(log, "    Replacing [{0}]", PrintValue(value));1550 1551      FunctionValueCache body_result_maker(1552          [this, name, offset_type, offset, argument,1553           value](llvm::Function *function) -> llvm::Value * {1554            // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult,1555            // in cases where the result variable is an rvalue, we have to1556            // synthesize a dereference of the appropriate structure entry in1557            // order to produce the static variable that the AST thinks it is1558            // accessing.1559 1560            llvm::Instruction *entry_instruction = llvm::cast<Instruction>(1561                m_entry_instruction_finder.GetValue(function));1562 1563            Type *int8Ty = Type::getInt8Ty(function->getContext());1564            ConstantInt *offset_int(1565                ConstantInt::get(offset_type, offset, true));1566            GetElementPtrInst *get_element_ptr =1567                GetElementPtrInst::Create(int8Ty, argument, offset_int, "",1568                                          entry_instruction->getIterator());1569 1570            if (name == m_result_name && !m_result_is_pointer) {1571              LoadInst *load =1572                  new LoadInst(value->getType(), get_element_ptr, "",1573                               entry_instruction->getIterator());1574 1575              return load;1576            } else {1577              return get_element_ptr;1578            }1579          });1580 1581      if (Constant *constant = dyn_cast<Constant>(value)) {1582        if (!UnfoldConstant(constant, &llvm_function, body_result_maker,1583                            m_entry_instruction_finder, m_error_stream)) {1584          return false;1585        }1586      } else if (Instruction *instruction = dyn_cast<Instruction>(value)) {1587        if (instruction->getParent()->getParent() != &llvm_function) {1588          m_error_stream.PutCString("error: Capturing non-local variables in "1589                                    "expressions is unsupported.\n");1590          return false;1591        }1592        value->replaceAllUsesWith(1593            body_result_maker.GetValue(instruction->getParent()->getParent()));1594      } else {1595        LLDB_LOG(log, "Unhandled non-constant type: \"{0}\"",1596                 PrintValue(value));1597        return false;1598      }1599 1600      if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))1601        var->eraseFromParent();1602    }1603  }1604 1605  LLDB_LOG(log, "Total structure [align {0}, size {1}]", (int64_t)alignment,1606           (uint64_t)size);1607 1608  return true;1609}1610 1611bool IRForTarget::runOnModule(Module &llvm_module) {1612  lldb_private::Log *log(GetLog(LLDBLog::Expressions));1613 1614  m_module = &llvm_module;1615  m_target_data = &m_module->getDataLayout();1616  m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(),1617                                      m_target_data->getPointerSizeInBits());1618 1619  if (log) {1620    std::string s;1621    raw_string_ostream oss(s);1622 1623    m_module->print(oss, nullptr);1624 1625    LLDB_LOG(log, "Module as passed in to IRForTarget: \n\"{0}\"", s);1626  }1627 1628  Function *const main_function =1629      m_func_name.IsEmpty() ? nullptr1630                            : m_module->getFunction(m_func_name.GetStringRef());1631 1632  if (!m_func_name.IsEmpty() && !main_function) {1633    LLDB_LOG(log, "Couldn't find \"{0}()\" in the module", m_func_name);1634 1635    m_error_stream.Format("Internal error [IRForTarget]: Couldn't find wrapper "1636                          "'{0}' in the module",1637                          m_func_name);1638 1639    return false;1640  }1641 1642  if (main_function) {1643    if (!FixFunctionLinkage(*main_function)) {1644      LLDB_LOG(log, "Couldn't fix the linkage for the function");1645 1646      return false;1647    }1648  }1649 1650  ////////////////////////////////////////////////////////////1651  // Replace $__lldb_expr_result with a persistent variable1652  //1653 1654  if (main_function) {1655    if (!CreateResultVariable(*main_function)) {1656      LLDB_LOG(log, "CreateResultVariable() failed");1657 1658      // CreateResultVariable() reports its own errors, so we don't do so here1659 1660      return false;1661    }1662  }1663 1664  if (log && log->GetVerbose()) {1665    std::string s;1666    raw_string_ostream oss(s);1667 1668    m_module->print(oss, nullptr);1669 1670    LLDB_LOG(log, "Module after creating the result variable: \n\"{0}\"", s);1671  }1672 1673  for (llvm::Function &function : *m_module) {1674    for (BasicBlock &bb : function) {1675      if (!RemoveGuards(bb)) {1676        LLDB_LOG(log, "RemoveGuards() failed");1677 1678        // RemoveGuards() reports its own errors, so we don't do so here1679 1680        return false;1681      }1682 1683      if (!RewritePersistentAllocs(bb)) {1684        LLDB_LOG(log, "RewritePersistentAllocs() failed");1685 1686        // RewritePersistentAllocs() reports its own errors, so we don't do so1687        // here1688 1689        return false;1690      }1691 1692      if (!RemoveCXAAtExit(bb)) {1693        LLDB_LOG(log, "RemoveCXAAtExit() failed");1694 1695        // RemoveCXAAtExit() reports its own errors, so we don't do so here1696 1697        return false;1698      }1699    }1700  }1701 1702  ///////////////////////////////////////////////////////////////////////////////1703  // Fix all Objective-C constant strings to use NSStringWithCString:encoding:1704  //1705 1706  if (!RewriteObjCConstStrings()) {1707    LLDB_LOG(log, "RewriteObjCConstStrings() failed");1708 1709    // RewriteObjCConstStrings() reports its own errors, so we don't do so here1710 1711    return false;1712  }1713 1714  for (llvm::Function &function : *m_module) {1715    for (llvm::BasicBlock &bb : function) {1716      if (!RewriteObjCSelectors(bb)) {1717        LLDB_LOG(log, "RewriteObjCSelectors() failed");1718 1719        // RewriteObjCSelectors() reports its own errors, so we don't do so1720        // here1721 1722        return false;1723      }1724    }1725  }1726 1727  for (llvm::Function &function : *m_module) {1728    for (BasicBlock &bb : function) {1729      if (!ResolveCalls(bb)) {1730        LLDB_LOG(log, "ResolveCalls() failed");1731 1732        // ResolveCalls() reports its own errors, so we don't do so here1733 1734        return false;1735      }1736    }1737  }1738 1739  ////////////////////////////////////////////////////////////////////////1740  // Run function-level passes that only make sense on the main function1741  //1742 1743  if (main_function) {1744    if (!ResolveExternals(*main_function)) {1745      LLDB_LOG(log, "ResolveExternals() failed");1746 1747      // ResolveExternals() reports its own errors, so we don't do so here1748 1749      return false;1750    }1751 1752    if (!ReplaceVariables(*main_function)) {1753      LLDB_LOG(log, "ReplaceVariables() failed");1754 1755      // ReplaceVariables() reports its own errors, so we don't do so here1756 1757      return false;1758    }1759  }1760 1761  if (log && log->GetVerbose()) {1762    std::string s;1763    raw_string_ostream oss(s);1764 1765    m_module->print(oss, nullptr);1766 1767    LLDB_LOG(log, "Module after preparing for execution: \n\"{0}\"", s);1768  }1769 1770  return true;1771}1772