1292932Sdim//===-- IRForTarget.cpp -----------------------------------------*- C++ -*-===// 2292932Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6292932Sdim// 7292932Sdim//===----------------------------------------------------------------------===// 8292932Sdim 9292932Sdim#include "IRForTarget.h" 10292932Sdim 11292932Sdim#include "ClangExpressionDeclMap.h" 12292932Sdim 13292932Sdim#include "llvm/IR/Constants.h" 14292932Sdim#include "llvm/IR/DataLayout.h" 15292932Sdim#include "llvm/IR/InstrTypes.h" 16292932Sdim#include "llvm/IR/Instructions.h" 17292932Sdim#include "llvm/IR/Intrinsics.h" 18292932Sdim#include "llvm/IR/LegacyPassManager.h" 19292932Sdim#include "llvm/IR/Metadata.h" 20314564Sdim#include "llvm/IR/Module.h" 21292932Sdim#include "llvm/IR/ValueSymbolTable.h" 22314564Sdim#include "llvm/Support/raw_ostream.h" 23314564Sdim#include "llvm/Transforms/IPO.h" 24292932Sdim 25292932Sdim#include "clang/AST/ASTContext.h" 26292932Sdim 27309124Sdim#include "lldb/Core/dwarf.h" 28292932Sdim#include "lldb/Expression/IRExecutionUnit.h" 29292932Sdim#include "lldb/Expression/IRInterpreter.h" 30292932Sdim#include "lldb/Symbol/ClangASTContext.h" 31309124Sdim#include "lldb/Symbol/ClangUtil.h" 32292932Sdim#include "lldb/Symbol/CompilerType.h" 33321369Sdim#include "lldb/Utility/ConstString.h" 34321369Sdim#include "lldb/Utility/DataBufferHeap.h" 35321369Sdim#include "lldb/Utility/Endian.h" 36321369Sdim#include "lldb/Utility/Log.h" 37344779Sdim#include "lldb/Utility/Scalar.h" 38321369Sdim#include "lldb/Utility/StreamString.h" 39292932Sdim 40292932Sdim#include <map> 41292932Sdim 42292932Sdimusing namespace llvm; 43292932Sdim 44292932Sdimstatic char ID; 45292932Sdim 46360784Sdimtypedef SmallVector<Instruction *, 2> InstrList; 47360784Sdim 48314564SdimIRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker) 49314564Sdim : m_maker(maker), m_values() {} 50292932Sdim 51314564SdimIRForTarget::FunctionValueCache::~FunctionValueCache() {} 52292932Sdim 53292932Sdimllvm::Value * 54314564SdimIRForTarget::FunctionValueCache::GetValue(llvm::Function *function) { 55314564Sdim if (!m_values.count(function)) { 56314564Sdim llvm::Value *ret = m_maker(function); 57314564Sdim m_values[function] = ret; 58314564Sdim return ret; 59314564Sdim } 60314564Sdim return m_values[function]; 61292932Sdim} 62292932Sdim 63314564Sdimstatic llvm::Value *FindEntryInstruction(llvm::Function *function) { 64314564Sdim if (function->empty()) 65353358Sdim return nullptr; 66292932Sdim 67314564Sdim return function->getEntryBlock().getFirstNonPHIOrDbg(); 68292932Sdim} 69292932Sdim 70314564SdimIRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map, 71314564Sdim bool resolve_vars, 72314564Sdim lldb_private::IRExecutionUnit &execution_unit, 73314564Sdim lldb_private::Stream &error_stream, 74314564Sdim const char *func_name) 75314564Sdim : ModulePass(ID), m_resolve_vars(resolve_vars), m_func_name(func_name), 76353358Sdim m_module(nullptr), m_decl_map(decl_map), 77353358Sdim m_CFStringCreateWithBytes(nullptr), m_sel_registerName(nullptr), 78353358Sdim m_objc_getClass(nullptr), m_intptr_ty(nullptr), 79353358Sdim m_error_stream(error_stream), m_execution_unit(execution_unit), 80353358Sdim m_result_store(nullptr), m_result_is_pointer(false), 81353358Sdim m_reloc_placeholder(nullptr), 82314564Sdim m_entry_instruction_finder(FindEntryInstruction) {} 83292932Sdim 84292932Sdim/* Handy utility functions used at several places in the code */ 85292932Sdim 86314564Sdimstatic std::string PrintValue(const Value *value, bool truncate = false) { 87314564Sdim std::string s; 88314564Sdim if (value) { 89292932Sdim raw_string_ostream rso(s); 90314564Sdim value->print(rso); 91292932Sdim rso.flush(); 92292932Sdim if (truncate) 93314564Sdim s.resize(s.length() - 1); 94314564Sdim } 95314564Sdim return s; 96292932Sdim} 97292932Sdim 98314564Sdimstatic std::string PrintType(const llvm::Type *type, bool truncate = false) { 99314564Sdim std::string s; 100314564Sdim raw_string_ostream rso(s); 101314564Sdim type->print(rso); 102314564Sdim rso.flush(); 103314564Sdim if (truncate) 104314564Sdim s.resize(s.length() - 1); 105314564Sdim return s; 106292932Sdim} 107292932Sdim 108314564SdimIRForTarget::~IRForTarget() {} 109292932Sdim 110314564Sdimbool IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) { 111314564Sdim llvm_function.setLinkage(GlobalValue::ExternalLinkage); 112314564Sdim 113314564Sdim return true; 114292932Sdim} 115292932Sdim 116314564Sdimclang::NamedDecl *IRForTarget::DeclForGlobal(const GlobalValue *global_val, 117314564Sdim Module *module) { 118314564Sdim NamedMDNode *named_metadata = 119314564Sdim module->getNamedMetadata("clang.global.decl.ptrs"); 120292932Sdim 121314564Sdim if (!named_metadata) 122353358Sdim return nullptr; 123292932Sdim 124314564Sdim unsigned num_nodes = named_metadata->getNumOperands(); 125314564Sdim unsigned node_index; 126292932Sdim 127314564Sdim for (node_index = 0; node_index < num_nodes; ++node_index) { 128314564Sdim llvm::MDNode *metadata_node = 129314564Sdim dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index)); 130314564Sdim if (!metadata_node) 131353358Sdim return nullptr; 132292932Sdim 133314564Sdim if (metadata_node->getNumOperands() != 2) 134314564Sdim continue; 135292932Sdim 136314564Sdim if (mdconst::dyn_extract_or_null<GlobalValue>( 137314564Sdim metadata_node->getOperand(0)) != global_val) 138314564Sdim continue; 139292932Sdim 140314564Sdim ConstantInt *constant_int = 141314564Sdim mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1)); 142292932Sdim 143314564Sdim if (!constant_int) 144353358Sdim return nullptr; 145292932Sdim 146314564Sdim uintptr_t ptr = constant_int->getZExtValue(); 147292932Sdim 148314564Sdim return reinterpret_cast<clang::NamedDecl *>(ptr); 149314564Sdim } 150292932Sdim 151353358Sdim return nullptr; 152292932Sdim} 153292932Sdim 154314564Sdimclang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) { 155314564Sdim return DeclForGlobal(global_val, m_module); 156292932Sdim} 157292932Sdim 158360784Sdim/// Returns true iff the mangled symbol is for a static guard variable. 159360784Sdimstatic bool isGuardVariableSymbol(llvm::StringRef mangled_symbol, 160360784Sdim bool check_ms_abi = true) { 161360784Sdim bool result = mangled_symbol.startswith("_ZGV"); // Itanium ABI guard variable 162360784Sdim if (check_ms_abi) 163360784Sdim result |= mangled_symbol.endswith("@4IA"); // Microsoft ABI 164360784Sdim return result; 165360784Sdim} 166360784Sdim 167314564Sdimbool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { 168314564Sdim lldb_private::Log *log( 169314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 170292932Sdim 171314564Sdim if (!m_resolve_vars) 172314564Sdim return true; 173292932Sdim 174314564Sdim // Find the result variable. If it doesn't exist, we can give up right here. 175292932Sdim 176314564Sdim ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable(); 177292932Sdim 178360784Sdim llvm::StringRef result_name; 179360784Sdim bool found_result = false; 180292932Sdim 181360784Sdim for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) { 182360784Sdim result_name = value_symbol.first(); 183292932Sdim 184360784Sdim // Check if this is a guard variable. It seems this causes some hiccups 185360784Sdim // on Windows, so let's only check for Itanium guard variables. 186360784Sdim bool is_guard_var = isGuardVariableSymbol(result_name, /*MS ABI*/ false); 187360784Sdim 188360784Sdim if (result_name.contains("$__lldb_expr_result_ptr") && !is_guard_var) { 189360784Sdim found_result = true; 190314564Sdim m_result_is_pointer = true; 191314564Sdim break; 192314564Sdim } 193292932Sdim 194360784Sdim if (result_name.contains("$__lldb_expr_result") && !is_guard_var) { 195360784Sdim found_result = true; 196314564Sdim m_result_is_pointer = false; 197314564Sdim break; 198292932Sdim } 199314564Sdim } 200292932Sdim 201360784Sdim if (!found_result) { 202360784Sdim LLDB_LOG(log, "Couldn't find result variable"); 203292932Sdim 204314564Sdim return true; 205314564Sdim } 206292932Sdim 207360784Sdim LLDB_LOG(log, "Result name: \"{0}\"", result_name); 208314564Sdim 209314564Sdim Value *result_value = m_module->getNamedValue(result_name); 210314564Sdim 211314564Sdim if (!result_value) { 212360784Sdim LLDB_LOG(log, "Result variable had no data"); 213292932Sdim 214360784Sdim m_error_stream.Format("Internal error [IRForTarget]: Result variable's " 215360784Sdim "name ({0}) exists, but not its definition\n", 216314564Sdim result_name); 217292932Sdim 218314564Sdim return false; 219314564Sdim } 220292932Sdim 221360784Sdim LLDB_LOG(log, "Found result in the IR: \"{0}\"", 222360784Sdim PrintValue(result_value, false)); 223292932Sdim 224314564Sdim GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value); 225292932Sdim 226314564Sdim if (!result_global) { 227360784Sdim LLDB_LOG(log, "Result variable isn't a GlobalVariable"); 228292932Sdim 229360784Sdim m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) " 230314564Sdim "is defined, but is not a global variable\n", 231314564Sdim result_name); 232292932Sdim 233314564Sdim return false; 234314564Sdim } 235292932Sdim 236314564Sdim clang::NamedDecl *result_decl = DeclForGlobal(result_global); 237314564Sdim if (!result_decl) { 238360784Sdim LLDB_LOG(log, "Result variable doesn't have a corresponding Decl"); 239292932Sdim 240360784Sdim m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) " 241314564Sdim "does not have a corresponding Clang entity\n", 242314564Sdim result_name); 243292932Sdim 244314564Sdim return false; 245314564Sdim } 246292932Sdim 247314564Sdim if (log) { 248314564Sdim std::string decl_desc_str; 249314564Sdim raw_string_ostream decl_desc_stream(decl_desc_str); 250314564Sdim result_decl->print(decl_desc_stream); 251314564Sdim decl_desc_stream.flush(); 252292932Sdim 253360784Sdim LLDB_LOG(log, "Found result decl: \"{0}\"", decl_desc_str); 254314564Sdim } 255292932Sdim 256314564Sdim clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl); 257314564Sdim if (!result_var) { 258360784Sdim LLDB_LOG(log, "Result variable Decl isn't a VarDecl"); 259292932Sdim 260360784Sdim m_error_stream.Format("Internal error [IRForTarget]: Result variable " 261360784Sdim "({0})'s corresponding Clang entity isn't a " 262314564Sdim "variable\n", 263314564Sdim result_name); 264292932Sdim 265314564Sdim return false; 266314564Sdim } 267292932Sdim 268314564Sdim // Get the next available result name from m_decl_map and create the 269341825Sdim // persistent variable for it 270292932Sdim 271314564Sdim // If the result is an Lvalue, it is emitted as a pointer; see 272314564Sdim // ASTResultSynthesizer::SynthesizeBodyResult. 273314564Sdim if (m_result_is_pointer) { 274314564Sdim clang::QualType pointer_qual_type = result_var->getType(); 275314564Sdim const clang::Type *pointer_type = pointer_qual_type.getTypePtr(); 276314564Sdim 277314564Sdim const clang::PointerType *pointer_pointertype = 278314564Sdim pointer_type->getAs<clang::PointerType>(); 279314564Sdim const clang::ObjCObjectPointerType *pointer_objcobjpointertype = 280314564Sdim pointer_type->getAs<clang::ObjCObjectPointerType>(); 281314564Sdim 282314564Sdim if (pointer_pointertype) { 283314564Sdim clang::QualType element_qual_type = pointer_pointertype->getPointeeType(); 284314564Sdim 285314564Sdim m_result_type = lldb_private::TypeFromParser( 286314564Sdim element_qual_type.getAsOpaquePtr(), 287314564Sdim lldb_private::ClangASTContext::GetASTContext( 288314564Sdim &result_decl->getASTContext())); 289314564Sdim } else if (pointer_objcobjpointertype) { 290314564Sdim clang::QualType element_qual_type = 291314564Sdim clang::QualType(pointer_objcobjpointertype->getObjectType(), 0); 292314564Sdim 293314564Sdim m_result_type = lldb_private::TypeFromParser( 294314564Sdim element_qual_type.getAsOpaquePtr(), 295314564Sdim lldb_private::ClangASTContext::GetASTContext( 296314564Sdim &result_decl->getASTContext())); 297314564Sdim } else { 298360784Sdim LLDB_LOG(log, "Expected result to have pointer type, but it did not"); 299314564Sdim 300360784Sdim m_error_stream.Format("Internal error [IRForTarget]: Lvalue result ({0}) " 301314564Sdim "is not a pointer variable\n", 302314564Sdim result_name); 303314564Sdim 304314564Sdim return false; 305292932Sdim } 306314564Sdim } else { 307314564Sdim m_result_type = lldb_private::TypeFromParser( 308314564Sdim result_var->getType().getAsOpaquePtr(), 309314564Sdim lldb_private::ClangASTContext::GetASTContext( 310314564Sdim &result_decl->getASTContext())); 311314564Sdim } 312292932Sdim 313314564Sdim lldb::TargetSP target_sp(m_execution_unit.GetTarget()); 314314564Sdim lldb_private::ExecutionContext exe_ctx(target_sp, true); 315344779Sdim llvm::Optional<uint64_t> bit_size = 316344779Sdim m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope()); 317344779Sdim if (!bit_size) { 318314564Sdim lldb_private::StreamString type_desc_stream; 319314564Sdim m_result_type.DumpTypeDescription(&type_desc_stream); 320292932Sdim 321360784Sdim LLDB_LOG(log, "Result type has unknown size"); 322292932Sdim 323314564Sdim m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' " 324314564Sdim "couldn't be determined\n", 325314564Sdim type_desc_stream.GetData()); 326314564Sdim return false; 327314564Sdim } 328292932Sdim 329314564Sdim if (log) { 330314564Sdim lldb_private::StreamString type_desc_stream; 331314564Sdim m_result_type.DumpTypeDescription(&type_desc_stream); 332292932Sdim 333360784Sdim LLDB_LOG(log, "Result decl type: \"{0}\"", type_desc_stream.GetData()); 334314564Sdim } 335292932Sdim 336314564Sdim m_result_name = lldb_private::ConstString("$RESULT_NAME"); 337292932Sdim 338360784Sdim LLDB_LOG(log, "Creating a new result global: \"{0}\" with size {1}", 339360784Sdim m_result_name, m_result_type.GetByteSize(nullptr).getValueOr(0)); 340292932Sdim 341314564Sdim // Construct a new result global and set up its metadata 342292932Sdim 343314564Sdim GlobalVariable *new_result_global = new GlobalVariable( 344314564Sdim (*m_module), result_global->getType()->getElementType(), 345353358Sdim false, /* not constant */ 346353358Sdim GlobalValue::ExternalLinkage, nullptr, /* no initializer */ 347314564Sdim m_result_name.GetCString()); 348292932Sdim 349341825Sdim // It's too late in compilation to create a new VarDecl for this, but we 350341825Sdim // don't need to. We point the metadata at the old VarDecl. This creates an 351341825Sdim // odd anomaly: a variable with a Value whose name is something like $0 and a 352314564Sdim // Decl whose name is $__lldb_expr_result. This condition is handled in 353314564Sdim // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is 354314564Sdim // fixed up. 355292932Sdim 356314564Sdim ConstantInt *new_constant_int = 357314564Sdim ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()), 358360784Sdim reinterpret_cast<uintptr_t>(result_decl), false); 359292932Sdim 360314564Sdim llvm::Metadata *values[2]; 361314564Sdim values[0] = ConstantAsMetadata::get(new_result_global); 362314564Sdim values[1] = ConstantAsMetadata::get(new_constant_int); 363292932Sdim 364314564Sdim ArrayRef<Metadata *> value_ref(values, 2); 365292932Sdim 366314564Sdim MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref); 367314564Sdim NamedMDNode *named_metadata = 368314564Sdim m_module->getNamedMetadata("clang.global.decl.ptrs"); 369314564Sdim named_metadata->addOperand(persistent_global_md); 370314564Sdim 371360784Sdim LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(result_global), 372360784Sdim PrintValue(new_result_global)); 373314564Sdim 374314564Sdim if (result_global->use_empty()) { 375314564Sdim // We need to synthesize a store for this variable, because otherwise 376314564Sdim // there's nothing to put into its equivalent persistent variable. 377314564Sdim 378314564Sdim BasicBlock &entry_block(llvm_function.getEntryBlock()); 379314564Sdim Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg()); 380314564Sdim 381314564Sdim if (!first_entry_instruction) 382314564Sdim return false; 383314564Sdim 384314564Sdim if (!result_global->hasInitializer()) { 385360784Sdim LLDB_LOG(log, "Couldn't find initializer for unused variable"); 386314564Sdim 387360784Sdim m_error_stream.Format("Internal error [IRForTarget]: Result variable " 388360784Sdim "({0}) has no writes and no initializer\n", 389314564Sdim result_name); 390314564Sdim 391314564Sdim return false; 392292932Sdim } 393292932Sdim 394314564Sdim Constant *initializer = result_global->getInitializer(); 395292932Sdim 396314564Sdim StoreInst *synthesized_store = 397314564Sdim new StoreInst(initializer, new_result_global, first_entry_instruction); 398314564Sdim 399360784Sdim LLDB_LOG(log, "Synthesized result store \"{0}\"\n", 400360784Sdim PrintValue(synthesized_store)); 401314564Sdim } else { 402314564Sdim result_global->replaceAllUsesWith(new_result_global); 403314564Sdim } 404292932Sdim 405314564Sdim if (!m_decl_map->AddPersistentVariable( 406314564Sdim result_decl, m_result_name, m_result_type, true, m_result_is_pointer)) 407314564Sdim return false; 408292932Sdim 409314564Sdim result_global->eraseFromParent(); 410292932Sdim 411314564Sdim return true; 412314564Sdim} 413292932Sdim 414314564Sdimbool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str, 415314564Sdim llvm::GlobalVariable *cstr) { 416314564Sdim lldb_private::Log *log( 417314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 418292932Sdim 419314564Sdim Type *ns_str_ty = ns_str->getType(); 420292932Sdim 421314564Sdim Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext()); 422314564Sdim Type *i32_ty = Type::getInt32Ty(m_module->getContext()); 423314564Sdim Type *i8_ty = Type::getInt8Ty(m_module->getContext()); 424292932Sdim 425314564Sdim if (!m_CFStringCreateWithBytes) { 426314564Sdim lldb::addr_t CFStringCreateWithBytes_addr; 427292932Sdim 428314564Sdim static lldb_private::ConstString g_CFStringCreateWithBytes_str( 429314564Sdim "CFStringCreateWithBytes"); 430314564Sdim 431353358Sdim bool missing_weak = false; 432314564Sdim CFStringCreateWithBytes_addr = 433353358Sdim m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str, 434353358Sdim missing_weak); 435353358Sdim if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS || missing_weak) { 436314564Sdim log->PutCString("Couldn't find CFStringCreateWithBytes in the target"); 437314564Sdim 438314564Sdim m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C " 439314564Sdim "constant string requires " 440314564Sdim "CFStringCreateWithBytes\n"); 441314564Sdim 442314564Sdim return false; 443314564Sdim } 444314564Sdim 445360784Sdim LLDB_LOG(log, "Found CFStringCreateWithBytes at {0}", 446360784Sdim CFStringCreateWithBytes_addr); 447292932Sdim 448314564Sdim // Build the function type: 449314564Sdim // 450314564Sdim // CFStringRef CFStringCreateWithBytes ( 451314564Sdim // CFAllocatorRef alloc, 452314564Sdim // const UInt8 *bytes, 453314564Sdim // CFIndex numBytes, 454314564Sdim // CFStringEncoding encoding, 455314564Sdim // Boolean isExternalRepresentation 456314564Sdim // ); 457314564Sdim // 458314564Sdim // We make the following substitutions: 459314564Sdim // 460314564Sdim // CFStringRef -> i8* 461314564Sdim // CFAllocatorRef -> i8* 462314564Sdim // UInt8 * -> i8* 463314564Sdim // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its 464341825Sdim // pointer size for now) CFStringEncoding -> i32 Boolean -> i8 465292932Sdim 466314564Sdim Type *arg_type_array[5]; 467292932Sdim 468314564Sdim arg_type_array[0] = i8_ptr_ty; 469314564Sdim arg_type_array[1] = i8_ptr_ty; 470314564Sdim arg_type_array[2] = m_intptr_ty; 471314564Sdim arg_type_array[3] = i32_ty; 472314564Sdim arg_type_array[4] = i8_ty; 473292932Sdim 474314564Sdim ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5); 475292932Sdim 476353358Sdim llvm::FunctionType *CFSCWB_ty = 477314564Sdim FunctionType::get(ns_str_ty, CFSCWB_arg_types, false); 478292932Sdim 479314564Sdim // Build the constant containing the pointer to the function 480314564Sdim PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty); 481314564Sdim Constant *CFSCWB_addr_int = 482314564Sdim ConstantInt::get(m_intptr_ty, CFStringCreateWithBytes_addr, false); 483353358Sdim m_CFStringCreateWithBytes = { 484353358Sdim CFSCWB_ty, ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty)}; 485314564Sdim } 486292932Sdim 487353358Sdim ConstantDataSequential *string_array = nullptr; 488292932Sdim 489314564Sdim if (cstr) 490314564Sdim string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer()); 491292932Sdim 492314564Sdim Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty); 493314564Sdim Constant *bytes_arg = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty) 494314564Sdim : Constant::getNullValue(i8_ptr_ty); 495314564Sdim Constant *numBytes_arg = ConstantInt::get( 496314564Sdim m_intptr_ty, cstr ? (string_array->getNumElements() - 1) * string_array->getElementByteSize() : 0, false); 497314564Sdim int encoding_flags = 0; 498314564Sdim switch (cstr ? string_array->getElementByteSize() : 1) { 499314564Sdim case 1: 500314564Sdim encoding_flags = 0x08000100; /* 0x08000100 is kCFStringEncodingUTF8 */ 501314564Sdim break; 502314564Sdim case 2: 503314564Sdim encoding_flags = 0x0100; /* 0x0100 is kCFStringEncodingUTF16 */ 504314564Sdim break; 505314564Sdim case 4: 506314564Sdim encoding_flags = 0x0c000100; /* 0x0c000100 is kCFStringEncodingUTF32 */ 507314564Sdim break; 508314564Sdim default: 509314564Sdim encoding_flags = 0x0600; /* fall back to 0x0600, kCFStringEncodingASCII */ 510321369Sdim LLDB_LOG(log, "Encountered an Objective-C constant string with unusual " 511314564Sdim "element size {0}", 512321369Sdim string_array->getElementByteSize()); 513314564Sdim } 514314564Sdim Constant *encoding_arg = ConstantInt::get(i32_ty, encoding_flags, false); 515314564Sdim Constant *isExternal_arg = 516314564Sdim ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */ 517314564Sdim 518314564Sdim Value *argument_array[5]; 519314564Sdim 520314564Sdim argument_array[0] = alloc_arg; 521314564Sdim argument_array[1] = bytes_arg; 522314564Sdim argument_array[2] = numBytes_arg; 523314564Sdim argument_array[3] = encoding_arg; 524314564Sdim argument_array[4] = isExternal_arg; 525314564Sdim 526314564Sdim ArrayRef<Value *> CFSCWB_arguments(argument_array, 5); 527314564Sdim 528314564Sdim FunctionValueCache CFSCWB_Caller( 529314564Sdim [this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * { 530314564Sdim return CallInst::Create( 531314564Sdim m_CFStringCreateWithBytes, CFSCWB_arguments, 532314564Sdim "CFStringCreateWithBytes", 533314564Sdim llvm::cast<Instruction>( 534314564Sdim m_entry_instruction_finder.GetValue(function))); 535314564Sdim }); 536314564Sdim 537314564Sdim if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder, 538314564Sdim m_error_stream)) { 539360784Sdim LLDB_LOG(log, "Couldn't replace the NSString with the result of the call"); 540314564Sdim 541314564Sdim m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an " 542314564Sdim "Objective-C constant string with a dynamic " 543314564Sdim "string\n"); 544314564Sdim 545314564Sdim return false; 546314564Sdim } 547314564Sdim 548314564Sdim ns_str->eraseFromParent(); 549314564Sdim 550314564Sdim return true; 551314564Sdim} 552314564Sdim 553314564Sdimbool IRForTarget::RewriteObjCConstStrings() { 554314564Sdim lldb_private::Log *log( 555314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 556314564Sdim 557314564Sdim ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable(); 558314564Sdim 559360784Sdim for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) { 560360784Sdim llvm::StringRef value_name = value_symbol.first(); 561314564Sdim 562360784Sdim if (value_name.contains("_unnamed_cfstring_")) { 563360784Sdim Value *nsstring_value = value_symbol.second; 564314564Sdim 565314564Sdim GlobalVariable *nsstring_global = 566314564Sdim dyn_cast<GlobalVariable>(nsstring_value); 567314564Sdim 568314564Sdim if (!nsstring_global) { 569360784Sdim LLDB_LOG(log, "NSString variable is not a GlobalVariable"); 570292932Sdim 571314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " 572314564Sdim "constant string is not a global variable\n"); 573314564Sdim 574292932Sdim return false; 575314564Sdim } 576292932Sdim 577314564Sdim if (!nsstring_global->hasInitializer()) { 578360784Sdim LLDB_LOG(log, "NSString variable does not have an initializer"); 579292932Sdim 580314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " 581314564Sdim "constant string does not have an initializer\n"); 582292932Sdim 583314564Sdim return false; 584314564Sdim } 585292932Sdim 586314564Sdim ConstantStruct *nsstring_struct = 587314564Sdim dyn_cast<ConstantStruct>(nsstring_global->getInitializer()); 588292932Sdim 589314564Sdim if (!nsstring_struct) { 590360784Sdim LLDB_LOG(log, 591360784Sdim "NSString variable's initializer is not a ConstantStruct"); 592292932Sdim 593314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " 594314564Sdim "constant string is not a structure constant\n"); 595292932Sdim 596314564Sdim return false; 597314564Sdim } 598292932Sdim 599314564Sdim // We expect the following structure: 600314564Sdim // 601314564Sdim // struct { 602314564Sdim // int *isa; 603314564Sdim // int flags; 604314564Sdim // char *str; 605314564Sdim // long length; 606314564Sdim // }; 607292932Sdim 608314564Sdim if (nsstring_struct->getNumOperands() != 4) { 609292932Sdim 610360784Sdim LLDB_LOG(log, 611360784Sdim "NSString variable's initializer structure has an " 612360784Sdim "unexpected number of members. Should be 4, is {0}", 613360784Sdim nsstring_struct->getNumOperands()); 614360784Sdim 615314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: The struct for an " 616314564Sdim "Objective-C constant string is not as " 617314564Sdim "expected\n"); 618292932Sdim 619314564Sdim return false; 620314564Sdim } 621314564Sdim 622314564Sdim Constant *nsstring_member = nsstring_struct->getOperand(2); 623314564Sdim 624314564Sdim if (!nsstring_member) { 625360784Sdim LLDB_LOG(log, "NSString initializer's str element was empty"); 626292932Sdim 627314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " 628314564Sdim "constant string does not have a string " 629314564Sdim "initializer\n"); 630292932Sdim 631314564Sdim return false; 632314564Sdim } 633292932Sdim 634314564Sdim ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member); 635292932Sdim 636314564Sdim if (!nsstring_expr) { 637360784Sdim LLDB_LOG(log, 638360784Sdim "NSString initializer's str element is not a ConstantExpr"); 639292932Sdim 640314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " 641314564Sdim "constant string's string initializer is not " 642314564Sdim "constant\n"); 643292932Sdim 644314564Sdim return false; 645314564Sdim } 646292932Sdim 647314564Sdim GlobalVariable *cstr_global = nullptr; 648292932Sdim 649314564Sdim if (nsstring_expr->getOpcode() == Instruction::GetElementPtr) { 650314564Sdim Constant *nsstring_cstr = nsstring_expr->getOperand(0); 651314564Sdim cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr); 652314564Sdim } else if (nsstring_expr->getOpcode() == Instruction::BitCast) { 653314564Sdim Constant *nsstring_cstr = nsstring_expr->getOperand(0); 654314564Sdim cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr); 655314564Sdim } 656292932Sdim 657314564Sdim if (!cstr_global) { 658360784Sdim LLDB_LOG(log, 659360784Sdim "NSString initializer's str element is not a GlobalVariable"); 660292932Sdim 661314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Unhandled" 662314564Sdim "constant string initializer\n"); 663292932Sdim 664314564Sdim return false; 665314564Sdim } 666292932Sdim 667314564Sdim if (!cstr_global->hasInitializer()) { 668360784Sdim LLDB_LOG(log, "NSString initializer's str element does not have an " 669360784Sdim "initializer"); 670292932Sdim 671314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " 672314564Sdim "constant string's string initializer doesn't " 673314564Sdim "point to initialized data\n"); 674292932Sdim 675314564Sdim return false; 676314564Sdim } 677314564Sdim 678314564Sdim /* 679314564Sdim if (!cstr_array) 680314564Sdim { 681314564Sdim if (log) 682314564Sdim log->PutCString("NSString initializer's str element is not a 683314564Sdim ConstantArray"); 684314564Sdim 685314564Sdim if (m_error_stream) 686314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: An 687314564Sdim Objective-C constant string's string initializer doesn't point to an 688314564Sdim array\n"); 689314564Sdim 690314564Sdim return false; 691314564Sdim } 692314564Sdim 693314564Sdim if (!cstr_array->isCString()) 694314564Sdim { 695314564Sdim if (log) 696314564Sdim log->PutCString("NSString initializer's str element is not a C 697314564Sdim string array"); 698314564Sdim 699314564Sdim if (m_error_stream) 700314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: An 701314564Sdim Objective-C constant string's string initializer doesn't point to a C 702314564Sdim string\n"); 703314564Sdim 704314564Sdim return false; 705314564Sdim } 706314564Sdim */ 707314564Sdim 708314564Sdim ConstantDataArray *cstr_array = 709314564Sdim dyn_cast<ConstantDataArray>(cstr_global->getInitializer()); 710314564Sdim 711360784Sdim if (cstr_array) 712360784Sdim LLDB_LOG(log, "Found NSString constant {0}, which contains \"{1}\"", 713360784Sdim value_name, cstr_array->getAsString()); 714360784Sdim else 715360784Sdim LLDB_LOG(log, "Found NSString constant {0}, which contains \"\"", 716360784Sdim value_name); 717314564Sdim 718314564Sdim if (!cstr_array) 719353358Sdim cstr_global = nullptr; 720314564Sdim 721314564Sdim if (!RewriteObjCConstString(nsstring_global, cstr_global)) { 722360784Sdim LLDB_LOG(log, "Error rewriting the constant string"); 723292932Sdim 724314564Sdim // We don't print an error message here because RewriteObjCConstString 725314564Sdim // has done so for us. 726292932Sdim 727292932Sdim return false; 728314564Sdim } 729292932Sdim } 730314564Sdim } 731292932Sdim 732360784Sdim for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) { 733360784Sdim llvm::StringRef value_name = value_symbol.first(); 734292932Sdim 735360784Sdim if (value_name == "__CFConstantStringClassReference") { 736360784Sdim GlobalVariable *gv = dyn_cast<GlobalVariable>(value_symbol.second); 737292932Sdim 738314564Sdim if (!gv) { 739360784Sdim LLDB_LOG(log, 740360784Sdim "__CFConstantStringClassReference is not a global variable"); 741292932Sdim 742314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Found a " 743314564Sdim "CFConstantStringClassReference, but it is not a " 744314564Sdim "global object\n"); 745292932Sdim 746314564Sdim return false; 747314564Sdim } 748292932Sdim 749314564Sdim gv->eraseFromParent(); 750292932Sdim 751314564Sdim break; 752314564Sdim } 753314564Sdim } 754292932Sdim 755314564Sdim return true; 756314564Sdim} 757292932Sdim 758314564Sdimstatic bool IsObjCSelectorRef(Value *value) { 759314564Sdim GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value); 760292932Sdim 761344779Sdim return !(!global_variable || !global_variable->hasName() || 762344779Sdim !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_")); 763314564Sdim} 764292932Sdim 765314564Sdim// This function does not report errors; its callers are responsible. 766314564Sdimbool IRForTarget::RewriteObjCSelector(Instruction *selector_load) { 767314564Sdim lldb_private::Log *log( 768314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 769292932Sdim 770314564Sdim LoadInst *load = dyn_cast<LoadInst>(selector_load); 771292932Sdim 772314564Sdim if (!load) 773314564Sdim return false; 774292932Sdim 775314564Sdim // Unpack the message name from the selector. In LLVM IR, an objc_msgSend 776314564Sdim // gets represented as 777314564Sdim // 778341825Sdim // %tmp = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*> %call = call 779341825Sdim // i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; <i8*> 780314564Sdim // 781314564Sdim // where %obj is the object pointer and %tmp is the selector. 782314564Sdim // 783314564Sdim // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called 784314564Sdim // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_". 785314564Sdim // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string. 786292932Sdim 787314564Sdim // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr) 788314564Sdim // and get the string from its target 789292932Sdim 790314564Sdim GlobalVariable *_objc_selector_references_ = 791314564Sdim dyn_cast<GlobalVariable>(load->getPointerOperand()); 792292932Sdim 793314564Sdim if (!_objc_selector_references_ || 794314564Sdim !_objc_selector_references_->hasInitializer()) 795314564Sdim return false; 796292932Sdim 797314564Sdim Constant *osr_initializer = _objc_selector_references_->getInitializer(); 798292932Sdim 799314564Sdim ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer); 800292932Sdim 801314564Sdim if (!osr_initializer_expr || 802314564Sdim osr_initializer_expr->getOpcode() != Instruction::GetElementPtr) 803314564Sdim return false; 804292932Sdim 805314564Sdim Value *osr_initializer_base = osr_initializer_expr->getOperand(0); 806292932Sdim 807314564Sdim if (!osr_initializer_base) 808314564Sdim return false; 809292932Sdim 810314564Sdim // Find the string's initializer (a ConstantArray) and get the string from it 811292932Sdim 812314564Sdim GlobalVariable *_objc_meth_var_name_ = 813314564Sdim dyn_cast<GlobalVariable>(osr_initializer_base); 814292932Sdim 815314564Sdim if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer()) 816314564Sdim return false; 817292932Sdim 818314564Sdim Constant *omvn_initializer = _objc_meth_var_name_->getInitializer(); 819292932Sdim 820314564Sdim ConstantDataArray *omvn_initializer_array = 821314564Sdim dyn_cast<ConstantDataArray>(omvn_initializer); 822292932Sdim 823314564Sdim if (!omvn_initializer_array->isString()) 824314564Sdim return false; 825292932Sdim 826314564Sdim std::string omvn_initializer_string = omvn_initializer_array->getAsString(); 827292932Sdim 828360784Sdim LLDB_LOG(log, "Found Objective-C selector reference \"{0}\"", 829360784Sdim omvn_initializer_string); 830292932Sdim 831314564Sdim // Construct a call to sel_registerName 832292932Sdim 833314564Sdim if (!m_sel_registerName) { 834314564Sdim lldb::addr_t sel_registerName_addr; 835292932Sdim 836353358Sdim bool missing_weak = false; 837314564Sdim static lldb_private::ConstString g_sel_registerName_str("sel_registerName"); 838353358Sdim sel_registerName_addr = m_execution_unit.FindSymbol(g_sel_registerName_str, 839353358Sdim missing_weak); 840353358Sdim if (sel_registerName_addr == LLDB_INVALID_ADDRESS || missing_weak) 841314564Sdim return false; 842292932Sdim 843360784Sdim LLDB_LOG(log, "Found sel_registerName at {0}", sel_registerName_addr); 844292932Sdim 845341825Sdim // Build the function type: struct objc_selector 846341825Sdim // *sel_registerName(uint8_t*) 847292932Sdim 848314564Sdim // The below code would be "more correct," but in actuality what's required 849314564Sdim // is uint8_t* 850314564Sdim // Type *sel_type = StructType::get(m_module->getContext()); 851314564Sdim // Type *sel_ptr_type = PointerType::getUnqual(sel_type); 852314564Sdim Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext()); 853292932Sdim 854314564Sdim Type *type_array[1]; 855292932Sdim 856314564Sdim type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext()); 857292932Sdim 858314564Sdim ArrayRef<Type *> srN_arg_types(type_array, 1); 859292932Sdim 860353358Sdim llvm::FunctionType *srN_type = 861314564Sdim FunctionType::get(sel_ptr_type, srN_arg_types, false); 862292932Sdim 863314564Sdim // Build the constant containing the pointer to the function 864314564Sdim PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type); 865314564Sdim Constant *srN_addr_int = 866314564Sdim ConstantInt::get(m_intptr_ty, sel_registerName_addr, false); 867353358Sdim m_sel_registerName = {srN_type, 868353358Sdim ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty)}; 869314564Sdim } 870292932Sdim 871314564Sdim Value *argument_array[1]; 872292932Sdim 873314564Sdim Constant *omvn_pointer = ConstantExpr::getBitCast( 874314564Sdim _objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext())); 875292932Sdim 876314564Sdim argument_array[0] = omvn_pointer; 877292932Sdim 878314564Sdim ArrayRef<Value *> srN_arguments(argument_array, 1); 879292932Sdim 880314564Sdim CallInst *srN_call = CallInst::Create(m_sel_registerName, srN_arguments, 881314564Sdim "sel_registerName", selector_load); 882292932Sdim 883314564Sdim // Replace the load with the call in all users 884292932Sdim 885314564Sdim selector_load->replaceAllUsesWith(srN_call); 886292932Sdim 887314564Sdim selector_load->eraseFromParent(); 888292932Sdim 889314564Sdim return true; 890314564Sdim} 891292932Sdim 892314564Sdimbool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) { 893314564Sdim lldb_private::Log *log( 894314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 895292932Sdim 896314564Sdim InstrList selector_loads; 897292932Sdim 898360784Sdim for (Instruction &inst : basic_block) { 899314564Sdim if (LoadInst *load = dyn_cast<LoadInst>(&inst)) 900314564Sdim if (IsObjCSelectorRef(load->getPointerOperand())) 901314564Sdim selector_loads.push_back(&inst); 902314564Sdim } 903292932Sdim 904360784Sdim for (Instruction *inst : selector_loads) { 905360784Sdim if (!RewriteObjCSelector(inst)) { 906314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a " 907314564Sdim "static reference to an Objective-C selector to a " 908314564Sdim "dynamic reference\n"); 909314564Sdim 910360784Sdim LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C selector"); 911314564Sdim 912314564Sdim return false; 913292932Sdim } 914314564Sdim } 915292932Sdim 916314564Sdim return true; 917292932Sdim} 918292932Sdim 919314564Sdimstatic bool IsObjCClassReference(Value *value) { 920314564Sdim GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value); 921292932Sdim 922344779Sdim return !(!global_variable || !global_variable->hasName() || 923344779Sdim !global_variable->getName().startswith("OBJC_CLASS_REFERENCES_")); 924292932Sdim} 925292932Sdim 926292932Sdim// This function does not report errors; its callers are responsible. 927314564Sdimbool IRForTarget::RewriteObjCClassReference(Instruction *class_load) { 928314564Sdim lldb_private::Log *log( 929314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 930292932Sdim 931314564Sdim LoadInst *load = dyn_cast<LoadInst>(class_load); 932292932Sdim 933314564Sdim if (!load) 934314564Sdim return false; 935292932Sdim 936314564Sdim // Unpack the class name from the reference. In LLVM IR, a reference to an 937314564Sdim // Objective-C class gets represented as 938314564Sdim // 939314564Sdim // %tmp = load %struct._objc_class*, 940314564Sdim // %struct._objc_class** @OBJC_CLASS_REFERENCES_, align 4 941314564Sdim // 942314564Sdim // @"OBJC_CLASS_REFERENCES_ is a bitcast of a character array called 943341825Sdim // @OBJC_CLASS_NAME_. @OBJC_CLASS_NAME contains the string. 944292932Sdim 945341825Sdim // Find the pointer's initializer (a ConstantExpr with opcode BitCast) and 946341825Sdim // get the string from its target 947292932Sdim 948314564Sdim GlobalVariable *_objc_class_references_ = 949314564Sdim dyn_cast<GlobalVariable>(load->getPointerOperand()); 950292932Sdim 951314564Sdim if (!_objc_class_references_ || 952314564Sdim !_objc_class_references_->hasInitializer()) 953314564Sdim return false; 954292932Sdim 955314564Sdim Constant *ocr_initializer = _objc_class_references_->getInitializer(); 956292932Sdim 957314564Sdim ConstantExpr *ocr_initializer_expr = dyn_cast<ConstantExpr>(ocr_initializer); 958292932Sdim 959314564Sdim if (!ocr_initializer_expr || 960314564Sdim ocr_initializer_expr->getOpcode() != Instruction::BitCast) 961314564Sdim return false; 962292932Sdim 963314564Sdim Value *ocr_initializer_base = ocr_initializer_expr->getOperand(0); 964292932Sdim 965314564Sdim if (!ocr_initializer_base) 966314564Sdim return false; 967292932Sdim 968314564Sdim // Find the string's initializer (a ConstantArray) and get the string from it 969292932Sdim 970314564Sdim GlobalVariable *_objc_class_name_ = 971314564Sdim dyn_cast<GlobalVariable>(ocr_initializer_base); 972292932Sdim 973314564Sdim if (!_objc_class_name_ || !_objc_class_name_->hasInitializer()) 974314564Sdim return false; 975292932Sdim 976314564Sdim Constant *ocn_initializer = _objc_class_name_->getInitializer(); 977292932Sdim 978314564Sdim ConstantDataArray *ocn_initializer_array = 979314564Sdim dyn_cast<ConstantDataArray>(ocn_initializer); 980292932Sdim 981314564Sdim if (!ocn_initializer_array->isString()) 982314564Sdim return false; 983292932Sdim 984314564Sdim std::string ocn_initializer_string = ocn_initializer_array->getAsString(); 985292932Sdim 986360784Sdim LLDB_LOG(log, "Found Objective-C class reference \"{0}\"", 987360784Sdim ocn_initializer_string); 988292932Sdim 989314564Sdim // Construct a call to objc_getClass 990292932Sdim 991314564Sdim if (!m_objc_getClass) { 992314564Sdim lldb::addr_t objc_getClass_addr; 993292932Sdim 994353358Sdim bool missing_weak = false; 995314564Sdim static lldb_private::ConstString g_objc_getClass_str("objc_getClass"); 996353358Sdim objc_getClass_addr = m_execution_unit.FindSymbol(g_objc_getClass_str, 997353358Sdim missing_weak); 998353358Sdim if (objc_getClass_addr == LLDB_INVALID_ADDRESS || missing_weak) 999314564Sdim return false; 1000292932Sdim 1001360784Sdim LLDB_LOG(log, "Found objc_getClass at {0}", objc_getClass_addr); 1002292932Sdim 1003314564Sdim // Build the function type: %struct._objc_class *objc_getClass(i8*) 1004292932Sdim 1005314564Sdim Type *class_type = load->getType(); 1006314564Sdim Type *type_array[1]; 1007314564Sdim type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext()); 1008292932Sdim 1009314564Sdim ArrayRef<Type *> ogC_arg_types(type_array, 1); 1010292932Sdim 1011353358Sdim llvm::FunctionType *ogC_type = 1012314564Sdim FunctionType::get(class_type, ogC_arg_types, false); 1013292932Sdim 1014314564Sdim // Build the constant containing the pointer to the function 1015314564Sdim PointerType *ogC_ptr_ty = PointerType::getUnqual(ogC_type); 1016314564Sdim Constant *ogC_addr_int = 1017314564Sdim ConstantInt::get(m_intptr_ty, objc_getClass_addr, false); 1018353358Sdim m_objc_getClass = {ogC_type, 1019353358Sdim ConstantExpr::getIntToPtr(ogC_addr_int, ogC_ptr_ty)}; 1020314564Sdim } 1021292932Sdim 1022314564Sdim Value *argument_array[1]; 1023292932Sdim 1024314564Sdim Constant *ocn_pointer = ConstantExpr::getBitCast( 1025314564Sdim _objc_class_name_, Type::getInt8PtrTy(m_module->getContext())); 1026292932Sdim 1027314564Sdim argument_array[0] = ocn_pointer; 1028292932Sdim 1029314564Sdim ArrayRef<Value *> ogC_arguments(argument_array, 1); 1030292932Sdim 1031314564Sdim CallInst *ogC_call = CallInst::Create(m_objc_getClass, ogC_arguments, 1032314564Sdim "objc_getClass", class_load); 1033292932Sdim 1034314564Sdim // Replace the load with the call in all users 1035292932Sdim 1036314564Sdim class_load->replaceAllUsesWith(ogC_call); 1037292932Sdim 1038314564Sdim class_load->eraseFromParent(); 1039292932Sdim 1040314564Sdim return true; 1041292932Sdim} 1042292932Sdim 1043314564Sdimbool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) { 1044314564Sdim lldb_private::Log *log( 1045314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1046292932Sdim 1047314564Sdim InstrList class_loads; 1048292932Sdim 1049360784Sdim for (Instruction &inst : basic_block) { 1050314564Sdim if (LoadInst *load = dyn_cast<LoadInst>(&inst)) 1051314564Sdim if (IsObjCClassReference(load->getPointerOperand())) 1052314564Sdim class_loads.push_back(&inst); 1053314564Sdim } 1054292932Sdim 1055360784Sdim for (Instruction *inst : class_loads) { 1056360784Sdim if (!RewriteObjCClassReference(inst)) { 1057314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a " 1058314564Sdim "static reference to an Objective-C class to a " 1059314564Sdim "dynamic reference\n"); 1060292932Sdim 1061360784Sdim LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C class"); 1062292932Sdim 1063314564Sdim return false; 1064292932Sdim } 1065314564Sdim } 1066292932Sdim 1067314564Sdim return true; 1068292932Sdim} 1069292932Sdim 1070292932Sdim// This function does not report errors; its callers are responsible. 1071314564Sdimbool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) { 1072314564Sdim lldb_private::Log *log( 1073314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1074292932Sdim 1075314564Sdim AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc); 1076292932Sdim 1077314564Sdim MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr"); 1078292932Sdim 1079314564Sdim if (!alloc_md || !alloc_md->getNumOperands()) 1080314564Sdim return false; 1081292932Sdim 1082314564Sdim ConstantInt *constant_int = 1083314564Sdim mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0)); 1084292932Sdim 1085314564Sdim if (!constant_int) 1086314564Sdim return false; 1087292932Sdim 1088314564Sdim // We attempt to register this as a new persistent variable with the DeclMap. 1089292932Sdim 1090314564Sdim uintptr_t ptr = constant_int->getZExtValue(); 1091292932Sdim 1092314564Sdim clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr); 1093292932Sdim 1094314564Sdim lldb_private::TypeFromParser result_decl_type( 1095314564Sdim decl->getType().getAsOpaquePtr(), 1096314564Sdim lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext())); 1097292932Sdim 1098314564Sdim StringRef decl_name(decl->getName()); 1099314564Sdim lldb_private::ConstString persistent_variable_name(decl_name.data(), 1100314564Sdim decl_name.size()); 1101314564Sdim if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name, 1102314564Sdim result_decl_type, false, false)) 1103314564Sdim return false; 1104292932Sdim 1105314564Sdim GlobalVariable *persistent_global = new GlobalVariable( 1106353358Sdim (*m_module), alloc->getType(), false, /* not constant */ 1107353358Sdim GlobalValue::ExternalLinkage, nullptr, /* no initializer */ 1108314564Sdim alloc->getName().str()); 1109292932Sdim 1110341825Sdim // What we're going to do here is make believe this was a regular old 1111341825Sdim // external variable. That means we need to make the metadata valid. 1112292932Sdim 1113314564Sdim NamedMDNode *named_metadata = 1114314564Sdim m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs"); 1115292932Sdim 1116314564Sdim llvm::Metadata *values[2]; 1117314564Sdim values[0] = ConstantAsMetadata::get(persistent_global); 1118314564Sdim values[1] = ConstantAsMetadata::get(constant_int); 1119292932Sdim 1120314564Sdim ArrayRef<llvm::Metadata *> value_ref(values, 2); 1121292932Sdim 1122314564Sdim MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref); 1123314564Sdim named_metadata->addOperand(persistent_global_md); 1124292932Sdim 1125314564Sdim // Now, since the variable is a pointer variable, we will drop in a load of 1126341825Sdim // that pointer variable. 1127292932Sdim 1128314564Sdim LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc); 1129292932Sdim 1130360784Sdim LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(alloc), 1131360784Sdim PrintValue(persistent_load)); 1132292932Sdim 1133314564Sdim alloc->replaceAllUsesWith(persistent_load); 1134314564Sdim alloc->eraseFromParent(); 1135292932Sdim 1136314564Sdim return true; 1137292932Sdim} 1138292932Sdim 1139314564Sdimbool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) { 1140314564Sdim if (!m_resolve_vars) 1141314564Sdim return true; 1142292932Sdim 1143314564Sdim lldb_private::Log *log( 1144314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1145292932Sdim 1146314564Sdim InstrList pvar_allocs; 1147292932Sdim 1148360784Sdim for (Instruction &inst : basic_block) { 1149292932Sdim 1150314564Sdim if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) { 1151314564Sdim llvm::StringRef alloc_name = alloc->getName(); 1152292932Sdim 1153314564Sdim if (alloc_name.startswith("$") && !alloc_name.startswith("$__lldb")) { 1154314564Sdim if (alloc_name.find_first_of("0123456789") == 1) { 1155360784Sdim LLDB_LOG(log, "Rejecting a numeric persistent variable."); 1156292932Sdim 1157314564Sdim m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, " 1158314564Sdim "$1, ... are reserved for use as result " 1159314564Sdim "names\n"); 1160292932Sdim 1161314564Sdim return false; 1162314564Sdim } 1163292932Sdim 1164314564Sdim pvar_allocs.push_back(alloc); 1165314564Sdim } 1166292932Sdim } 1167314564Sdim } 1168292932Sdim 1169360784Sdim for (Instruction *inst : pvar_allocs) { 1170360784Sdim if (!RewritePersistentAlloc(inst)) { 1171314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite " 1172314564Sdim "the creation of a persistent variable\n"); 1173292932Sdim 1174360784Sdim LLDB_LOG(log, "Couldn't rewrite the creation of a persistent variable"); 1175292932Sdim 1176314564Sdim return false; 1177292932Sdim } 1178314564Sdim } 1179292932Sdim 1180314564Sdim return true; 1181292932Sdim} 1182292932Sdim 1183292932Sdim// This function does not report errors; its callers are responsible. 1184314564Sdimbool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) { 1185314564Sdim lldb_private::Log *log( 1186314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1187292932Sdim 1188360784Sdim LLDB_LOG(log, "MaybeHandleVariable ({0})", PrintValue(llvm_value_ptr)); 1189292932Sdim 1190314564Sdim if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) { 1191314564Sdim switch (constant_expr->getOpcode()) { 1192314564Sdim default: 1193314564Sdim break; 1194314564Sdim case Instruction::GetElementPtr: 1195314564Sdim case Instruction::BitCast: 1196314564Sdim Value *s = constant_expr->getOperand(0); 1197314564Sdim if (!MaybeHandleVariable(s)) 1198314564Sdim return false; 1199292932Sdim } 1200314564Sdim } else if (GlobalVariable *global_variable = 1201314564Sdim dyn_cast<GlobalVariable>(llvm_value_ptr)) { 1202314564Sdim if (!GlobalValue::isExternalLinkage(global_variable->getLinkage())) 1203314564Sdim return true; 1204292932Sdim 1205314564Sdim clang::NamedDecl *named_decl = DeclForGlobal(global_variable); 1206292932Sdim 1207314564Sdim if (!named_decl) { 1208314564Sdim if (IsObjCSelectorRef(llvm_value_ptr)) 1209314564Sdim return true; 1210292932Sdim 1211314564Sdim if (!global_variable->hasExternalLinkage()) 1212314564Sdim return true; 1213292932Sdim 1214360784Sdim LLDB_LOG(log, "Found global variable \"{0}\" without metadata", 1215360784Sdim global_variable->getName()); 1216292932Sdim 1217314564Sdim return false; 1218314564Sdim } 1219292932Sdim 1220360784Sdim llvm::StringRef name(named_decl->getName()); 1221292932Sdim 1222314564Sdim clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl); 1223353358Sdim if (value_decl == nullptr) 1224314564Sdim return false; 1225292932Sdim 1226360784Sdim lldb_private::CompilerType compiler_type( 1227360784Sdim lldb_private::ClangASTContext::GetASTContext( 1228360784Sdim &value_decl->getASTContext()), 1229360784Sdim value_decl->getType().getAsOpaquePtr()); 1230292932Sdim 1231353358Sdim const Type *value_type = nullptr; 1232292932Sdim 1233360784Sdim if (name.startswith("$")) { 1234314564Sdim // The $__lldb_expr_result name indicates the return value has allocated 1235341825Sdim // as a static variable. Per the comment at 1236341825Sdim // ASTResultSynthesizer::SynthesizeBodyResult, accesses to this static 1237341825Sdim // variable need to be redirected to the result of dereferencing a 1238341825Sdim // pointer that is passed in as one of the arguments. 1239314564Sdim // 1240314564Sdim // Consequently, when reporting the size of the type, we report a pointer 1241341825Sdim // type pointing to the type of $__lldb_expr_result, not the type itself. 1242314564Sdim // 1243314564Sdim // We also do this for any user-declared persistent variables. 1244314564Sdim compiler_type = compiler_type.GetPointerType(); 1245314564Sdim value_type = PointerType::get(global_variable->getType(), 0); 1246314564Sdim } else { 1247314564Sdim value_type = global_variable->getType(); 1248314564Sdim } 1249292932Sdim 1250344779Sdim llvm::Optional<uint64_t> value_size = compiler_type.GetByteSize(nullptr); 1251344779Sdim if (!value_size) 1252344779Sdim return false; 1253360784Sdim llvm::Optional<size_t> opt_alignment = compiler_type.GetTypeBitAlign(nullptr); 1254360784Sdim if (!opt_alignment) 1255360784Sdim return false; 1256360784Sdim lldb::offset_t value_alignment = (*opt_alignment + 7ull) / 8ull; 1257292932Sdim 1258360784Sdim LLDB_LOG(log, 1259360784Sdim "Type of \"{0}\" is [clang \"{1}\", llvm \"{2}\"] [size {3}, " 1260360784Sdim "align {4}]", 1261360784Sdim name, 1262360784Sdim lldb_private::ClangUtil::GetQualType(compiler_type).getAsString(), 1263360784Sdim PrintType(value_type), *value_size, value_alignment); 1264292932Sdim 1265360784Sdim if (named_decl) 1266360784Sdim m_decl_map->AddValueToStruct(named_decl, lldb_private::ConstString(name), 1267360784Sdim llvm_value_ptr, *value_size, 1268360784Sdim value_alignment); 1269314564Sdim } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) { 1270360784Sdim LLDB_LOG(log, "Function pointers aren't handled right now"); 1271292932Sdim 1272314564Sdim return false; 1273314564Sdim } 1274314564Sdim 1275314564Sdim return true; 1276292932Sdim} 1277292932Sdim 1278292932Sdim// This function does not report errors; its callers are responsible. 1279314564Sdimbool IRForTarget::HandleSymbol(Value *symbol) { 1280314564Sdim lldb_private::Log *log( 1281314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1282292932Sdim 1283314564Sdim lldb_private::ConstString name(symbol->getName().str().c_str()); 1284292932Sdim 1285314564Sdim lldb::addr_t symbol_addr = 1286314564Sdim m_decl_map->GetSymbolAddress(name, lldb::eSymbolTypeAny); 1287292932Sdim 1288314564Sdim if (symbol_addr == LLDB_INVALID_ADDRESS) { 1289360784Sdim LLDB_LOG(log, "Symbol \"{0}\" had no address", name); 1290292932Sdim 1291314564Sdim return false; 1292314564Sdim } 1293292932Sdim 1294360784Sdim LLDB_LOG(log, "Found \"{0}\" at {1}", name, symbol_addr); 1295292932Sdim 1296314564Sdim Type *symbol_type = symbol->getType(); 1297292932Sdim 1298314564Sdim Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false); 1299292932Sdim 1300314564Sdim Value *symbol_addr_ptr = 1301314564Sdim ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type); 1302292932Sdim 1303360784Sdim LLDB_LOG(log, "Replacing {0} with {1}", PrintValue(symbol), 1304360784Sdim PrintValue(symbol_addr_ptr)); 1305292932Sdim 1306314564Sdim symbol->replaceAllUsesWith(symbol_addr_ptr); 1307292932Sdim 1308314564Sdim return true; 1309292932Sdim} 1310292932Sdim 1311314564Sdimbool IRForTarget::MaybeHandleCallArguments(CallInst *Old) { 1312314564Sdim lldb_private::Log *log( 1313314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1314292932Sdim 1315360784Sdim LLDB_LOG(log, "MaybeHandleCallArguments({0})", PrintValue(Old)); 1316292932Sdim 1317314564Sdim for (unsigned op_index = 0, num_ops = Old->getNumArgOperands(); 1318314564Sdim op_index < num_ops; ++op_index) 1319360784Sdim // conservatively believe that this is a store 1320360784Sdim if (!MaybeHandleVariable(Old->getArgOperand(op_index))) { 1321314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite " 1322314564Sdim "one of the arguments of a function call.\n"); 1323292932Sdim 1324314564Sdim return false; 1325314564Sdim } 1326292932Sdim 1327314564Sdim return true; 1328292932Sdim} 1329292932Sdim 1330314564Sdimbool IRForTarget::HandleObjCClass(Value *classlist_reference) { 1331314564Sdim lldb_private::Log *log( 1332314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1333292932Sdim 1334314564Sdim GlobalVariable *global_variable = 1335314564Sdim dyn_cast<GlobalVariable>(classlist_reference); 1336292932Sdim 1337314564Sdim if (!global_variable) 1338314564Sdim return false; 1339292932Sdim 1340314564Sdim Constant *initializer = global_variable->getInitializer(); 1341292932Sdim 1342314564Sdim if (!initializer) 1343314564Sdim return false; 1344292932Sdim 1345314564Sdim if (!initializer->hasName()) 1346314564Sdim return false; 1347292932Sdim 1348314564Sdim StringRef name(initializer->getName()); 1349314564Sdim lldb_private::ConstString name_cstr(name.str().c_str()); 1350314564Sdim lldb::addr_t class_ptr = 1351314564Sdim m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass); 1352292932Sdim 1353360784Sdim LLDB_LOG(log, "Found reference to Objective-C class {0} ({1})", name, 1354360784Sdim (unsigned long long)class_ptr); 1355292932Sdim 1356314564Sdim if (class_ptr == LLDB_INVALID_ADDRESS) 1357314564Sdim return false; 1358292932Sdim 1359314564Sdim if (global_variable->use_empty()) 1360314564Sdim return false; 1361292932Sdim 1362314564Sdim SmallVector<LoadInst *, 2> load_instructions; 1363292932Sdim 1364314564Sdim for (llvm::User *u : global_variable->users()) { 1365314564Sdim if (LoadInst *load_instruction = dyn_cast<LoadInst>(u)) 1366314564Sdim load_instructions.push_back(load_instruction); 1367314564Sdim } 1368292932Sdim 1369314564Sdim if (load_instructions.empty()) 1370314564Sdim return false; 1371292932Sdim 1372314564Sdim Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr); 1373292932Sdim 1374314564Sdim for (LoadInst *load_instruction : load_instructions) { 1375314564Sdim Constant *class_bitcast = 1376314564Sdim ConstantExpr::getIntToPtr(class_addr, load_instruction->getType()); 1377292932Sdim 1378314564Sdim load_instruction->replaceAllUsesWith(class_bitcast); 1379292932Sdim 1380314564Sdim load_instruction->eraseFromParent(); 1381314564Sdim } 1382292932Sdim 1383314564Sdim return true; 1384292932Sdim} 1385292932Sdim 1386314564Sdimbool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) { 1387314564Sdim std::vector<CallInst *> calls_to_remove; 1388292932Sdim 1389360784Sdim for (Instruction &inst : basic_block) { 1390314564Sdim CallInst *call = dyn_cast<CallInst>(&inst); 1391292932Sdim 1392314564Sdim // MaybeHandleCallArguments handles error reporting; we are silent here 1393314564Sdim if (!call) 1394314564Sdim continue; 1395292932Sdim 1396314564Sdim bool remove = false; 1397292932Sdim 1398314564Sdim llvm::Function *func = call->getCalledFunction(); 1399292932Sdim 1400314564Sdim if (func && func->getName() == "__cxa_atexit") 1401314564Sdim remove = true; 1402292932Sdim 1403314564Sdim llvm::Value *val = call->getCalledValue(); 1404292932Sdim 1405314564Sdim if (val && val->getName() == "__cxa_atexit") 1406314564Sdim remove = true; 1407292932Sdim 1408314564Sdim if (remove) 1409314564Sdim calls_to_remove.push_back(call); 1410314564Sdim } 1411292932Sdim 1412360784Sdim for (CallInst *ci : calls_to_remove) 1413360784Sdim ci->eraseFromParent(); 1414292932Sdim 1415314564Sdim return true; 1416292932Sdim} 1417292932Sdim 1418314564Sdimbool IRForTarget::ResolveCalls(BasicBlock &basic_block) { 1419314564Sdim // Prepare the current basic block for execution in the remote process 1420292932Sdim 1421360784Sdim for (Instruction &inst : basic_block) { 1422314564Sdim CallInst *call = dyn_cast<CallInst>(&inst); 1423292932Sdim 1424314564Sdim // MaybeHandleCallArguments handles error reporting; we are silent here 1425314564Sdim if (call && !MaybeHandleCallArguments(call)) 1426314564Sdim return false; 1427314564Sdim } 1428292932Sdim 1429314564Sdim return true; 1430292932Sdim} 1431292932Sdim 1432314564Sdimbool IRForTarget::ResolveExternals(Function &llvm_function) { 1433314564Sdim lldb_private::Log *log( 1434314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1435292932Sdim 1436314564Sdim for (GlobalVariable &global_var : m_module->globals()) { 1437360784Sdim llvm::StringRef global_name = global_var.getName(); 1438292932Sdim 1439360784Sdim LLDB_LOG(log, "Examining {0}, DeclForGlobalValue returns {1}", global_name, 1440360784Sdim static_cast<void *>(DeclForGlobal(&global_var))); 1441292932Sdim 1442360784Sdim if (global_name.startswith("OBJC_IVAR")) { 1443314564Sdim if (!HandleSymbol(&global_var)) { 1444360784Sdim m_error_stream.Format("Error [IRForTarget]: Couldn't find Objective-C " 1445360784Sdim "indirect ivar symbol {0}\n", 1446360784Sdim global_name); 1447292932Sdim 1448314564Sdim return false; 1449314564Sdim } 1450360784Sdim } else if (global_name.contains("OBJC_CLASSLIST_REFERENCES_$")) { 1451314564Sdim if (!HandleObjCClass(&global_var)) { 1452314564Sdim m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class " 1453314564Sdim "for an Objective-C static method call\n"); 1454292932Sdim 1455314564Sdim return false; 1456314564Sdim } 1457360784Sdim } else if (global_name.contains("OBJC_CLASSLIST_SUP_REFS_$")) { 1458314564Sdim if (!HandleObjCClass(&global_var)) { 1459314564Sdim m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class " 1460314564Sdim "for an Objective-C static method call\n"); 1461292932Sdim 1462314564Sdim return false; 1463314564Sdim } 1464314564Sdim } else if (DeclForGlobal(&global_var)) { 1465314564Sdim if (!MaybeHandleVariable(&global_var)) { 1466360784Sdim m_error_stream.Format("Internal error [IRForTarget]: Couldn't rewrite " 1467360784Sdim "external variable {0}\n", 1468360784Sdim global_name); 1469292932Sdim 1470314564Sdim return false; 1471314564Sdim } 1472292932Sdim } 1473314564Sdim } 1474292932Sdim 1475314564Sdim return true; 1476292932Sdim} 1477292932Sdim 1478314564Sdimstatic bool isGuardVariableRef(Value *V) { 1479360784Sdim Constant *Old = dyn_cast<Constant>(V); 1480292932Sdim 1481360784Sdim if (!Old) 1482314564Sdim return false; 1483292932Sdim 1484360784Sdim if (auto CE = dyn_cast<ConstantExpr>(V)) { 1485314564Sdim if (CE->getOpcode() != Instruction::BitCast) 1486314564Sdim return false; 1487292932Sdim 1488314564Sdim Old = CE->getOperand(0); 1489314564Sdim } 1490292932Sdim 1491314564Sdim GlobalVariable *GV = dyn_cast<GlobalVariable>(Old); 1492292932Sdim 1493360784Sdim if (!GV || !GV->hasName() || !isGuardVariableSymbol(GV->getName())) 1494314564Sdim return false; 1495292932Sdim 1496314564Sdim return true; 1497292932Sdim} 1498292932Sdim 1499314564Sdimvoid IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction *guard_load) { 1500314564Sdim Constant *zero(Constant::getNullValue(guard_load->getType())); 1501314564Sdim guard_load->replaceAllUsesWith(zero); 1502314564Sdim guard_load->eraseFromParent(); 1503292932Sdim} 1504292932Sdim 1505314564Sdimstatic void ExciseGuardStore(Instruction *guard_store) { 1506314564Sdim guard_store->eraseFromParent(); 1507292932Sdim} 1508292932Sdim 1509314564Sdimbool IRForTarget::RemoveGuards(BasicBlock &basic_block) { 1510314564Sdim // Eliminate any reference to guard variables found. 1511292932Sdim 1512314564Sdim InstrList guard_loads; 1513314564Sdim InstrList guard_stores; 1514292932Sdim 1515360784Sdim for (Instruction &inst : basic_block) { 1516292932Sdim 1517314564Sdim if (LoadInst *load = dyn_cast<LoadInst>(&inst)) 1518314564Sdim if (isGuardVariableRef(load->getPointerOperand())) 1519314564Sdim guard_loads.push_back(&inst); 1520292932Sdim 1521314564Sdim if (StoreInst *store = dyn_cast<StoreInst>(&inst)) 1522314564Sdim if (isGuardVariableRef(store->getPointerOperand())) 1523314564Sdim guard_stores.push_back(&inst); 1524314564Sdim } 1525292932Sdim 1526360784Sdim for (Instruction *inst : guard_loads) 1527360784Sdim TurnGuardLoadIntoZero(inst); 1528292932Sdim 1529360784Sdim for (Instruction *inst : guard_stores) 1530360784Sdim ExciseGuardStore(inst); 1531292932Sdim 1532314564Sdim return true; 1533292932Sdim} 1534292932Sdim 1535292932Sdim// This function does not report errors; its callers are responsible. 1536314564Sdimbool IRForTarget::UnfoldConstant(Constant *old_constant, 1537314564Sdim llvm::Function *llvm_function, 1538314564Sdim FunctionValueCache &value_maker, 1539314564Sdim FunctionValueCache &entry_instruction_finder, 1540314564Sdim lldb_private::Stream &error_stream) { 1541314564Sdim SmallVector<User *, 16> users; 1542292932Sdim 1543314564Sdim // We do this because the use list might change, invalidating our iterator. 1544314564Sdim // Much better to keep a work list ourselves. 1545314564Sdim for (llvm::User *u : old_constant->users()) 1546314564Sdim users.push_back(u); 1547292932Sdim 1548314564Sdim for (size_t i = 0; i < users.size(); ++i) { 1549314564Sdim User *user = users[i]; 1550292932Sdim 1551314564Sdim if (Constant *constant = dyn_cast<Constant>(user)) { 1552314564Sdim // synthesize a new non-constant equivalent of the constant 1553292932Sdim 1554314564Sdim if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) { 1555314564Sdim switch (constant_expr->getOpcode()) { 1556314564Sdim default: 1557314564Sdim error_stream.Printf("error [IRForTarget internal]: Unhandled " 1558314564Sdim "constant expression type: \"%s\"", 1559314564Sdim PrintValue(constant_expr).c_str()); 1560314564Sdim return false; 1561314564Sdim case Instruction::BitCast: { 1562314564Sdim FunctionValueCache bit_cast_maker( 1563314564Sdim [&value_maker, &entry_instruction_finder, old_constant, 1564314564Sdim constant_expr](llvm::Function *function) -> llvm::Value * { 1565314564Sdim // UnaryExpr 1566314564Sdim // OperandList[0] is value 1567292932Sdim 1568314564Sdim if (constant_expr->getOperand(0) != old_constant) 1569314564Sdim return constant_expr; 1570292932Sdim 1571314564Sdim return new BitCastInst( 1572314564Sdim value_maker.GetValue(function), constant_expr->getType(), 1573314564Sdim "", llvm::cast<Instruction>( 1574314564Sdim entry_instruction_finder.GetValue(function))); 1575314564Sdim }); 1576292932Sdim 1577314564Sdim if (!UnfoldConstant(constant_expr, llvm_function, bit_cast_maker, 1578314564Sdim entry_instruction_finder, error_stream)) 1579314564Sdim return false; 1580314564Sdim } break; 1581314564Sdim case Instruction::GetElementPtr: { 1582314564Sdim // GetElementPtrConstantExpr 1583314564Sdim // OperandList[0] is base 1584314564Sdim // OperandList[1]... are indices 1585292932Sdim 1586314564Sdim FunctionValueCache get_element_pointer_maker( 1587314564Sdim [&value_maker, &entry_instruction_finder, old_constant, 1588314564Sdim constant_expr](llvm::Function *function) -> llvm::Value * { 1589314564Sdim Value *ptr = constant_expr->getOperand(0); 1590292932Sdim 1591314564Sdim if (ptr == old_constant) 1592314564Sdim ptr = value_maker.GetValue(function); 1593292932Sdim 1594314564Sdim std::vector<Value *> index_vector; 1595292932Sdim 1596314564Sdim unsigned operand_index; 1597314564Sdim unsigned num_operands = constant_expr->getNumOperands(); 1598292932Sdim 1599314564Sdim for (operand_index = 1; operand_index < num_operands; 1600314564Sdim ++operand_index) { 1601314564Sdim Value *operand = constant_expr->getOperand(operand_index); 1602292932Sdim 1603314564Sdim if (operand == old_constant) 1604314564Sdim operand = value_maker.GetValue(function); 1605292932Sdim 1606314564Sdim index_vector.push_back(operand); 1607314564Sdim } 1608292932Sdim 1609314564Sdim ArrayRef<Value *> indices(index_vector); 1610292932Sdim 1611314564Sdim return GetElementPtrInst::Create( 1612314564Sdim nullptr, ptr, indices, "", 1613314564Sdim llvm::cast<Instruction>( 1614314564Sdim entry_instruction_finder.GetValue(function))); 1615314564Sdim }); 1616292932Sdim 1617314564Sdim if (!UnfoldConstant(constant_expr, llvm_function, 1618314564Sdim get_element_pointer_maker, 1619314564Sdim entry_instruction_finder, error_stream)) 1620314564Sdim return false; 1621314564Sdim } break; 1622292932Sdim } 1623314564Sdim } else { 1624314564Sdim error_stream.Printf( 1625314564Sdim "error [IRForTarget internal]: Unhandled constant type: \"%s\"", 1626314564Sdim PrintValue(constant).c_str()); 1627314564Sdim return false; 1628314564Sdim } 1629314564Sdim } else { 1630314564Sdim if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) { 1631314564Sdim if (llvm_function && inst->getParent()->getParent() != llvm_function) { 1632314564Sdim error_stream.PutCString("error: Capturing non-local variables in " 1633314564Sdim "expressions is unsupported.\n"); 1634314564Sdim return false; 1635292932Sdim } 1636314564Sdim inst->replaceUsesOfWith( 1637314564Sdim old_constant, value_maker.GetValue(inst->getParent()->getParent())); 1638314564Sdim } else { 1639314564Sdim error_stream.Printf( 1640314564Sdim "error [IRForTarget internal]: Unhandled non-constant type: \"%s\"", 1641314564Sdim PrintValue(user).c_str()); 1642314564Sdim return false; 1643314564Sdim } 1644292932Sdim } 1645314564Sdim } 1646292932Sdim 1647314564Sdim if (!isa<GlobalValue>(old_constant)) { 1648314564Sdim old_constant->destroyConstant(); 1649314564Sdim } 1650292932Sdim 1651314564Sdim return true; 1652292932Sdim} 1653292932Sdim 1654314564Sdimbool IRForTarget::ReplaceVariables(Function &llvm_function) { 1655314564Sdim if (!m_resolve_vars) 1656314564Sdim return true; 1657292932Sdim 1658314564Sdim lldb_private::Log *log( 1659314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1660292932Sdim 1661314564Sdim m_decl_map->DoStructLayout(); 1662292932Sdim 1663360784Sdim LLDB_LOG(log, "Element arrangement:"); 1664292932Sdim 1665314564Sdim uint32_t num_elements; 1666314564Sdim uint32_t element_index; 1667292932Sdim 1668314564Sdim size_t size; 1669314564Sdim lldb::offset_t alignment; 1670292932Sdim 1671314564Sdim if (!m_decl_map->GetStructInfo(num_elements, size, alignment)) 1672314564Sdim return false; 1673292932Sdim 1674321369Sdim Function::arg_iterator iter(llvm_function.arg_begin()); 1675292932Sdim 1676321369Sdim if (iter == llvm_function.arg_end()) { 1677314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes no " 1678314564Sdim "arguments (should take at least a struct pointer)"); 1679292932Sdim 1680314564Sdim return false; 1681314564Sdim } 1682292932Sdim 1683314564Sdim Argument *argument = &*iter; 1684292932Sdim 1685314564Sdim if (argument->getName().equals("this")) { 1686314564Sdim ++iter; 1687292932Sdim 1688321369Sdim if (iter == llvm_function.arg_end()) { 1689314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only " 1690314564Sdim "'this' argument (should take a struct pointer " 1691314564Sdim "too)"); 1692292932Sdim 1693314564Sdim return false; 1694292932Sdim } 1695292932Sdim 1696314564Sdim argument = &*iter; 1697314564Sdim } else if (argument->getName().equals("self")) { 1698314564Sdim ++iter; 1699292932Sdim 1700321369Sdim if (iter == llvm_function.arg_end()) { 1701314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only " 1702314564Sdim "'self' argument (should take '_cmd' and a struct " 1703314564Sdim "pointer too)"); 1704292932Sdim 1705314564Sdim return false; 1706314564Sdim } 1707292932Sdim 1708314564Sdim if (!iter->getName().equals("_cmd")) { 1709360784Sdim m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes '{0}' " 1710314564Sdim "after 'self' argument (should take '_cmd')", 1711360784Sdim iter->getName()); 1712292932Sdim 1713314564Sdim return false; 1714314564Sdim } 1715292932Sdim 1716314564Sdim ++iter; 1717292932Sdim 1718321369Sdim if (iter == llvm_function.arg_end()) { 1719314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only " 1720314564Sdim "'self' and '_cmd' arguments (should take a struct " 1721314564Sdim "pointer too)"); 1722292932Sdim 1723314564Sdim return false; 1724292932Sdim } 1725292932Sdim 1726314564Sdim argument = &*iter; 1727314564Sdim } 1728292932Sdim 1729314564Sdim if (!argument->getName().equals("$__lldb_arg")) { 1730360784Sdim m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes an " 1731360784Sdim "argument named '{0}' instead of the struct pointer", 1732360784Sdim argument->getName()); 1733292932Sdim 1734314564Sdim return false; 1735314564Sdim } 1736292932Sdim 1737360784Sdim LLDB_LOG(log, "Arg: \"{0}\"", PrintValue(argument)); 1738292932Sdim 1739314564Sdim BasicBlock &entry_block(llvm_function.getEntryBlock()); 1740314564Sdim Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg()); 1741292932Sdim 1742314564Sdim if (!FirstEntryInstruction) { 1743314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find the " 1744314564Sdim "first instruction in the wrapper for use in " 1745314564Sdim "rewriting"); 1746292932Sdim 1747314564Sdim return false; 1748314564Sdim } 1749292932Sdim 1750314564Sdim LLVMContext &context(m_module->getContext()); 1751314564Sdim IntegerType *offset_type(Type::getInt32Ty(context)); 1752292932Sdim 1753314564Sdim if (!offset_type) { 1754314564Sdim m_error_stream.Printf( 1755314564Sdim "Internal error [IRForTarget]: Couldn't produce an offset type"); 1756292932Sdim 1757314564Sdim return false; 1758314564Sdim } 1759292932Sdim 1760314564Sdim for (element_index = 0; element_index < num_elements; ++element_index) { 1761353358Sdim const clang::NamedDecl *decl = nullptr; 1762353358Sdim Value *value = nullptr; 1763314564Sdim lldb::offset_t offset; 1764314564Sdim lldb_private::ConstString name; 1765292932Sdim 1766314564Sdim if (!m_decl_map->GetStructElement(decl, value, offset, name, 1767314564Sdim element_index)) { 1768314564Sdim m_error_stream.Printf( 1769314564Sdim "Internal error [IRForTarget]: Structure information is incomplete"); 1770292932Sdim 1771314564Sdim return false; 1772314564Sdim } 1773292932Sdim 1774360784Sdim LLDB_LOG(log, " \"{0}\" (\"{1}\") placed at {2}", name, 1775360784Sdim decl->getNameAsString(), offset); 1776292932Sdim 1777314564Sdim if (value) { 1778360784Sdim LLDB_LOG(log, " Replacing [{0}]", PrintValue(value)); 1779292932Sdim 1780314564Sdim FunctionValueCache body_result_maker( 1781314564Sdim [this, name, offset_type, offset, argument, 1782314564Sdim value](llvm::Function *function) -> llvm::Value * { 1783341825Sdim // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, 1784341825Sdim // in cases where the result variable is an rvalue, we have to 1785341825Sdim // synthesize a dereference of the appropriate structure entry in 1786341825Sdim // order to produce the static variable that the AST thinks it is 1787341825Sdim // accessing. 1788292932Sdim 1789314564Sdim llvm::Instruction *entry_instruction = llvm::cast<Instruction>( 1790314564Sdim m_entry_instruction_finder.GetValue(function)); 1791292932Sdim 1792314564Sdim ConstantInt *offset_int( 1793314564Sdim ConstantInt::get(offset_type, offset, true)); 1794314564Sdim GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create( 1795314564Sdim nullptr, argument, offset_int, "", entry_instruction); 1796292932Sdim 1797314564Sdim if (name == m_result_name && !m_result_is_pointer) { 1798314564Sdim BitCastInst *bit_cast = new BitCastInst( 1799314564Sdim get_element_ptr, value->getType()->getPointerTo(), "", 1800314564Sdim entry_instruction); 1801292932Sdim 1802314564Sdim LoadInst *load = new LoadInst(bit_cast, "", entry_instruction); 1803292932Sdim 1804314564Sdim return load; 1805314564Sdim } else { 1806314564Sdim BitCastInst *bit_cast = new BitCastInst( 1807314564Sdim get_element_ptr, value->getType(), "", entry_instruction); 1808292932Sdim 1809314564Sdim return bit_cast; 1810292932Sdim } 1811314564Sdim }); 1812292932Sdim 1813314564Sdim if (Constant *constant = dyn_cast<Constant>(value)) { 1814314564Sdim if (!UnfoldConstant(constant, &llvm_function, body_result_maker, 1815314564Sdim m_entry_instruction_finder, m_error_stream)) { 1816314564Sdim return false; 1817292932Sdim } 1818314564Sdim } else if (Instruction *instruction = dyn_cast<Instruction>(value)) { 1819314564Sdim if (instruction->getParent()->getParent() != &llvm_function) { 1820314564Sdim m_error_stream.PutCString("error: Capturing non-local variables in " 1821314564Sdim "expressions is unsupported.\n"); 1822314564Sdim return false; 1823314564Sdim } 1824314564Sdim value->replaceAllUsesWith( 1825314564Sdim body_result_maker.GetValue(instruction->getParent()->getParent())); 1826314564Sdim } else { 1827360784Sdim LLDB_LOG(log, "Unhandled non-constant type: \"{0}\"", 1828360784Sdim PrintValue(value)); 1829314564Sdim return false; 1830314564Sdim } 1831314564Sdim 1832314564Sdim if (GlobalVariable *var = dyn_cast<GlobalVariable>(value)) 1833314564Sdim var->eraseFromParent(); 1834292932Sdim } 1835314564Sdim } 1836292932Sdim 1837360784Sdim LLDB_LOG(log, "Total structure [align {0}, size {1}]", (int64_t)alignment, 1838360784Sdim (uint64_t)size); 1839292932Sdim 1840314564Sdim return true; 1841292932Sdim} 1842292932Sdim 1843314564Sdimbool IRForTarget::runOnModule(Module &llvm_module) { 1844314564Sdim lldb_private::Log *log( 1845314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1846292932Sdim 1847314564Sdim m_module = &llvm_module; 1848314564Sdim m_target_data.reset(new DataLayout(m_module)); 1849314564Sdim m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(), 1850314564Sdim m_target_data->getPointerSizeInBits()); 1851292932Sdim 1852314564Sdim if (log) { 1853314564Sdim std::string s; 1854314564Sdim raw_string_ostream oss(s); 1855292932Sdim 1856353358Sdim m_module->print(oss, nullptr); 1857292932Sdim 1858314564Sdim oss.flush(); 1859292932Sdim 1860360784Sdim LLDB_LOG(log, "Module as passed in to IRForTarget: \n\"{0}\"", s); 1861314564Sdim } 1862292932Sdim 1863314564Sdim Function *const main_function = 1864314564Sdim m_func_name.IsEmpty() ? nullptr 1865314564Sdim : m_module->getFunction(m_func_name.GetStringRef()); 1866292932Sdim 1867314564Sdim if (!m_func_name.IsEmpty() && !main_function) { 1868360784Sdim LLDB_LOG(log, "Couldn't find \"{0}()\" in the module", m_func_name); 1869292932Sdim 1870360784Sdim m_error_stream.Format("Internal error [IRForTarget]: Couldn't find wrapper " 1871360784Sdim "'{0}' in the module", 1872360784Sdim m_func_name); 1873292932Sdim 1874314564Sdim return false; 1875314564Sdim } 1876292932Sdim 1877314564Sdim if (main_function) { 1878314564Sdim if (!FixFunctionLinkage(*main_function)) { 1879360784Sdim LLDB_LOG(log, "Couldn't fix the linkage for the function"); 1880292932Sdim 1881314564Sdim return false; 1882292932Sdim } 1883314564Sdim } 1884292932Sdim 1885314564Sdim llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext()); 1886292932Sdim 1887314564Sdim m_reloc_placeholder = new llvm::GlobalVariable( 1888314564Sdim (*m_module), int8_ty, false /* IsConstant */, 1889314564Sdim GlobalVariable::InternalLinkage, Constant::getNullValue(int8_ty), 1890353358Sdim "reloc_placeholder", nullptr /* InsertBefore */, 1891314564Sdim GlobalVariable::NotThreadLocal /* ThreadLocal */, 0 /* AddressSpace */); 1892292932Sdim 1893314564Sdim //////////////////////////////////////////////////////////// 1894314564Sdim // Replace $__lldb_expr_result with a persistent variable 1895314564Sdim // 1896292932Sdim 1897314564Sdim if (main_function) { 1898314564Sdim if (!CreateResultVariable(*main_function)) { 1899360784Sdim LLDB_LOG(log, "CreateResultVariable() failed"); 1900292932Sdim 1901314564Sdim // CreateResultVariable() reports its own errors, so we don't do so here 1902292932Sdim 1903314564Sdim return false; 1904292932Sdim } 1905314564Sdim } 1906292932Sdim 1907314564Sdim if (log && log->GetVerbose()) { 1908314564Sdim std::string s; 1909314564Sdim raw_string_ostream oss(s); 1910292932Sdim 1911353358Sdim m_module->print(oss, nullptr); 1912292932Sdim 1913314564Sdim oss.flush(); 1914292932Sdim 1915360784Sdim LLDB_LOG(log, "Module after creating the result variable: \n\"{0}\"", s); 1916314564Sdim } 1917292932Sdim 1918360784Sdim for (llvm::Function &function : *m_module) { 1919360784Sdim for (BasicBlock &bb : function) { 1920360784Sdim if (!RemoveGuards(bb)) { 1921360784Sdim LLDB_LOG(log, "RemoveGuards() failed"); 1922292932Sdim 1923314564Sdim // RemoveGuards() reports its own errors, so we don't do so here 1924292932Sdim 1925314564Sdim return false; 1926314564Sdim } 1927292932Sdim 1928360784Sdim if (!RewritePersistentAllocs(bb)) { 1929360784Sdim LLDB_LOG(log, "RewritePersistentAllocs() failed"); 1930292932Sdim 1931314564Sdim // RewritePersistentAllocs() reports its own errors, so we don't do so 1932314564Sdim // here 1933292932Sdim 1934314564Sdim return false; 1935314564Sdim } 1936292932Sdim 1937360784Sdim if (!RemoveCXAAtExit(bb)) { 1938360784Sdim LLDB_LOG(log, "RemoveCXAAtExit() failed"); 1939292932Sdim 1940314564Sdim // RemoveCXAAtExit() reports its own errors, so we don't do so here 1941292932Sdim 1942314564Sdim return false; 1943314564Sdim } 1944292932Sdim } 1945314564Sdim } 1946292932Sdim 1947314564Sdim /////////////////////////////////////////////////////////////////////////////// 1948314564Sdim // Fix all Objective-C constant strings to use NSStringWithCString:encoding: 1949314564Sdim // 1950292932Sdim 1951314564Sdim if (!RewriteObjCConstStrings()) { 1952360784Sdim LLDB_LOG(log, "RewriteObjCConstStrings() failed"); 1953314564Sdim 1954314564Sdim // RewriteObjCConstStrings() reports its own errors, so we don't do so here 1955314564Sdim 1956314564Sdim return false; 1957314564Sdim } 1958314564Sdim 1959360784Sdim for (llvm::Function &function : *m_module) { 1960360784Sdim for (llvm::BasicBlock &bb : function) { 1961360784Sdim if (!RewriteObjCSelectors(bb)) { 1962360784Sdim LLDB_LOG(log, "RewriteObjCSelectors() failed"); 1963314564Sdim 1964341825Sdim // RewriteObjCSelectors() reports its own errors, so we don't do so 1965341825Sdim // here 1966292932Sdim 1967292932Sdim return false; 1968314564Sdim } 1969292932Sdim 1970360784Sdim if (!RewriteObjCClassReferences(bb)) { 1971360784Sdim LLDB_LOG(log, "RewriteObjCClassReferences() failed"); 1972292932Sdim 1973314564Sdim // RewriteObjCClasses() reports its own errors, so we don't do so here 1974292932Sdim 1975314564Sdim return false; 1976314564Sdim } 1977292932Sdim } 1978314564Sdim } 1979292932Sdim 1980360784Sdim for (llvm::Function &function : *m_module) { 1981360784Sdim for (BasicBlock &bb : function) { 1982360784Sdim if (!ResolveCalls(bb)) { 1983360784Sdim LLDB_LOG(log, "ResolveCalls() failed"); 1984292932Sdim 1985314564Sdim // ResolveCalls() reports its own errors, so we don't do so here 1986292932Sdim 1987314564Sdim return false; 1988314564Sdim } 1989292932Sdim } 1990314564Sdim } 1991292932Sdim 1992314564Sdim //////////////////////////////////////////////////////////////////////// 1993314564Sdim // Run function-level passes that only make sense on the main function 1994314564Sdim // 1995292932Sdim 1996314564Sdim if (main_function) { 1997314564Sdim if (!ResolveExternals(*main_function)) { 1998360784Sdim LLDB_LOG(log, "ResolveExternals() failed"); 1999292932Sdim 2000314564Sdim // ResolveExternals() reports its own errors, so we don't do so here 2001292932Sdim 2002314564Sdim return false; 2003314564Sdim } 2004292932Sdim 2005314564Sdim if (!ReplaceVariables(*main_function)) { 2006360784Sdim LLDB_LOG(log, "ReplaceVariables() failed"); 2007292932Sdim 2008314564Sdim // ReplaceVariables() reports its own errors, so we don't do so here 2009292932Sdim 2010314564Sdim return false; 2011292932Sdim } 2012314564Sdim } 2013292932Sdim 2014314564Sdim if (log && log->GetVerbose()) { 2015314564Sdim std::string s; 2016314564Sdim raw_string_ostream oss(s); 2017292932Sdim 2018353358Sdim m_module->print(oss, nullptr); 2019292932Sdim 2020314564Sdim oss.flush(); 2021292932Sdim 2022360784Sdim LLDB_LOG(log, "Module after preparing for execution: \n\"{0}\"", s); 2023314564Sdim } 2024292932Sdim 2025314564Sdim return true; 2026292932Sdim} 2027292932Sdim 2028314564Sdimvoid IRForTarget::assignPassManager(PMStack &pass_mgr_stack, 2029314564Sdim PassManagerType pass_mgr_type) {} 2030292932Sdim 2031314564SdimPassManagerType IRForTarget::getPotentialPassManagerType() const { 2032314564Sdim return PMT_ModulePassManager; 2033292932Sdim} 2034