147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan//===-- IRForTarget.cpp -----------------------------------------*- C++ -*-===// 25cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan// 35cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan// The LLVM Compiler Infrastructure 45cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan// 55cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan// This file is distributed under the University of Illinois Open Source 65cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan// License. See LICENSE.TXT for details. 75cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan// 85cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan//===----------------------------------------------------------------------===// 95cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 105cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan#include "lldb/Expression/IRForTarget.h" 115cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 125cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan#include "llvm/Support/raw_ostream.h" 13a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Constants.h" 14a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/DataLayout.h" 15a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/InstrTypes.h" 16a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Instructions.h" 17a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Intrinsics.h" 18a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Module.h" 1906dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan#include "llvm/PassManager.h" 2006dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan#include "llvm/Transforms/IPO.h" 21a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/ValueSymbolTable.h" 228bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 238bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan#include "clang/AST/ASTContext.h" 245cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 255cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan#include "lldb/Core/dwarf.h" 261cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan#include "lldb/Core/ConstString.h" 271cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan#include "lldb/Core/DataBufferHeap.h" 285cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan#include "lldb/Core/Log.h" 295cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan#include "lldb/Core/Scalar.h" 305cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan#include "lldb/Core/StreamString.h" 315cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan#include "lldb/Expression/ClangExpressionDeclMap.h" 321cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan#include "lldb/Expression/IRExecutionUnit.h" 3347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan#include "lldb/Expression/IRInterpreter.h" 34c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan#include "lldb/Host/Endian.h" 35696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan#include "lldb/Symbol/ClangASTContext.h" 3652f792329be5db8e38961350589e97e8f2823acdGreg Clayton#include "lldb/Symbol/ClangASTType.h" 375cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 385cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan#include <map> 395cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 405cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callananusing namespace llvm; 415cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 423351dacda090c21c203d2300f38e2f45d8f78f4dSean Callananstatic char ID; 433351dacda090c21c203d2300f38e2f45d8f78f4dSean Callanan 441cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean CallananIRForTarget::StaticDataAllocator::StaticDataAllocator(lldb_private::IRExecutionUnit &execution_unit) : 451cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan m_execution_unit(execution_unit), 460f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_stream_string(lldb_private::Stream::eBinary, execution_unit.GetAddressByteSize(), execution_unit.GetByteOrder()), 471cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan m_allocation(LLDB_INVALID_ADDRESS) 48c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan{ 49c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan} 50c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 514a20587f56a05955ea94f650cb39245a092b0c69Sean CallananIRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker) : 524a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan m_maker(maker), 534a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan m_values() 544a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan{ 554a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan} 564a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 574a20587f56a05955ea94f650cb39245a092b0c69Sean CallananIRForTarget::FunctionValueCache::~FunctionValueCache() 584a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan{ 594a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan} 604a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 614a20587f56a05955ea94f650cb39245a092b0c69Sean Callananllvm::Value *IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) 624a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan{ 634a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (!m_values.count(function)) 644a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 654a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan llvm::Value *ret = m_maker(function); 664a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan m_values[function] = ret; 674a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return ret; 684a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan } 694a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return m_values[function]; 704a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan} 714a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 721cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callananlldb::addr_t IRForTarget::StaticDataAllocator::Allocate() 73c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan{ 741cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan lldb_private::Error err; 751cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan 761cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan if (m_allocation != LLDB_INVALID_ADDRESS) 771cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan { 781cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan m_execution_unit.FreeNow(m_allocation); 791cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan m_allocation = LLDB_INVALID_ADDRESS; 801cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan } 811cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan 821cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan m_allocation = m_execution_unit.WriteNow((const uint8_t*)m_stream_string.GetData(), m_stream_string.GetSize(), err); 831cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan 841cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan return m_allocation; 85c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan} 86c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 874a20587f56a05955ea94f650cb39245a092b0c69Sean Callananstatic llvm::Value *FindEntryInstruction (llvm::Function *function) 884a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan{ 894a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (function->empty()) 904a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return NULL; 914a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 924a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return function->getEntryBlock().getFirstNonPHIOrDbg(); 934a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan} 944a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 953c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg ClaytonIRForTarget::IRForTarget (lldb_private::ClangExpressionDeclMap *decl_map, 963c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton bool resolve_vars, 971cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan lldb_private::IRExecutionUnit &execution_unit, 9897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan lldb_private::Stream *error_stream, 993c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton const char *func_name) : 10047a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan ModulePass(ID), 101dbeb3e1e038a75f00fd565203839020e1d00a7c6Stephen Wilson m_resolve_vars(resolve_vars), 102dbeb3e1e038a75f00fd565203839020e1d00a7c6Stephen Wilson m_func_name(func_name), 103c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan m_module(NULL), 1042bc9eb3ba78efc64a273729b480bafc3bbaa433aJohnny Chen m_decl_map(decl_map), 1051cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan m_data_allocator(execution_unit), 1066ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan m_CFStringCreateWithBytes(NULL), 10765dafa8344c8c018e346dd331a7782081a896239Sean Callanan m_sel_registerName(NULL), 108dbeb3e1e038a75f00fd565203839020e1d00a7c6Stephen Wilson m_error_stream(error_stream), 109696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan m_result_store(NULL), 110696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan m_result_is_pointer(false), 1114a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan m_reloc_placeholder(NULL), 1124a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan m_entry_instruction_finder (FindEntryInstruction) 1135cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan{ 1145cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan} 1155cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 116771131d04344e57abb340699f54dce77a511bc71Sean Callanan/* Handy utility functions used at several places in the code */ 117a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 118a48fe1637ec6a381e500633c087f76662e364c20Sean Callananstatic std::string 1193c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg ClaytonPrintValue(const Value *value, bool truncate = false) 120a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan{ 121a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan std::string s; 1226f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham if (value) 1236f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham { 1246f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham raw_string_ostream rso(s); 1256f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham value->print(rso); 1266f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham rso.flush(); 1276f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham if (truncate) 1286f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham s.resize(s.length() - 1); 1296f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham } 130a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan return s; 131a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan} 132a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 133771131d04344e57abb340699f54dce77a511bc71Sean Callananstatic std::string 13452f792329be5db8e38961350589e97e8f2823acdGreg ClaytonPrintType(const llvm::Type *type, bool truncate = false) 135771131d04344e57abb340699f54dce77a511bc71Sean Callanan{ 136771131d04344e57abb340699f54dce77a511bc71Sean Callanan std::string s; 137771131d04344e57abb340699f54dce77a511bc71Sean Callanan raw_string_ostream rso(s); 1383c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton type->print(rso); 139771131d04344e57abb340699f54dce77a511bc71Sean Callanan rso.flush(); 140771131d04344e57abb340699f54dce77a511bc71Sean Callanan if (truncate) 141771131d04344e57abb340699f54dce77a511bc71Sean Callanan s.resize(s.length() - 1); 142771131d04344e57abb340699f54dce77a511bc71Sean Callanan return s; 143771131d04344e57abb340699f54dce77a511bc71Sean Callanan} 144771131d04344e57abb340699f54dce77a511bc71Sean Callanan 1455cf4a1ca412654c3f912e2b3cea931fb814f322fSean CallananIRForTarget::~IRForTarget() 1465cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan{ 1475cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan} 1485cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 149c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callananbool 150c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) 151c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan{ 152c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan llvm_function.setLinkage(GlobalValue::ExternalLinkage); 153c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 154fecc09c3709262515add87254cb973ce5175f17bSean Callanan std::string name = llvm_function.getName().str(); 155c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 156c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan return true; 157c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan} 158c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 15982b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callananbool 1605c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean CallananIRForTarget::GetFunctionAddress (llvm::Function *fun, 1615c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan uint64_t &fun_addr, 1625c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan lldb_private::ConstString &name, 1635c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan Constant **&value_ptr) 1645c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan{ 165952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1665c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 1675c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan fun_addr = LLDB_INVALID_ADDRESS; 1685c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan name.Clear(); 1695c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan value_ptr = NULL; 1705c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 1715c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (fun->isIntrinsic()) 1725c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan { 1735c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan Intrinsic::ID intrinsic_id = (Intrinsic::ID)fun->getIntrinsicID(); 1745c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 1755c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan switch (intrinsic_id) 1765c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan { 1775c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan default: 1785c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (log) 1795c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan log->Printf("Unresolved intrinsic \"%s\"", Intrinsic::getName(intrinsic_id).c_str()); 1805c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 1815c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (m_error_stream) 1825c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Call to unhandled compiler intrinsic '%s'\n", Intrinsic::getName(intrinsic_id).c_str()); 1835c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 1845c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan return false; 1855c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan case Intrinsic::memcpy: 1865c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan { 1875c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan static lldb_private::ConstString g_memcpy_str ("memcpy"); 1885c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan name = g_memcpy_str; 1895c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan } 1905c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan break; 1917befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan case Intrinsic::memset: 1927befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan { 1937befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan static lldb_private::ConstString g_memset_str ("memset"); 1947befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan name = g_memset_str; 1957befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan } 1967befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan break; 1975c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan } 1985c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 1995c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (log && name) 2005c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan log->Printf("Resolved intrinsic name \"%s\"", name.GetCString()); 2015c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan } 2025c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan else 2035c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan { 2045c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan name.SetCStringWithLength (fun->getName().data(), fun->getName().size()); 2055c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan } 2065c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 2075c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan // Find the address of the function. 2085c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 2095c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan clang::NamedDecl *fun_decl = DeclForGlobal (fun); 2105c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 2115c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (fun_decl) 2125c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan { 213c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan if (!m_decl_map->GetFunctionInfo (fun_decl, fun_addr)) 2145c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan { 2159b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton lldb_private::ConstString altnernate_name; 216f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton bool found_it = m_decl_map->GetFunctionAddress (name, fun_addr); 217f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton if (!found_it) 218f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton { 219f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton // Check for an alternate mangling for "std::basic_string<char>" 220f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton // that is part of the itanium C++ name mangling scheme 221f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton const char *name_cstr = name.GetCString(); 2226f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham if (name_cstr && strncmp(name_cstr, "_ZNKSbIcE", strlen("_ZNKSbIcE")) == 0) 223f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton { 224f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton std::string alternate_mangling("_ZNKSs"); 225f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton alternate_mangling.append (name_cstr + strlen("_ZNKSbIcE")); 2269b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton altnernate_name.SetCString(alternate_mangling.c_str()); 2279b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton found_it = m_decl_map->GetFunctionAddress (altnernate_name, fun_addr); 228f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton } 229f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton } 2305c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 231f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton if (!found_it) 2325c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan { 2339b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton lldb_private::Mangled mangled_name(name); 2349b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton lldb_private::Mangled alt_mangled_name(altnernate_name); 2355c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (log) 236f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton { 2379b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton if (alt_mangled_name) 2389b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton log->Printf("Function \"%s\" (alternate name \"%s\") has no address", 2399b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton mangled_name.GetName().GetCString(), 2409b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton alt_mangled_name.GetName().GetCString()); 241f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton else 2429b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton log->Printf("Function \"%s\" had no address", 2439b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton mangled_name.GetName().GetCString()); 244f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton } 2455c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 2465c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (m_error_stream) 247f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton { 2489b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton if (alt_mangled_name) 2499b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton m_error_stream->Printf("error: call to a function '%s' (alternate name '%s') that is not present in the target\n", 2509b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton mangled_name.GetName().GetCString(), 2519b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton alt_mangled_name.GetName().GetCString()); 252d9865518043af19069e10a5c56ed68551c7891adGreg Clayton else if (mangled_name.GetMangledName()) 253d9865518043af19069e10a5c56ed68551c7891adGreg Clayton m_error_stream->Printf("error: call to a function '%s' ('%s') that is not present in the target\n", 254d9865518043af19069e10a5c56ed68551c7891adGreg Clayton mangled_name.GetName().GetCString(), 255d9865518043af19069e10a5c56ed68551c7891adGreg Clayton mangled_name.GetMangledName().GetCString()); 256f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton else 2579b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton m_error_stream->Printf("error: call to a function '%s' that is not present in the target\n", 2589b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton mangled_name.GetName().GetCString()); 259f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton } 2605c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan return false; 2615c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan } 2625c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan } 2635c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan } 2645c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan else 2655c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan { 2665c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (!m_decl_map->GetFunctionAddress (name, fun_addr)) 2675c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan { 2685c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (log) 2695c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan log->Printf ("Metadataless function \"%s\" had no address", name.GetCString()); 2705c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 2715c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (m_error_stream) 2725c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan m_error_stream->Printf("Error [IRForTarget]: Call to a symbol-only function '%s' that is not present in the target\n", name.GetCString()); 2735c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 2745c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan return false; 2755c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan } 2765c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan } 2775c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 2785c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (log) 2795f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), fun_addr); 2805c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 2815c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan return true; 2825c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan} 2835c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 2845c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callananllvm::Constant * 2855c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean CallananIRForTarget::BuildFunctionPointer (llvm::Type *type, 2865c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan uint64_t ptr) 2875c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan{ 2885c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(), 2894fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32); 2905c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan PointerType *fun_ptr_ty = PointerType::getUnqual(type); 2915c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan Constant *fun_addr_int = ConstantInt::get(intptr_ty, ptr, false); 2925c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty); 2935c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan} 2945c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 295715f6b0843d0099761464f05e4f899cb69e63320Sean Callananvoid 296715f6b0843d0099761464f05e4f899cb69e63320Sean CallananIRForTarget::RegisterFunctionMetadata(LLVMContext &context, 297715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan llvm::Value *function_ptr, 298715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan const char *name) 299715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan{ 300715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan for (Value::use_iterator i = function_ptr->use_begin(), e = function_ptr->use_end(); 301715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan i != e; 302715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan ++i) 303715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan { 304715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan Value *user = *i; 305715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan 306715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan if (Instruction *user_inst = dyn_cast<Instruction>(user)) 307715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan { 308804930f1d6f0b79f837acadf76b9d7b75cd412cdDaniel Malea MDString* md_name = MDString::get(context, StringRef(name)); 309804930f1d6f0b79f837acadf76b9d7b75cd412cdDaniel Malea 310804930f1d6f0b79f837acadf76b9d7b75cd412cdDaniel Malea MDNode *metadata = MDNode::get(context, md_name); 311804930f1d6f0b79f837acadf76b9d7b75cd412cdDaniel Malea 312715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan user_inst->setMetadata("lldb.call.realName", metadata); 313715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan } 314715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan else 315715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan { 316715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan RegisterFunctionMetadata (context, user, name); 317715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan } 318715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan } 319715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan} 320715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan 3215c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callananbool 3224a20587f56a05955ea94f650cb39245a092b0c69Sean CallananIRForTarget::ResolveFunctionPointers(llvm::Module &llvm_module) 3235c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan{ 324952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 3255c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 3265c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan for (llvm::Module::iterator fi = llvm_module.begin(); 3275c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan fi != llvm_module.end(); 3285c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan ++fi) 3295c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan { 3305c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan Function *fun = fi; 3315c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 3325c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan bool is_decl = fun->isDeclaration(); 3335c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 3345c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (log) 335fecc09c3709262515add87254cb973ce5175f17bSean Callanan log->Printf("Examining %s function %s", (is_decl ? "declaration" : "non-declaration"), fun->getName().str().c_str()); 3365c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 3375c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (!is_decl) 3385c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan continue; 3395c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 3405c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (fun->hasNUses(0)) 3415c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan continue; // ignore 3425c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 3435c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan uint64_t addr = LLDB_INVALID_ADDRESS; 3445c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan lldb_private::ConstString name; 3455c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan Constant **value_ptr = NULL; 3465c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 3475c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (!GetFunctionAddress(fun, 3485c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan addr, 3495c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan name, 3505c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan value_ptr)) 3515c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan return false; // GetFunctionAddress reports its own errors 3525c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 3535c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan Constant *value = BuildFunctionPointer(fun->getFunctionType(), addr); 3545c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 355715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan RegisterFunctionMetadata (llvm_module.getContext(), fun, name.AsCString()); 356715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan 3575c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (value_ptr) 3585c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan *value_ptr = value; 359eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit 360eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit // If we are replacing a function with the nobuiltin attribute, it may 361eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit // be called with the builtin attribute on call sites. Remove any such 362eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit // attributes since it's illegal to have a builtin call to something 363eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit // other than a nobuiltin function. 364eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit if (fun->hasFnAttribute(Attribute::NoBuiltin)) { 365eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit Attribute builtin = Attribute::get(fun->getContext(), Attribute::Builtin); 366eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit 367eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit for (auto u = fun->use_begin(), e = fun->use_end(); u != e; ++u) { 368eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit if (auto call = dyn_cast<CallInst>(*u)) { 369eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit call->removeAttribute(AttributeSet::FunctionIndex, builtin); 370eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit } 371eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit } 372eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit } 3735c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 3745c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan fun->replaceAllUsesWith(value); 3755c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan } 3765c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 3775c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan return true; 3785c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan} 3795c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 38047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan 381696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callananclang::NamedDecl * 38247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean CallananIRForTarget::DeclForGlobal (const GlobalValue *global_val, Module *module) 383696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan{ 38447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan NamedMDNode *named_metadata = module->getNamedMetadata("clang.global.decl.ptrs"); 385696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan 386696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan if (!named_metadata) 387696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan return NULL; 388696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan 389696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan unsigned num_nodes = named_metadata->getNumOperands(); 390696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan unsigned node_index; 391696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan 392696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan for (node_index = 0; 393696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan node_index < num_nodes; 394696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan ++node_index) 395696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan { 396696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan MDNode *metadata_node = named_metadata->getOperand(node_index); 397696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan 398696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan if (!metadata_node) 399696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan return NULL; 400696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan 401696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan if (metadata_node->getNumOperands() != 2) 402696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan continue; 403696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan 404696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan if (metadata_node->getOperand(0) != global_val) 405696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan continue; 406696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan 407696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan ConstantInt *constant_int = dyn_cast<ConstantInt>(metadata_node->getOperand(1)); 408696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan 409696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan if (!constant_int) 410696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan return NULL; 411696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan 412696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan uintptr_t ptr = constant_int->getZExtValue(); 413696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan 414696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan return reinterpret_cast<clang::NamedDecl *>(ptr); 415696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan } 416696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan 417696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan return NULL; 418696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan} 419696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan 42047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callananclang::NamedDecl * 42147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean CallananIRForTarget::DeclForGlobal (GlobalValue *global_val) 42247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan{ 42347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan return DeclForGlobal(global_val, m_module); 42447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan} 42547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan 42605a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callananbool 427c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::CreateResultVariable (llvm::Function &llvm_function) 42882b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan{ 429952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 43082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 431e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan if (!m_resolve_vars) 432e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan return true; 433e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 434e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan // Find the result variable. If it doesn't exist, we can give up right here. 43582b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 436c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable(); 4373c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 4389b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan std::string result_name_str; 4393c9c5eb466869ede185e879d14a47335fb43194dSean Callanan const char *result_name = NULL; 4403c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 4413c9c5eb466869ede185e879d14a47335fb43194dSean Callanan for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end(); 4423c9c5eb466869ede185e879d14a47335fb43194dSean Callanan vi != ve; 4433c9c5eb466869ede185e879d14a47335fb43194dSean Callanan ++vi) 4443c9c5eb466869ede185e879d14a47335fb43194dSean Callanan { 4459b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan result_name_str = vi->first().str(); 4469b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan const char *value_name = result_name_str.c_str(); 4479b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 4489b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan if (strstr(value_name, "$__lldb_expr_result_ptr") && 449880b2ca643dd4a03a1a7b8113239cfa6006ed382Sean Callanan strncmp(value_name, "_ZGV", 4)) 4506a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan { 4519b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan result_name = value_name; 4526a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan m_result_is_pointer = true; 4536a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan break; 4546a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan } 4556a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan 4569b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan if (strstr(value_name, "$__lldb_expr_result") && 457880b2ca643dd4a03a1a7b8113239cfa6006ed382Sean Callanan strncmp(value_name, "_ZGV", 4)) 458c04743d68391ae090e6ebada32b6fb87cdc03d30Sean Callanan { 4599b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan result_name = value_name; 4606a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan m_result_is_pointer = false; 461c04743d68391ae090e6ebada32b6fb87cdc03d30Sean Callanan break; 462c04743d68391ae090e6ebada32b6fb87cdc03d30Sean Callanan } 4633c9c5eb466869ede185e879d14a47335fb43194dSean Callanan } 4643c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 4653c9c5eb466869ede185e879d14a47335fb43194dSean Callanan if (!result_name) 46682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan { 46782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan if (log) 46882b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan log->PutCString("Couldn't find result variable"); 4693c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 470e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan return true; 47182b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan } 4723c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 473c04743d68391ae090e6ebada32b6fb87cdc03d30Sean Callanan if (log) 474b5037af312160b2f396aad579e45619af3126e4aGreg Clayton log->Printf("Result name: \"%s\"", result_name); 475c04743d68391ae090e6ebada32b6fb87cdc03d30Sean Callanan 476c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan Value *result_value = m_module->getNamedValue(result_name); 4773c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 4783c9c5eb466869ede185e879d14a47335fb43194dSean Callanan if (!result_value) 4793c9c5eb466869ede185e879d14a47335fb43194dSean Callanan { 4803c9c5eb466869ede185e879d14a47335fb43194dSean Callanan if (log) 4813c9c5eb466869ede185e879d14a47335fb43194dSean Callanan log->PutCString("Result variable had no data"); 4826a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan 48397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 48497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Result variable's name (%s) exists, but not its definition\n", result_name); 48597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 4863c9c5eb466869ede185e879d14a47335fb43194dSean Callanan return false; 4873c9c5eb466869ede185e879d14a47335fb43194dSean Callanan } 488e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 48982b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan if (log) 490b5037af312160b2f396aad579e45619af3126e4aGreg Clayton log->Printf("Found result in the IR: \"%s\"", PrintValue(result_value, false).c_str()); 49182b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 49282b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value); 49382b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 49482b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan if (!result_global) 49582b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan { 49682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan if (log) 49782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan log->PutCString("Result variable isn't a GlobalVariable"); 49897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 49997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 50097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) is defined, but is not a global variable\n", result_name); 50197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 50282b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan return false; 50382b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan } 50482b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 505c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan clang::NamedDecl *result_decl = DeclForGlobal (result_global); 506696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan if (!result_decl) 50782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan { 50882b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan if (log) 509696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan log->PutCString("Result variable doesn't have a corresponding Decl"); 51082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 51197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 512696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) does not have a corresponding Clang entity\n", result_name); 51397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 51482b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan return false; 51582b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan } 51682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 517696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan if (log) 51882b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan { 519696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan std::string decl_desc_str; 520696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan raw_string_ostream decl_desc_stream(decl_desc_str); 521696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan result_decl->print(decl_desc_stream); 522696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan decl_desc_stream.flush(); 52382b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 524696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str()); 52582b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan } 52682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 527696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl); 528696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan if (!result_var) 52982b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan { 53082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan if (log) 531696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan log->PutCString("Result variable Decl isn't a VarDecl"); 53297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 53397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 534696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s)'s corresponding Clang entity isn't a variable\n", result_name); 53597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 53682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan return false; 53782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan } 53882b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 53982b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan // Get the next available result name from m_decl_map and create the persistent 54082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan // variable for it 54147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan 542696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan // If the result is an Lvalue, it is emitted as a pointer; see 543696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan // ASTResultSynthesizer::SynthesizeBodyResult. 5446a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan if (m_result_is_pointer) 5456a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan { 546696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan clang::QualType pointer_qual_type = result_var->getType(); 547d5b3c351ea23e8e36d47056e50b1df773ae9050aSean Callanan const clang::Type *pointer_type = pointer_qual_type.getTypePtr(); 5484fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan 54921f2e192079b6aa9ddd2d25283e19abdb38eeeb5Sean Callanan const clang::PointerType *pointer_pointertype = pointer_type->getAs<clang::PointerType>(); 55021f2e192079b6aa9ddd2d25283e19abdb38eeeb5Sean Callanan const clang::ObjCObjectPointerType *pointer_objcobjpointertype = pointer_type->getAs<clang::ObjCObjectPointerType>(); 5516a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan 5524fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan if (pointer_pointertype) 5534fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan { 5544fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan clang::QualType element_qual_type = pointer_pointertype->getPointeeType(); 5554fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan 5564fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(), 5574fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan &result_decl->getASTContext()); 5584fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan } 5594fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan else if (pointer_objcobjpointertype) 5604fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan { 5614fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan clang::QualType element_qual_type = clang::QualType(pointer_objcobjpointertype->getObjectType(), 0); 5624fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan 5634fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(), 5644fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan &result_decl->getASTContext()); 5654fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan } 5664fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan else 5676a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan { 5686a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan if (log) 5696a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan log->PutCString("Expected result to have pointer type, but it did not"); 57097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 57197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 57297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Lvalue result (%s) is not a pointer variable\n", result_name); 57397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 5746a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan return false; 5756a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan } 5766a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan } 5776a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan else 5786a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan { 57947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan m_result_type = lldb_private::TypeFromParser(result_var->getType().getAsOpaquePtr(), 5805a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan &result_decl->getASTContext()); 5815a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan } 5825a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan 58352f792329be5db8e38961350589e97e8f2823acdGreg Clayton if (m_result_type.GetBitSize() == 0) 5845a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan { 5855a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan lldb_private::StreamString type_desc_stream; 5865a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan m_result_type.DumpTypeDescription(&type_desc_stream); 5875a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan 5885a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan if (log) 5895a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan log->Printf("Result type has size 0"); 5905a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan 5915a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan if (m_error_stream) 592b6f9ee73d2abe30242e37e6e0436b4998c35c888Sean Callanan m_error_stream->Printf("Error [IRForTarget]: Size of result type '%s' couldn't be determined\n", 5935a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan type_desc_stream.GetData()); 594b6f9ee73d2abe30242e37e6e0436b4998c35c888Sean Callanan return false; 5956a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan } 5966a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan 597696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan if (log) 598696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan { 599696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan lldb_private::StreamString type_desc_stream; 60047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan m_result_type.DumpTypeDescription(&type_desc_stream); 601696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan 6025a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData()); 603696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan } 604696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan 6050f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_result_name = lldb_private::ConstString("$RESULT_NAME"); 60682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 60782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan if (log) 608fe6dc6e241c52822710380cec0931351a1d7b2d3Greg Clayton log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64, 6095a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan m_result_name.GetCString(), 61052f792329be5db8e38961350589e97e8f2823acdGreg Clayton m_result_type.GetByteSize()); 61182b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 61282b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan // Construct a new result global and set up its metadata 61382b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 614c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan GlobalVariable *new_result_global = new GlobalVariable((*m_module), 61582b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan result_global->getType()->getElementType(), 61682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan false, /* not constant */ 61782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan GlobalValue::ExternalLinkage, 61882b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan NULL, /* no initializer */ 6196a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan m_result_name.GetCString ()); 62082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 62182b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan // It's too late in compilation to create a new VarDecl for this, but we don't 62282b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan // need to. We point the metadata at the old VarDecl. This creates an odd 62382b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan // anomaly: a variable with a Value whose name is something like $0 and a 6248de27c761a22187ef63fb60000894be163e7285fGreg Clayton // Decl whose name is $__lldb_expr_result. This condition is handled in 62582b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is 62682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan // fixed up. 62782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 628c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ConstantInt *new_constant_int = ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()), 629696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan reinterpret_cast<uint64_t>(result_decl), 63082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan false); 63182b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 63282b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan llvm::Value* values[2]; 63382b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan values[0] = new_result_global; 63482b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan values[1] = new_constant_int; 63582b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 6360de254aaec7d6766379191e5397ec2294042c5d7Sean Callanan ArrayRef<Value*> value_ref(values, 2); 6370de254aaec7d6766379191e5397ec2294042c5d7Sean Callanan 638c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref); 639c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan NamedMDNode *named_metadata = m_module->getNamedMetadata("clang.global.decl.ptrs"); 64082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan named_metadata->addOperand(persistent_global_md); 64182b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 64282b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan if (log) 643b5037af312160b2f396aad579e45619af3126e4aGreg Clayton log->Printf("Replacing \"%s\" with \"%s\"", 6442e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan PrintValue(result_global).c_str(), 64582b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan PrintValue(new_result_global).c_str()); 6462e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan 6472e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan if (result_global->hasNUses(0)) 6482e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan { 6492e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan // We need to synthesize a store for this variable, because otherwise 6502e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan // there's nothing to put into its equivalent persistent variable. 6512e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan 6528de27c761a22187ef63fb60000894be163e7285fGreg Clayton BasicBlock &entry_block(llvm_function.getEntryBlock()); 6532e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg()); 6542e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan 6552e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan if (!first_entry_instruction) 6562e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan return false; 6572e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan 6582e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan if (!result_global->hasInitializer()) 6592e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan { 6602e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan if (log) 6612e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan log->Printf("Couldn't find initializer for unused variable"); 66297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 66397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 66497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) has no writes and no initializer\n", result_name); 66597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 6662e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan return false; 6672e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan } 6682e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan 6692e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan Constant *initializer = result_global->getInitializer(); 67005a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan 6712c344ca60ed19b1284633f795c4dc52245bd8f67Greg Clayton StoreInst *synthesized_store = new StoreInst(initializer, 6722c344ca60ed19b1284633f795c4dc52245bd8f67Greg Clayton new_result_global, 6732c344ca60ed19b1284633f795c4dc52245bd8f67Greg Clayton first_entry_instruction); 6742e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan 6752e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan if (log) 676b5037af312160b2f396aad579e45619af3126e4aGreg Clayton log->Printf("Synthesized result store \"%s\"\n", PrintValue(synthesized_store).c_str()); 6772e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan } 6782e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan else 6792e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan { 6802e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan result_global->replaceAllUsesWith(new_result_global); 6812e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan } 68282b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 6830f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (!m_decl_map->AddPersistentVariable(result_decl, 6840f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_result_name, 6850f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_result_type, 6860f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan true, 6870f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_result_is_pointer)) 6880f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan return false; 6890f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 69082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan result_global->eraseFromParent(); 69182b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 69282b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan return true; 69382b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan} 69482b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 69558021ccb9087a5199bb6af0fbdb9ab429d4f9acaJohnny Chen#if 0 696952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Claytonstatic void DebugUsers(Log *log, Value *value, uint8_t depth) 6976ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan{ 6986ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (!depth) 6996ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return; 7006ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 7016ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan depth--; 7026ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 70358021ccb9087a5199bb6af0fbdb9ab429d4f9acaJohnny Chen if (log) 70458021ccb9087a5199bb6af0fbdb9ab429d4f9acaJohnny Chen log->Printf(" <Begin %d users>", value->getNumUses()); 7056ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 7063c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton for (Value::use_iterator ui = value->use_begin(), ue = value->use_end(); 7076ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan ui != ue; 7086ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan ++ui) 7096ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 71058021ccb9087a5199bb6af0fbdb9ab429d4f9acaJohnny Chen if (log) 71158021ccb9087a5199bb6af0fbdb9ab429d4f9acaJohnny Chen log->Printf(" <Use %p> %s", *ui, PrintValue(*ui).c_str()); 7126ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan DebugUsers(log, *ui, depth); 7136ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 7146ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 71558021ccb9087a5199bb6af0fbdb9ab429d4f9acaJohnny Chen if (log) 71658021ccb9087a5199bb6af0fbdb9ab429d4f9acaJohnny Chen log->Printf(" <End uses>"); 7176ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan} 71858021ccb9087a5199bb6af0fbdb9ab429d4f9acaJohnny Chen#endif 7196ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 7204a20587f56a05955ea94f650cb39245a092b0c69Sean Callananbool 721c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::RewriteObjCConstString (llvm::GlobalVariable *ns_str, 7224a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan llvm::GlobalVariable *cstr) 7236ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan{ 724952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 7256ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 7269b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan Type *ns_str_ty = ns_str->getType(); 727c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 7289b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext()); 7299b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(), 7304fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan (m_module->getPointerSize() 731ce6335881f330581f641ef808602cac192664adfMicah Villmow == Module::Pointer64) ? 64 : 32); 7329b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan Type *i32_ty = Type::getInt32Ty(m_module->getContext()); 7339b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan Type *i8_ty = Type::getInt8Ty(m_module->getContext()); 7346ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 7356ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (!m_CFStringCreateWithBytes) 7366ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 7376ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan lldb::addr_t CFStringCreateWithBytes_addr; 7386ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 7396ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan static lldb_private::ConstString g_CFStringCreateWithBytes_str ("CFStringCreateWithBytes"); 7406ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 7416ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (!m_decl_map->GetFunctionAddress (g_CFStringCreateWithBytes_str, CFStringCreateWithBytes_addr)) 7426ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 7436ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 7446ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan log->PutCString("Couldn't find CFStringCreateWithBytes in the target"); 7456ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 74697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 74797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Error [IRForTarget]: Rewriting an Objective-C constant string requires CFStringCreateWithBytes\n"); 74897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 7496ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return false; 7506ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 7516ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 7526ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 7535f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64, CFStringCreateWithBytes_addr); 7546ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 7556ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // Build the function type: 7566ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // 7576ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // CFStringRef CFStringCreateWithBytes ( 7586ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // CFAllocatorRef alloc, 7596ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // const UInt8 *bytes, 7606ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // CFIndex numBytes, 7616ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // CFStringEncoding encoding, 7626ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // Boolean isExternalRepresentation 7636ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // ); 7646ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // 7656ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // We make the following substitutions: 7666ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // 7676ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // CFStringRef -> i8* 7686ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // CFAllocatorRef -> i8* 7696ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // UInt8 * -> i8* 7706ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its pointer size for now) 7716ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // CFStringEncoding -> i32 7726ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // Boolean -> i8 7736ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 7749b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan Type *arg_type_array[5]; 7759b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 7769b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan arg_type_array[0] = i8_ptr_ty; 7779b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan arg_type_array[1] = i8_ptr_ty; 7789b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan arg_type_array[2] = intptr_ty; 7799b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan arg_type_array[3] = i32_ty; 7809b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan arg_type_array[4] = i8_ty; 7819b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 7829b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5); 7839b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 784c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan llvm::Type *CFSCWB_ty = FunctionType::get(ns_str_ty, CFSCWB_arg_types, false); 7856ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 7866ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // Build the constant containing the pointer to the function 7876ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty); 7886ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan Constant *CFSCWB_addr_int = ConstantInt::get(intptr_ty, CFStringCreateWithBytes_addr, false); 7896ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan m_CFStringCreateWithBytes = ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty); 7906ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 7916ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 79239a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan ConstantDataSequential *string_array = NULL; 7930ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan 7940ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan if (cstr) 79539a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer()); 7969b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 7976ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty); 7980ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan Constant *bytes_arg = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty) : Constant::getNullValue(i8_ptr_ty); 79939a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan Constant *numBytes_arg = ConstantInt::get(intptr_ty, cstr ? string_array->getNumElements() - 1 : 0, false); 8006ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan Constant *encoding_arg = ConstantInt::get(i32_ty, 0x0600, false); /* 0x0600 is kCFStringEncodingASCII */ 8016ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan Constant *isExternal_arg = ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */ 8026ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 8039b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan Value *argument_array[5]; 8049b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 8059b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan argument_array[0] = alloc_arg; 8069b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan argument_array[1] = bytes_arg; 8079b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan argument_array[2] = numBytes_arg; 8089b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan argument_array[3] = encoding_arg; 8099b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan argument_array[4] = isExternal_arg; 8109b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 8119b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan ArrayRef <Value *> CFSCWB_arguments(argument_array, 5); 8126ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 8134a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan FunctionValueCache CFSCWB_Caller ([this, &CFSCWB_arguments] (llvm::Function *function)->llvm::Value * { 8144a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return CallInst::Create(m_CFStringCreateWithBytes, 8154a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan CFSCWB_arguments, 8164a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan "CFStringCreateWithBytes", 8174a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan llvm::cast<Instruction>(m_entry_instruction_finder.GetValue(function))); 8184a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan }); 819ae71e30fe0c0e0d5fd1bf9062274798060df674cSean Callanan 8204a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (!UnfoldConstant(ns_str, CFSCWB_Caller, m_entry_instruction_finder)) 8216ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 8226ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 8236ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan log->PutCString("Couldn't replace the NSString with the result of the call"); 8246ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 82597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 82697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Error [IRForTarget]: Couldn't replace an Objective-C constant string with a dynamic string\n"); 82797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 8286ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return false; 8296ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 8306ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 8313c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton ns_str->eraseFromParent(); 8326ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 8336ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return true; 8346ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan} 8356ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 8366ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callananbool 8374a20587f56a05955ea94f650cb39245a092b0c69Sean CallananIRForTarget::RewriteObjCConstStrings() 8386ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan{ 839952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 8406ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 841c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable(); 8426ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 8436ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end(); 8446ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan vi != ve; 8456ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan ++vi) 8466ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 8479b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan std::string value_name = vi->first().str(); 8489b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan const char *value_name_cstr = value_name.c_str(); 8499b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 8509b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan if (strstr(value_name_cstr, "_unnamed_cfstring_")) 8516ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 8526ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan Value *nsstring_value = vi->second; 8536ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 8546ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan GlobalVariable *nsstring_global = dyn_cast<GlobalVariable>(nsstring_value); 8556ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 8566ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (!nsstring_global) 8576ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 8586ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 8596ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan log->PutCString("NSString variable is not a GlobalVariable"); 86097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 86197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 86297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string is not a global variable\n"); 86397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 8646ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return false; 8656ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 8666ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 8676ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (!nsstring_global->hasInitializer()) 8686ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 8696ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 8706ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan log->PutCString("NSString variable does not have an initializer"); 87197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 87297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 87397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string does not have an initializer\n"); 87497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 8756ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return false; 8766ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 8776ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 8786ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan ConstantStruct *nsstring_struct = dyn_cast<ConstantStruct>(nsstring_global->getInitializer()); 8796ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 8806ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (!nsstring_struct) 8816ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 8826ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 8836ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan log->PutCString("NSString variable's initializer is not a ConstantStruct"); 88497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 88597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 88697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string is not a structure constant\n"); 88797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 8886ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return false; 8896ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 8906ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 8916ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // We expect the following structure: 8926ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // 8936ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // struct { 8946ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // int *isa; 8956ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // int flags; 8966ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // char *str; 8976ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // long length; 8986ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // }; 8996ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 9006ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (nsstring_struct->getNumOperands() != 4) 9016ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 9026ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 9036ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan log->Printf("NSString variable's initializer structure has an unexpected number of members. Should be 4, is %d", nsstring_struct->getNumOperands()); 90497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 90597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 90697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: The struct for an Objective-C constant string is not as expected\n"); 90797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 9086ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return false; 9096ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 9106ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 9116ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan Constant *nsstring_member = nsstring_struct->getOperand(2); 9126ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 9136ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (!nsstring_member) 9146ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 9156ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 9166ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan log->PutCString("NSString initializer's str element was empty"); 91797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 91897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 91997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string does not have a string initializer\n"); 92097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 9216ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return false; 9226ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 9236ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 9246ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member); 9256ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 9266ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (!nsstring_expr) 9276ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 9286ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 9296ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan log->PutCString("NSString initializer's str element is not a ConstantExpr"); 93097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 93197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 93297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer is not constant\n"); 93397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 9346ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return false; 9356ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 9366ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 9376ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (nsstring_expr->getOpcode() != Instruction::GetElementPtr) 9386ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 9396ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 9406ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan log->Printf("NSString initializer's str element is not a GetElementPtr expression, it's a %s", nsstring_expr->getOpcodeName()); 94197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 94297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 94397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer is not an array\n"); 94497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 9456ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return false; 9466ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 9476ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 9486ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan Constant *nsstring_cstr = nsstring_expr->getOperand(0); 9496ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 9506ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan GlobalVariable *cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr); 9516ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 9526ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (!cstr_global) 9536ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 9546ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 9556ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan log->PutCString("NSString initializer's str element is not a GlobalVariable"); 95697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 95797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 95897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to a global\n"); 95965e2aeef29f572ead90029e21b5bc3fec5c01afeSean Callanan 9606ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return false; 9616ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 9626ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 9636ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (!cstr_global->hasInitializer()) 9646ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 9656ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 9666ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan log->PutCString("NSString initializer's str element does not have an initializer"); 96797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 96897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 96997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to initialized data\n"); 97097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 9716ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return false; 9726ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 9730ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan 9740ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan /* 9756ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (!cstr_array) 9766ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 9776ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 9786ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan log->PutCString("NSString initializer's str element is not a ConstantArray"); 97997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 98097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 98197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to an array\n"); 98297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 9836ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return false; 9846ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 9856ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 9866ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (!cstr_array->isCString()) 9876ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 9886ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 9896ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan log->PutCString("NSString initializer's str element is not a C string array"); 99097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 99197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 99297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to a C string\n"); 99397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 9946ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return false; 9956ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 9960ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan */ 9970ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan 99839a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan ConstantDataArray *cstr_array = dyn_cast<ConstantDataArray>(cstr_global->getInitializer()); 9996ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 10006ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 10010ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan { 10020ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan if (cstr_array) 100339a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan log->Printf("Found NSString constant %s, which contains \"%s\"", value_name_cstr, cstr_array->getAsString().str().c_str()); 10040ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan else 10059b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan log->Printf("Found NSString constant %s, which contains \"\"", value_name_cstr); 10060ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan } 10070ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan 10080ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan if (!cstr_array) 10090ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan cstr_global = NULL; 10106ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 10114a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (!RewriteObjCConstString(nsstring_global, cstr_global)) 101297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan { 10136ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 10146ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan log->PutCString("Error rewriting the constant string"); 101597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 101697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan // We don't print an error message here because RewriteObjCConstString has done so for us. 101797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 10186ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return false; 10196ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 10206ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 10216ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 10226ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 10236ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end(); 10246ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan vi != ve; 10256ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan ++vi) 10266ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 10279b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan std::string value_name = vi->first().str(); 10289b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan const char *value_name_cstr = value_name.c_str(); 10299b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 10309b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan if (!strcmp(value_name_cstr, "__CFConstantStringClassReference")) 10316ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 10326ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan GlobalVariable *gv = dyn_cast<GlobalVariable>(vi->second); 10336ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 10346ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (!gv) 10356ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan { 10366ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (log) 10376ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan log->PutCString("__CFConstantStringClassReference is not a global variable"); 103897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 103997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 104097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Found a CFConstantStringClassReference, but it is not a global object\n"); 104197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 10426ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return false; 10436ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 10446ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 10456ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan gv->eraseFromParent(); 10466ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 10476ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan break; 10486ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 10496ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan } 10506ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 10516ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return true; 10526ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan} 10536ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 10543c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Claytonstatic bool IsObjCSelectorRef (Value *value) 1055f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan{ 10563c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value); 1057f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 10583c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton if (!global_variable || !global_variable->hasName() || !global_variable->getName().startswith("\01L_OBJC_SELECTOR_REFERENCES_")) 1059f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan return false; 1060f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1061f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan return true; 1062f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan} 1063f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 106497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan// This function does not report errors; its callers are responsible. 1065f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callananbool 1066c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::RewriteObjCSelector (Instruction* selector_load) 1067f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan{ 1068952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1069f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1070f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan LoadInst *load = dyn_cast<LoadInst>(selector_load); 1071f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1072f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan if (!load) 1073f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan return false; 1074f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1075f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan // Unpack the message name from the selector. In LLVM IR, an objc_msgSend gets represented as 1076f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan // 1077f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan // %tmp = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_" ; <i8*> 1078f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan // %call = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; <i8*> 1079f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan // 1080f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan // where %obj is the object pointer and %tmp is the selector. 1081f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan // 10823c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton // @"\01L_OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_". 10833c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string. 1084f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1085f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr) and get the string from its target 1086f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1087f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan GlobalVariable *_objc_selector_references_ = dyn_cast<GlobalVariable>(load->getPointerOperand()); 1088f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1089f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan if (!_objc_selector_references_ || !_objc_selector_references_->hasInitializer()) 1090f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan return false; 1091f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1092f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan Constant *osr_initializer = _objc_selector_references_->getInitializer(); 1093f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1094f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer); 1095f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1096f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan if (!osr_initializer_expr || osr_initializer_expr->getOpcode() != Instruction::GetElementPtr) 1097f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan return false; 1098f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1099f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan Value *osr_initializer_base = osr_initializer_expr->getOperand(0); 1100f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1101f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan if (!osr_initializer_base) 1102f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan return false; 1103f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1104f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan // Find the string's initializer (a ConstantArray) and get the string from it 1105f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1106f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan GlobalVariable *_objc_meth_var_name_ = dyn_cast<GlobalVariable>(osr_initializer_base); 1107f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1108f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer()) 1109f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan return false; 1110f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1111f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan Constant *omvn_initializer = _objc_meth_var_name_->getInitializer(); 1112f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 111339a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan ConstantDataArray *omvn_initializer_array = dyn_cast<ConstantDataArray>(omvn_initializer); 1114f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1115f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan if (!omvn_initializer_array->isString()) 1116f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan return false; 1117f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1118f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan std::string omvn_initializer_string = omvn_initializer_array->getAsString(); 1119f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1120f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan if (log) 1121b5037af312160b2f396aad579e45619af3126e4aGreg Clayton log->Printf("Found Objective-C selector reference \"%s\"", omvn_initializer_string.c_str()); 1122f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1123f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan // Construct a call to sel_registerName 1124f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1125f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan if (!m_sel_registerName) 1126f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan { 1127b5037af312160b2f396aad579e45619af3126e4aGreg Clayton lldb::addr_t sel_registerName_addr; 1128f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 11298de27c761a22187ef63fb60000894be163e7285fGreg Clayton static lldb_private::ConstString g_sel_registerName_str ("sel_registerName"); 1130b5037af312160b2f396aad579e45619af3126e4aGreg Clayton if (!m_decl_map->GetFunctionAddress (g_sel_registerName_str, sel_registerName_addr)) 1131f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan return false; 1132f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1133c2c6f7781b6721e73ccf5ed842d00906ae27f191Sean Callanan if (log) 11345f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea log->Printf("Found sel_registerName at 0x%" PRIx64, sel_registerName_addr); 1135c2c6f7781b6721e73ccf5ed842d00906ae27f191Sean Callanan 1136f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan // Build the function type: struct objc_selector *sel_registerName(uint8_t*) 1137f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1138f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan // The below code would be "more correct," but in actuality what's required is uint8_t* 1139c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan //Type *sel_type = StructType::get(m_module->getContext()); 1140f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan //Type *sel_ptr_type = PointerType::getUnqual(sel_type); 11419b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext()); 11429b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 11439b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan Type *type_array[1]; 11449b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 11459b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext()); 11469b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 11479b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan ArrayRef<Type *> srN_arg_types(type_array, 1); 1148f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1149f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan llvm::Type *srN_type = FunctionType::get(sel_ptr_type, srN_arg_types, false); 1150f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1151f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan // Build the constant containing the pointer to the function 11529b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(), 11534fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32); 1154f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type); 1155b5037af312160b2f396aad579e45619af3126e4aGreg Clayton Constant *srN_addr_int = ConstantInt::get(intptr_ty, sel_registerName_addr, false); 1156f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan m_sel_registerName = ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty); 1157f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan } 1158f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 11599b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan Value *argument_array[1]; 11609b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 1161c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan Constant *omvn_pointer = ConstantExpr::getBitCast(_objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext())); 1162f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 11639b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan argument_array[0] = omvn_pointer; 1164f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 11659b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan ArrayRef<Value *> srN_arguments(argument_array, 1); 11669b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 1167f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan CallInst *srN_call = CallInst::Create(m_sel_registerName, 11689b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan srN_arguments, 11696ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan "sel_registerName", 1170f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan selector_load); 1171f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1172f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan // Replace the load with the call in all users 1173f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1174f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan selector_load->replaceAllUsesWith(srN_call); 1175f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1176f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan selector_load->eraseFromParent(); 1177f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1178f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan return true; 1179f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan} 1180f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1181f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callananbool 1182c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::RewriteObjCSelectors (BasicBlock &basic_block) 1183f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan{ 1184952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1185f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1186f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan BasicBlock::iterator ii; 1187f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1188f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan typedef SmallVector <Instruction*, 2> InstrList; 1189f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan typedef InstrList::iterator InstrIterator; 1190f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1191f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan InstrList selector_loads; 1192f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 11933c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton for (ii = basic_block.begin(); 11943c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton ii != basic_block.end(); 1195f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan ++ii) 1196f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan { 1197f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan Instruction &inst = *ii; 1198f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1199f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan if (LoadInst *load = dyn_cast<LoadInst>(&inst)) 12003c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton if (IsObjCSelectorRef(load->getPointerOperand())) 1201f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan selector_loads.push_back(&inst); 1202f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan } 1203f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1204f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan InstrIterator iter; 1205f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1206f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan for (iter = selector_loads.begin(); 1207f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan iter != selector_loads.end(); 1208f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan ++iter) 1209f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan { 1210c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (!RewriteObjCSelector(*iter)) 1211f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan { 121297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 121397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Couldn't change a static reference to an Objective-C selector to a dynamic reference\n"); 121497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 12154c3fb4b50a87e6e08987096d7edacc26545f58dcEnrico Granata if (log) 1216f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan log->PutCString("Couldn't rewrite a reference to an Objective-C selector"); 121797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 1218f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan return false; 1219f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan } 1220f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan } 1221f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 1222f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan return true; 1223f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan} 1224f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 122597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan// This function does not report errors; its callers are responsible. 1226a48fe1637ec6a381e500633c087f76662e364c20Sean Callananbool 1227c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::RewritePersistentAlloc (llvm::Instruction *persistent_alloc) 1228a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan{ 1229952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 123097678d17ac9bcb66f7092178109271991ab16533Sean Callanan 1231a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc); 1232a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1233a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr"); 1234a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1235a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan if (!alloc_md || !alloc_md->getNumOperands()) 1236a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan return false; 1237a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1238a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan ConstantInt *constant_int = dyn_cast<ConstantInt>(alloc_md->getOperand(0)); 1239a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1240a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan if (!constant_int) 1241a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan return false; 1242a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1243a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan // We attempt to register this as a new persistent variable with the DeclMap. 1244a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1245a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan uintptr_t ptr = constant_int->getZExtValue(); 1246a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 124782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr); 1248a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 124982b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan lldb_private::TypeFromParser result_decl_type (decl->getType().getAsOpaquePtr(), 125082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan &decl->getASTContext()); 125182b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 12528de27c761a22187ef63fb60000894be163e7285fGreg Clayton StringRef decl_name (decl->getName()); 12538de27c761a22187ef63fb60000894be163e7285fGreg Clayton lldb_private::ConstString persistent_variable_name (decl_name.data(), decl_name.size()); 12546a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name, result_decl_type, false, false)) 1255a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan return false; 1256a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1257c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan GlobalVariable *persistent_global = new GlobalVariable((*m_module), 125897678d17ac9bcb66f7092178109271991ab16533Sean Callanan alloc->getType(), 1259a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan false, /* not constant */ 1260a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan GlobalValue::ExternalLinkage, 1261a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan NULL, /* no initializer */ 1262a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan alloc->getName().str().c_str()); 1263a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1264a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan // What we're going to do here is make believe this was a regular old external 1265a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan // variable. That means we need to make the metadata valid. 1266a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 12672b03efefef987b2e4f8710d877b55ececc61ac9cSean Callanan NamedMDNode *named_metadata = m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs"); 1268a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1269a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan llvm::Value* values[2]; 1270a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan values[0] = persistent_global; 1271a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan values[1] = constant_int; 12720de254aaec7d6766379191e5397ec2294042c5d7Sean Callanan 12730de254aaec7d6766379191e5397ec2294042c5d7Sean Callanan ArrayRef<llvm::Value*> value_ref(values, 2); 1274a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1275c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref); 1276a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan named_metadata->addOperand(persistent_global_md); 1277a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 127897678d17ac9bcb66f7092178109271991ab16533Sean Callanan // Now, since the variable is a pointer variable, we will drop in a load of that 127997678d17ac9bcb66f7092178109271991ab16533Sean Callanan // pointer variable. 128097678d17ac9bcb66f7092178109271991ab16533Sean Callanan 128197678d17ac9bcb66f7092178109271991ab16533Sean Callanan LoadInst *persistent_load = new LoadInst (persistent_global, "", alloc); 128297678d17ac9bcb66f7092178109271991ab16533Sean Callanan 128397678d17ac9bcb66f7092178109271991ab16533Sean Callanan if (log) 128497678d17ac9bcb66f7092178109271991ab16533Sean Callanan log->Printf("Replacing \"%s\" with \"%s\"", 128597678d17ac9bcb66f7092178109271991ab16533Sean Callanan PrintValue(alloc).c_str(), 128697678d17ac9bcb66f7092178109271991ab16533Sean Callanan PrintValue(persistent_load).c_str()); 128797678d17ac9bcb66f7092178109271991ab16533Sean Callanan 128897678d17ac9bcb66f7092178109271991ab16533Sean Callanan alloc->replaceAllUsesWith(persistent_load); 1289a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan alloc->eraseFromParent(); 1290a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1291a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan return true; 1292a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan} 1293a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1294a48fe1637ec6a381e500633c087f76662e364c20Sean Callananbool 1295c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) 1296a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan{ 1297e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan if (!m_resolve_vars) 1298e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan return true; 1299e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 1300952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1301a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1302a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan BasicBlock::iterator ii; 1303a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1304a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan typedef SmallVector <Instruction*, 2> InstrList; 1305a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan typedef InstrList::iterator InstrIterator; 1306a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1307a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan InstrList pvar_allocs; 1308a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 13093c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton for (ii = basic_block.begin(); 13103c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton ii != basic_block.end(); 1311a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan ++ii) 1312a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan { 1313a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan Instruction &inst = *ii; 1314a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1315a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) 1316237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan { 1317237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan llvm::StringRef alloc_name = alloc->getName(); 1318237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan 1319237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan if (alloc_name.startswith("$") && 1320237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan !alloc_name.startswith("$__lldb")) 1321237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan { 1322237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan if (alloc_name.find_first_of("0123456789") == 1) 1323237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan { 1324237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan if (log) 1325237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan log->Printf("Rejecting a numeric persistent variable."); 1326237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan 132797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 132897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Error [IRForTarget]: Names starting with $0, $1, ... are reserved for use as result names\n"); 132997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 1330237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan return false; 1331237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan } 1332237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan 1333a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan pvar_allocs.push_back(alloc); 1334237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan } 1335237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan } 1336a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan } 1337a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1338a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan InstrIterator iter; 1339a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1340a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan for (iter = pvar_allocs.begin(); 1341a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan iter != pvar_allocs.end(); 1342a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan ++iter) 1343a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan { 1344c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (!RewritePersistentAlloc(*iter)) 1345a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan { 134697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 134797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Couldn't rewrite the creation of a persistent variable\n"); 134897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 13494c3fb4b50a87e6e08987096d7edacc26545f58dcEnrico Granata if (log) 1350a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan log->PutCString("Couldn't rewrite the creation of a persistent variable"); 135197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 1352a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan return false; 1353a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan } 1354a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan } 1355a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1356a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan return true; 1357a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan} 1358a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 1359c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callananbool 1360c7ca466fa99aea0e4e81530157bc8927682cae00Sean CallananIRForTarget::MaterializeInitializer (uint8_t *data, Constant *initializer) 1361c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan{ 1362c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan if (!initializer) 1363c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan return true; 1364c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1365952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1366c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1367c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan if (log && log->GetVerbose()) 1368c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan log->Printf(" MaterializeInitializer(%p, %s)", data, PrintValue(initializer).c_str()); 1369c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1370c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan Type *initializer_type = initializer->getType(); 1371c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1372c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer)) 1373c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan { 1374c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan memcpy (data, int_initializer->getValue().getRawData(), m_target_data->getTypeStoreSize(initializer_type)); 1375c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan return true; 1376c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan } 137739a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan else if (ConstantDataArray *array_initializer = dyn_cast<ConstantDataArray>(initializer)) 1378c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan { 1379c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan if (array_initializer->isString()) 1380c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan { 1381c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan std::string array_initializer_string = array_initializer->getAsString(); 1382c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan memcpy (data, array_initializer_string.c_str(), m_target_data->getTypeStoreSize(initializer_type)); 1383c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan } 1384c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan else 1385c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan { 1386c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan ArrayType *array_initializer_type = array_initializer->getType(); 1387c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan Type *array_element_type = array_initializer_type->getElementType(); 1388c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1389c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan size_t element_size = m_target_data->getTypeAllocSize(array_element_type); 1390c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 13913e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i) 1392c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan { 139339a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan Value *operand_value = array_initializer->getOperand(i); 139439a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan Constant *operand_constant = dyn_cast<Constant>(operand_value); 139539a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan 139639a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan if (!operand_constant) 139739a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan return false; 139839a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan 139939a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan if (!MaterializeInitializer(data + (i * element_size), operand_constant)) 1400c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan return false; 1401c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan } 1402c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan } 1403c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan return true; 1404c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan } 1405c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan else if (ConstantStruct *struct_initializer = dyn_cast<ConstantStruct>(initializer)) 1406c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan { 1407c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan StructType *struct_initializer_type = struct_initializer->getType(); 1408c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan const StructLayout *struct_layout = m_target_data->getStructLayout(struct_initializer_type); 1409c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 14103e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs for (unsigned i = 0; 1411c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan i < struct_initializer->getNumOperands(); 1412c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan ++i) 1413c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan { 1414c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan if (!MaterializeInitializer(data + struct_layout->getElementOffset(i), struct_initializer->getOperand(i))) 1415c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan return false; 1416c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan } 1417c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan return true; 1418c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan } 1419e2172fd8191f1f6493a4388f7082bd2f2f43d67fSean Callanan else if (isa<ConstantAggregateZero>(initializer)) 1420e2172fd8191f1f6493a4388f7082bd2f2f43d67fSean Callanan { 1421e2172fd8191f1f6493a4388f7082bd2f2f43d67fSean Callanan memset(data, 0, m_target_data->getTypeStoreSize(initializer_type)); 1422e2172fd8191f1f6493a4388f7082bd2f2f43d67fSean Callanan return true; 1423e2172fd8191f1f6493a4388f7082bd2f2f43d67fSean Callanan } 1424c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan return false; 1425c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan} 1426c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1427c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callananbool 1428c7ca466fa99aea0e4e81530157bc8927682cae00Sean CallananIRForTarget::MaterializeInternalVariable (GlobalVariable *global_variable) 1429c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan{ 1430c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan if (GlobalVariable::isExternalLinkage(global_variable->getLinkage())) 1431c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan return false; 1432c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1433c41606fe0aeeac867d5d0b64abfe2444c5d36bf2Sean Callanan if (global_variable == m_reloc_placeholder) 1434c41606fe0aeeac867d5d0b64abfe2444c5d36bf2Sean Callanan return true; 1435c41606fe0aeeac867d5d0b64abfe2444c5d36bf2Sean Callanan 14361cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan uint64_t offset = m_data_allocator.GetStream().GetSize(); 1437c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1438c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan llvm::Type *variable_type = global_variable->getType(); 1439c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1440c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan Constant *initializer = global_variable->getInitializer(); 1441c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1442c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan llvm::Type *initializer_type = initializer->getType(); 1443c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1444c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan size_t size = m_target_data->getTypeAllocSize(initializer_type); 14451d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan size_t align = m_target_data->getPrefTypeAlignment(initializer_type); 14461d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan 14471d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan const size_t mask = (align - 1); 14481d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan uint64_t aligned_offset = (offset + mask) & ~mask; 14491cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0); 14501d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan offset = aligned_offset; 1451c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1452c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan lldb_private::DataBufferHeap data(size, '\0'); 1453c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1454c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan if (initializer) 1455c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan if (!MaterializeInitializer(data.GetBytes(), initializer)) 1456c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan return false; 1457c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 14581cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan m_data_allocator.GetStream().Write(data.GetBytes(), data.GetByteSize()); 1459c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1460c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan Constant *new_pointer = BuildRelocation(variable_type, offset); 1461c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1462c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan global_variable->replaceAllUsesWith(new_pointer); 1463c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1464c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan global_variable->eraseFromParent(); 1465c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1466c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan return true; 1467c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan} 1468c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 146997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan// This function does not report errors; its callers are responsible. 14708bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callananbool 1471c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::MaybeHandleVariable (Value *llvm_value_ptr) 14725cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan{ 1473952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 14744844365bea9261f6afe24508d413d80ea2400abdSean Callanan 14754844365bea9261f6afe24508d413d80ea2400abdSean Callanan if (log) 1476b9f09a6188dc2b48bf7f5677bc1eef9a73c3fa25Sean Callanan log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str()); 14779a8774383dc91717151f85b32f3677aef102a77aSean Callanan 14788de27c761a22187ef63fb60000894be163e7285fGreg Clayton if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) 1479bc2928a7a6b973327bf10f153c3c0479bc11e4c5Sean Callanan { 148093a4b1a8d6ad9a5d1e18a38b5ec55de5b7f6e724Sean Callanan switch (constant_expr->getOpcode()) 1481bc2928a7a6b973327bf10f153c3c0479bc11e4c5Sean Callanan { 148293a4b1a8d6ad9a5d1e18a38b5ec55de5b7f6e724Sean Callanan default: 148393a4b1a8d6ad9a5d1e18a38b5ec55de5b7f6e724Sean Callanan break; 148493a4b1a8d6ad9a5d1e18a38b5ec55de5b7f6e724Sean Callanan case Instruction::GetElementPtr: 148593a4b1a8d6ad9a5d1e18a38b5ec55de5b7f6e724Sean Callanan case Instruction::BitCast: 1486bc2928a7a6b973327bf10f153c3c0479bc11e4c5Sean Callanan Value *s = constant_expr->getOperand(0); 1487c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (!MaybeHandleVariable(s)) 14884844365bea9261f6afe24508d413d80ea2400abdSean Callanan return false; 1489bc2928a7a6b973327bf10f153c3c0479bc11e4c5Sean Callanan } 1490bc2928a7a6b973327bf10f153c3c0479bc11e4c5Sean Callanan } 1491f921cf530ecb96381c93a34c313e4967a6e79834Sean Callanan else if (GlobalVariable *global_variable = dyn_cast<GlobalVariable>(llvm_value_ptr)) 1492f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan { 1493c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan if (!GlobalValue::isExternalLinkage(global_variable->getLinkage())) 1494c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan return MaterializeInternalVariable(global_variable); 1495c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 1496c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan clang::NamedDecl *named_decl = DeclForGlobal(global_variable); 14978bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 1498f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan if (!named_decl) 1499f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan { 15003c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton if (IsObjCSelectorRef(llvm_value_ptr)) 1501f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan return true; 1502f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 15037cd4674d027ed726eb8830b455e95249846b7899Sean Callanan if (!global_variable->hasExternalLinkage()) 15047cd4674d027ed726eb8830b455e95249846b7899Sean Callanan return true; 15057cd4674d027ed726eb8830b455e95249846b7899Sean Callanan 1506f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan if (log) 1507b5037af312160b2f396aad579e45619af3126e4aGreg Clayton log->Printf("Found global variable \"%s\" without metadata", global_variable->getName().str().c_str()); 150897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 1509f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan return false; 1510f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan } 1511f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan 15128de27c761a22187ef63fb60000894be163e7285fGreg Clayton std::string name (named_decl->getName().str()); 1513810f22d18ca8f9d31f49d79bb4b51a9f2fd96deaSean Callanan 151452f792329be5db8e38961350589e97e8f2823acdGreg Clayton clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl); 151552f792329be5db8e38961350589e97e8f2823acdGreg Clayton if (value_decl == NULL) 1516810f22d18ca8f9d31f49d79bb4b51a9f2fd96deaSean Callanan return false; 151752f792329be5db8e38961350589e97e8f2823acdGreg Clayton 151852f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb_private::ClangASTType clang_type(&value_decl->getASTContext(), value_decl->getType()); 1519771131d04344e57abb340699f54dce77a511bc71Sean Callanan 152058baaada202ea16e928f0c76e9124d42fd3655cdSean Callanan const Type *value_type = NULL; 152152f792329be5db8e38961350589e97e8f2823acdGreg Clayton 152297678d17ac9bcb66f7092178109271991ab16533Sean Callanan if (name[0] == '$') 15236a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan { 15246a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan // The $__lldb_expr_result name indicates the the return value has allocated as 15256a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan // a static variable. Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, 15266a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan // accesses to this static variable need to be redirected to the result of dereferencing 15276a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan // a pointer that is passed in as one of the arguments. 15286a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan // 15296a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan // Consequently, when reporting the size of the type, we report a pointer type pointing 15306a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan // to the type of $__lldb_expr_result, not the type itself. 153197678d17ac9bcb66f7092178109271991ab16533Sean Callanan // 153297678d17ac9bcb66f7092178109271991ab16533Sean Callanan // We also do this for any user-declared persistent variables. 153352f792329be5db8e38961350589e97e8f2823acdGreg Clayton clang_type = clang_type.GetPointerType(); 15346a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan value_type = PointerType::get(global_variable->getType(), 0); 15356a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan } 15366a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan else 15376a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan { 15386a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan value_type = global_variable->getType(); 15396a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan } 154052f792329be5db8e38961350589e97e8f2823acdGreg Clayton 154152f792329be5db8e38961350589e97e8f2823acdGreg Clayton const uint64_t value_size = clang_type.GetByteSize(); 154252f792329be5db8e38961350589e97e8f2823acdGreg Clayton off_t value_alignment = (clang_type.GetTypeBitAlign() + 7ull) / 8ull; 15433aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan 1544771131d04344e57abb340699f54dce77a511bc71Sean Callanan if (log) 154552f792329be5db8e38961350589e97e8f2823acdGreg Clayton { 1546fe6dc6e241c52822710380cec0931351a1d7b2d3Greg Clayton log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRId64 "]", 1547771131d04344e57abb340699f54dce77a511bc71Sean Callanan name.c_str(), 154852f792329be5db8e38961350589e97e8f2823acdGreg Clayton clang_type.GetQualType().getAsString().c_str(), 154952f792329be5db8e38961350589e97e8f2823acdGreg Clayton PrintType(value_type).c_str(), 1550771131d04344e57abb340699f54dce77a511bc71Sean Callanan value_size, 1551771131d04344e57abb340699f54dce77a511bc71Sean Callanan value_alignment); 155252f792329be5db8e38961350589e97e8f2823acdGreg Clayton } 15533aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan 15548bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 15558c12720c108cd5e7ed792596749218d8400f647eSean Callanan if (named_decl && !m_decl_map->AddValueToStruct(named_decl, 15568de27c761a22187ef63fb60000894be163e7285fGreg Clayton lldb_private::ConstString (name.c_str()), 15578de27c761a22187ef63fb60000894be163e7285fGreg Clayton llvm_value_ptr, 1558ba992c58b25ec0a67ef430024dc3dca154982dc9Sean Callanan value_size, 1559ba992c58b25ec0a67ef430024dc3dca154982dc9Sean Callanan value_alignment)) 15609a8774383dc91717151f85b32f3677aef102a77aSean Callanan { 15619a8774383dc91717151f85b32f3677aef102a77aSean Callanan if (!global_variable->hasExternalLinkage()) 15629a8774383dc91717151f85b32f3677aef102a77aSean Callanan return true; 15632a90dd0ce40c583af74333987a48fc82d7d0adf5Sean Callanan else if (HandleSymbol (global_variable)) 15642a90dd0ce40c583af74333987a48fc82d7d0adf5Sean Callanan return true; 15659a8774383dc91717151f85b32f3677aef102a77aSean Callanan else 15669a8774383dc91717151f85b32f3677aef102a77aSean Callanan return false; 15679a8774383dc91717151f85b32f3677aef102a77aSean Callanan } 15688bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan } 1569f3143b7faf3f934282859b62575537366565a0eeSean Callanan else if (dyn_cast<llvm::Function>(llvm_value_ptr)) 15704844365bea9261f6afe24508d413d80ea2400abdSean Callanan { 15714844365bea9261f6afe24508d413d80ea2400abdSean Callanan if (log) 15724844365bea9261f6afe24508d413d80ea2400abdSean Callanan log->Printf("Function pointers aren't handled right now"); 15734844365bea9261f6afe24508d413d80ea2400abdSean Callanan 15744844365bea9261f6afe24508d413d80ea2400abdSean Callanan return false; 15754844365bea9261f6afe24508d413d80ea2400abdSean Callanan } 15768bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 15778bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan return true; 15788bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan} 15798bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 158097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan// This function does not report errors; its callers are responsible. 15818bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callananbool 1582c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::HandleSymbol (Value *symbol) 1583819749647b1605f75753f625050cb240292c08b0Sean Callanan{ 1584952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1585c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan 1586c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan lldb_private::ConstString name(symbol->getName().str().c_str()); 1587c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan 158821ef5bb658e4582339bedf5befc10c13953bdac0Sean Callanan lldb::addr_t symbol_addr = m_decl_map->GetSymbolAddress (name, lldb::eSymbolTypeAny); 1589c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan 1590cbc07cfd435fb703d8feb69b97ca8590e6ee2fd8Greg Clayton if (symbol_addr == LLDB_INVALID_ADDRESS) 1591c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan { 1592c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan if (log) 1593c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan log->Printf ("Symbol \"%s\" had no address", name.GetCString()); 1594c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan 1595c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan return false; 1596c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan } 1597c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan 1598c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan if (log) 15995f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr); 1600c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan 16019b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan Type *symbol_type = symbol->getType(); 16029b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(), 16034fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32); 1604c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan 1605c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan Constant *symbol_addr_int = ConstantInt::get(intptr_ty, symbol_addr, false); 1606c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan 1607c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan Value *symbol_addr_ptr = ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type); 1608c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan 1609c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan if (log) 1610c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(), PrintValue(symbol_addr_ptr).c_str()); 1611c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan 1612c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan symbol->replaceAllUsesWith(symbol_addr_ptr); 1613c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan 1614c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan return true; 1615c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan} 1616c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan 1617c7674af9458fbad6f07fa73609c354abf93af2dcSean Callananbool 1618c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::MaybeHandleCallArguments (CallInst *Old) 1619dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callanan{ 1620952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 16214844365bea9261f6afe24508d413d80ea2400abdSean Callanan 16224844365bea9261f6afe24508d413d80ea2400abdSean Callanan if (log) 16234844365bea9261f6afe24508d413d80ea2400abdSean Callanan log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str()); 1624dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callanan 16256ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan for (unsigned op_index = 0, num_ops = Old->getNumArgOperands(); 1626dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callanan op_index < num_ops; 1627dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callanan ++op_index) 1628c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (!MaybeHandleVariable(Old->getArgOperand(op_index))) // conservatively believe that this is a store 162997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan { 163097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 163197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Couldn't rewrite one of the arguments of a function call.\n"); 163297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 1633dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callanan return false; 163497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan } 163597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 1636dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callanan return true; 1637dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callanan} 1638dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callanan 1639dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callananbool 16409911d2fa3380028c9b798110bd1dcdeb44920421Sean CallananIRForTarget::HandleObjCClass(Value *classlist_reference) 16419911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan{ 1642952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 16439911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 16449911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan GlobalVariable *global_variable = dyn_cast<GlobalVariable>(classlist_reference); 16459911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 16469911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan if (!global_variable) 16479911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan return false; 16489911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 16499911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan Constant *initializer = global_variable->getInitializer(); 16509911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 16519911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan if (!initializer) 16529911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan return false; 16539911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 16549911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan if (!initializer->hasName()) 16559911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan return false; 16569911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 16579911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan StringRef name(initializer->getName()); 16589911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan lldb_private::ConstString name_cstr(name.str().c_str()); 165916d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton lldb::addr_t class_ptr = m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass); 16609911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 16619911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan if (log) 16629911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan log->Printf("Found reference to Objective-C class %s (0x%llx)", name_cstr.AsCString(), (unsigned long long)class_ptr); 16639911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 16649911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan if (class_ptr == LLDB_INVALID_ADDRESS) 16659911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan return false; 16669911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 16679911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan if (global_variable->use_begin() == global_variable->use_end()) 16689911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan return false; 16699911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 16705365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan SmallVector<LoadInst *, 2> load_instructions; 16715365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan 16729911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan for (Value::use_iterator i = global_variable->use_begin(), e = global_variable->use_end(); 16739911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan i != e; 16749911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan ++i) 16759911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan { 16765365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan if (LoadInst *load_instruction = dyn_cast<LoadInst>(*i)) 16775365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan load_instructions.push_back(load_instruction); 16789911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan } 16799911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 16805365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan if (load_instructions.empty()) 16819911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan return false; 16829911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 16839911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(), 16844fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan (m_module->getPointerSize() 1685ce6335881f330581f641ef808602cac192664adfMicah Villmow == Module::Pointer64) ? 64 : 32); 16869911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 16879911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan Constant *class_addr = ConstantInt::get(intptr_ty, (uint64_t)class_ptr); 16889911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 16895365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan for (LoadInst *load_instruction : load_instructions) 16905365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan { 16915365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan Constant *class_bitcast = ConstantExpr::getIntToPtr(class_addr, load_instruction->getType()); 16925365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan 16935365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan load_instruction->replaceAllUsesWith(class_bitcast); 16949911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 16955365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan load_instruction->eraseFromParent(); 16965365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan } 16979911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 16989911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan return true; 16999911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan} 17009911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 17019911d2fa3380028c9b798110bd1dcdeb44920421Sean Callananbool 17021850f94688f9362c78c27e5472afe022a56c08dfSean CallananIRForTarget::RemoveCXAAtExit (BasicBlock &basic_block) 17031850f94688f9362c78c27e5472afe022a56c08dfSean Callanan{ 17041850f94688f9362c78c27e5472afe022a56c08dfSean Callanan BasicBlock::iterator ii; 17051850f94688f9362c78c27e5472afe022a56c08dfSean Callanan 17061850f94688f9362c78c27e5472afe022a56c08dfSean Callanan std::vector<CallInst *> calls_to_remove; 17071850f94688f9362c78c27e5472afe022a56c08dfSean Callanan 17081850f94688f9362c78c27e5472afe022a56c08dfSean Callanan for (ii = basic_block.begin(); 17091850f94688f9362c78c27e5472afe022a56c08dfSean Callanan ii != basic_block.end(); 17101850f94688f9362c78c27e5472afe022a56c08dfSean Callanan ++ii) 17111850f94688f9362c78c27e5472afe022a56c08dfSean Callanan { 17121850f94688f9362c78c27e5472afe022a56c08dfSean Callanan Instruction &inst = *ii; 17131850f94688f9362c78c27e5472afe022a56c08dfSean Callanan 17141850f94688f9362c78c27e5472afe022a56c08dfSean Callanan CallInst *call = dyn_cast<CallInst>(&inst); 17151850f94688f9362c78c27e5472afe022a56c08dfSean Callanan 17161850f94688f9362c78c27e5472afe022a56c08dfSean Callanan // MaybeHandleCallArguments handles error reporting; we are silent here 17171850f94688f9362c78c27e5472afe022a56c08dfSean Callanan if (!call) 17181850f94688f9362c78c27e5472afe022a56c08dfSean Callanan continue; 17191850f94688f9362c78c27e5472afe022a56c08dfSean Callanan 17201850f94688f9362c78c27e5472afe022a56c08dfSean Callanan bool remove = false; 17211850f94688f9362c78c27e5472afe022a56c08dfSean Callanan 17221850f94688f9362c78c27e5472afe022a56c08dfSean Callanan llvm::Function *func = call->getCalledFunction(); 17231850f94688f9362c78c27e5472afe022a56c08dfSean Callanan 17241850f94688f9362c78c27e5472afe022a56c08dfSean Callanan if (func && func->getName() == "__cxa_atexit") 17251850f94688f9362c78c27e5472afe022a56c08dfSean Callanan remove = true; 17261850f94688f9362c78c27e5472afe022a56c08dfSean Callanan 17271850f94688f9362c78c27e5472afe022a56c08dfSean Callanan llvm::Value *val = call->getCalledValue(); 17281850f94688f9362c78c27e5472afe022a56c08dfSean Callanan 17291850f94688f9362c78c27e5472afe022a56c08dfSean Callanan if (val && val->getName() == "__cxa_atexit") 17301850f94688f9362c78c27e5472afe022a56c08dfSean Callanan remove = true; 17311850f94688f9362c78c27e5472afe022a56c08dfSean Callanan 17321850f94688f9362c78c27e5472afe022a56c08dfSean Callanan if (remove) 17331850f94688f9362c78c27e5472afe022a56c08dfSean Callanan calls_to_remove.push_back(call); 17341850f94688f9362c78c27e5472afe022a56c08dfSean Callanan } 17351850f94688f9362c78c27e5472afe022a56c08dfSean Callanan 17361850f94688f9362c78c27e5472afe022a56c08dfSean Callanan for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(), ce = calls_to_remove.end(); 17371850f94688f9362c78c27e5472afe022a56c08dfSean Callanan ci != ce; 17381850f94688f9362c78c27e5472afe022a56c08dfSean Callanan ++ci) 17391850f94688f9362c78c27e5472afe022a56c08dfSean Callanan { 17401850f94688f9362c78c27e5472afe022a56c08dfSean Callanan (*ci)->eraseFromParent(); 17411850f94688f9362c78c27e5472afe022a56c08dfSean Callanan } 17421850f94688f9362c78c27e5472afe022a56c08dfSean Callanan 17431850f94688f9362c78c27e5472afe022a56c08dfSean Callanan return true; 17441850f94688f9362c78c27e5472afe022a56c08dfSean Callanan} 17451850f94688f9362c78c27e5472afe022a56c08dfSean Callanan 17461850f94688f9362c78c27e5472afe022a56c08dfSean Callananbool 1747c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::ResolveCalls(BasicBlock &basic_block) 17488bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan{ 17495cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan ///////////////////////////////////////////////////////////////////////// 17505cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan // Prepare the current basic block for execution in the remote process 17515cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan // 17525cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 175302fbafa1bf2bb77bf8f25af3403d7d8721a3f8b1Sean Callanan BasicBlock::iterator ii; 17548bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 17553c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton for (ii = basic_block.begin(); 17563c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton ii != basic_block.end(); 17578bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan ++ii) 17588bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan { 17598bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan Instruction &inst = *ii; 17608bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 17611d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan CallInst *call = dyn_cast<CallInst>(&inst); 1762ba992c58b25ec0a67ef430024dc3dca154982dc9Sean Callanan 176397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan // MaybeHandleCallArguments handles error reporting; we are silent here 1764c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (call && !MaybeHandleCallArguments(call)) 17654844365bea9261f6afe24508d413d80ea2400abdSean Callanan return false; 17668bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan } 17678bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 17688bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan return true; 17698bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan} 17708bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 17711d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callananbool 1772c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::ResolveExternals (Function &llvm_function) 17731d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan{ 1774952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1775ae71e30fe0c0e0d5fd1bf9062274798060df674cSean Callanan 1776c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan for (Module::global_iterator global = m_module->global_begin(), end = m_module->global_end(); 17771d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan global != end; 17781d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan ++global) 17791d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan { 17801c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan if (!global) 17811c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan { 17821c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan if (m_error_stream) 17831c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: global variable is NULL"); 17841c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan 17851c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan return false; 17861c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan } 17871c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan 17881c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan std::string global_name = (*global).getName().str(); 17891c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan 17903c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton if (log) 17913c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton log->Printf("Examining %s, DeclForGlobalValue returns %p", 17921c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan global_name.c_str(), 1793c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan DeclForGlobal(global)); 17949911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 17959911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan if (global_name.find("OBJC_IVAR") == 0) 1796c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan { 1797c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (!HandleSymbol(global)) 179897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan { 179997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 18001c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan m_error_stream->Printf("Error [IRForTarget]: Couldn't find Objective-C indirect ivar symbol %s\n", global_name.c_str()); 180197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 1802c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan return false; 180397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan } 1804c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan } 18059911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan else if (global_name.find("OBJC_CLASSLIST_REFERENCES_$") != global_name.npos) 18069911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan { 18079911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan if (!HandleObjCClass(global)) 18089911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan { 18099911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan if (m_error_stream) 18109911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan m_error_stream->Printf("Error [IRForTarget]: Couldn't resolve the class for an Objective-C static method call\n"); 18119911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan 18129911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan return false; 18139911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan } 18149911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan } 18152dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan else if (global_name.find("OBJC_CLASSLIST_SUP_REFS_$") != global_name.npos) 18162dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan { 18172dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan if (!HandleObjCClass(global)) 18182dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan { 18192dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan if (m_error_stream) 18202dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan m_error_stream->Printf("Error [IRForTarget]: Couldn't resolve the class for an Objective-C static method call\n"); 18212dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan 18222dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan return false; 18232dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan } 18242dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan } 1825c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan else if (DeclForGlobal(global)) 1826c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan { 1827c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (!MaybeHandleVariable (global)) 182897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan { 182997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 18301c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Couldn't rewrite external variable %s\n", global_name.c_str()); 183197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 1832c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan return false; 183397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan } 1834c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan } 18351d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan } 18361d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan 18371d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan return true; 18381d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan} 18391d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan 1840c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callananbool 1841c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::ReplaceStrings () 1842c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan{ 1843952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1844c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1845c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan typedef std::map <GlobalVariable *, size_t> OffsetsTy; 1846c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1847c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan OffsetsTy offsets; 1848c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1849c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan for (Module::global_iterator gi = m_module->global_begin(), ge = m_module->global_end(); 1850c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan gi != ge; 1851c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ++gi) 1852c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 1853c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan GlobalVariable *gv = gi; 1854c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1855c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (!gv->hasInitializer()) 1856c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan continue; 1857c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1858c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan Constant *gc = gv->getInitializer(); 1859c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 18601b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan std::string str; 1861c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 18621b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan if (gc->isNullValue()) 18631b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan { 18641b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan Type *gc_type = gc->getType(); 18651b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan 18661b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan ArrayType *gc_array_type = dyn_cast<ArrayType>(gc_type); 18671b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan 18681b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan if (!gc_array_type) 18691b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan continue; 18701b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan 18711b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan Type *gc_element_type = gc_array_type->getElementType(); 18721b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan 18731b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan IntegerType *gc_integer_type = dyn_cast<IntegerType>(gc_element_type); 18741b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan 18751b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan if (gc_integer_type->getBitWidth() != 8) 18761b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan continue; 18771b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan 18781b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan str = ""; 18791b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan } 18801b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan else 18811b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan { 188239a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan ConstantDataArray *gc_array = dyn_cast<ConstantDataArray>(gc); 18831b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan 18841b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan if (!gc_array) 18851b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan continue; 1886c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 18871b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan if (!gc_array->isCString()) 18881b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan continue; 1889c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 18901b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan if (log) 18911b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan log->Printf("Found a GlobalVariable with string initializer %s", PrintValue(gc).c_str()); 1892c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 18931b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan str = gc_array->getAsString(); 18941b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan } 18951b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan 18961cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan offsets[gv] = m_data_allocator.GetStream().GetSize(); 1897c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 18981cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan m_data_allocator.GetStream().Write(str.c_str(), str.length() + 1); 1899c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 1900c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 19019b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan Type *char_ptr_ty = Type::getInt8PtrTy(m_module->getContext()); 1902c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1903c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan for (OffsetsTy::iterator oi = offsets.begin(), oe = offsets.end(); 1904c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan oi != oe; 1905c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ++oi) 1906c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 1907c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan GlobalVariable *gv = oi->first; 1908c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan size_t offset = oi->second; 1909c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1910c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan Constant *new_initializer = BuildRelocation(char_ptr_ty, offset); 1911c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1912c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (log) 1913c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan log->Printf("Replacing GV %s with %s", PrintValue(gv).c_str(), PrintValue(new_initializer).c_str()); 1914c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1915c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan for (GlobalVariable::use_iterator ui = gv->use_begin(), ue = gv->use_end(); 1916c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ui != ue; 1917c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ++ui) 1918c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 1919c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (log) 1920c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan log->Printf("Found use %s", PrintValue(*ui).c_str()); 1921c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1922c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ConstantExpr *const_expr = dyn_cast<ConstantExpr>(*ui); 1923c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan StoreInst *store_inst = dyn_cast<StoreInst>(*ui); 1924c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1925c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (const_expr) 1926c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 1927c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (const_expr->getOpcode() != Instruction::GetElementPtr) 1928c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 1929c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (log) 1930c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan log->Printf("Use (%s) of string variable is not a GetElementPtr constant", PrintValue(const_expr).c_str()); 1931c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1932c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan return false; 1933c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 1934c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 19351b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan Constant *bit_cast = ConstantExpr::getBitCast(new_initializer, const_expr->getOperand(0)->getType()); 19361b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan Constant *new_gep = const_expr->getWithOperandReplaced(0, bit_cast); 19371b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan 19381b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan const_expr->replaceAllUsesWith(new_gep); 1939c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 1940c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan else if (store_inst) 1941c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 1942c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan Constant *bit_cast = ConstantExpr::getBitCast(new_initializer, store_inst->getValueOperand()->getType()); 1943c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1944c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan store_inst->setOperand(0, bit_cast); 1945c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 1946c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan else 1947c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 1948c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (log) 1949c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan log->Printf("Use (%s) of string variable is neither a constant nor a store", PrintValue(const_expr).c_str()); 1950c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1951c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan return false; 1952c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 1953c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 1954c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1955c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan gv->eraseFromParent(); 1956c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 1957c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1958c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan return true; 1959c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan} 1960c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1961c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callananbool 1962c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::ReplaceStaticLiterals (llvm::BasicBlock &basic_block) 1963c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan{ 1964952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1965c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1966c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan typedef SmallVector <Value*, 2> ConstantList; 1967c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan typedef SmallVector <llvm::Instruction*, 2> UserList; 1968c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan typedef ConstantList::iterator ConstantIterator; 1969c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan typedef UserList::iterator UserIterator; 1970c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1971c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ConstantList static_constants; 1972c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan UserList static_users; 1973c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1974c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan for (BasicBlock::iterator ii = basic_block.begin(), ie = basic_block.end(); 1975c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ii != ie; 1976c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ++ii) 1977c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 1978c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan llvm::Instruction &inst = *ii; 1979c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1980c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan for (Instruction::op_iterator oi = inst.op_begin(), oe = inst.op_end(); 1981c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan oi != oe; 1982c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ++oi) 1983c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 1984c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan Value *operand_val = oi->get(); 1985c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1986c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ConstantFP *operand_constant_fp = dyn_cast<ConstantFP>(operand_val); 1987c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 198826c05d93aaca1505b92c7ebee65b4078c82f335aSean Callanan if (operand_constant_fp/* && operand_constant_fp->getType()->isX86_FP80Ty()*/) 1989c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 1990c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan static_constants.push_back(operand_val); 1991c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan static_users.push_back(ii); 1992c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 1993c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 1994c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 1995c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 1996c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ConstantIterator constant_iter; 1997c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan UserIterator user_iter; 199854b38413f62af3bcaeb8802a978cc621c8e88eb1Greg Clayton 1999c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan for (constant_iter = static_constants.begin(), user_iter = static_users.begin(); 2000c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan constant_iter != static_constants.end(); 2001c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ++constant_iter, ++user_iter) 2002c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 2003c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan Value *operand_val = *constant_iter; 2004c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan llvm::Instruction *inst = *user_iter; 2005c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2006c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ConstantFP *operand_constant_fp = dyn_cast<ConstantFP>(operand_val); 2007c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2008c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (operand_constant_fp) 2009c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 20100f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan Type *operand_type = operand_constant_fp->getType(); 20110f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 2012c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan APFloat operand_apfloat = operand_constant_fp->getValueAPF(); 2013c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan APInt operand_apint = operand_apfloat.bitcastToAPInt(); 2014c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2015c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan const uint8_t* operand_raw_data = (const uint8_t*)operand_apint.getRawData(); 2016c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan size_t operand_data_size = operand_apint.getBitWidth() / 8; 2017c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2018c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (log) 2019c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 2020c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan std::string s; 2021c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan raw_string_ostream ss(s); 2022c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan for (size_t index = 0; 2023c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan index < operand_data_size; 2024c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ++index) 2025c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 2026c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ss << (uint32_t)operand_raw_data[index]; 2027c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ss << " "; 2028c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 2029c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ss.flush(); 2030c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 20317e5fa7fc1f8efd24c078e063b2c4b5e13ba5be20Jason Molenda log->Printf("Found ConstantFP with size %lu and raw data %s", operand_data_size, s.c_str()); 2032c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 2033c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2034c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan lldb_private::DataBufferHeap data(operand_data_size, 0); 2035c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 20361cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan if (lldb::endian::InlHostByteOrder() != m_data_allocator.GetStream().GetByteOrder()) 2037c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 2038c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan uint8_t *data_bytes = data.GetBytes(); 2039c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2040c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan for (size_t index = 0; 2041c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan index < operand_data_size; 2042c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan ++index) 2043c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 2044c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan data_bytes[index] = operand_raw_data[operand_data_size - (1 + index)]; 2045c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 2046c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 2047c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan else 2048c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 2049c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan memcpy(data.GetBytes(), operand_raw_data, operand_data_size); 2050c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 2051c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 20521cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan uint64_t offset = m_data_allocator.GetStream().GetSize(); 2053c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 20541d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan size_t align = m_target_data->getPrefTypeAlignment(operand_type); 20551d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan 20561d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan const size_t mask = (align - 1); 20571d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan uint64_t aligned_offset = (offset + mask) & ~mask; 20581cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0); 20591d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan offset = aligned_offset; 20601d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan 20611cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan m_data_allocator.GetStream().Write(data.GetBytes(), operand_data_size); 2062c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 20639b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan llvm::Type *fp_ptr_ty = operand_constant_fp->getType()->getPointerTo(); 2064c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 20650f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan Constant *new_pointer = BuildRelocation(fp_ptr_ty, aligned_offset); 2066c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2067c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan llvm::LoadInst *fp_load = new llvm::LoadInst(new_pointer, "fp_load", inst); 2068c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2069c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan operand_constant_fp->replaceAllUsesWith(fp_load); 2070c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 2071c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 2072c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2073c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan return true; 2074c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan} 2075c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 207602fbafa1bf2bb77bf8f25af3403d7d8721a3f8b1Sean Callananstatic bool isGuardVariableRef(Value *V) 207745839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan{ 207858baaada202ea16e928f0c76e9124d42fd3655cdSean Callanan Constant *Old = NULL; 207945839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 20806ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (!(Old = dyn_cast<Constant>(V))) 208145839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan return false; 208245839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 208358baaada202ea16e928f0c76e9124d42fd3655cdSean Callanan ConstantExpr *CE = NULL; 208447a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan 208547a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan if ((CE = dyn_cast<ConstantExpr>(V))) 208647a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan { 208747a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan if (CE->getOpcode() != Instruction::BitCast) 208847a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan return false; 208947a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan 20906ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan Old = CE->getOperand(0); 209147a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan } 209247a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan 20936ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan GlobalVariable *GV = dyn_cast<GlobalVariable>(Old); 209445839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 209545839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan if (!GV || !GV->hasName() || !GV->getName().startswith("_ZGV")) 209645839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan return false; 209745839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 209845839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan return true; 209945839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan} 210045839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 2101c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callananvoid 2102c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::TurnGuardLoadIntoZero(llvm::Instruction* guard_load) 210345839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan{ 2104c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan Constant* zero(ConstantInt::get(Type::getInt8Ty(m_module->getContext()), 0, true)); 210545839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 210645839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan Value::use_iterator ui; 210745839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 210845839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan for (ui = guard_load->use_begin(); 210945839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan ui != guard_load->use_end(); 211045839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan ++ui) 2111b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan { 21126e71340988075f55c85e8bfcbc503ceaceb157c7Greg Clayton if (isa<Constant>(*ui)) 2113b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan { 2114b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan // do nothing for the moment 2115b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan } 2116b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan else 2117b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan { 2118b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan ui->replaceUsesOfWith(guard_load, zero); 2119b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan } 2120b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan } 212145839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 212245839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan guard_load->eraseFromParent(); 212345839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan} 212445839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 212545839276c3de51a55adef98a2a20a98f2ba428a9Sean Callananstatic void ExciseGuardStore(Instruction* guard_store) 212645839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan{ 212745839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan guard_store->eraseFromParent(); 212845839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan} 212945839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 213045839276c3de51a55adef98a2a20a98f2ba428a9Sean Callananbool 2131c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::RemoveGuards(BasicBlock &basic_block) 213245839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan{ 213345839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan /////////////////////////////////////////////////////// 213445839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan // Eliminate any reference to guard variables found. 213545839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan // 213645839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 213702fbafa1bf2bb77bf8f25af3403d7d8721a3f8b1Sean Callanan BasicBlock::iterator ii; 213845839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 213902fbafa1bf2bb77bf8f25af3403d7d8721a3f8b1Sean Callanan typedef SmallVector <Instruction*, 2> InstrList; 214045839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan typedef InstrList::iterator InstrIterator; 214145839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 214245839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan InstrList guard_loads; 214345839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan InstrList guard_stores; 214445839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 21453c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton for (ii = basic_block.begin(); 21463c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton ii != basic_block.end(); 214745839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan ++ii) 214845839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan { 214945839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan Instruction &inst = *ii; 215045839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 215145839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan if (LoadInst *load = dyn_cast<LoadInst>(&inst)) 215245839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan if (isGuardVariableRef(load->getPointerOperand())) 215345839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan guard_loads.push_back(&inst); 215445839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 215545839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan if (StoreInst *store = dyn_cast<StoreInst>(&inst)) 215645839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan if (isGuardVariableRef(store->getPointerOperand())) 215745839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan guard_stores.push_back(&inst); 215845839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan } 215945839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 216045839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan InstrIterator iter; 216145839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 216245839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan for (iter = guard_loads.begin(); 216345839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan iter != guard_loads.end(); 216445839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan ++iter) 2165c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan TurnGuardLoadIntoZero(*iter); 216645839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 216745839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan for (iter = guard_stores.begin(); 216845839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan iter != guard_stores.end(); 216945839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan ++iter) 217045839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan ExciseGuardStore(*iter); 217145839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 217245839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan return true; 217345839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan} 217445839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan 217597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan// This function does not report errors; its callers are responsible. 21766ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callananbool 21774a20587f56a05955ea94f650cb39245a092b0c69Sean CallananIRForTarget::UnfoldConstant(Constant *old_constant, 21784a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan FunctionValueCache &value_maker, 21794a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan FunctionValueCache &entry_instruction_finder) 2180bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan{ 2181952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 2182bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan 2183bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan Value::use_iterator ui; 2184bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan 2185a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan SmallVector<User*, 16> users; 2186a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 2187a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan // We do this because the use list might change, invalidating our iterator. 2188a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan // Much better to keep a work list ourselves. 21893c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton for (ui = old_constant->use_begin(); 21903c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton ui != old_constant->use_end(); 2191bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan ++ui) 2192a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan users.push_back(*ui); 2193bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan 21942bc9eb3ba78efc64a273729b480bafc3bbaa433aJohnny Chen for (size_t i = 0; 2195a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan i < users.size(); 2196a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan ++i) 2197a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan { 2198a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan User *user = users[i]; 2199a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 2200bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan if (Constant *constant = dyn_cast<Constant>(user)) 2201bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan { 2202bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan // synthesize a new non-constant equivalent of the constant 2203bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan 2204bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) 2205bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan { 2206bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan switch (constant_expr->getOpcode()) 2207bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan { 2208bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan default: 2209bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan if (log) 2210b5037af312160b2f396aad579e45619af3126e4aGreg Clayton log->Printf("Unhandled constant expression type: \"%s\"", PrintValue(constant_expr).c_str()); 2211bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan return false; 2212bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan case Instruction::BitCast: 22134a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 22144a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan FunctionValueCache bit_cast_maker ([&value_maker, &entry_instruction_finder, old_constant, constant_expr] (llvm::Function *function)->llvm::Value* { 22154a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan // UnaryExpr 22164a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan // OperandList[0] is value 22174a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 22184a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (constant_expr->getOperand(0) != old_constant) 22194a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return constant_expr; 22204a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 22214a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return new BitCastInst(value_maker.GetValue(function), 22224a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan constant_expr->getType(), 22234a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan "", 22244a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan llvm::cast<Instruction>(entry_instruction_finder.GetValue(function))); 22254a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan }); 2226bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan 2227250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan if (!UnfoldConstant(constant_expr, bit_cast_maker, entry_instruction_finder)) 2228250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan return false; 2229bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan } 2230bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan break; 2231bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan case Instruction::GetElementPtr: 2232bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan { 2233bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan // GetElementPtrConstantExpr 2234bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan // OperandList[0] is base 2235bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan // OperandList[1]... are indices 2236bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan 22374a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan FunctionValueCache get_element_pointer_maker ([&value_maker, &entry_instruction_finder, old_constant, constant_expr] (llvm::Function *function)->llvm::Value* { 22384a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan Value *ptr = constant_expr->getOperand(0); 2239bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan 22404a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (ptr == old_constant) 22414a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan ptr = value_maker.GetValue(function); 2242bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan 22434a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan std::vector<Value*> index_vector; 22444a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 22454a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan unsigned operand_index; 22464a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan unsigned num_operands = constant_expr->getNumOperands(); 22474a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 22484a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan for (operand_index = 1; 22494a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan operand_index < num_operands; 22504a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan ++operand_index) 22514a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 22524a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan Value *operand = constant_expr->getOperand(operand_index); 22534a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 22544a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (operand == old_constant) 22554a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan operand = value_maker.GetValue(function); 22564a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 22574a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan index_vector.push_back(operand); 22584a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan } 22594a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 22604a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan ArrayRef <Value*> indices(index_vector); 22614a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 22624a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return GetElementPtrInst::Create(ptr, indices, "", llvm::cast<Instruction>(entry_instruction_finder.GetValue(function))); 22634a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan }); 2264bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan 2265250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan if (!UnfoldConstant(constant_expr, get_element_pointer_maker, entry_instruction_finder)) 2266250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan return false; 2267bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan } 2268bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan break; 2269bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan } 2270bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan } 2271bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan else 2272bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan { 2273bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan if (log) 2274b5037af312160b2f396aad579e45619af3126e4aGreg Clayton log->Printf("Unhandled constant type: \"%s\"", PrintValue(constant).c_str()); 2275bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan return false; 2276bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan } 2277bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan } 2278bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan else 2279bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan { 22804a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) 22814a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 22824a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan inst->replaceUsesOfWith(old_constant, value_maker.GetValue(inst->getParent()->getParent())); 22834a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan } 22844a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan else 22854a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 22864a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (log) 22874a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan log->Printf("Unhandled non-constant type: \"%s\"", PrintValue(user).c_str()); 22884a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return false; 22894a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan } 2290bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan } 2291bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan } 2292bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan 2293250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan if (!isa<GlobalValue>(old_constant)) 2294250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan { 2295250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan old_constant->destroyConstant(); 2296250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan } 2297250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan 2298bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan return true; 2299bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan} 2300bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan 23018bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callananbool 2302c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::ReplaceVariables (Function &llvm_function) 23038bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan{ 2304e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan if (!m_resolve_vars) 2305e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan return true; 2306e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 2307952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 23088bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 23098bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan m_decl_map->DoStructLayout(); 23108bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 23118bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan if (log) 23128bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan log->Printf("Element arrangement:"); 23138bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 23148bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan uint32_t num_elements; 23158bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan uint32_t element_index; 23168bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 23178bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan size_t size; 23188bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan off_t alignment; 23198bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 23208bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan if (!m_decl_map->GetStructInfo (num_elements, size, alignment)) 23218bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan return false; 23228bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 23233c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton Function::arg_iterator iter(llvm_function.getArgumentList().begin()); 23248bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 23253c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton if (iter == llvm_function.getArgumentList().end()) 232697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan { 232797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 232897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes no arguments (should take at least a struct pointer)"); 232997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 23308bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan return false; 233197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan } 233297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 233302fbafa1bf2bb77bf8f25af3403d7d8721a3f8b1Sean Callanan Argument *argument = iter; 23348bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 23353c9c5eb466869ede185e879d14a47335fb43194dSean Callanan if (argument->getName().equals("this")) 23363c9c5eb466869ede185e879d14a47335fb43194dSean Callanan { 23373c9c5eb466869ede185e879d14a47335fb43194dSean Callanan ++iter; 23383c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 23393c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton if (iter == llvm_function.getArgumentList().end()) 234097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan { 234197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 234297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes only 'this' argument (should take a struct pointer too)"); 234397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 23443c9c5eb466869ede185e879d14a47335fb43194dSean Callanan return false; 234597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan } 23463c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 23473c9c5eb466869ede185e879d14a47335fb43194dSean Callanan argument = iter; 23483c9c5eb466869ede185e879d14a47335fb43194dSean Callanan } 23493aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan else if (argument->getName().equals("self")) 23503aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan { 23513aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan ++iter; 23523aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan 23533aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan if (iter == llvm_function.getArgumentList().end()) 235497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan { 235597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 235697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes only 'self' argument (should take '_cmd' and a struct pointer too)"); 235797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 23583aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan return false; 235997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan } 23603aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan 23613aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan if (!iter->getName().equals("_cmd")) 236297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan { 236397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 236497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes '%s' after 'self' argument (should take '_cmd')", iter->getName().str().c_str()); 236597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 23663aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan return false; 236797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan } 23683aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan 23693aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan ++iter; 23703aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan 23713aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan if (iter == llvm_function.getArgumentList().end()) 237297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan { 237397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 237497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes only 'self' and '_cmd' arguments (should take a struct pointer too)"); 237597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 23763aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan return false; 237797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan } 23783aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan 23793aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan argument = iter; 23803aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan } 23813c9c5eb466869ede185e879d14a47335fb43194dSean Callanan 23828de27c761a22187ef63fb60000894be163e7285fGreg Clayton if (!argument->getName().equals("$__lldb_arg")) 238397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan { 238497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 238597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes an argument named '%s' instead of the struct pointer", argument->getName().str().c_str()); 238697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 23878bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan return false; 238897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan } 238997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 23905cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan if (log) 2391b5037af312160b2f396aad579e45619af3126e4aGreg Clayton log->Printf("Arg: \"%s\"", PrintValue(argument).c_str()); 23928bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 23933c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton BasicBlock &entry_block(llvm_function.getEntryBlock()); 23946ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg()); 23958bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 23966ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan if (!FirstEntryInstruction) 239797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan { 239897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 239997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Couldn't find the first instruction in the wrapper for use in rewriting"); 240097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 24018bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan return false; 240297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan } 24038bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 2404c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan LLVMContext &context(m_module->getContext()); 24059b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan IntegerType *offset_type(Type::getInt32Ty(context)); 24068bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 24078bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan if (!offset_type) 240897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan { 240997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 241097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Couldn't produce an offset type"); 241197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 24128bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan return false; 241397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan } 24148bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 24158bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan for (element_index = 0; element_index < num_elements; ++element_index) 24165cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan { 241758baaada202ea16e928f0c76e9124d42fd3655cdSean Callanan const clang::NamedDecl *decl = NULL; 241858baaada202ea16e928f0c76e9124d42fd3655cdSean Callanan Value *value = NULL; 24198bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan off_t offset; 24208de27c761a22187ef63fb60000894be163e7285fGreg Clayton lldb_private::ConstString name; 24215cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 242245690fe3b8b4efb101dd31085413381021a69c2fSean Callanan if (!m_decl_map->GetStructElement (decl, value, offset, name, element_index)) 242397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan { 242497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 242597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Structure information is incomplete"); 242697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 24278bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan return false; 242897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan } 242997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 24308bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan if (log) 24315f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea log->Printf(" \"%s\" (\"%s\") placed at %" PRId64, 24328de27c761a22187ef63fb60000894be163e7285fGreg Clayton name.GetCString(), 2433c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan decl->getNameAsString().c_str(), 24348bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan offset); 24354a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 2436c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan if (value) 24376a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan { 2438c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan if (log) 2439c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan log->Printf(" Replacing [%s]", PrintValue(value).c_str()); 24406a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan 24414a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan FunctionValueCache body_result_maker ([this, name, offset_type, offset, argument, value] (llvm::Function *function)->llvm::Value * { 24424a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, in cases where the result 24434a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan // variable is an rvalue, we have to synthesize a dereference of the appropriate structure 24444a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan // entry in order to produce the static variable that the AST thinks it is accessing. 2445c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 24464a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan llvm::Instruction *entry_instruction = llvm::cast<Instruction>(m_entry_instruction_finder.GetValue(function)); 2447c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 24484a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan ConstantInt *offset_int(ConstantInt::get(offset_type, offset, true)); 24494a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(argument, 24504a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan offset_int, 24514a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan "", 24524a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan entry_instruction); 24534a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 24544a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (name == m_result_name && !m_result_is_pointer) 24554a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 24564a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan BitCastInst *bit_cast = new BitCastInst(get_element_ptr, 24574a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan value->getType()->getPointerTo(), 24584a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan "", 24594a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan entry_instruction); 24604a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 24614a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan LoadInst *load = new LoadInst(bit_cast, "", entry_instruction); 24624a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 24634a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return load; 24644a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan } 24654a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan else 24664a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 24674a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", entry_instruction); 24684a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 24694a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return bit_cast; 24704a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan } 24714a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan }); 24724a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 24734a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (Constant *constant = dyn_cast<Constant>(value)) 24744a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 24754a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan UnfoldConstant(constant, body_result_maker, m_entry_instruction_finder); 2476c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan } 24774a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan else if (Instruction *instruction = dyn_cast<Instruction>(value)) 2478c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan { 24794a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan value->replaceAllUsesWith(body_result_maker.GetValue(instruction->getParent()->getParent())); 2480c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan } 2481c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan else 24824a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 24834a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (log) 24844a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan log->Printf("Unhandled non-constant type: \"%s\"", PrintValue(value).c_str()); 24854a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return false; 24864a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan } 2487c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan 2488c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan if (GlobalVariable *var = dyn_cast<GlobalVariable>(value)) 2489c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan var->eraseFromParent(); 2490c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan } 24915cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan } 24925cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 24938bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan if (log) 24945f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea log->Printf("Total structure [align %" PRId64 ", size %lu]", alignment, size); 24958bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 24965cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan return true; 24975cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan} 24985cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 2499c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callananllvm::Constant * 2500952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg ClaytonIRForTarget::BuildRelocation(llvm::Type *type, uint64_t offset) 2501c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan{ 25029b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(), 25034fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32); 2504c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2505c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan llvm::Constant *offset_int = ConstantInt::get(intptr_ty, offset); 25069b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 25079b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan llvm::Constant *offset_array[1]; 25089b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 25099b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan offset_array[0] = offset_int; 25109b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 25119b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1); 25129b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan 25139b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(m_reloc_placeholder, offsets); 2514c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan llvm::Constant *reloc_getbitcast = ConstantExpr::getBitCast(reloc_getelementptr, type); 2515c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2516c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan return reloc_getbitcast; 2517c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan} 2518c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2519c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callananbool 2520c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::CompleteDataAllocation () 25211cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan{ 2522952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 2523c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 25241cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan if (!m_data_allocator.GetStream().GetSize()) 2525c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan return true; 2526c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 25271cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan lldb::addr_t allocation = m_data_allocator.Allocate(); 2528c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2529c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (log) 2530c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 2531c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (allocation) 2532c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan log->Printf("Allocated static data at 0x%llx", (unsigned long long)allocation); 2533c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan else 2534c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan log->Printf("Failed to allocate static data"); 2535c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 2536c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 25371cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan if (!allocation || allocation == LLDB_INVALID_ADDRESS) 2538c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan return false; 2539c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 25409b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(), 25414fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32); 2542c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2543c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan Constant *relocated_addr = ConstantInt::get(intptr_ty, (uint64_t)allocation); 2544c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan Constant *relocated_bitcast = ConstantExpr::getIntToPtr(relocated_addr, llvm::Type::getInt8PtrTy(m_module->getContext())); 2545c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2546c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan m_reloc_placeholder->replaceAllUsesWith(relocated_bitcast); 2547c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2548c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan m_reloc_placeholder->eraseFromParent(); 2549c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2550c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan return true; 2551c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan} 2552c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 25535cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callananbool 255406dc17f8eb821d7256fd42e56f85c2779a29f689Sean CallananIRForTarget::StripAllGVs (Module &llvm_module) 255506dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan{ 2556952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 255706dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan std::vector<GlobalVariable *> global_vars; 255806dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan std::set<GlobalVariable *>erased_vars; 255906dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan 256006dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan bool erased = true; 256106dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan 256206dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan while (erased) 256306dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan { 256406dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan erased = false; 256506dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan 256606dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan for (Module::global_iterator gi = llvm_module.global_begin(), ge = llvm_module.global_end(); 256706dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan gi != ge; 256806dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan ++gi) 256906dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan { 257006dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan GlobalVariable *global_var = dyn_cast<GlobalVariable>(gi); 257106dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan 257206dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan global_var->removeDeadConstantUsers(); 257306dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan 257406dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan if (global_var->use_empty()) 257506dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan { 257606dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan if (log) 257706dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan log->Printf("Did remove %s", 257806dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan PrintValue(global_var).c_str()); 257906dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan global_var->eraseFromParent(); 258006dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan erased = true; 258106dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan break; 258206dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan } 258306dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan } 258406dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan } 258506dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan 258606dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan for (Module::global_iterator gi = llvm_module.global_begin(), ge = llvm_module.global_end(); 258706dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan gi != ge; 258806dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan ++gi) 258906dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan { 259006dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan GlobalVariable *global_var = dyn_cast<GlobalVariable>(gi); 259106dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan 259206dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan GlobalValue::use_iterator ui = global_var->use_begin(); 259306dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan 25940052123c1f8cd5ad42756f0205e93c9fd11bdcb2Jim Ingham if (log) 25950052123c1f8cd5ad42756f0205e93c9fd11bdcb2Jim Ingham log->Printf("Couldn't remove %s because of %s", 25960052123c1f8cd5ad42756f0205e93c9fd11bdcb2Jim Ingham PrintValue(global_var).c_str(), 25970052123c1f8cd5ad42756f0205e93c9fd11bdcb2Jim Ingham PrintValue(*ui).c_str()); 259806dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan } 259906dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan 260006dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan return true; 260106dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan} 260206dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan 260306dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callananbool 26043c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg ClaytonIRForTarget::runOnModule (Module &llvm_module) 26055cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan{ 2606952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 26075cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 2608c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan m_module = &llvm_module; 26093051ed73a487e92f12f8b6062f8415781453da21Micah Villmow m_target_data.reset(new DataLayout(m_module)); 26104a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 26114a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (log) 26124a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 26134a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan std::string s; 26144a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan raw_string_ostream oss(s); 26154a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 26164a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan m_module->print(oss, NULL); 26174a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 26184a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan oss.flush(); 26194a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 26204a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str()); 26214a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan } 2622c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 26234a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan Function* main_function = m_module->getFunction(StringRef(m_func_name.c_str())); 26245cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 26254a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (!main_function) 26265cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan { 26275cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan if (log) 2628b5037af312160b2f396aad579e45619af3126e4aGreg Clayton log->Printf("Couldn't find \"%s()\" in the module", m_func_name.c_str()); 262997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 263097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan if (m_error_stream) 2631c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan m_error_stream->Printf("Internal error [IRForTarget]: Couldn't find wrapper '%s' in the module", m_func_name.c_str()); 26326a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan 26335cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan return false; 26345cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan } 2635c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 26364a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (!FixFunctionLinkage (*main_function)) 2637c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 2638c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (log) 2639c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan log->Printf("Couldn't fix the linkage for the function"); 2640c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2641c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan return false; 2642c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 2643c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 26449b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan llvm::Type *intptr_ty = Type::getInt8Ty(m_module->getContext()); 2645c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 26464a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan m_reloc_placeholder = new llvm::GlobalVariable((*m_module), 2647c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan intptr_ty, 264806dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan false /* IsConstant */, 2649c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan GlobalVariable::InternalLinkage, 2650c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan Constant::getNullValue(intptr_ty), 2651c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan "reloc_placeholder", 2652c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan NULL /* InsertBefore */, 265306dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan GlobalVariable::NotThreadLocal /* ThreadLocal */, 2654c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 0 /* AddressSpace */); 26554a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 265682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan //////////////////////////////////////////////////////////// 26578de27c761a22187ef63fb60000894be163e7285fGreg Clayton // Replace $__lldb_expr_result with a persistent variable 265882b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan // 265982b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan 26604a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (!CreateResultVariable(*main_function)) 26613aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan { 26623aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan if (log) 26633aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan log->Printf("CreateResultVariable() failed"); 266497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 266597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan // CreateResultVariable() reports its own errors, so we don't do so here 266697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 266782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan return false; 26683aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan } 26691850f94688f9362c78c27e5472afe022a56c08dfSean Callanan 26707b8eb76b6e96913bd26a6f5ad9d7667a66aabbc3Sean Callanan if (log && log->GetVerbose()) 2671c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 2672c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan std::string s; 2673c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan raw_string_ostream oss(s); 2674c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2675c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan m_module->print(oss, NULL); 2676c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2677c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan oss.flush(); 2678c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2679c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan log->Printf("Module after creating the result variable: \n\"%s\"", s.c_str()); 2680c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 2681c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 26824a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan for (Module::iterator fi = m_module->begin(), fe = m_module->end(); 26834a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan fi != fe; 26844a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan ++fi) 26854a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 26864a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan llvm::Function *function = fi; 26874a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 26884a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (function->begin() == function->end()) 26894a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan continue; 26904a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 26914a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan Function::iterator bbi; 26924a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 26934a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan for (bbi = function->begin(); 26944a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan bbi != function->end(); 26954a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan ++bbi) 26964a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 26974a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (!RemoveGuards(*bbi)) 26984a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 26994a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (log) 27004a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan log->Printf("RemoveGuards() failed"); 27014a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 27024a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan // RemoveGuards() reports its own errors, so we don't do so here 27034a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 27044a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return false; 27054a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan } 27064a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 27074a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (!RewritePersistentAllocs(*bbi)) 27084a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 27094a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (log) 27104a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan log->Printf("RewritePersistentAllocs() failed"); 27114a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 27124a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan // RewritePersistentAllocs() reports its own errors, so we don't do so here 27134a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 27144a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return false; 27154a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan } 27164a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 27174a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (!RemoveCXAAtExit(*bbi)) 27184a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 27194a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (log) 27204a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan log->Printf("RemoveCXAAtExit() failed"); 27214a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 27224a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan // RemoveCXAAtExit() reports its own errors, so we don't do so here 27234a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 27244a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return false; 27254a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan } 27264a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan } 27274a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan } 27284a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 27296ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan /////////////////////////////////////////////////////////////////////////////// 27306ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // Fix all Objective-C constant strings to use NSStringWithCString:encoding: 27316ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan // 27324a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 27334a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (!RewriteObjCConstStrings()) 27343aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan { 27353aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan if (log) 27363aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan log->Printf("RewriteObjCConstStrings() failed"); 273797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 273897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan // RewriteObjCConstStrings() reports its own errors, so we don't do so here 273997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 27406ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan return false; 27413aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan } 27426ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan 27435c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan /////////////////////////////// 27445c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan // Resolve function pointers 27455c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan // 27465c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 27474a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (!ResolveFunctionPointers(llvm_module)) 27485c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan { 27495c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan if (log) 27505c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan log->Printf("ResolveFunctionPointers() failed"); 27515c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 27525c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan // ResolveFunctionPointers() reports its own errors, so we don't do so here 27535c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 27545c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan return false; 27555c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan } 27565c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan 27574a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan for (Module::iterator fi = m_module->begin(), fe = m_module->end(); 27584a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan fi != fe; 27594a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan ++fi) 27605cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan { 27614a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan llvm::Function *function = fi; 27624a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 27634a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan for (llvm::Function::iterator bbi = function->begin(), bbe = function->end(); 27644a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan bbi != bbe; 27654a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan ++bbi) 27663aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan { 27674a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (!RewriteObjCSelectors(*bbi)) 27684a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 27694a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (log) 27704a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan log->Printf("RewriteObjCSelectors() failed"); 27714a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 27724a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan // RewriteObjCSelectors() reports its own errors, so we don't do so here 27734a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 27744a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return false; 27754a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan } 27763aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan } 2777083b37663cb6d880f989c6887085edf499e4525fSean Callanan } 2778a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan 27794a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan for (Module::iterator fi = m_module->begin(), fe = m_module->end(); 27804a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan fi != fe; 27814a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan ++fi) 2782083b37663cb6d880f989c6887085edf499e4525fSean Callanan { 27834a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan llvm::Function *function = fi; 2784c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 27854a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan for (llvm::Function::iterator bbi = function->begin(), bbe = function->end(); 27864a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan bbi != bbe; 27874a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan ++bbi) 2788c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 27894a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (!ResolveCalls(*bbi)) 27904a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 27914a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (log) 27924a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan log->Printf("ResolveCalls() failed"); 27934a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 27944a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan // ResolveCalls() reports its own errors, so we don't do so here 27954a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 27964a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return false; 27974a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan } 2798c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 27994a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (!ReplaceStaticLiterals(*bbi)) 28004a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan { 28014a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (log) 28024a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan log->Printf("ReplaceStaticLiterals() failed"); 28034a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 28044a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan return false; 28054a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan } 2806c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 28078bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan } 28084a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 28094a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan //////////////////////////////////////////////////////////////////////// 28104a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan // Run function-level passes that only make sense on the main function 2811771131d04344e57abb340699f54dce77a511bc71Sean Callanan // 2812771131d04344e57abb340699f54dce77a511bc71Sean Callanan 28134a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (!ResolveExternals(*main_function)) 28143aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan { 28153aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan if (log) 28163aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan log->Printf("ResolveExternals() failed"); 281797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 281897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan // ResolveExternals() reports its own errors, so we don't do so here 281997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 28201d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan return false; 28213aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan } 28221d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan 28234a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan if (!ReplaceVariables(*main_function)) 28243aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan { 28253aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan if (log) 28263aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan log->Printf("ReplaceVariables() failed"); 282797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 282897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan // ReplaceVariables() reports its own errors, so we don't do so here 282997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan 2830771131d04344e57abb340699f54dce77a511bc71Sean Callanan return false; 28313aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan } 28324a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 2833c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (!ReplaceStrings()) 2834c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 2835c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (log) 2836c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan log->Printf("ReplaceStrings() failed"); 2837c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2838c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan return false; 2839c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 2840c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2841c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (!CompleteDataAllocation()) 2842c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 2843c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (log) 2844c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan log->Printf("CompleteDataAllocation() failed"); 2845c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 2846c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan return false; 2847c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 28484a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan 284906dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan if (!StripAllGVs(llvm_module)) 285006dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan { 285106dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan if (log) 285206dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan log->Printf("StripAllGVs() failed"); 285306dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan } 285406dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan 28557b8eb76b6e96913bd26a6f5ad9d7667a66aabbc3Sean Callanan if (log && log->GetVerbose()) 28568bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan { 2857321fe9e06c68dfeed55839d71603713b1ea3bb70Sean Callanan std::string s; 2858321fe9e06c68dfeed55839d71603713b1ea3bb70Sean Callanan raw_string_ostream oss(s); 2859321fe9e06c68dfeed55839d71603713b1ea3bb70Sean Callanan 2860c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan m_module->print(oss, NULL); 2861321fe9e06c68dfeed55839d71603713b1ea3bb70Sean Callanan 2862321fe9e06c68dfeed55839d71603713b1ea3bb70Sean Callanan oss.flush(); 28638bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan 2864b5037af312160b2f396aad579e45619af3126e4aGreg Clayton log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str()); 28655cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan } 28665cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 28675cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan return true; 28685cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan} 28695cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 28705cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callananvoid 28713c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg ClaytonIRForTarget::assignPassManager (PMStack &pass_mgr_stack, PassManagerType pass_mgr_type) 28725cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan{ 28735cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan} 28745cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan 28755cf4a1ca412654c3f912e2b3cea931fb814f322fSean CallananPassManagerType 28765cf4a1ca412654c3f912e2b3cea931fb814f322fSean CallananIRForTarget::getPotentialPassManagerType() const 28775cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan{ 28785cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan return PMT_ModulePassManager; 28795cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan} 2880