IRForTarget.cpp revision 314564
1292932Sdim//===-- IRForTarget.cpp -----------------------------------------*- C++ -*-===// 2292932Sdim// 3292932Sdim// The LLVM Compiler Infrastructure 4292932Sdim// 5292932Sdim// This file is distributed under the University of Illinois Open Source 6292932Sdim// License. See LICENSE.TXT for details. 7292932Sdim// 8292932Sdim//===----------------------------------------------------------------------===// 9292932Sdim 10292932Sdim#include "IRForTarget.h" 11292932Sdim 12292932Sdim#include "ClangExpressionDeclMap.h" 13292932Sdim 14292932Sdim#include "llvm/IR/Constants.h" 15292932Sdim#include "llvm/IR/DataLayout.h" 16292932Sdim#include "llvm/IR/InstrTypes.h" 17292932Sdim#include "llvm/IR/Instructions.h" 18292932Sdim#include "llvm/IR/Intrinsics.h" 19292932Sdim#include "llvm/IR/LegacyPassManager.h" 20292932Sdim#include "llvm/IR/Metadata.h" 21314564Sdim#include "llvm/IR/Module.h" 22292932Sdim#include "llvm/IR/ValueSymbolTable.h" 23314564Sdim#include "llvm/Support/raw_ostream.h" 24314564Sdim#include "llvm/Transforms/IPO.h" 25292932Sdim 26292932Sdim#include "clang/AST/ASTContext.h" 27292932Sdim 28292932Sdim#include "lldb/Core/ConstString.h" 29292932Sdim#include "lldb/Core/DataBufferHeap.h" 30292932Sdim#include "lldb/Core/Log.h" 31292932Sdim#include "lldb/Core/Scalar.h" 32292932Sdim#include "lldb/Core/StreamString.h" 33309124Sdim#include "lldb/Core/dwarf.h" 34292932Sdim#include "lldb/Expression/IRExecutionUnit.h" 35292932Sdim#include "lldb/Expression/IRInterpreter.h" 36292932Sdim#include "lldb/Host/Endian.h" 37292932Sdim#include "lldb/Symbol/ClangASTContext.h" 38309124Sdim#include "lldb/Symbol/ClangUtil.h" 39292932Sdim#include "lldb/Symbol/CompilerType.h" 40292932Sdim 41292932Sdim#include <map> 42292932Sdim 43292932Sdimusing namespace llvm; 44292932Sdim 45292932Sdimstatic char ID; 46292932Sdim 47314564SdimIRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker) 48314564Sdim : m_maker(maker), m_values() {} 49292932Sdim 50314564SdimIRForTarget::FunctionValueCache::~FunctionValueCache() {} 51292932Sdim 52292932Sdimllvm::Value * 53314564SdimIRForTarget::FunctionValueCache::GetValue(llvm::Function *function) { 54314564Sdim if (!m_values.count(function)) { 55314564Sdim llvm::Value *ret = m_maker(function); 56314564Sdim m_values[function] = ret; 57314564Sdim return ret; 58314564Sdim } 59314564Sdim return m_values[function]; 60292932Sdim} 61292932Sdim 62314564Sdimstatic llvm::Value *FindEntryInstruction(llvm::Function *function) { 63314564Sdim if (function->empty()) 64314564Sdim return NULL; 65292932Sdim 66314564Sdim return function->getEntryBlock().getFirstNonPHIOrDbg(); 67292932Sdim} 68292932Sdim 69314564SdimIRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map, 70314564Sdim bool resolve_vars, 71314564Sdim lldb_private::IRExecutionUnit &execution_unit, 72314564Sdim lldb_private::Stream &error_stream, 73314564Sdim const char *func_name) 74314564Sdim : ModulePass(ID), m_resolve_vars(resolve_vars), m_func_name(func_name), 75314564Sdim m_module(NULL), m_decl_map(decl_map), m_CFStringCreateWithBytes(NULL), 76314564Sdim m_sel_registerName(NULL), m_objc_getClass(NULL), m_intptr_ty(NULL), 77314564Sdim m_error_stream(error_stream), 78314564Sdim m_execution_unit(execution_unit), m_result_store(NULL), 79314564Sdim m_result_is_pointer(false), m_reloc_placeholder(NULL), 80314564Sdim m_entry_instruction_finder(FindEntryInstruction) {} 81292932Sdim 82292932Sdim/* Handy utility functions used at several places in the code */ 83292932Sdim 84314564Sdimstatic std::string PrintValue(const Value *value, bool truncate = false) { 85314564Sdim std::string s; 86314564Sdim if (value) { 87292932Sdim raw_string_ostream rso(s); 88314564Sdim value->print(rso); 89292932Sdim rso.flush(); 90292932Sdim if (truncate) 91314564Sdim s.resize(s.length() - 1); 92314564Sdim } 93314564Sdim return s; 94292932Sdim} 95292932Sdim 96314564Sdimstatic std::string PrintType(const llvm::Type *type, bool truncate = false) { 97314564Sdim std::string s; 98314564Sdim raw_string_ostream rso(s); 99314564Sdim type->print(rso); 100314564Sdim rso.flush(); 101314564Sdim if (truncate) 102314564Sdim s.resize(s.length() - 1); 103314564Sdim return s; 104292932Sdim} 105292932Sdim 106314564SdimIRForTarget::~IRForTarget() {} 107292932Sdim 108314564Sdimbool IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) { 109314564Sdim llvm_function.setLinkage(GlobalValue::ExternalLinkage); 110314564Sdim 111314564Sdim return true; 112292932Sdim} 113292932Sdim 114314564Sdimclang::NamedDecl *IRForTarget::DeclForGlobal(const GlobalValue *global_val, 115314564Sdim Module *module) { 116314564Sdim NamedMDNode *named_metadata = 117314564Sdim module->getNamedMetadata("clang.global.decl.ptrs"); 118292932Sdim 119314564Sdim if (!named_metadata) 120314564Sdim return NULL; 121292932Sdim 122314564Sdim unsigned num_nodes = named_metadata->getNumOperands(); 123314564Sdim unsigned node_index; 124292932Sdim 125314564Sdim for (node_index = 0; node_index < num_nodes; ++node_index) { 126314564Sdim llvm::MDNode *metadata_node = 127314564Sdim dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index)); 128314564Sdim if (!metadata_node) 129314564Sdim return NULL; 130292932Sdim 131314564Sdim if (metadata_node->getNumOperands() != 2) 132314564Sdim continue; 133292932Sdim 134314564Sdim if (mdconst::dyn_extract_or_null<GlobalValue>( 135314564Sdim metadata_node->getOperand(0)) != global_val) 136314564Sdim continue; 137292932Sdim 138314564Sdim ConstantInt *constant_int = 139314564Sdim mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1)); 140292932Sdim 141314564Sdim if (!constant_int) 142314564Sdim return NULL; 143292932Sdim 144314564Sdim uintptr_t ptr = constant_int->getZExtValue(); 145292932Sdim 146314564Sdim return reinterpret_cast<clang::NamedDecl *>(ptr); 147314564Sdim } 148292932Sdim 149314564Sdim return NULL; 150292932Sdim} 151292932Sdim 152314564Sdimclang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) { 153314564Sdim return DeclForGlobal(global_val, m_module); 154292932Sdim} 155292932Sdim 156314564Sdimbool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { 157314564Sdim lldb_private::Log *log( 158314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 159292932Sdim 160314564Sdim if (!m_resolve_vars) 161314564Sdim return true; 162292932Sdim 163314564Sdim // Find the result variable. If it doesn't exist, we can give up right here. 164292932Sdim 165314564Sdim ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable(); 166292932Sdim 167314564Sdim std::string result_name_str; 168314564Sdim const char *result_name = NULL; 169292932Sdim 170314564Sdim for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), 171314564Sdim ve = value_symbol_table.end(); 172314564Sdim vi != ve; ++vi) { 173314564Sdim result_name_str = vi->first().str(); 174314564Sdim const char *value_name = result_name_str.c_str(); 175292932Sdim 176314564Sdim if (strstr(value_name, "$__lldb_expr_result_ptr") && 177314564Sdim strncmp(value_name, "_ZGV", 4)) { 178314564Sdim result_name = value_name; 179314564Sdim m_result_is_pointer = true; 180314564Sdim break; 181314564Sdim } 182292932Sdim 183314564Sdim if (strstr(value_name, "$__lldb_expr_result") && 184314564Sdim strncmp(value_name, "_ZGV", 4)) { 185314564Sdim result_name = value_name; 186314564Sdim m_result_is_pointer = false; 187314564Sdim break; 188292932Sdim } 189314564Sdim } 190292932Sdim 191314564Sdim if (!result_name) { 192314564Sdim if (log) 193314564Sdim log->PutCString("Couldn't find result variable"); 194292932Sdim 195314564Sdim return true; 196314564Sdim } 197292932Sdim 198314564Sdim if (log) 199314564Sdim log->Printf("Result name: \"%s\"", result_name); 200314564Sdim 201314564Sdim Value *result_value = m_module->getNamedValue(result_name); 202314564Sdim 203314564Sdim if (!result_value) { 204292932Sdim if (log) 205314564Sdim log->PutCString("Result variable had no data"); 206292932Sdim 207314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Result variable's " 208314564Sdim "name (%s) exists, but not its definition\n", 209314564Sdim result_name); 210292932Sdim 211314564Sdim return false; 212314564Sdim } 213292932Sdim 214314564Sdim if (log) 215314564Sdim log->Printf("Found result in the IR: \"%s\"", 216314564Sdim PrintValue(result_value, false).c_str()); 217292932Sdim 218314564Sdim GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value); 219292932Sdim 220314564Sdim if (!result_global) { 221292932Sdim if (log) 222314564Sdim log->PutCString("Result variable isn't a GlobalVariable"); 223292932Sdim 224314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) " 225314564Sdim "is defined, but is not a global variable\n", 226314564Sdim result_name); 227292932Sdim 228314564Sdim return false; 229314564Sdim } 230292932Sdim 231314564Sdim clang::NamedDecl *result_decl = DeclForGlobal(result_global); 232314564Sdim if (!result_decl) { 233314564Sdim if (log) 234314564Sdim log->PutCString("Result variable doesn't have a corresponding Decl"); 235292932Sdim 236314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) " 237314564Sdim "does not have a corresponding Clang entity\n", 238314564Sdim result_name); 239292932Sdim 240314564Sdim return false; 241314564Sdim } 242292932Sdim 243314564Sdim if (log) { 244314564Sdim std::string decl_desc_str; 245314564Sdim raw_string_ostream decl_desc_stream(decl_desc_str); 246314564Sdim result_decl->print(decl_desc_stream); 247314564Sdim decl_desc_stream.flush(); 248292932Sdim 249314564Sdim log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str()); 250314564Sdim } 251292932Sdim 252314564Sdim clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl); 253314564Sdim if (!result_var) { 254292932Sdim if (log) 255314564Sdim log->PutCString("Result variable Decl isn't a VarDecl"); 256292932Sdim 257314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Result variable " 258314564Sdim "(%s)'s corresponding Clang entity isn't a " 259314564Sdim "variable\n", 260314564Sdim result_name); 261292932Sdim 262314564Sdim return false; 263314564Sdim } 264292932Sdim 265314564Sdim // Get the next available result name from m_decl_map and create the 266314564Sdim // persistent 267314564Sdim // variable for it 268292932Sdim 269314564Sdim // If the result is an Lvalue, it is emitted as a pointer; see 270314564Sdim // ASTResultSynthesizer::SynthesizeBodyResult. 271314564Sdim if (m_result_is_pointer) { 272314564Sdim clang::QualType pointer_qual_type = result_var->getType(); 273314564Sdim const clang::Type *pointer_type = pointer_qual_type.getTypePtr(); 274314564Sdim 275314564Sdim const clang::PointerType *pointer_pointertype = 276314564Sdim pointer_type->getAs<clang::PointerType>(); 277314564Sdim const clang::ObjCObjectPointerType *pointer_objcobjpointertype = 278314564Sdim pointer_type->getAs<clang::ObjCObjectPointerType>(); 279314564Sdim 280314564Sdim if (pointer_pointertype) { 281314564Sdim clang::QualType element_qual_type = pointer_pointertype->getPointeeType(); 282314564Sdim 283314564Sdim m_result_type = lldb_private::TypeFromParser( 284314564Sdim element_qual_type.getAsOpaquePtr(), 285314564Sdim lldb_private::ClangASTContext::GetASTContext( 286314564Sdim &result_decl->getASTContext())); 287314564Sdim } else if (pointer_objcobjpointertype) { 288314564Sdim clang::QualType element_qual_type = 289314564Sdim clang::QualType(pointer_objcobjpointertype->getObjectType(), 0); 290314564Sdim 291314564Sdim m_result_type = lldb_private::TypeFromParser( 292314564Sdim element_qual_type.getAsOpaquePtr(), 293314564Sdim lldb_private::ClangASTContext::GetASTContext( 294314564Sdim &result_decl->getASTContext())); 295314564Sdim } else { 296314564Sdim if (log) 297314564Sdim log->PutCString("Expected result to have pointer type, but it did not"); 298314564Sdim 299314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Lvalue result (%s) " 300314564Sdim "is not a pointer variable\n", 301314564Sdim result_name); 302314564Sdim 303314564Sdim return false; 304292932Sdim } 305314564Sdim } else { 306314564Sdim m_result_type = lldb_private::TypeFromParser( 307314564Sdim result_var->getType().getAsOpaquePtr(), 308314564Sdim lldb_private::ClangASTContext::GetASTContext( 309314564Sdim &result_decl->getASTContext())); 310314564Sdim } 311292932Sdim 312314564Sdim lldb::TargetSP target_sp(m_execution_unit.GetTarget()); 313314564Sdim lldb_private::ExecutionContext exe_ctx(target_sp, true); 314314564Sdim if (m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope()) == 0) { 315314564Sdim lldb_private::StreamString type_desc_stream; 316314564Sdim m_result_type.DumpTypeDescription(&type_desc_stream); 317292932Sdim 318314564Sdim if (log) 319314564Sdim log->Printf("Result type has size 0"); 320292932Sdim 321314564Sdim m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' " 322314564Sdim "couldn't be determined\n", 323314564Sdim type_desc_stream.GetData()); 324314564Sdim return false; 325314564Sdim } 326292932Sdim 327314564Sdim if (log) { 328314564Sdim lldb_private::StreamString type_desc_stream; 329314564Sdim m_result_type.DumpTypeDescription(&type_desc_stream); 330292932Sdim 331314564Sdim log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData()); 332314564Sdim } 333292932Sdim 334314564Sdim m_result_name = lldb_private::ConstString("$RESULT_NAME"); 335292932Sdim 336314564Sdim if (log) 337314564Sdim log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64, 338314564Sdim m_result_name.GetCString(), m_result_type.GetByteSize(nullptr)); 339292932Sdim 340314564Sdim // Construct a new result global and set up its metadata 341292932Sdim 342314564Sdim GlobalVariable *new_result_global = new GlobalVariable( 343314564Sdim (*m_module), result_global->getType()->getElementType(), 344314564Sdim false, /* not constant */ 345314564Sdim GlobalValue::ExternalLinkage, NULL, /* no initializer */ 346314564Sdim m_result_name.GetCString()); 347292932Sdim 348314564Sdim // It's too late in compilation to create a new VarDecl for this, but we don't 349314564Sdim // need to. We point the metadata at the old VarDecl. This creates an odd 350314564Sdim // anomaly: a variable with a Value whose name is something like $0 and a 351314564Sdim // Decl whose name is $__lldb_expr_result. This condition is handled in 352314564Sdim // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is 353314564Sdim // fixed up. 354292932Sdim 355314564Sdim ConstantInt *new_constant_int = 356314564Sdim ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()), 357314564Sdim reinterpret_cast<uint64_t>(result_decl), false); 358292932Sdim 359314564Sdim llvm::Metadata *values[2]; 360314564Sdim values[0] = ConstantAsMetadata::get(new_result_global); 361314564Sdim values[1] = ConstantAsMetadata::get(new_constant_int); 362292932Sdim 363314564Sdim ArrayRef<Metadata *> value_ref(values, 2); 364292932Sdim 365314564Sdim MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref); 366314564Sdim NamedMDNode *named_metadata = 367314564Sdim m_module->getNamedMetadata("clang.global.decl.ptrs"); 368314564Sdim named_metadata->addOperand(persistent_global_md); 369314564Sdim 370314564Sdim if (log) 371314564Sdim log->Printf("Replacing \"%s\" with \"%s\"", 372314564Sdim PrintValue(result_global).c_str(), 373314564Sdim PrintValue(new_result_global).c_str()); 374314564Sdim 375314564Sdim if (result_global->use_empty()) { 376314564Sdim // We need to synthesize a store for this variable, because otherwise 377314564Sdim // there's nothing to put into its equivalent persistent variable. 378314564Sdim 379314564Sdim BasicBlock &entry_block(llvm_function.getEntryBlock()); 380314564Sdim Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg()); 381314564Sdim 382314564Sdim if (!first_entry_instruction) 383314564Sdim return false; 384314564Sdim 385314564Sdim if (!result_global->hasInitializer()) { 386314564Sdim if (log) 387314564Sdim log->Printf("Couldn't find initializer for unused variable"); 388314564Sdim 389314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Result variable " 390314564Sdim "(%s) has no writes and no initializer\n", 391314564Sdim result_name); 392314564Sdim 393314564Sdim return false; 394292932Sdim } 395292932Sdim 396314564Sdim Constant *initializer = result_global->getInitializer(); 397292932Sdim 398314564Sdim StoreInst *synthesized_store = 399314564Sdim new StoreInst(initializer, new_result_global, first_entry_instruction); 400314564Sdim 401292932Sdim if (log) 402314564Sdim log->Printf("Synthesized result store \"%s\"\n", 403314564Sdim PrintValue(synthesized_store).c_str()); 404314564Sdim } else { 405314564Sdim result_global->replaceAllUsesWith(new_result_global); 406314564Sdim } 407292932Sdim 408314564Sdim if (!m_decl_map->AddPersistentVariable( 409314564Sdim result_decl, m_result_name, m_result_type, true, m_result_is_pointer)) 410314564Sdim return false; 411292932Sdim 412314564Sdim result_global->eraseFromParent(); 413292932Sdim 414314564Sdim return true; 415314564Sdim} 416292932Sdim 417314564Sdimbool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str, 418314564Sdim llvm::GlobalVariable *cstr) { 419314564Sdim lldb_private::Log *log( 420314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 421292932Sdim 422314564Sdim Type *ns_str_ty = ns_str->getType(); 423292932Sdim 424314564Sdim Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext()); 425314564Sdim Type *i32_ty = Type::getInt32Ty(m_module->getContext()); 426314564Sdim Type *i8_ty = Type::getInt8Ty(m_module->getContext()); 427292932Sdim 428314564Sdim if (!m_CFStringCreateWithBytes) { 429314564Sdim lldb::addr_t CFStringCreateWithBytes_addr; 430292932Sdim 431314564Sdim static lldb_private::ConstString g_CFStringCreateWithBytes_str( 432314564Sdim "CFStringCreateWithBytes"); 433314564Sdim 434314564Sdim CFStringCreateWithBytes_addr = 435314564Sdim m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str); 436314564Sdim if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS) { 437314564Sdim if (log) 438314564Sdim log->PutCString("Couldn't find CFStringCreateWithBytes in the target"); 439314564Sdim 440314564Sdim m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C " 441314564Sdim "constant string requires " 442314564Sdim "CFStringCreateWithBytes\n"); 443314564Sdim 444314564Sdim return false; 445314564Sdim } 446314564Sdim 447292932Sdim if (log) 448314564Sdim log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64, 449314564Sdim CFStringCreateWithBytes_addr); 450292932Sdim 451314564Sdim // Build the function type: 452314564Sdim // 453314564Sdim // CFStringRef CFStringCreateWithBytes ( 454314564Sdim // CFAllocatorRef alloc, 455314564Sdim // const UInt8 *bytes, 456314564Sdim // CFIndex numBytes, 457314564Sdim // CFStringEncoding encoding, 458314564Sdim // Boolean isExternalRepresentation 459314564Sdim // ); 460314564Sdim // 461314564Sdim // We make the following substitutions: 462314564Sdim // 463314564Sdim // CFStringRef -> i8* 464314564Sdim // CFAllocatorRef -> i8* 465314564Sdim // UInt8 * -> i8* 466314564Sdim // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its 467314564Sdim // pointer size for now) 468314564Sdim // CFStringEncoding -> i32 469314564Sdim // Boolean -> i8 470292932Sdim 471314564Sdim Type *arg_type_array[5]; 472292932Sdim 473314564Sdim arg_type_array[0] = i8_ptr_ty; 474314564Sdim arg_type_array[1] = i8_ptr_ty; 475314564Sdim arg_type_array[2] = m_intptr_ty; 476314564Sdim arg_type_array[3] = i32_ty; 477314564Sdim arg_type_array[4] = i8_ty; 478292932Sdim 479314564Sdim ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5); 480292932Sdim 481314564Sdim llvm::Type *CFSCWB_ty = 482314564Sdim FunctionType::get(ns_str_ty, CFSCWB_arg_types, false); 483292932Sdim 484314564Sdim // Build the constant containing the pointer to the function 485314564Sdim PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty); 486314564Sdim Constant *CFSCWB_addr_int = 487314564Sdim ConstantInt::get(m_intptr_ty, CFStringCreateWithBytes_addr, false); 488314564Sdim m_CFStringCreateWithBytes = 489314564Sdim ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty); 490314564Sdim } 491292932Sdim 492314564Sdim ConstantDataSequential *string_array = NULL; 493292932Sdim 494314564Sdim if (cstr) 495314564Sdim string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer()); 496292932Sdim 497314564Sdim Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty); 498314564Sdim Constant *bytes_arg = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty) 499314564Sdim : Constant::getNullValue(i8_ptr_ty); 500314564Sdim Constant *numBytes_arg = ConstantInt::get( 501314564Sdim m_intptr_ty, cstr ? (string_array->getNumElements() - 1) * string_array->getElementByteSize() : 0, false); 502314564Sdim int encoding_flags = 0; 503314564Sdim switch (cstr ? string_array->getElementByteSize() : 1) { 504314564Sdim case 1: 505314564Sdim encoding_flags = 0x08000100; /* 0x08000100 is kCFStringEncodingUTF8 */ 506314564Sdim break; 507314564Sdim case 2: 508314564Sdim encoding_flags = 0x0100; /* 0x0100 is kCFStringEncodingUTF16 */ 509314564Sdim break; 510314564Sdim case 4: 511314564Sdim encoding_flags = 0x0c000100; /* 0x0c000100 is kCFStringEncodingUTF32 */ 512314564Sdim break; 513314564Sdim default: 514314564Sdim encoding_flags = 0x0600; /* fall back to 0x0600, kCFStringEncodingASCII */ 515314564Sdim if (log) { 516314564Sdim log->Format("Encountered an Objective-C constant string with unusual " 517314564Sdim "element size {0}", 518314564Sdim string_array->getElementByteSize()); 519314564Sdim } 520314564Sdim } 521314564Sdim Constant *encoding_arg = ConstantInt::get(i32_ty, encoding_flags, false); 522314564Sdim Constant *isExternal_arg = 523314564Sdim ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */ 524314564Sdim 525314564Sdim Value *argument_array[5]; 526314564Sdim 527314564Sdim argument_array[0] = alloc_arg; 528314564Sdim argument_array[1] = bytes_arg; 529314564Sdim argument_array[2] = numBytes_arg; 530314564Sdim argument_array[3] = encoding_arg; 531314564Sdim argument_array[4] = isExternal_arg; 532314564Sdim 533314564Sdim ArrayRef<Value *> CFSCWB_arguments(argument_array, 5); 534314564Sdim 535314564Sdim FunctionValueCache CFSCWB_Caller( 536314564Sdim [this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * { 537314564Sdim return CallInst::Create( 538314564Sdim m_CFStringCreateWithBytes, CFSCWB_arguments, 539314564Sdim "CFStringCreateWithBytes", 540314564Sdim llvm::cast<Instruction>( 541314564Sdim m_entry_instruction_finder.GetValue(function))); 542314564Sdim }); 543314564Sdim 544314564Sdim if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder, 545314564Sdim m_error_stream)) { 546314564Sdim if (log) 547314564Sdim log->PutCString( 548314564Sdim "Couldn't replace the NSString with the result of the call"); 549314564Sdim 550314564Sdim m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an " 551314564Sdim "Objective-C constant string with a dynamic " 552314564Sdim "string\n"); 553314564Sdim 554314564Sdim return false; 555314564Sdim } 556314564Sdim 557314564Sdim ns_str->eraseFromParent(); 558314564Sdim 559314564Sdim return true; 560314564Sdim} 561314564Sdim 562314564Sdimbool IRForTarget::RewriteObjCConstStrings() { 563314564Sdim lldb_private::Log *log( 564314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 565314564Sdim 566314564Sdim ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable(); 567314564Sdim 568314564Sdim for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), 569314564Sdim ve = value_symbol_table.end(); 570314564Sdim vi != ve; ++vi) { 571314564Sdim std::string value_name = vi->first().str(); 572314564Sdim const char *value_name_cstr = value_name.c_str(); 573314564Sdim 574314564Sdim if (strstr(value_name_cstr, "_unnamed_cfstring_")) { 575314564Sdim Value *nsstring_value = vi->second; 576314564Sdim 577314564Sdim GlobalVariable *nsstring_global = 578314564Sdim dyn_cast<GlobalVariable>(nsstring_value); 579314564Sdim 580314564Sdim if (!nsstring_global) { 581292932Sdim if (log) 582314564Sdim log->PutCString("NSString variable is not a GlobalVariable"); 583292932Sdim 584314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " 585314564Sdim "constant string is not a global variable\n"); 586314564Sdim 587292932Sdim return false; 588314564Sdim } 589292932Sdim 590314564Sdim if (!nsstring_global->hasInitializer()) { 591314564Sdim if (log) 592314564Sdim log->PutCString("NSString variable does not have an initializer"); 593292932Sdim 594314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " 595314564Sdim "constant string does not have an initializer\n"); 596292932Sdim 597314564Sdim return false; 598314564Sdim } 599292932Sdim 600314564Sdim ConstantStruct *nsstring_struct = 601314564Sdim dyn_cast<ConstantStruct>(nsstring_global->getInitializer()); 602292932Sdim 603314564Sdim if (!nsstring_struct) { 604314564Sdim if (log) 605314564Sdim log->PutCString( 606314564Sdim "NSString variable's initializer is not a ConstantStruct"); 607292932Sdim 608314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " 609314564Sdim "constant string is not a structure constant\n"); 610292932Sdim 611314564Sdim return false; 612314564Sdim } 613292932Sdim 614314564Sdim // We expect the following structure: 615314564Sdim // 616314564Sdim // struct { 617314564Sdim // int *isa; 618314564Sdim // int flags; 619314564Sdim // char *str; 620314564Sdim // long length; 621314564Sdim // }; 622292932Sdim 623314564Sdim if (nsstring_struct->getNumOperands() != 4) { 624314564Sdim if (log) 625314564Sdim log->Printf("NSString variable's initializer structure has an " 626314564Sdim "unexpected number of members. Should be 4, is %d", 627314564Sdim nsstring_struct->getNumOperands()); 628292932Sdim 629314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: The struct for an " 630314564Sdim "Objective-C constant string is not as " 631314564Sdim "expected\n"); 632292932Sdim 633314564Sdim return false; 634314564Sdim } 635314564Sdim 636314564Sdim Constant *nsstring_member = nsstring_struct->getOperand(2); 637314564Sdim 638314564Sdim if (!nsstring_member) { 639292932Sdim if (log) 640314564Sdim log->PutCString("NSString initializer's str element was empty"); 641292932Sdim 642314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " 643314564Sdim "constant string does not have a string " 644314564Sdim "initializer\n"); 645292932Sdim 646314564Sdim return false; 647314564Sdim } 648292932Sdim 649314564Sdim ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member); 650292932Sdim 651314564Sdim if (!nsstring_expr) { 652314564Sdim if (log) 653314564Sdim log->PutCString( 654314564Sdim "NSString initializer's str element is not a ConstantExpr"); 655292932Sdim 656314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " 657314564Sdim "constant string's string initializer is not " 658314564Sdim "constant\n"); 659292932Sdim 660314564Sdim return false; 661314564Sdim } 662292932Sdim 663314564Sdim GlobalVariable *cstr_global = nullptr; 664292932Sdim 665314564Sdim if (nsstring_expr->getOpcode() == Instruction::GetElementPtr) { 666314564Sdim Constant *nsstring_cstr = nsstring_expr->getOperand(0); 667314564Sdim cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr); 668314564Sdim } else if (nsstring_expr->getOpcode() == Instruction::BitCast) { 669314564Sdim Constant *nsstring_cstr = nsstring_expr->getOperand(0); 670314564Sdim cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr); 671314564Sdim } 672292932Sdim 673314564Sdim if (!cstr_global) { 674314564Sdim if (log) 675314564Sdim log->PutCString( 676314564Sdim "NSString initializer's str element is not a GlobalVariable"); 677292932Sdim 678314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Unhandled" 679314564Sdim "constant string initializer\n"); 680292932Sdim 681314564Sdim return false; 682314564Sdim } 683292932Sdim 684314564Sdim if (!cstr_global->hasInitializer()) { 685314564Sdim if (log) 686314564Sdim log->PutCString("NSString initializer's str element does not have an " 687314564Sdim "initializer"); 688292932Sdim 689314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C " 690314564Sdim "constant string's string initializer doesn't " 691314564Sdim "point to initialized data\n"); 692292932Sdim 693314564Sdim return false; 694314564Sdim } 695314564Sdim 696314564Sdim /* 697314564Sdim if (!cstr_array) 698314564Sdim { 699314564Sdim if (log) 700314564Sdim log->PutCString("NSString initializer's str element is not a 701314564Sdim ConstantArray"); 702314564Sdim 703314564Sdim if (m_error_stream) 704314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: An 705314564Sdim Objective-C constant string's string initializer doesn't point to an 706314564Sdim array\n"); 707314564Sdim 708314564Sdim return false; 709314564Sdim } 710314564Sdim 711314564Sdim if (!cstr_array->isCString()) 712314564Sdim { 713314564Sdim if (log) 714314564Sdim log->PutCString("NSString initializer's str element is not a C 715314564Sdim string array"); 716314564Sdim 717314564Sdim if (m_error_stream) 718314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: An 719314564Sdim Objective-C constant string's string initializer doesn't point to a C 720314564Sdim string\n"); 721314564Sdim 722314564Sdim return false; 723314564Sdim } 724314564Sdim */ 725314564Sdim 726314564Sdim ConstantDataArray *cstr_array = 727314564Sdim dyn_cast<ConstantDataArray>(cstr_global->getInitializer()); 728314564Sdim 729314564Sdim if (log) { 730314564Sdim if (cstr_array) 731314564Sdim log->Printf("Found NSString constant %s, which contains \"%s\"", 732314564Sdim value_name_cstr, cstr_array->getAsString().str().c_str()); 733314564Sdim else 734314564Sdim log->Printf("Found NSString constant %s, which contains \"\"", 735314564Sdim value_name_cstr); 736314564Sdim } 737314564Sdim 738314564Sdim if (!cstr_array) 739314564Sdim cstr_global = NULL; 740314564Sdim 741314564Sdim if (!RewriteObjCConstString(nsstring_global, cstr_global)) { 742292932Sdim if (log) 743314564Sdim log->PutCString("Error rewriting the constant string"); 744292932Sdim 745314564Sdim // We don't print an error message here because RewriteObjCConstString 746314564Sdim // has done so for us. 747292932Sdim 748292932Sdim return false; 749314564Sdim } 750292932Sdim } 751314564Sdim } 752292932Sdim 753314564Sdim for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), 754314564Sdim ve = value_symbol_table.end(); 755314564Sdim vi != ve; ++vi) { 756314564Sdim std::string value_name = vi->first().str(); 757314564Sdim const char *value_name_cstr = value_name.c_str(); 758292932Sdim 759314564Sdim if (!strcmp(value_name_cstr, "__CFConstantStringClassReference")) { 760314564Sdim GlobalVariable *gv = dyn_cast<GlobalVariable>(vi->second); 761292932Sdim 762314564Sdim if (!gv) { 763314564Sdim if (log) 764314564Sdim log->PutCString( 765314564Sdim "__CFConstantStringClassReference is not a global variable"); 766292932Sdim 767314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Found a " 768314564Sdim "CFConstantStringClassReference, but it is not a " 769314564Sdim "global object\n"); 770292932Sdim 771314564Sdim return false; 772314564Sdim } 773292932Sdim 774314564Sdim gv->eraseFromParent(); 775292932Sdim 776314564Sdim break; 777314564Sdim } 778314564Sdim } 779292932Sdim 780314564Sdim return true; 781314564Sdim} 782292932Sdim 783314564Sdimstatic bool IsObjCSelectorRef(Value *value) { 784314564Sdim GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value); 785292932Sdim 786314564Sdim if (!global_variable || !global_variable->hasName() || 787314564Sdim !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_")) 788314564Sdim return false; 789292932Sdim 790314564Sdim return true; 791314564Sdim} 792292932Sdim 793314564Sdim// This function does not report errors; its callers are responsible. 794314564Sdimbool IRForTarget::RewriteObjCSelector(Instruction *selector_load) { 795314564Sdim lldb_private::Log *log( 796314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 797292932Sdim 798314564Sdim LoadInst *load = dyn_cast<LoadInst>(selector_load); 799292932Sdim 800314564Sdim if (!load) 801314564Sdim return false; 802292932Sdim 803314564Sdim // Unpack the message name from the selector. In LLVM IR, an objc_msgSend 804314564Sdim // gets represented as 805314564Sdim // 806314564Sdim // %tmp = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*> 807314564Sdim // %call = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) 808314564Sdim // ; <i8*> 809314564Sdim // 810314564Sdim // where %obj is the object pointer and %tmp is the selector. 811314564Sdim // 812314564Sdim // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called 813314564Sdim // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_". 814314564Sdim // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string. 815292932Sdim 816314564Sdim // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr) 817314564Sdim // and get the string from its target 818292932Sdim 819314564Sdim GlobalVariable *_objc_selector_references_ = 820314564Sdim dyn_cast<GlobalVariable>(load->getPointerOperand()); 821292932Sdim 822314564Sdim if (!_objc_selector_references_ || 823314564Sdim !_objc_selector_references_->hasInitializer()) 824314564Sdim return false; 825292932Sdim 826314564Sdim Constant *osr_initializer = _objc_selector_references_->getInitializer(); 827292932Sdim 828314564Sdim ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer); 829292932Sdim 830314564Sdim if (!osr_initializer_expr || 831314564Sdim osr_initializer_expr->getOpcode() != Instruction::GetElementPtr) 832314564Sdim return false; 833292932Sdim 834314564Sdim Value *osr_initializer_base = osr_initializer_expr->getOperand(0); 835292932Sdim 836314564Sdim if (!osr_initializer_base) 837314564Sdim return false; 838292932Sdim 839314564Sdim // Find the string's initializer (a ConstantArray) and get the string from it 840292932Sdim 841314564Sdim GlobalVariable *_objc_meth_var_name_ = 842314564Sdim dyn_cast<GlobalVariable>(osr_initializer_base); 843292932Sdim 844314564Sdim if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer()) 845314564Sdim return false; 846292932Sdim 847314564Sdim Constant *omvn_initializer = _objc_meth_var_name_->getInitializer(); 848292932Sdim 849314564Sdim ConstantDataArray *omvn_initializer_array = 850314564Sdim dyn_cast<ConstantDataArray>(omvn_initializer); 851292932Sdim 852314564Sdim if (!omvn_initializer_array->isString()) 853314564Sdim return false; 854292932Sdim 855314564Sdim std::string omvn_initializer_string = omvn_initializer_array->getAsString(); 856292932Sdim 857314564Sdim if (log) 858314564Sdim log->Printf("Found Objective-C selector reference \"%s\"", 859314564Sdim omvn_initializer_string.c_str()); 860292932Sdim 861314564Sdim // Construct a call to sel_registerName 862292932Sdim 863314564Sdim if (!m_sel_registerName) { 864314564Sdim lldb::addr_t sel_registerName_addr; 865292932Sdim 866314564Sdim static lldb_private::ConstString g_sel_registerName_str("sel_registerName"); 867314564Sdim sel_registerName_addr = m_execution_unit.FindSymbol(g_sel_registerName_str); 868314564Sdim if (sel_registerName_addr == LLDB_INVALID_ADDRESS) 869314564Sdim return false; 870292932Sdim 871314564Sdim if (log) 872314564Sdim log->Printf("Found sel_registerName at 0x%" PRIx64, 873314564Sdim sel_registerName_addr); 874292932Sdim 875314564Sdim // Build the function type: struct objc_selector *sel_registerName(uint8_t*) 876292932Sdim 877314564Sdim // The below code would be "more correct," but in actuality what's required 878314564Sdim // is uint8_t* 879314564Sdim // Type *sel_type = StructType::get(m_module->getContext()); 880314564Sdim // Type *sel_ptr_type = PointerType::getUnqual(sel_type); 881314564Sdim Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext()); 882292932Sdim 883314564Sdim Type *type_array[1]; 884292932Sdim 885314564Sdim type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext()); 886292932Sdim 887314564Sdim ArrayRef<Type *> srN_arg_types(type_array, 1); 888292932Sdim 889314564Sdim llvm::Type *srN_type = 890314564Sdim FunctionType::get(sel_ptr_type, srN_arg_types, false); 891292932Sdim 892314564Sdim // Build the constant containing the pointer to the function 893314564Sdim PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type); 894314564Sdim Constant *srN_addr_int = 895314564Sdim ConstantInt::get(m_intptr_ty, sel_registerName_addr, false); 896314564Sdim m_sel_registerName = ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty); 897314564Sdim } 898292932Sdim 899314564Sdim Value *argument_array[1]; 900292932Sdim 901314564Sdim Constant *omvn_pointer = ConstantExpr::getBitCast( 902314564Sdim _objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext())); 903292932Sdim 904314564Sdim argument_array[0] = omvn_pointer; 905292932Sdim 906314564Sdim ArrayRef<Value *> srN_arguments(argument_array, 1); 907292932Sdim 908314564Sdim CallInst *srN_call = CallInst::Create(m_sel_registerName, srN_arguments, 909314564Sdim "sel_registerName", selector_load); 910292932Sdim 911314564Sdim // Replace the load with the call in all users 912292932Sdim 913314564Sdim selector_load->replaceAllUsesWith(srN_call); 914292932Sdim 915314564Sdim selector_load->eraseFromParent(); 916292932Sdim 917314564Sdim return true; 918314564Sdim} 919292932Sdim 920314564Sdimbool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) { 921314564Sdim lldb_private::Log *log( 922314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 923292932Sdim 924314564Sdim BasicBlock::iterator ii; 925292932Sdim 926314564Sdim typedef SmallVector<Instruction *, 2> InstrList; 927314564Sdim typedef InstrList::iterator InstrIterator; 928292932Sdim 929314564Sdim InstrList selector_loads; 930292932Sdim 931314564Sdim for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { 932314564Sdim Instruction &inst = *ii; 933292932Sdim 934314564Sdim if (LoadInst *load = dyn_cast<LoadInst>(&inst)) 935314564Sdim if (IsObjCSelectorRef(load->getPointerOperand())) 936314564Sdim selector_loads.push_back(&inst); 937314564Sdim } 938292932Sdim 939314564Sdim InstrIterator iter; 940292932Sdim 941314564Sdim for (iter = selector_loads.begin(); iter != selector_loads.end(); ++iter) { 942314564Sdim if (!RewriteObjCSelector(*iter)) { 943314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a " 944314564Sdim "static reference to an Objective-C selector to a " 945314564Sdim "dynamic reference\n"); 946314564Sdim 947314564Sdim if (log) 948314564Sdim log->PutCString( 949314564Sdim "Couldn't rewrite a reference to an Objective-C selector"); 950314564Sdim 951314564Sdim return false; 952292932Sdim } 953314564Sdim } 954292932Sdim 955314564Sdim return true; 956292932Sdim} 957292932Sdim 958314564Sdimstatic bool IsObjCClassReference(Value *value) { 959314564Sdim GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value); 960292932Sdim 961314564Sdim if (!global_variable || !global_variable->hasName() || 962314564Sdim !global_variable->getName().startswith("OBJC_CLASS_REFERENCES_")) 963314564Sdim return false; 964292932Sdim 965314564Sdim return true; 966292932Sdim} 967292932Sdim 968292932Sdim// This function does not report errors; its callers are responsible. 969314564Sdimbool IRForTarget::RewriteObjCClassReference(Instruction *class_load) { 970314564Sdim lldb_private::Log *log( 971314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 972292932Sdim 973314564Sdim LoadInst *load = dyn_cast<LoadInst>(class_load); 974292932Sdim 975314564Sdim if (!load) 976314564Sdim return false; 977292932Sdim 978314564Sdim // Unpack the class name from the reference. In LLVM IR, a reference to an 979314564Sdim // Objective-C class gets represented as 980314564Sdim // 981314564Sdim // %tmp = load %struct._objc_class*, 982314564Sdim // %struct._objc_class** @OBJC_CLASS_REFERENCES_, align 4 983314564Sdim // 984314564Sdim // @"OBJC_CLASS_REFERENCES_ is a bitcast of a character array called 985314564Sdim // @OBJC_CLASS_NAME_. 986314564Sdim // @OBJC_CLASS_NAME contains the string. 987292932Sdim 988314564Sdim // Find the pointer's initializer (a ConstantExpr with opcode BitCast) 989314564Sdim // and get the string from its target 990292932Sdim 991314564Sdim GlobalVariable *_objc_class_references_ = 992314564Sdim dyn_cast<GlobalVariable>(load->getPointerOperand()); 993292932Sdim 994314564Sdim if (!_objc_class_references_ || 995314564Sdim !_objc_class_references_->hasInitializer()) 996314564Sdim return false; 997292932Sdim 998314564Sdim Constant *ocr_initializer = _objc_class_references_->getInitializer(); 999292932Sdim 1000314564Sdim ConstantExpr *ocr_initializer_expr = dyn_cast<ConstantExpr>(ocr_initializer); 1001292932Sdim 1002314564Sdim if (!ocr_initializer_expr || 1003314564Sdim ocr_initializer_expr->getOpcode() != Instruction::BitCast) 1004314564Sdim return false; 1005292932Sdim 1006314564Sdim Value *ocr_initializer_base = ocr_initializer_expr->getOperand(0); 1007292932Sdim 1008314564Sdim if (!ocr_initializer_base) 1009314564Sdim return false; 1010292932Sdim 1011314564Sdim // Find the string's initializer (a ConstantArray) and get the string from it 1012292932Sdim 1013314564Sdim GlobalVariable *_objc_class_name_ = 1014314564Sdim dyn_cast<GlobalVariable>(ocr_initializer_base); 1015292932Sdim 1016314564Sdim if (!_objc_class_name_ || !_objc_class_name_->hasInitializer()) 1017314564Sdim return false; 1018292932Sdim 1019314564Sdim Constant *ocn_initializer = _objc_class_name_->getInitializer(); 1020292932Sdim 1021314564Sdim ConstantDataArray *ocn_initializer_array = 1022314564Sdim dyn_cast<ConstantDataArray>(ocn_initializer); 1023292932Sdim 1024314564Sdim if (!ocn_initializer_array->isString()) 1025314564Sdim return false; 1026292932Sdim 1027314564Sdim std::string ocn_initializer_string = ocn_initializer_array->getAsString(); 1028292932Sdim 1029314564Sdim if (log) 1030314564Sdim log->Printf("Found Objective-C class reference \"%s\"", 1031314564Sdim ocn_initializer_string.c_str()); 1032292932Sdim 1033314564Sdim // Construct a call to objc_getClass 1034292932Sdim 1035314564Sdim if (!m_objc_getClass) { 1036314564Sdim lldb::addr_t objc_getClass_addr; 1037292932Sdim 1038314564Sdim static lldb_private::ConstString g_objc_getClass_str("objc_getClass"); 1039314564Sdim objc_getClass_addr = m_execution_unit.FindSymbol(g_objc_getClass_str); 1040314564Sdim if (objc_getClass_addr == LLDB_INVALID_ADDRESS) 1041314564Sdim return false; 1042292932Sdim 1043314564Sdim if (log) 1044314564Sdim log->Printf("Found objc_getClass at 0x%" PRIx64, 1045314564Sdim objc_getClass_addr); 1046292932Sdim 1047314564Sdim // Build the function type: %struct._objc_class *objc_getClass(i8*) 1048292932Sdim 1049314564Sdim Type *class_type = load->getType(); 1050314564Sdim Type *type_array[1]; 1051314564Sdim type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext()); 1052292932Sdim 1053314564Sdim ArrayRef<Type *> ogC_arg_types(type_array, 1); 1054292932Sdim 1055314564Sdim llvm::Type *ogC_type = 1056314564Sdim FunctionType::get(class_type, ogC_arg_types, false); 1057292932Sdim 1058314564Sdim // Build the constant containing the pointer to the function 1059314564Sdim PointerType *ogC_ptr_ty = PointerType::getUnqual(ogC_type); 1060314564Sdim Constant *ogC_addr_int = 1061314564Sdim ConstantInt::get(m_intptr_ty, objc_getClass_addr, false); 1062314564Sdim m_objc_getClass = ConstantExpr::getIntToPtr(ogC_addr_int, ogC_ptr_ty); 1063314564Sdim } 1064292932Sdim 1065314564Sdim Value *argument_array[1]; 1066292932Sdim 1067314564Sdim Constant *ocn_pointer = ConstantExpr::getBitCast( 1068314564Sdim _objc_class_name_, Type::getInt8PtrTy(m_module->getContext())); 1069292932Sdim 1070314564Sdim argument_array[0] = ocn_pointer; 1071292932Sdim 1072314564Sdim ArrayRef<Value *> ogC_arguments(argument_array, 1); 1073292932Sdim 1074314564Sdim CallInst *ogC_call = CallInst::Create(m_objc_getClass, ogC_arguments, 1075314564Sdim "objc_getClass", class_load); 1076292932Sdim 1077314564Sdim // Replace the load with the call in all users 1078292932Sdim 1079314564Sdim class_load->replaceAllUsesWith(ogC_call); 1080292932Sdim 1081314564Sdim class_load->eraseFromParent(); 1082292932Sdim 1083314564Sdim return true; 1084292932Sdim} 1085292932Sdim 1086314564Sdimbool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) { 1087314564Sdim lldb_private::Log *log( 1088314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1089292932Sdim 1090314564Sdim BasicBlock::iterator ii; 1091292932Sdim 1092314564Sdim typedef SmallVector<Instruction *, 2> InstrList; 1093314564Sdim typedef InstrList::iterator InstrIterator; 1094292932Sdim 1095314564Sdim InstrList class_loads; 1096292932Sdim 1097314564Sdim for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { 1098314564Sdim Instruction &inst = *ii; 1099292932Sdim 1100314564Sdim if (LoadInst *load = dyn_cast<LoadInst>(&inst)) 1101314564Sdim if (IsObjCClassReference(load->getPointerOperand())) 1102314564Sdim class_loads.push_back(&inst); 1103314564Sdim } 1104292932Sdim 1105314564Sdim InstrIterator iter; 1106292932Sdim 1107314564Sdim for (iter = class_loads.begin(); iter != class_loads.end(); ++iter) { 1108314564Sdim if (!RewriteObjCClassReference(*iter)) { 1109314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a " 1110314564Sdim "static reference to an Objective-C class to a " 1111314564Sdim "dynamic reference\n"); 1112292932Sdim 1113314564Sdim if (log) 1114314564Sdim log->PutCString( 1115314564Sdim "Couldn't rewrite a reference to an Objective-C class"); 1116292932Sdim 1117314564Sdim return false; 1118292932Sdim } 1119314564Sdim } 1120292932Sdim 1121314564Sdim return true; 1122292932Sdim} 1123292932Sdim 1124292932Sdim// This function does not report errors; its callers are responsible. 1125314564Sdimbool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) { 1126314564Sdim lldb_private::Log *log( 1127314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1128292932Sdim 1129314564Sdim AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc); 1130292932Sdim 1131314564Sdim MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr"); 1132292932Sdim 1133314564Sdim if (!alloc_md || !alloc_md->getNumOperands()) 1134314564Sdim return false; 1135292932Sdim 1136314564Sdim ConstantInt *constant_int = 1137314564Sdim mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0)); 1138292932Sdim 1139314564Sdim if (!constant_int) 1140314564Sdim return false; 1141292932Sdim 1142314564Sdim // We attempt to register this as a new persistent variable with the DeclMap. 1143292932Sdim 1144314564Sdim uintptr_t ptr = constant_int->getZExtValue(); 1145292932Sdim 1146314564Sdim clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr); 1147292932Sdim 1148314564Sdim lldb_private::TypeFromParser result_decl_type( 1149314564Sdim decl->getType().getAsOpaquePtr(), 1150314564Sdim lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext())); 1151292932Sdim 1152314564Sdim StringRef decl_name(decl->getName()); 1153314564Sdim lldb_private::ConstString persistent_variable_name(decl_name.data(), 1154314564Sdim decl_name.size()); 1155314564Sdim if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name, 1156314564Sdim result_decl_type, false, false)) 1157314564Sdim return false; 1158292932Sdim 1159314564Sdim GlobalVariable *persistent_global = new GlobalVariable( 1160314564Sdim (*m_module), alloc->getType(), false, /* not constant */ 1161314564Sdim GlobalValue::ExternalLinkage, NULL, /* no initializer */ 1162314564Sdim alloc->getName().str()); 1163292932Sdim 1164314564Sdim // What we're going to do here is make believe this was a regular old external 1165314564Sdim // variable. That means we need to make the metadata valid. 1166292932Sdim 1167314564Sdim NamedMDNode *named_metadata = 1168314564Sdim m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs"); 1169292932Sdim 1170314564Sdim llvm::Metadata *values[2]; 1171314564Sdim values[0] = ConstantAsMetadata::get(persistent_global); 1172314564Sdim values[1] = ConstantAsMetadata::get(constant_int); 1173292932Sdim 1174314564Sdim ArrayRef<llvm::Metadata *> value_ref(values, 2); 1175292932Sdim 1176314564Sdim MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref); 1177314564Sdim named_metadata->addOperand(persistent_global_md); 1178292932Sdim 1179314564Sdim // Now, since the variable is a pointer variable, we will drop in a load of 1180314564Sdim // that 1181314564Sdim // pointer variable. 1182292932Sdim 1183314564Sdim LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc); 1184292932Sdim 1185314564Sdim if (log) 1186314564Sdim log->Printf("Replacing \"%s\" with \"%s\"", PrintValue(alloc).c_str(), 1187314564Sdim PrintValue(persistent_load).c_str()); 1188292932Sdim 1189314564Sdim alloc->replaceAllUsesWith(persistent_load); 1190314564Sdim alloc->eraseFromParent(); 1191292932Sdim 1192314564Sdim return true; 1193292932Sdim} 1194292932Sdim 1195314564Sdimbool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) { 1196314564Sdim if (!m_resolve_vars) 1197314564Sdim return true; 1198292932Sdim 1199314564Sdim lldb_private::Log *log( 1200314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1201292932Sdim 1202314564Sdim BasicBlock::iterator ii; 1203292932Sdim 1204314564Sdim typedef SmallVector<Instruction *, 2> InstrList; 1205314564Sdim typedef InstrList::iterator InstrIterator; 1206292932Sdim 1207314564Sdim InstrList pvar_allocs; 1208292932Sdim 1209314564Sdim for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { 1210314564Sdim Instruction &inst = *ii; 1211292932Sdim 1212314564Sdim if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) { 1213314564Sdim llvm::StringRef alloc_name = alloc->getName(); 1214292932Sdim 1215314564Sdim if (alloc_name.startswith("$") && !alloc_name.startswith("$__lldb")) { 1216314564Sdim if (alloc_name.find_first_of("0123456789") == 1) { 1217314564Sdim if (log) 1218314564Sdim log->Printf("Rejecting a numeric persistent variable."); 1219292932Sdim 1220314564Sdim m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, " 1221314564Sdim "$1, ... are reserved for use as result " 1222314564Sdim "names\n"); 1223292932Sdim 1224314564Sdim return false; 1225314564Sdim } 1226292932Sdim 1227314564Sdim pvar_allocs.push_back(alloc); 1228314564Sdim } 1229292932Sdim } 1230314564Sdim } 1231292932Sdim 1232314564Sdim InstrIterator iter; 1233292932Sdim 1234314564Sdim for (iter = pvar_allocs.begin(); iter != pvar_allocs.end(); ++iter) { 1235314564Sdim if (!RewritePersistentAlloc(*iter)) { 1236314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite " 1237314564Sdim "the creation of a persistent variable\n"); 1238292932Sdim 1239314564Sdim if (log) 1240314564Sdim log->PutCString( 1241314564Sdim "Couldn't rewrite the creation of a persistent variable"); 1242292932Sdim 1243314564Sdim return false; 1244292932Sdim } 1245314564Sdim } 1246292932Sdim 1247314564Sdim return true; 1248292932Sdim} 1249292932Sdim 1250314564Sdimbool IRForTarget::MaterializeInitializer(uint8_t *data, Constant *initializer) { 1251314564Sdim if (!initializer) 1252314564Sdim return true; 1253292932Sdim 1254314564Sdim lldb_private::Log *log( 1255314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1256292932Sdim 1257314564Sdim if (log && log->GetVerbose()) 1258314564Sdim log->Printf(" MaterializeInitializer(%p, %s)", (void *)data, 1259314564Sdim PrintValue(initializer).c_str()); 1260292932Sdim 1261314564Sdim Type *initializer_type = initializer->getType(); 1262292932Sdim 1263314564Sdim if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer)) { 1264314564Sdim size_t constant_size = m_target_data->getTypeStoreSize(initializer_type); 1265314564Sdim lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc( 1266314564Sdim llvm::NextPowerOf2(constant_size) * 8); 1267309124Sdim 1268314564Sdim lldb_private::Error get_data_error; 1269314564Sdim if (!scalar.GetAsMemoryData(data, constant_size, 1270314564Sdim lldb_private::endian::InlHostByteOrder(), 1271314564Sdim get_data_error)) 1272314564Sdim return false; 1273309124Sdim 1274314564Sdim return true; 1275314564Sdim } else if (ConstantDataArray *array_initializer = 1276314564Sdim dyn_cast<ConstantDataArray>(initializer)) { 1277314564Sdim if (array_initializer->isString()) { 1278314564Sdim std::string array_initializer_string = array_initializer->getAsString(); 1279314564Sdim memcpy(data, array_initializer_string.c_str(), 1280314564Sdim m_target_data->getTypeStoreSize(initializer_type)); 1281314564Sdim } else { 1282314564Sdim ArrayType *array_initializer_type = array_initializer->getType(); 1283314564Sdim Type *array_element_type = array_initializer_type->getElementType(); 1284292932Sdim 1285314564Sdim size_t element_size = m_target_data->getTypeAllocSize(array_element_type); 1286292932Sdim 1287314564Sdim for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i) { 1288314564Sdim Value *operand_value = array_initializer->getOperand(i); 1289314564Sdim Constant *operand_constant = dyn_cast<Constant>(operand_value); 1290292932Sdim 1291314564Sdim if (!operand_constant) 1292314564Sdim return false; 1293292932Sdim 1294314564Sdim if (!MaterializeInitializer(data + (i * element_size), 1295314564Sdim operand_constant)) 1296314564Sdim return false; 1297314564Sdim } 1298292932Sdim } 1299314564Sdim return true; 1300314564Sdim } else if (ConstantStruct *struct_initializer = 1301314564Sdim dyn_cast<ConstantStruct>(initializer)) { 1302314564Sdim StructType *struct_initializer_type = struct_initializer->getType(); 1303314564Sdim const StructLayout *struct_layout = 1304314564Sdim m_target_data->getStructLayout(struct_initializer_type); 1305292932Sdim 1306314564Sdim for (unsigned i = 0; i < struct_initializer->getNumOperands(); ++i) { 1307314564Sdim if (!MaterializeInitializer(data + struct_layout->getElementOffset(i), 1308314564Sdim struct_initializer->getOperand(i))) 1309314564Sdim return false; 1310292932Sdim } 1311314564Sdim return true; 1312314564Sdim } else if (isa<ConstantAggregateZero>(initializer)) { 1313314564Sdim memset(data, 0, m_target_data->getTypeStoreSize(initializer_type)); 1314314564Sdim return true; 1315314564Sdim } 1316314564Sdim return false; 1317292932Sdim} 1318292932Sdim 1319292932Sdim// This function does not report errors; its callers are responsible. 1320314564Sdimbool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) { 1321314564Sdim lldb_private::Log *log( 1322314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1323292932Sdim 1324314564Sdim if (log) 1325314564Sdim log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str()); 1326292932Sdim 1327314564Sdim if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) { 1328314564Sdim switch (constant_expr->getOpcode()) { 1329314564Sdim default: 1330314564Sdim break; 1331314564Sdim case Instruction::GetElementPtr: 1332314564Sdim case Instruction::BitCast: 1333314564Sdim Value *s = constant_expr->getOperand(0); 1334314564Sdim if (!MaybeHandleVariable(s)) 1335314564Sdim return false; 1336292932Sdim } 1337314564Sdim } else if (GlobalVariable *global_variable = 1338314564Sdim dyn_cast<GlobalVariable>(llvm_value_ptr)) { 1339314564Sdim if (!GlobalValue::isExternalLinkage(global_variable->getLinkage())) 1340314564Sdim return true; 1341292932Sdim 1342314564Sdim clang::NamedDecl *named_decl = DeclForGlobal(global_variable); 1343292932Sdim 1344314564Sdim if (!named_decl) { 1345314564Sdim if (IsObjCSelectorRef(llvm_value_ptr)) 1346314564Sdim return true; 1347292932Sdim 1348314564Sdim if (!global_variable->hasExternalLinkage()) 1349314564Sdim return true; 1350292932Sdim 1351314564Sdim if (log) 1352314564Sdim log->Printf("Found global variable \"%s\" without metadata", 1353314564Sdim global_variable->getName().str().c_str()); 1354292932Sdim 1355314564Sdim return false; 1356314564Sdim } 1357292932Sdim 1358314564Sdim std::string name(named_decl->getName().str()); 1359292932Sdim 1360314564Sdim clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl); 1361314564Sdim if (value_decl == NULL) 1362314564Sdim return false; 1363292932Sdim 1364314564Sdim lldb_private::CompilerType compiler_type(&value_decl->getASTContext(), 1365314564Sdim value_decl->getType()); 1366292932Sdim 1367314564Sdim const Type *value_type = NULL; 1368292932Sdim 1369314564Sdim if (name[0] == '$') { 1370314564Sdim // The $__lldb_expr_result name indicates the return value has allocated 1371314564Sdim // as 1372314564Sdim // a static variable. Per the comment at 1373314564Sdim // ASTResultSynthesizer::SynthesizeBodyResult, 1374314564Sdim // accesses to this static variable need to be redirected to the result of 1375314564Sdim // dereferencing 1376314564Sdim // a pointer that is passed in as one of the arguments. 1377314564Sdim // 1378314564Sdim // Consequently, when reporting the size of the type, we report a pointer 1379314564Sdim // type pointing 1380314564Sdim // to the type of $__lldb_expr_result, not the type itself. 1381314564Sdim // 1382314564Sdim // We also do this for any user-declared persistent variables. 1383314564Sdim compiler_type = compiler_type.GetPointerType(); 1384314564Sdim value_type = PointerType::get(global_variable->getType(), 0); 1385314564Sdim } else { 1386314564Sdim value_type = global_variable->getType(); 1387314564Sdim } 1388292932Sdim 1389314564Sdim const uint64_t value_size = compiler_type.GetByteSize(nullptr); 1390314564Sdim lldb::offset_t value_alignment = 1391314564Sdim (compiler_type.GetTypeBitAlign() + 7ull) / 8ull; 1392292932Sdim 1393314564Sdim if (log) { 1394314564Sdim log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 1395314564Sdim ", align %" PRIu64 "]", 1396314564Sdim name.c_str(), 1397314564Sdim lldb_private::ClangUtil::GetQualType(compiler_type) 1398314564Sdim .getAsString() 1399314564Sdim .c_str(), 1400314564Sdim PrintType(value_type).c_str(), value_size, value_alignment); 1401292932Sdim } 1402292932Sdim 1403314564Sdim if (named_decl && 1404314564Sdim !m_decl_map->AddValueToStruct( 1405314564Sdim named_decl, lldb_private::ConstString(name.c_str()), llvm_value_ptr, 1406314564Sdim value_size, value_alignment)) { 1407314564Sdim if (!global_variable->hasExternalLinkage()) 1408314564Sdim return true; 1409314564Sdim else 1410314564Sdim return true; 1411292932Sdim } 1412314564Sdim } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) { 1413314564Sdim if (log) 1414314564Sdim log->Printf("Function pointers aren't handled right now"); 1415292932Sdim 1416314564Sdim return false; 1417314564Sdim } 1418314564Sdim 1419314564Sdim return true; 1420292932Sdim} 1421292932Sdim 1422292932Sdim// This function does not report errors; its callers are responsible. 1423314564Sdimbool IRForTarget::HandleSymbol(Value *symbol) { 1424314564Sdim lldb_private::Log *log( 1425314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1426292932Sdim 1427314564Sdim lldb_private::ConstString name(symbol->getName().str().c_str()); 1428292932Sdim 1429314564Sdim lldb::addr_t symbol_addr = 1430314564Sdim m_decl_map->GetSymbolAddress(name, lldb::eSymbolTypeAny); 1431292932Sdim 1432314564Sdim if (symbol_addr == LLDB_INVALID_ADDRESS) { 1433314564Sdim if (log) 1434314564Sdim log->Printf("Symbol \"%s\" had no address", name.GetCString()); 1435292932Sdim 1436314564Sdim return false; 1437314564Sdim } 1438292932Sdim 1439314564Sdim if (log) 1440314564Sdim log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr); 1441292932Sdim 1442314564Sdim Type *symbol_type = symbol->getType(); 1443292932Sdim 1444314564Sdim Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false); 1445292932Sdim 1446314564Sdim Value *symbol_addr_ptr = 1447314564Sdim ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type); 1448292932Sdim 1449314564Sdim if (log) 1450314564Sdim log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(), 1451314564Sdim PrintValue(symbol_addr_ptr).c_str()); 1452292932Sdim 1453314564Sdim symbol->replaceAllUsesWith(symbol_addr_ptr); 1454292932Sdim 1455314564Sdim return true; 1456292932Sdim} 1457292932Sdim 1458314564Sdimbool IRForTarget::MaybeHandleCallArguments(CallInst *Old) { 1459314564Sdim lldb_private::Log *log( 1460314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1461292932Sdim 1462314564Sdim if (log) 1463314564Sdim log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str()); 1464292932Sdim 1465314564Sdim for (unsigned op_index = 0, num_ops = Old->getNumArgOperands(); 1466314564Sdim op_index < num_ops; ++op_index) 1467314564Sdim if (!MaybeHandleVariable(Old->getArgOperand( 1468314564Sdim op_index))) // conservatively believe that this is a store 1469314564Sdim { 1470314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite " 1471314564Sdim "one of the arguments of a function call.\n"); 1472292932Sdim 1473314564Sdim return false; 1474314564Sdim } 1475292932Sdim 1476314564Sdim return true; 1477292932Sdim} 1478292932Sdim 1479314564Sdimbool IRForTarget::HandleObjCClass(Value *classlist_reference) { 1480314564Sdim lldb_private::Log *log( 1481314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1482292932Sdim 1483314564Sdim GlobalVariable *global_variable = 1484314564Sdim dyn_cast<GlobalVariable>(classlist_reference); 1485292932Sdim 1486314564Sdim if (!global_variable) 1487314564Sdim return false; 1488292932Sdim 1489314564Sdim Constant *initializer = global_variable->getInitializer(); 1490292932Sdim 1491314564Sdim if (!initializer) 1492314564Sdim return false; 1493292932Sdim 1494314564Sdim if (!initializer->hasName()) 1495314564Sdim return false; 1496292932Sdim 1497314564Sdim StringRef name(initializer->getName()); 1498314564Sdim lldb_private::ConstString name_cstr(name.str().c_str()); 1499314564Sdim lldb::addr_t class_ptr = 1500314564Sdim m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass); 1501292932Sdim 1502314564Sdim if (log) 1503314564Sdim log->Printf("Found reference to Objective-C class %s (0x%llx)", 1504314564Sdim name_cstr.AsCString(), (unsigned long long)class_ptr); 1505292932Sdim 1506314564Sdim if (class_ptr == LLDB_INVALID_ADDRESS) 1507314564Sdim return false; 1508292932Sdim 1509314564Sdim if (global_variable->use_empty()) 1510314564Sdim return false; 1511292932Sdim 1512314564Sdim SmallVector<LoadInst *, 2> load_instructions; 1513292932Sdim 1514314564Sdim for (llvm::User *u : global_variable->users()) { 1515314564Sdim if (LoadInst *load_instruction = dyn_cast<LoadInst>(u)) 1516314564Sdim load_instructions.push_back(load_instruction); 1517314564Sdim } 1518292932Sdim 1519314564Sdim if (load_instructions.empty()) 1520314564Sdim return false; 1521292932Sdim 1522314564Sdim Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr); 1523292932Sdim 1524314564Sdim for (LoadInst *load_instruction : load_instructions) { 1525314564Sdim Constant *class_bitcast = 1526314564Sdim ConstantExpr::getIntToPtr(class_addr, load_instruction->getType()); 1527292932Sdim 1528314564Sdim load_instruction->replaceAllUsesWith(class_bitcast); 1529292932Sdim 1530314564Sdim load_instruction->eraseFromParent(); 1531314564Sdim } 1532292932Sdim 1533314564Sdim return true; 1534292932Sdim} 1535292932Sdim 1536314564Sdimbool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) { 1537314564Sdim BasicBlock::iterator ii; 1538292932Sdim 1539314564Sdim std::vector<CallInst *> calls_to_remove; 1540292932Sdim 1541314564Sdim for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { 1542314564Sdim Instruction &inst = *ii; 1543292932Sdim 1544314564Sdim CallInst *call = dyn_cast<CallInst>(&inst); 1545292932Sdim 1546314564Sdim // MaybeHandleCallArguments handles error reporting; we are silent here 1547314564Sdim if (!call) 1548314564Sdim continue; 1549292932Sdim 1550314564Sdim bool remove = false; 1551292932Sdim 1552314564Sdim llvm::Function *func = call->getCalledFunction(); 1553292932Sdim 1554314564Sdim if (func && func->getName() == "__cxa_atexit") 1555314564Sdim remove = true; 1556292932Sdim 1557314564Sdim llvm::Value *val = call->getCalledValue(); 1558292932Sdim 1559314564Sdim if (val && val->getName() == "__cxa_atexit") 1560314564Sdim remove = true; 1561292932Sdim 1562314564Sdim if (remove) 1563314564Sdim calls_to_remove.push_back(call); 1564314564Sdim } 1565292932Sdim 1566314564Sdim for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(), 1567314564Sdim ce = calls_to_remove.end(); 1568314564Sdim ci != ce; ++ci) { 1569314564Sdim (*ci)->eraseFromParent(); 1570314564Sdim } 1571292932Sdim 1572314564Sdim return true; 1573292932Sdim} 1574292932Sdim 1575314564Sdimbool IRForTarget::ResolveCalls(BasicBlock &basic_block) { 1576314564Sdim ///////////////////////////////////////////////////////////////////////// 1577314564Sdim // Prepare the current basic block for execution in the remote process 1578314564Sdim // 1579292932Sdim 1580314564Sdim BasicBlock::iterator ii; 1581292932Sdim 1582314564Sdim for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { 1583314564Sdim Instruction &inst = *ii; 1584292932Sdim 1585314564Sdim CallInst *call = dyn_cast<CallInst>(&inst); 1586292932Sdim 1587314564Sdim // MaybeHandleCallArguments handles error reporting; we are silent here 1588314564Sdim if (call && !MaybeHandleCallArguments(call)) 1589314564Sdim return false; 1590314564Sdim } 1591292932Sdim 1592314564Sdim return true; 1593292932Sdim} 1594292932Sdim 1595314564Sdimbool IRForTarget::ResolveExternals(Function &llvm_function) { 1596314564Sdim lldb_private::Log *log( 1597314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1598292932Sdim 1599314564Sdim for (GlobalVariable &global_var : m_module->globals()) { 1600314564Sdim std::string global_name = global_var.getName().str(); 1601292932Sdim 1602314564Sdim if (log) 1603314564Sdim log->Printf("Examining %s, DeclForGlobalValue returns %p", 1604314564Sdim global_name.c_str(), 1605314564Sdim static_cast<void *>(DeclForGlobal(&global_var))); 1606292932Sdim 1607314564Sdim if (global_name.find("OBJC_IVAR") == 0) { 1608314564Sdim if (!HandleSymbol(&global_var)) { 1609314564Sdim m_error_stream.Printf("Error [IRForTarget]: Couldn't find Objective-C " 1610314564Sdim "indirect ivar symbol %s\n", 1611314564Sdim global_name.c_str()); 1612292932Sdim 1613314564Sdim return false; 1614314564Sdim } 1615314564Sdim } else if (global_name.find("OBJC_CLASSLIST_REFERENCES_$") != 1616314564Sdim global_name.npos) { 1617314564Sdim if (!HandleObjCClass(&global_var)) { 1618314564Sdim m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class " 1619314564Sdim "for an Objective-C static method call\n"); 1620292932Sdim 1621314564Sdim return false; 1622314564Sdim } 1623314564Sdim } else if (global_name.find("OBJC_CLASSLIST_SUP_REFS_$") != 1624314564Sdim global_name.npos) { 1625314564Sdim if (!HandleObjCClass(&global_var)) { 1626314564Sdim m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class " 1627314564Sdim "for an Objective-C static method call\n"); 1628292932Sdim 1629314564Sdim return false; 1630314564Sdim } 1631314564Sdim } else if (DeclForGlobal(&global_var)) { 1632314564Sdim if (!MaybeHandleVariable(&global_var)) { 1633314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite " 1634314564Sdim "external variable %s\n", 1635314564Sdim global_name.c_str()); 1636292932Sdim 1637314564Sdim return false; 1638314564Sdim } 1639292932Sdim } 1640314564Sdim } 1641292932Sdim 1642314564Sdim return true; 1643292932Sdim} 1644292932Sdim 1645314564Sdimstatic bool isGuardVariableRef(Value *V) { 1646314564Sdim Constant *Old = NULL; 1647292932Sdim 1648314564Sdim if (!(Old = dyn_cast<Constant>(V))) 1649314564Sdim return false; 1650292932Sdim 1651314564Sdim ConstantExpr *CE = NULL; 1652292932Sdim 1653314564Sdim if ((CE = dyn_cast<ConstantExpr>(V))) { 1654314564Sdim if (CE->getOpcode() != Instruction::BitCast) 1655314564Sdim return false; 1656292932Sdim 1657314564Sdim Old = CE->getOperand(0); 1658314564Sdim } 1659292932Sdim 1660314564Sdim GlobalVariable *GV = dyn_cast<GlobalVariable>(Old); 1661292932Sdim 1662314564Sdim if (!GV || !GV->hasName() || 1663314564Sdim (!GV->getName().startswith("_ZGV") && // Itanium ABI guard variable 1664314564Sdim !GV->getName().endswith("@4IA"))) // Microsoft ABI guard variable 1665314564Sdim { 1666314564Sdim return false; 1667314564Sdim } 1668292932Sdim 1669314564Sdim return true; 1670292932Sdim} 1671292932Sdim 1672314564Sdimvoid IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction *guard_load) { 1673314564Sdim Constant *zero(Constant::getNullValue(guard_load->getType())); 1674314564Sdim guard_load->replaceAllUsesWith(zero); 1675314564Sdim guard_load->eraseFromParent(); 1676292932Sdim} 1677292932Sdim 1678314564Sdimstatic void ExciseGuardStore(Instruction *guard_store) { 1679314564Sdim guard_store->eraseFromParent(); 1680292932Sdim} 1681292932Sdim 1682314564Sdimbool IRForTarget::RemoveGuards(BasicBlock &basic_block) { 1683314564Sdim /////////////////////////////////////////////////////// 1684314564Sdim // Eliminate any reference to guard variables found. 1685314564Sdim // 1686292932Sdim 1687314564Sdim BasicBlock::iterator ii; 1688292932Sdim 1689314564Sdim typedef SmallVector<Instruction *, 2> InstrList; 1690314564Sdim typedef InstrList::iterator InstrIterator; 1691292932Sdim 1692314564Sdim InstrList guard_loads; 1693314564Sdim InstrList guard_stores; 1694292932Sdim 1695314564Sdim for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) { 1696314564Sdim Instruction &inst = *ii; 1697292932Sdim 1698314564Sdim if (LoadInst *load = dyn_cast<LoadInst>(&inst)) 1699314564Sdim if (isGuardVariableRef(load->getPointerOperand())) 1700314564Sdim guard_loads.push_back(&inst); 1701292932Sdim 1702314564Sdim if (StoreInst *store = dyn_cast<StoreInst>(&inst)) 1703314564Sdim if (isGuardVariableRef(store->getPointerOperand())) 1704314564Sdim guard_stores.push_back(&inst); 1705314564Sdim } 1706292932Sdim 1707314564Sdim InstrIterator iter; 1708292932Sdim 1709314564Sdim for (iter = guard_loads.begin(); iter != guard_loads.end(); ++iter) 1710314564Sdim TurnGuardLoadIntoZero(*iter); 1711292932Sdim 1712314564Sdim for (iter = guard_stores.begin(); iter != guard_stores.end(); ++iter) 1713314564Sdim ExciseGuardStore(*iter); 1714292932Sdim 1715314564Sdim return true; 1716292932Sdim} 1717292932Sdim 1718292932Sdim// This function does not report errors; its callers are responsible. 1719314564Sdimbool IRForTarget::UnfoldConstant(Constant *old_constant, 1720314564Sdim llvm::Function *llvm_function, 1721314564Sdim FunctionValueCache &value_maker, 1722314564Sdim FunctionValueCache &entry_instruction_finder, 1723314564Sdim lldb_private::Stream &error_stream) { 1724314564Sdim SmallVector<User *, 16> users; 1725292932Sdim 1726314564Sdim // We do this because the use list might change, invalidating our iterator. 1727314564Sdim // Much better to keep a work list ourselves. 1728314564Sdim for (llvm::User *u : old_constant->users()) 1729314564Sdim users.push_back(u); 1730292932Sdim 1731314564Sdim for (size_t i = 0; i < users.size(); ++i) { 1732314564Sdim User *user = users[i]; 1733292932Sdim 1734314564Sdim if (Constant *constant = dyn_cast<Constant>(user)) { 1735314564Sdim // synthesize a new non-constant equivalent of the constant 1736292932Sdim 1737314564Sdim if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) { 1738314564Sdim switch (constant_expr->getOpcode()) { 1739314564Sdim default: 1740314564Sdim error_stream.Printf("error [IRForTarget internal]: Unhandled " 1741314564Sdim "constant expression type: \"%s\"", 1742314564Sdim PrintValue(constant_expr).c_str()); 1743314564Sdim return false; 1744314564Sdim case Instruction::BitCast: { 1745314564Sdim FunctionValueCache bit_cast_maker( 1746314564Sdim [&value_maker, &entry_instruction_finder, old_constant, 1747314564Sdim constant_expr](llvm::Function *function) -> llvm::Value * { 1748314564Sdim // UnaryExpr 1749314564Sdim // OperandList[0] is value 1750292932Sdim 1751314564Sdim if (constant_expr->getOperand(0) != old_constant) 1752314564Sdim return constant_expr; 1753292932Sdim 1754314564Sdim return new BitCastInst( 1755314564Sdim value_maker.GetValue(function), constant_expr->getType(), 1756314564Sdim "", llvm::cast<Instruction>( 1757314564Sdim entry_instruction_finder.GetValue(function))); 1758314564Sdim }); 1759292932Sdim 1760314564Sdim if (!UnfoldConstant(constant_expr, llvm_function, bit_cast_maker, 1761314564Sdim entry_instruction_finder, error_stream)) 1762314564Sdim return false; 1763314564Sdim } break; 1764314564Sdim case Instruction::GetElementPtr: { 1765314564Sdim // GetElementPtrConstantExpr 1766314564Sdim // OperandList[0] is base 1767314564Sdim // OperandList[1]... are indices 1768292932Sdim 1769314564Sdim FunctionValueCache get_element_pointer_maker( 1770314564Sdim [&value_maker, &entry_instruction_finder, old_constant, 1771314564Sdim constant_expr](llvm::Function *function) -> llvm::Value * { 1772314564Sdim Value *ptr = constant_expr->getOperand(0); 1773292932Sdim 1774314564Sdim if (ptr == old_constant) 1775314564Sdim ptr = value_maker.GetValue(function); 1776292932Sdim 1777314564Sdim std::vector<Value *> index_vector; 1778292932Sdim 1779314564Sdim unsigned operand_index; 1780314564Sdim unsigned num_operands = constant_expr->getNumOperands(); 1781292932Sdim 1782314564Sdim for (operand_index = 1; operand_index < num_operands; 1783314564Sdim ++operand_index) { 1784314564Sdim Value *operand = constant_expr->getOperand(operand_index); 1785292932Sdim 1786314564Sdim if (operand == old_constant) 1787314564Sdim operand = value_maker.GetValue(function); 1788292932Sdim 1789314564Sdim index_vector.push_back(operand); 1790314564Sdim } 1791292932Sdim 1792314564Sdim ArrayRef<Value *> indices(index_vector); 1793292932Sdim 1794314564Sdim return GetElementPtrInst::Create( 1795314564Sdim nullptr, ptr, indices, "", 1796314564Sdim llvm::cast<Instruction>( 1797314564Sdim entry_instruction_finder.GetValue(function))); 1798314564Sdim }); 1799292932Sdim 1800314564Sdim if (!UnfoldConstant(constant_expr, llvm_function, 1801314564Sdim get_element_pointer_maker, 1802314564Sdim entry_instruction_finder, error_stream)) 1803314564Sdim return false; 1804314564Sdim } break; 1805292932Sdim } 1806314564Sdim } else { 1807314564Sdim error_stream.Printf( 1808314564Sdim "error [IRForTarget internal]: Unhandled constant type: \"%s\"", 1809314564Sdim PrintValue(constant).c_str()); 1810314564Sdim return false; 1811314564Sdim } 1812314564Sdim } else { 1813314564Sdim if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) { 1814314564Sdim if (llvm_function && inst->getParent()->getParent() != llvm_function) { 1815314564Sdim error_stream.PutCString("error: Capturing non-local variables in " 1816314564Sdim "expressions is unsupported.\n"); 1817314564Sdim return false; 1818292932Sdim } 1819314564Sdim inst->replaceUsesOfWith( 1820314564Sdim old_constant, value_maker.GetValue(inst->getParent()->getParent())); 1821314564Sdim } else { 1822314564Sdim error_stream.Printf( 1823314564Sdim "error [IRForTarget internal]: Unhandled non-constant type: \"%s\"", 1824314564Sdim PrintValue(user).c_str()); 1825314564Sdim return false; 1826314564Sdim } 1827292932Sdim } 1828314564Sdim } 1829292932Sdim 1830314564Sdim if (!isa<GlobalValue>(old_constant)) { 1831314564Sdim old_constant->destroyConstant(); 1832314564Sdim } 1833292932Sdim 1834314564Sdim return true; 1835292932Sdim} 1836292932Sdim 1837314564Sdimbool IRForTarget::ReplaceVariables(Function &llvm_function) { 1838314564Sdim if (!m_resolve_vars) 1839314564Sdim return true; 1840292932Sdim 1841314564Sdim lldb_private::Log *log( 1842314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 1843292932Sdim 1844314564Sdim m_decl_map->DoStructLayout(); 1845292932Sdim 1846314564Sdim if (log) 1847314564Sdim log->Printf("Element arrangement:"); 1848292932Sdim 1849314564Sdim uint32_t num_elements; 1850314564Sdim uint32_t element_index; 1851292932Sdim 1852314564Sdim size_t size; 1853314564Sdim lldb::offset_t alignment; 1854292932Sdim 1855314564Sdim if (!m_decl_map->GetStructInfo(num_elements, size, alignment)) 1856314564Sdim return false; 1857292932Sdim 1858314564Sdim Function::arg_iterator iter(llvm_function.getArgumentList().begin()); 1859292932Sdim 1860314564Sdim if (iter == llvm_function.getArgumentList().end()) { 1861314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes no " 1862314564Sdim "arguments (should take at least a struct pointer)"); 1863292932Sdim 1864314564Sdim return false; 1865314564Sdim } 1866292932Sdim 1867314564Sdim Argument *argument = &*iter; 1868292932Sdim 1869314564Sdim if (argument->getName().equals("this")) { 1870314564Sdim ++iter; 1871292932Sdim 1872314564Sdim if (iter == llvm_function.getArgumentList().end()) { 1873314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only " 1874314564Sdim "'this' argument (should take a struct pointer " 1875314564Sdim "too)"); 1876292932Sdim 1877314564Sdim return false; 1878292932Sdim } 1879292932Sdim 1880314564Sdim argument = &*iter; 1881314564Sdim } else if (argument->getName().equals("self")) { 1882314564Sdim ++iter; 1883292932Sdim 1884314564Sdim if (iter == llvm_function.getArgumentList().end()) { 1885314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only " 1886314564Sdim "'self' argument (should take '_cmd' and a struct " 1887314564Sdim "pointer too)"); 1888292932Sdim 1889314564Sdim return false; 1890314564Sdim } 1891292932Sdim 1892314564Sdim if (!iter->getName().equals("_cmd")) { 1893314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes '%s' " 1894314564Sdim "after 'self' argument (should take '_cmd')", 1895314564Sdim iter->getName().str().c_str()); 1896292932Sdim 1897314564Sdim return false; 1898314564Sdim } 1899292932Sdim 1900314564Sdim ++iter; 1901292932Sdim 1902314564Sdim if (iter == llvm_function.getArgumentList().end()) { 1903314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only " 1904314564Sdim "'self' and '_cmd' arguments (should take a struct " 1905314564Sdim "pointer too)"); 1906292932Sdim 1907314564Sdim return false; 1908292932Sdim } 1909292932Sdim 1910314564Sdim argument = &*iter; 1911314564Sdim } 1912292932Sdim 1913314564Sdim if (!argument->getName().equals("$__lldb_arg")) { 1914314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes an " 1915314564Sdim "argument named '%s' instead of the struct pointer", 1916314564Sdim argument->getName().str().c_str()); 1917292932Sdim 1918314564Sdim return false; 1919314564Sdim } 1920292932Sdim 1921314564Sdim if (log) 1922314564Sdim log->Printf("Arg: \"%s\"", PrintValue(argument).c_str()); 1923292932Sdim 1924314564Sdim BasicBlock &entry_block(llvm_function.getEntryBlock()); 1925314564Sdim Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg()); 1926292932Sdim 1927314564Sdim if (!FirstEntryInstruction) { 1928314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find the " 1929314564Sdim "first instruction in the wrapper for use in " 1930314564Sdim "rewriting"); 1931292932Sdim 1932314564Sdim return false; 1933314564Sdim } 1934292932Sdim 1935314564Sdim LLVMContext &context(m_module->getContext()); 1936314564Sdim IntegerType *offset_type(Type::getInt32Ty(context)); 1937292932Sdim 1938314564Sdim if (!offset_type) { 1939314564Sdim m_error_stream.Printf( 1940314564Sdim "Internal error [IRForTarget]: Couldn't produce an offset type"); 1941292932Sdim 1942314564Sdim return false; 1943314564Sdim } 1944292932Sdim 1945314564Sdim for (element_index = 0; element_index < num_elements; ++element_index) { 1946314564Sdim const clang::NamedDecl *decl = NULL; 1947314564Sdim Value *value = NULL; 1948314564Sdim lldb::offset_t offset; 1949314564Sdim lldb_private::ConstString name; 1950292932Sdim 1951314564Sdim if (!m_decl_map->GetStructElement(decl, value, offset, name, 1952314564Sdim element_index)) { 1953314564Sdim m_error_stream.Printf( 1954314564Sdim "Internal error [IRForTarget]: Structure information is incomplete"); 1955292932Sdim 1956314564Sdim return false; 1957314564Sdim } 1958292932Sdim 1959314564Sdim if (log) 1960314564Sdim log->Printf(" \"%s\" (\"%s\") placed at %" PRIu64, name.GetCString(), 1961314564Sdim decl->getNameAsString().c_str(), offset); 1962292932Sdim 1963314564Sdim if (value) { 1964314564Sdim if (log) 1965314564Sdim log->Printf(" Replacing [%s]", PrintValue(value).c_str()); 1966292932Sdim 1967314564Sdim FunctionValueCache body_result_maker( 1968314564Sdim [this, name, offset_type, offset, argument, 1969314564Sdim value](llvm::Function *function) -> llvm::Value * { 1970314564Sdim // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, in 1971314564Sdim // cases where the result 1972314564Sdim // variable is an rvalue, we have to synthesize a dereference of the 1973314564Sdim // appropriate structure 1974314564Sdim // entry in order to produce the static variable that the AST thinks 1975314564Sdim // it is accessing. 1976292932Sdim 1977314564Sdim llvm::Instruction *entry_instruction = llvm::cast<Instruction>( 1978314564Sdim m_entry_instruction_finder.GetValue(function)); 1979292932Sdim 1980314564Sdim ConstantInt *offset_int( 1981314564Sdim ConstantInt::get(offset_type, offset, true)); 1982314564Sdim GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create( 1983314564Sdim nullptr, argument, offset_int, "", entry_instruction); 1984292932Sdim 1985314564Sdim if (name == m_result_name && !m_result_is_pointer) { 1986314564Sdim BitCastInst *bit_cast = new BitCastInst( 1987314564Sdim get_element_ptr, value->getType()->getPointerTo(), "", 1988314564Sdim entry_instruction); 1989292932Sdim 1990314564Sdim LoadInst *load = new LoadInst(bit_cast, "", entry_instruction); 1991292932Sdim 1992314564Sdim return load; 1993314564Sdim } else { 1994314564Sdim BitCastInst *bit_cast = new BitCastInst( 1995314564Sdim get_element_ptr, value->getType(), "", entry_instruction); 1996292932Sdim 1997314564Sdim return bit_cast; 1998292932Sdim } 1999314564Sdim }); 2000292932Sdim 2001314564Sdim if (Constant *constant = dyn_cast<Constant>(value)) { 2002314564Sdim if (!UnfoldConstant(constant, &llvm_function, body_result_maker, 2003314564Sdim m_entry_instruction_finder, m_error_stream)) { 2004314564Sdim return false; 2005292932Sdim } 2006314564Sdim } else if (Instruction *instruction = dyn_cast<Instruction>(value)) { 2007314564Sdim if (instruction->getParent()->getParent() != &llvm_function) { 2008314564Sdim m_error_stream.PutCString("error: Capturing non-local variables in " 2009314564Sdim "expressions is unsupported.\n"); 2010314564Sdim return false; 2011314564Sdim } 2012314564Sdim value->replaceAllUsesWith( 2013314564Sdim body_result_maker.GetValue(instruction->getParent()->getParent())); 2014314564Sdim } else { 2015314564Sdim if (log) 2016314564Sdim log->Printf("Unhandled non-constant type: \"%s\"", 2017314564Sdim PrintValue(value).c_str()); 2018314564Sdim return false; 2019314564Sdim } 2020314564Sdim 2021314564Sdim if (GlobalVariable *var = dyn_cast<GlobalVariable>(value)) 2022314564Sdim var->eraseFromParent(); 2023292932Sdim } 2024314564Sdim } 2025292932Sdim 2026314564Sdim if (log) 2027314564Sdim log->Printf("Total structure [align %" PRId64 ", size %" PRIu64 "]", 2028314564Sdim (int64_t)alignment, (uint64_t)size); 2029292932Sdim 2030314564Sdim return true; 2031292932Sdim} 2032292932Sdim 2033314564Sdimllvm::Constant *IRForTarget::BuildRelocation(llvm::Type *type, 2034314564Sdim uint64_t offset) { 2035314564Sdim llvm::Constant *offset_int = ConstantInt::get(m_intptr_ty, offset); 2036292932Sdim 2037314564Sdim llvm::Constant *offset_array[1]; 2038292932Sdim 2039314564Sdim offset_array[0] = offset_int; 2040292932Sdim 2041314564Sdim llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1); 2042314564Sdim llvm::Type *char_type = llvm::Type::getInt8Ty(m_module->getContext()); 2043314564Sdim llvm::Type *char_pointer_type = char_type->getPointerTo(); 2044292932Sdim 2045314564Sdim llvm::Constant *reloc_placeholder_bitcast = 2046314564Sdim ConstantExpr::getBitCast(m_reloc_placeholder, char_pointer_type); 2047314564Sdim llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr( 2048314564Sdim char_type, reloc_placeholder_bitcast, offsets); 2049314564Sdim llvm::Constant *reloc_bitcast = 2050314564Sdim ConstantExpr::getBitCast(reloc_getelementptr, type); 2051292932Sdim 2052314564Sdim return reloc_bitcast; 2053292932Sdim} 2054292932Sdim 2055314564Sdimbool IRForTarget::runOnModule(Module &llvm_module) { 2056314564Sdim lldb_private::Log *log( 2057314564Sdim lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); 2058292932Sdim 2059314564Sdim m_module = &llvm_module; 2060314564Sdim m_target_data.reset(new DataLayout(m_module)); 2061314564Sdim m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(), 2062314564Sdim m_target_data->getPointerSizeInBits()); 2063292932Sdim 2064314564Sdim if (log) { 2065314564Sdim std::string s; 2066314564Sdim raw_string_ostream oss(s); 2067292932Sdim 2068314564Sdim m_module->print(oss, NULL); 2069292932Sdim 2070314564Sdim oss.flush(); 2071292932Sdim 2072314564Sdim log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str()); 2073314564Sdim } 2074292932Sdim 2075314564Sdim Function *const main_function = 2076314564Sdim m_func_name.IsEmpty() ? nullptr 2077314564Sdim : m_module->getFunction(m_func_name.GetStringRef()); 2078292932Sdim 2079314564Sdim if (!m_func_name.IsEmpty() && !main_function) { 2080314564Sdim if (log) 2081314564Sdim log->Printf("Couldn't find \"%s()\" in the module", 2082314564Sdim m_func_name.AsCString()); 2083292932Sdim 2084314564Sdim m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find wrapper " 2085314564Sdim "'%s' in the module", 2086314564Sdim m_func_name.AsCString()); 2087292932Sdim 2088314564Sdim return false; 2089314564Sdim } 2090292932Sdim 2091314564Sdim if (main_function) { 2092314564Sdim if (!FixFunctionLinkage(*main_function)) { 2093314564Sdim if (log) 2094314564Sdim log->Printf("Couldn't fix the linkage for the function"); 2095292932Sdim 2096314564Sdim return false; 2097292932Sdim } 2098314564Sdim } 2099292932Sdim 2100314564Sdim llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext()); 2101292932Sdim 2102314564Sdim m_reloc_placeholder = new llvm::GlobalVariable( 2103314564Sdim (*m_module), int8_ty, false /* IsConstant */, 2104314564Sdim GlobalVariable::InternalLinkage, Constant::getNullValue(int8_ty), 2105314564Sdim "reloc_placeholder", NULL /* InsertBefore */, 2106314564Sdim GlobalVariable::NotThreadLocal /* ThreadLocal */, 0 /* AddressSpace */); 2107292932Sdim 2108314564Sdim //////////////////////////////////////////////////////////// 2109314564Sdim // Replace $__lldb_expr_result with a persistent variable 2110314564Sdim // 2111292932Sdim 2112314564Sdim if (main_function) { 2113314564Sdim if (!CreateResultVariable(*main_function)) { 2114314564Sdim if (log) 2115314564Sdim log->Printf("CreateResultVariable() failed"); 2116292932Sdim 2117314564Sdim // CreateResultVariable() reports its own errors, so we don't do so here 2118292932Sdim 2119314564Sdim return false; 2120292932Sdim } 2121314564Sdim } 2122292932Sdim 2123314564Sdim if (log && log->GetVerbose()) { 2124314564Sdim std::string s; 2125314564Sdim raw_string_ostream oss(s); 2126292932Sdim 2127314564Sdim m_module->print(oss, NULL); 2128292932Sdim 2129314564Sdim oss.flush(); 2130292932Sdim 2131314564Sdim log->Printf("Module after creating the result variable: \n\"%s\"", 2132314564Sdim s.c_str()); 2133314564Sdim } 2134292932Sdim 2135314564Sdim for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe; 2136314564Sdim ++fi) { 2137314564Sdim llvm::Function *function = &*fi; 2138292932Sdim 2139314564Sdim if (function->begin() == function->end()) 2140314564Sdim continue; 2141292932Sdim 2142314564Sdim Function::iterator bbi; 2143292932Sdim 2144314564Sdim for (bbi = function->begin(); bbi != function->end(); ++bbi) { 2145314564Sdim if (!RemoveGuards(*bbi)) { 2146314564Sdim if (log) 2147314564Sdim log->Printf("RemoveGuards() failed"); 2148292932Sdim 2149314564Sdim // RemoveGuards() reports its own errors, so we don't do so here 2150292932Sdim 2151314564Sdim return false; 2152314564Sdim } 2153292932Sdim 2154314564Sdim if (!RewritePersistentAllocs(*bbi)) { 2155314564Sdim if (log) 2156314564Sdim log->Printf("RewritePersistentAllocs() failed"); 2157292932Sdim 2158314564Sdim // RewritePersistentAllocs() reports its own errors, so we don't do so 2159314564Sdim // here 2160292932Sdim 2161314564Sdim return false; 2162314564Sdim } 2163292932Sdim 2164314564Sdim if (!RemoveCXAAtExit(*bbi)) { 2165314564Sdim if (log) 2166314564Sdim log->Printf("RemoveCXAAtExit() failed"); 2167292932Sdim 2168314564Sdim // RemoveCXAAtExit() reports its own errors, so we don't do so here 2169292932Sdim 2170314564Sdim return false; 2171314564Sdim } 2172292932Sdim } 2173314564Sdim } 2174292932Sdim 2175314564Sdim /////////////////////////////////////////////////////////////////////////////// 2176314564Sdim // Fix all Objective-C constant strings to use NSStringWithCString:encoding: 2177314564Sdim // 2178292932Sdim 2179314564Sdim if (!RewriteObjCConstStrings()) { 2180314564Sdim if (log) 2181314564Sdim log->Printf("RewriteObjCConstStrings() failed"); 2182314564Sdim 2183314564Sdim // RewriteObjCConstStrings() reports its own errors, so we don't do so here 2184314564Sdim 2185314564Sdim return false; 2186314564Sdim } 2187314564Sdim 2188314564Sdim for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe; 2189314564Sdim ++fi) { 2190314564Sdim llvm::Function *function = &*fi; 2191314564Sdim 2192314564Sdim for (llvm::Function::iterator bbi = function->begin(), 2193314564Sdim bbe = function->end(); 2194314564Sdim bbi != bbe; ++bbi) { 2195314564Sdim if (!RewriteObjCSelectors(*bbi)) { 2196292932Sdim if (log) 2197314564Sdim log->Printf("RewriteObjCSelectors() failed"); 2198292932Sdim 2199314564Sdim // RewriteObjCSelectors() reports its own errors, so we don't do so here 2200292932Sdim 2201292932Sdim return false; 2202314564Sdim } 2203292932Sdim 2204314564Sdim if (!RewriteObjCClassReferences(*bbi)) { 2205314564Sdim if (log) 2206314564Sdim log->Printf("RewriteObjCClassReferences() failed"); 2207292932Sdim 2208314564Sdim // RewriteObjCClasses() reports its own errors, so we don't do so here 2209292932Sdim 2210314564Sdim return false; 2211314564Sdim } 2212292932Sdim } 2213314564Sdim } 2214292932Sdim 2215314564Sdim for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe; 2216314564Sdim ++fi) { 2217314564Sdim llvm::Function *function = &*fi; 2218292932Sdim 2219314564Sdim for (llvm::Function::iterator bbi = function->begin(), 2220314564Sdim bbe = function->end(); 2221314564Sdim bbi != bbe; ++bbi) { 2222314564Sdim if (!ResolveCalls(*bbi)) { 2223314564Sdim if (log) 2224314564Sdim log->Printf("ResolveCalls() failed"); 2225292932Sdim 2226314564Sdim // ResolveCalls() reports its own errors, so we don't do so here 2227292932Sdim 2228314564Sdim return false; 2229314564Sdim } 2230292932Sdim } 2231314564Sdim } 2232292932Sdim 2233314564Sdim //////////////////////////////////////////////////////////////////////// 2234314564Sdim // Run function-level passes that only make sense on the main function 2235314564Sdim // 2236292932Sdim 2237314564Sdim if (main_function) { 2238314564Sdim if (!ResolveExternals(*main_function)) { 2239314564Sdim if (log) 2240314564Sdim log->Printf("ResolveExternals() failed"); 2241292932Sdim 2242314564Sdim // ResolveExternals() reports its own errors, so we don't do so here 2243292932Sdim 2244314564Sdim return false; 2245314564Sdim } 2246292932Sdim 2247314564Sdim if (!ReplaceVariables(*main_function)) { 2248314564Sdim if (log) 2249314564Sdim log->Printf("ReplaceVariables() failed"); 2250292932Sdim 2251314564Sdim // ReplaceVariables() reports its own errors, so we don't do so here 2252292932Sdim 2253314564Sdim return false; 2254292932Sdim } 2255314564Sdim } 2256292932Sdim 2257314564Sdim if (log && log->GetVerbose()) { 2258314564Sdim std::string s; 2259314564Sdim raw_string_ostream oss(s); 2260292932Sdim 2261314564Sdim m_module->print(oss, NULL); 2262292932Sdim 2263314564Sdim oss.flush(); 2264292932Sdim 2265314564Sdim log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str()); 2266314564Sdim } 2267292932Sdim 2268314564Sdim return true; 2269292932Sdim} 2270292932Sdim 2271314564Sdimvoid IRForTarget::assignPassManager(PMStack &pass_mgr_stack, 2272314564Sdim PassManagerType pass_mgr_type) {} 2273292932Sdim 2274314564SdimPassManagerType IRForTarget::getPotentialPassManagerType() const { 2275314564Sdim return PMT_ModulePassManager; 2276292932Sdim} 2277