diff options
Diffstat (limited to 'lib/ExecutionEngine')
19 files changed, 359 insertions, 238 deletions
diff --git a/lib/ExecutionEngine/EventListenerCommon.h b/lib/ExecutionEngine/EventListenerCommon.h index 1c07c94..911d1d6 100644 --- a/lib/ExecutionEngine/EventListenerCommon.h +++ b/lib/ExecutionEngine/EventListenerCommon.h @@ -14,8 +14,8 @@ #ifndef EVENT_LISTENER_COMMON_H #define EVENT_LISTENER_COMMON_H +#include "llvm/DebugInfo.h" #include "llvm/Metadata.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/ValueHandle.h" #include "llvm/Support/Path.h" diff --git a/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp b/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp index 5dfa78f..c11c17e 100644 --- a/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp +++ b/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp @@ -16,11 +16,11 @@ #include "llvm/ExecutionEngine/JITEventListener.h" #define DEBUG_TYPE "amplifier-jit-event-listener" +#include "llvm/DebugInfo.h" #include "llvm/Function.h" #include "llvm/Metadata.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/OwningPtr.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/ExecutionEngine/IntelJITEventsWrapper.h" #include "llvm/Support/Debug.h" @@ -138,7 +138,7 @@ void IntelJITEventListener::NotifyFunctionEmitted( // the first instruction that has one if (FunctionMessage.source_file_name == 0) { MDNode *scope = I->Loc.getScope( - Details.MF->getFunction()->getContext()); + Details.MF->getFunction()->getContext()); FunctionMessage.source_file_name = const_cast<char*>( Filenames.getFullPath(scope)); } @@ -152,7 +152,7 @@ void IntelJITEventListener::NotifyFunctionEmitted( } Wrapper.iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, - &FunctionMessage); + &FunctionMessage); MethodIDs[FnStart] = FunctionMessage.method_id; } diff --git a/lib/ExecutionEngine/Interpreter/CMakeLists.txt b/lib/ExecutionEngine/Interpreter/CMakeLists.txt index d331f83..74df8f0 100644 --- a/lib/ExecutionEngine/Interpreter/CMakeLists.txt +++ b/lib/ExecutionEngine/Interpreter/CMakeLists.txt @@ -15,3 +15,5 @@ add_llvm_library(LLVMInterpreter if( LLVM_ENABLE_FFI ) target_link_libraries( LLVMInterpreter ${FFI_LIBRARY_PATH} ) endif() + +add_dependencies(LLVMInterpreter intrinsics_gen) diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index af47be9..5202b09 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -651,11 +651,40 @@ void Interpreter::visitSwitchInst(SwitchInst &I) { // Check to see if any of the cases match... BasicBlock *Dest = 0; for (SwitchInst::CaseIt i = I.case_begin(), e = I.case_end(); i != e; ++i) { - GenericValue CaseVal = getOperandValue(i.getCaseValue(), SF); - if (executeICMP_EQ(CondVal, CaseVal, ElTy).IntVal != 0) { - Dest = cast<BasicBlock>(i.getCaseSuccessor()); - break; + IntegersSubset& Case = i.getCaseValueEx(); + if (Case.isSingleNumber()) { + // FIXME: Currently work with ConstantInt based numbers. + const ConstantInt *CI = Case.getSingleNumber(0).toConstantInt(); + GenericValue Val = getOperandValue(const_cast<ConstantInt*>(CI), SF); + if (executeICMP_EQ(Val, CondVal, ElTy).IntVal != 0) { + Dest = cast<BasicBlock>(i.getCaseSuccessor()); + break; + } } + if (Case.isSingleNumbersOnly()) { + for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) { + // FIXME: Currently work with ConstantInt based numbers. + const ConstantInt *CI = Case.getSingleNumber(n).toConstantInt(); + GenericValue Val = getOperandValue(const_cast<ConstantInt*>(CI), SF); + if (executeICMP_EQ(Val, CondVal, ElTy).IntVal != 0) { + Dest = cast<BasicBlock>(i.getCaseSuccessor()); + break; + } + } + } else + for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) { + IntegersSubset::Range r = Case.getItem(n); + // FIXME: Currently work with ConstantInt based numbers. + const ConstantInt *LowCI = r.getLow().toConstantInt(); + const ConstantInt *HighCI = r.getHigh().toConstantInt(); + GenericValue Low = getOperandValue(const_cast<ConstantInt*>(LowCI), SF); + GenericValue High = getOperandValue(const_cast<ConstantInt*>(HighCI), SF); + if (executeICMP_ULE(Low, CondVal, ElTy).IntVal != 0 && + executeICMP_ULE(CondVal, High, ElTy).IntVal != 0) { + Dest = cast<BasicBlock>(i.getCaseSuccessor()); + break; + } + } } if (!Dest) Dest = I.getDefaultDest(); // No cases matched: use default SwitchToNewBasicBlock(Dest, SF); diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp index a942299..97995ad 100644 --- a/lib/ExecutionEngine/JIT/JIT.cpp +++ b/lib/ExecutionEngine/JIT/JIT.cpp @@ -361,7 +361,7 @@ bool JIT::removeModule(Module *M) { MutexGuard locked(lock); - if (jitstate->getModule() == M) { + if (jitstate && jitstate->getModule() == M) { delete jitstate; jitstate = 0; } @@ -433,13 +433,18 @@ GenericValue JIT::runFunction(Function *F, } break; case 1: - if (FTy->getNumParams() == 1 && - FTy->getParamType(0)->isIntegerTy(32)) { + if (FTy->getParamType(0)->isIntegerTy(32)) { GenericValue rv; int (*PF)(int) = (int(*)(int))(intptr_t)FPtr; rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue())); return rv; } + if (FTy->getParamType(0)->isPointerTy()) { + GenericValue rv; + int (*PF)(char *) = (int(*)(char *))(intptr_t)FPtr; + rv.IntVal = APInt(32, PF((char*)GVTOP(ArgValues[0]))); + return rv; + } break; } } diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index 504c8bd..ff3a9dc 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -17,9 +17,9 @@ #include "JITDwarfEmitter.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Constants.h" -#include "llvm/Module.h" +#include "llvm/DebugInfo.h" #include "llvm/DerivedTypes.h" -#include "llvm/Analysis/DebugInfo.h" +#include "llvm/Module.h" #include "llvm/CodeGen/JITCodeEmitter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineCodeInfo.h" @@ -108,13 +108,18 @@ namespace { /// particular GlobalVariable so that we can reuse them if necessary. GlobalToIndirectSymMapTy GlobalToIndirectSymMap; +#ifndef NDEBUG /// Instance of the JIT this ResolverState serves. JIT *TheJIT; +#endif public: JITResolverState(JIT *jit) : FunctionToLazyStubMap(this), - FunctionToCallSitesMap(this), - TheJIT(jit) {} + FunctionToCallSitesMap(this) { +#ifndef NDEBUG + TheJIT = jit; +#endif + } FunctionToLazyStubMapTy& getFunctionToLazyStubMap( const MutexGuard& locked) { diff --git a/lib/ExecutionEngine/JIT/JITMemoryManager.cpp b/lib/ExecutionEngine/JIT/JITMemoryManager.cpp index 2d1775c..7be6ef8 100644 --- a/lib/ExecutionEngine/JIT/JITMemoryManager.cpp +++ b/lib/ExecutionEngine/JIT/JITMemoryManager.cpp @@ -852,7 +852,7 @@ static int jit_noop() { /// for resolving library symbols, not code generated symbols. /// void *DefaultJITMemoryManager::getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure) { + bool AbortOnFailure) { // Check to see if this is one of the functions we want to intercept. Note, // we cast to intptr_t here to silence a -pedantic warning that complains // about casting a function pointer to a normal pointer. diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp index 44f89cf..739ffd7d8 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/MutexGuard.h" #include "llvm/Target/TargetData.h" using namespace llvm; @@ -45,7 +46,7 @@ ExecutionEngine *MCJIT::createJIT(Module *M, // If the target supports JIT code generation, create the JIT. if (TargetJITInfo *TJ = TM->getJITInfo()) - return new MCJIT(M, TM, *TJ, new MCJITMemoryManager(JMM, M), GVsWithCode); + return new MCJIT(M, TM, *TJ, new MCJITMemoryManager(JMM), GVsWithCode); if (ErrorStr) *ErrorStr = "target does not support JIT code generation"; @@ -54,9 +55,35 @@ ExecutionEngine *MCJIT::createJIT(Module *M, MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji, RTDyldMemoryManager *MM, bool AllocateGVsWithCode) - : ExecutionEngine(m), TM(tm), MemMgr(MM), M(m), OS(Buffer), Dyld(MM) { + : ExecutionEngine(m), TM(tm), Ctx(0), MemMgr(MM), Dyld(MM), + isCompiled(false), M(m), OS(Buffer) { setTargetData(TM->getTargetData()); +} + +MCJIT::~MCJIT() { + delete MemMgr; + delete TM; +} + +void MCJIT::emitObject(Module *m) { + /// Currently, MCJIT only supports a single module and the module passed to + /// this function call is expected to be the contained module. The module + /// is passed as a parameter here to prepare for multiple module support in + /// the future. + assert(M == m); + + // Get a thread lock to make sure we aren't trying to compile multiple times + MutexGuard locked(lock); + + // FIXME: Track compilation state on a per-module basis when multiple modules + // are supported. + // Re-compilation is not supported + if (isCompiled) + return; + + PassManager PM; + PM.add(new TargetData(*TM->getTargetData())); // Turn the machine code intermediate representation into bytes in memory @@ -69,23 +96,22 @@ MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji, // FIXME: When we support multiple modules, we'll want to move the code // gen and finalization out of the constructor here and do it more // on-demand as part of getPointerToFunction(). - PM.run(*M); + PM.run(*m); // Flush the output buffer so the SmallVector gets its data. OS.flush(); // Load the object into the dynamic linker. - MemoryBuffer *MB = MemoryBuffer::getMemBuffer(StringRef(Buffer.data(), + MemoryBuffer* MB = MemoryBuffer::getMemBuffer(StringRef(Buffer.data(), Buffer.size()), "", false); if (Dyld.loadObject(MB)) report_fatal_error(Dyld.getErrorString()); + // Resolve any relocations. Dyld.resolveRelocations(); -} -MCJIT::~MCJIT() { - delete MemMgr; - delete TM; + // FIXME: Add support for per-module compilation state + isCompiled = true; } void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) { @@ -93,6 +119,10 @@ void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) { } void *MCJIT::getPointerToFunction(Function *F) { + // FIXME: Add support for per-module compilation state + if (!isCompiled) + emitObject(M); + if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) { bool AbortOnFailure = !F->hasExternalWeakLinkage(); void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure); @@ -100,6 +130,7 @@ void *MCJIT::getPointerToFunction(Function *F) { return Addr; } + // FIXME: Should the Dyld be retaining module information? Probably not. // FIXME: Should we be using the mangler for this? Probably. StringRef BaseName = F->getName(); if (BaseName[0] == '\1') @@ -217,7 +248,11 @@ GenericValue MCJIT::runFunction(Function *F, } void *MCJIT::getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure){ + bool AbortOnFailure) { + // FIXME: Add support for per-module compilation state + if (!isCompiled) + emitObject(M); + if (!isSymbolSearchingDisabled() && MemMgr) { void *ptr = MemMgr->getPointerToNamedFunction(Name, false); if (ptr) @@ -231,7 +266,7 @@ void *MCJIT::getPointerToNamedFunction(const std::string &Name, if (AbortOnFailure) { report_fatal_error("Program used external function '"+Name+ - "' which could not be resolved!"); + "' which could not be resolved!"); } return 0; } diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.h b/lib/ExecutionEngine/MCJIT/MCJIT.h index 2b3df98..1d272e9 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.h +++ b/lib/ExecutionEngine/MCJIT/MCJIT.h @@ -29,17 +29,16 @@ class MCJIT : public ExecutionEngine { TargetMachine *TM; MCContext *Ctx; RTDyldMemoryManager *MemMgr; + RuntimeDyld Dyld; - // FIXME: These may need moved to a separate 'jitstate' member like the - // non-MC JIT does for multithreading and such. Just keep them here for now. - PassManager PM; + // FIXME: Add support for multiple modules + bool isCompiled; Module *M; - // FIXME: This really doesn't belong here. + + // FIXME: Move these to a single container which manages JITed objects SmallVector<char, 4096> Buffer; // Working buffer into which we JIT. raw_svector_ostream OS; - RuntimeDyld Dyld; - public: ~MCJIT(); @@ -91,6 +90,14 @@ public: TargetMachine *TM); // @} + +protected: + /// emitObject -- Generate a JITed object in memory from the specified module + /// Currently, MCJIT only supports a single module and the module passed to + /// this function call is expected to be the contained module. The module + /// is passed as a parameter here to prepare for multiple module support in + /// the future. + void emitObject(Module *M); }; } // End llvm namespace diff --git a/lib/ExecutionEngine/MCJIT/MCJITMemoryManager.h b/lib/ExecutionEngine/MCJIT/MCJITMemoryManager.h index a68949a..441aaeb 100644 --- a/lib/ExecutionEngine/MCJIT/MCJITMemoryManager.h +++ b/lib/ExecutionEngine/MCJIT/MCJITMemoryManager.h @@ -22,24 +22,20 @@ namespace llvm { // matching LLVM IR counterparts in the module(s) being compiled. class MCJITMemoryManager : public RTDyldMemoryManager { virtual void anchor(); - JITMemoryManager *JMM; + OwningPtr<JITMemoryManager> JMM; - // FIXME: Multiple modules. - Module *M; public: - MCJITMemoryManager(JITMemoryManager *jmm, Module *m) : - JMM(jmm?jmm:JITMemoryManager::CreateDefaultMemManager()), M(m) {} - // We own the JMM, so make sure to delete it. - ~MCJITMemoryManager() { delete JMM; } + MCJITMemoryManager(JITMemoryManager *jmm) : + JMM(jmm?jmm:JITMemoryManager::CreateDefaultMemManager()) {} uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) { - return JMM->allocateSpace(Size, Alignment); + return JMM->allocateDataSection(Size, Alignment, SectionID); } uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) { - return JMM->allocateSpace(Size, Alignment); + return JMM->allocateCodeSection(Size, Alignment, SectionID); } virtual void *getPointerToNamedFunction(const std::string &Name, diff --git a/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp b/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp index e6142e3..6b8e9d1 100644 --- a/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp +++ b/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp @@ -16,9 +16,9 @@ #include "llvm/ExecutionEngine/JITEventListener.h" #define DEBUG_TYPE "oprofile-jit-event-listener" +#include "llvm/DebugInfo.h" #include "llvm/Function.h" #include "llvm/ADT/OwningPtr.h" -#include "llvm/Analysis/DebugInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/ExecutionEngine/OProfileWrapper.h" #include "llvm/Support/Debug.h" diff --git a/lib/ExecutionEngine/RuntimeDyld/ObjectImage.h b/lib/ExecutionEngine/RuntimeDyld/ObjectImage.h index 8206ead..c3e3572 100644 --- a/lib/ExecutionEngine/RuntimeDyld/ObjectImage.h +++ b/lib/ExecutionEngine/RuntimeDyld/ObjectImage.h @@ -48,7 +48,7 @@ public: virtual void updateSymbolAddress(const object::SymbolRef &Sym, uint64_t Addr) {} - // Subclasses can override this method to provide JIT debugging support + // Subclasses can override these methods to provide JIT debugging support virtual void registerWithDebugger() {} virtual void deregisterWithDebugger() {} }; diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 1b1840a..b464040 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -39,7 +39,7 @@ namespace { // Resolve the relocations for all symbols we currently know about. void RuntimeDyldImpl::resolveRelocations() { // First, resolve relocations associated with external symbols. - resolveSymbols(); + resolveExternalSymbols(); // Just iterate over the sections we have and resolve all the relocations // in them. Gross overkill, but it gets the job done. @@ -59,8 +59,8 @@ void RuntimeDyldImpl::mapSectionAddress(void *LocalAddress, llvm_unreachable("Attempting to remap address of unknown section!"); } -// Subclasses can implement this method to create specialized image instances -// The caller owns the the pointer that is returned. +// Subclasses can implement this method to create specialized image instances. +// The caller owns the pointer that is returned. ObjectImage *RuntimeDyldImpl::createObjectImage(const MemoryBuffer *InputBuffer) { ObjectFile *ObjFile = ObjectFile::createObjectFile(const_cast<MemoryBuffer*> (InputBuffer)); @@ -75,11 +75,15 @@ bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) { Arch = (Triple::ArchType)obj->getArch(); - LocalSymbolMap LocalSymbols; // Functions and data symbols from the - // object file. - ObjSectionToIDMap LocalSections; // Used sections from the object file - CommonSymbolMap CommonSymbols; // Common symbols requiring allocation - uint64_t CommonSize = 0; + // Symbols found in this object + StringMap<SymbolLoc> LocalSymbols; + // Used sections from the object file + ObjSectionToIDMap LocalSections; + + // Common symbols requiring allocation, and the total size required to + // allocate all common symbols. + CommonSymbolMap CommonSymbols; + uint64_t CommonSize = 0; error_code err; // Parse symbols @@ -106,28 +110,29 @@ bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) { if (SymType == object::SymbolRef::ST_Function || SymType == object::SymbolRef::ST_Data) { uint64_t FileOffset; - StringRef sData; + StringRef SectionData; section_iterator si = obj->end_sections(); Check(i->getFileOffset(FileOffset)); Check(i->getSection(si)); if (si == obj->end_sections()) continue; - Check(si->getContents(sData)); + Check(si->getContents(SectionData)); const uint8_t* SymPtr = (const uint8_t*)InputBuffer->getBufferStart() + (uintptr_t)FileOffset; - uintptr_t SectOffset = (uintptr_t)(SymPtr - (const uint8_t*)sData.begin()); + uintptr_t SectOffset = (uintptr_t)(SymPtr - + (const uint8_t*)SectionData.begin()); unsigned SectionID = findOrEmitSection(*obj, *si, SymType == object::SymbolRef::ST_Function, LocalSections); - bool isGlobal = flags & SymbolRef::SF_Global; LocalSymbols[Name.data()] = SymbolLoc(SectionID, SectOffset); DEBUG(dbgs() << "\tFileOffset: " << format("%p", (uintptr_t)FileOffset) << " flags: " << flags << " SID: " << SectionID << " Offset: " << format("%p", SectOffset)); + bool isGlobal = flags & SymbolRef::SF_Global; if (isGlobal) - SymbolTable[Name] = SymbolLoc(SectionID, SectOffset); + GlobalSymbolTable[Name] = SymbolLoc(SectionID, SectOffset); } } DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name << "\n"); @@ -137,7 +142,7 @@ bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) { if (CommonSize != 0) emitCommonSymbols(*obj, CommonSymbols, CommonSize, LocalSymbols); - // Parse and proccess relocations + // Parse and process relocations DEBUG(dbgs() << "Parse relocations:\n"); for (section_iterator si = obj->begin_sections(), se = obj->end_sections(); si != se; si.increment(err)) { @@ -150,7 +155,7 @@ bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) { e = si->end_relocations(); i != e; i.increment(err)) { Check(err); - // If it's first relocation in this section, find its SectionID + // If it's the first relocation in this section, find its SectionID if (isFirstRelocation) { SectionID = findOrEmitSection(*obj, *si, true, LocalSections); DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n"); @@ -177,10 +182,10 @@ bool RuntimeDyldImpl::loadObject(const MemoryBuffer *InputBuffer) { return false; } -unsigned RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj, - const CommonSymbolMap &Map, - uint64_t TotalSize, - LocalSymbolMap &LocalSymbols) { +void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj, + const CommonSymbolMap &CommonSymbols, + uint64_t TotalSize, + SymbolTableMap &SymbolTable) { // Allocate memory for the section unsigned SectionID = Sections.size(); uint8_t *Addr = MemMgr->allocateDataSection(TotalSize, sizeof(void*), @@ -197,18 +202,16 @@ unsigned RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj, << "\n"); // Assign the address of each symbol - for (CommonSymbolMap::const_iterator it = Map.begin(), itEnd = Map.end(); - it != itEnd; it++) { - uint64_t Size = it->second; + for (CommonSymbolMap::const_iterator it = CommonSymbols.begin(), + itEnd = CommonSymbols.end(); it != itEnd; it++) { StringRef Name; it->first.getName(Name); Obj.updateSymbolAddress(it->first, (uint64_t)Addr); - LocalSymbols[Name.data()] = SymbolLoc(SectionID, Offset); + SymbolTable[Name.data()] = SymbolLoc(SectionID, Offset); + uint64_t Size = it->second; Offset += Size; Addr += Size; } - - return SectionID; } unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj, @@ -274,8 +277,8 @@ unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj, } else { // Even if we didn't load the section, we need to record an entry for it - // to handle later processing (and by 'handle' I mean don't do anything - // with these sections). + // to handle later processing (and by 'handle' I mean don't do anything + // with these sections). Allocate = 0; Addr = 0; DEBUG(dbgs() << "emitSection SectionID: " << SectionID @@ -307,28 +310,26 @@ unsigned RuntimeDyldImpl::findOrEmitSection(ObjectImage &Obj, return SectionID; } -void RuntimeDyldImpl::AddRelocation(const RelocationValueRef &Value, - unsigned SectionID, uintptr_t Offset, - uint32_t RelType) { - DEBUG(dbgs() << "AddRelocation SymNamePtr: " << format("%p", Value.SymbolName) - << " SID: " << Value.SectionID - << " Addend: " << format("%p", Value.Addend) - << " Offset: " << format("%p", Offset) - << " RelType: " << format("%x", RelType) - << "\n"); +void RuntimeDyldImpl::addRelocationForSection(const RelocationEntry &RE, + unsigned SectionID) { + Relocations[SectionID].push_back(RE); +} - if (Value.SymbolName == 0) { - Relocations[Value.SectionID].push_back(RelocationEntry( - SectionID, - Offset, - RelType, - Value.Addend)); - } else - SymbolRelocations[Value.SymbolName].push_back(RelocationEntry( - SectionID, - Offset, - RelType, - Value.Addend)); +void RuntimeDyldImpl::addRelocationForSymbol(const RelocationEntry &RE, + StringRef SymbolName) { + // Relocation by symbol. If the symbol is found in the global symbol table, + // create an appropriate section relocation. Otherwise, add it to + // ExternalSymbolRelocations. + SymbolTableMap::const_iterator Loc = + GlobalSymbolTable.find(SymbolName); + if (Loc == GlobalSymbolTable.end()) { + ExternalSymbolRelocations[SymbolName].push_back(RE); + } else { + // Copy the RE since we want to modify its addend. + RelocationEntry RECopy = RE; + RECopy.Addend += Loc->second.second; + Relocations[Loc->second.first].push_back(RECopy); + } } uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) { @@ -369,12 +370,12 @@ void RuntimeDyldImpl::resolveRelocationEntry(const RelocationEntry &RE, uint8_t *Target = Sections[RE.SectionID].Address + RE.Offset; DEBUG(dbgs() << "\tSectionID: " << RE.SectionID << " + " << RE.Offset << " (" << format("%p", Target) << ")" - << " Data: " << RE.Data + << " RelType: " << RE.RelType << " Addend: " << RE.Addend << "\n"); resolveRelocation(Target, Sections[RE.SectionID].LoadAddress + RE.Offset, - Value, RE.Data, RE.Addend); + Value, RE.RelType, RE.Addend); } } @@ -385,16 +386,14 @@ void RuntimeDyldImpl::resolveRelocationList(const RelocationList &Relocs, } } -// resolveSymbols - Resolve any relocations to the specified symbols if -// we know where it lives. -void RuntimeDyldImpl::resolveSymbols() { - StringMap<RelocationList>::iterator i = SymbolRelocations.begin(), - e = SymbolRelocations.end(); +void RuntimeDyldImpl::resolveExternalSymbols() { + StringMap<RelocationList>::iterator i = ExternalSymbolRelocations.begin(), + e = ExternalSymbolRelocations.end(); for (; i != e; i++) { StringRef Name = i->first(); RelocationList &Relocs = i->second; - StringMap<SymbolLoc>::const_iterator Loc = SymbolTable.find(Name); - if (Loc == SymbolTable.end()) { + SymbolTableMap::const_iterator Loc = GlobalSymbolTable.find(Name); + if (Loc == GlobalSymbolTable.end()) { // This is an external symbol, try to get it address from // MemoryManager. uint8_t *Addr = (uint8_t*) MemMgr->getPointerToNamedFunction(Name.data(), @@ -404,15 +403,7 @@ void RuntimeDyldImpl::resolveSymbols() { << "\n"); resolveRelocationList(Relocs, (uintptr_t)Addr); } else { - // Change the relocation to be section relative rather than symbol - // relative and move it to the resolved relocation list. - DEBUG(dbgs() << "Resolving symbol '" << Name << "'\n"); - for (int i = 0, e = Relocs.size(); i != e; ++i) { - RelocationEntry Entry = Relocs[i]; - Entry.Addend += Loc->second.second; - Relocations[Loc->second.first].push_back(Entry); - } - Relocs.clear(); + report_fatal_error("Expected external symbol"); } } } diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index db6da8c..75bb586 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -55,7 +55,7 @@ public: const MemoryBuffer& getBuffer() const { return *InputData; } - // Methods for type inquiry through isa, cast, and dyn_cast + // Methods for type inquiry through isa, cast and dyn_cast static inline bool classof(const Binary *v) { return (isa<ELFObjectFile<target_endianness, is64Bits> >(v) && classof(cast<ELFObjectFile<target_endianness, is64Bits> >(v))); @@ -208,10 +208,9 @@ void RuntimeDyldELF::resolveX86_64Relocation(uint8_t *LocalAddress, case ELF::R_X86_64_32: case ELF::R_X86_64_32S: { Value += Addend; - // FIXME: Handle the possibility of this assertion failing - assert((Type == ELF::R_X86_64_32 && !(Value & 0xFFFFFFFF00000000ULL)) || - (Type == ELF::R_X86_64_32S && - (Value & 0xFFFFFFFF00000000ULL) == 0xFFFFFFFF00000000ULL)); + assert((Type == ELF::R_X86_64_32 && (Value <= UINT32_MAX)) || + (Type == ELF::R_X86_64_32S && + ((int64_t)Value <= INT32_MAX && (int64_t)Value >= INT32_MIN))); uint32_t TruncatedAddr = (Value & 0xFFFFFFFF); uint32_t *Target = reinterpret_cast<uint32_t*>(LocalAddress); *Target = TruncatedAddr; @@ -220,7 +219,7 @@ void RuntimeDyldELF::resolveX86_64Relocation(uint8_t *LocalAddress, case ELF::R_X86_64_PC32: { uint32_t *Placeholder = reinterpret_cast<uint32_t*>(LocalAddress); int64_t RealOffset = *Placeholder + Value + Addend - FinalAddress; - assert(RealOffset <= 214783647 && RealOffset >= -214783648); + assert(RealOffset <= INT32_MAX && RealOffset >= INT32_MIN); int32_t TruncOffset = (RealOffset & 0xFFFFFFFF); *Placeholder = TruncOffset; break; @@ -248,7 +247,7 @@ void RuntimeDyldELF::resolveX86Relocation(uint8_t *LocalAddress, } default: // There are other relocation types, but it appears these are the - // only ones currently used by the LLVM ELF object writer + // only ones currently used by the LLVM ELF object writer llvm_unreachable("Relocation type not implemented yet!"); break; } @@ -334,28 +333,31 @@ void RuntimeDyldELF::resolveRelocation(uint8_t *LocalAddress, void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel, ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, - LocalSymbolMap &Symbols, + const SymbolTableMap &Symbols, StubMap &Stubs) { uint32_t RelType = (uint32_t)(Rel.Type & 0xffffffffL); intptr_t Addend = (intptr_t)Rel.AdditionalInfo; - RelocationValueRef Value; - StringRef TargetName; const SymbolRef &Symbol = Rel.Symbol; + + // Obtain the symbol name which is referenced in the relocation + StringRef TargetName; Symbol.getName(TargetName); DEBUG(dbgs() << "\t\tRelType: " << RelType << " Addend: " << Addend << " TargetName: " << TargetName << "\n"); - // First look the symbol in object file symbols. - LocalSymbolMap::iterator lsi = Symbols.find(TargetName.data()); + RelocationValueRef Value; + // First search for the symbol in the local symbol table + SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data()); if (lsi != Symbols.end()) { Value.SectionID = lsi->second.first; Value.Addend = lsi->second.second; } else { - // Second look the symbol in global symbol table. - StringMap<SymbolLoc>::iterator gsi = SymbolTable.find(TargetName.data()); - if (gsi != SymbolTable.end()) { + // Search for the symbol in the global symbol table + SymbolTableMap::const_iterator gsi = + GlobalSymbolTable.find(TargetName.data()); + if (gsi != GlobalSymbolTable.end()) { Value.SectionID = gsi->second.first; Value.Addend = gsi->second.second; } else { @@ -366,7 +368,7 @@ void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel, // TODO: Now ELF SymbolRef::ST_Debug = STT_SECTION, it's not obviously // and can be changed by another developers. Maybe best way is add // a new symbol type ST_Section to SymbolRef and use it. - section_iterator si = Obj.end_sections(); + section_iterator si(Obj.end_sections()); Symbol.getSection(si); if (si == Obj.end_sections()) llvm_unreachable("Symbol section not found, bad object file format!"); @@ -410,14 +412,24 @@ void RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel, Stubs[Value] = Section.StubOffset; uint8_t *StubTargetAddr = createStubFunction(Section.Address + Section.StubOffset); - AddRelocation(Value, Rel.SectionID, - StubTargetAddr - Section.Address, ELF::R_ARM_ABS32); + RelocationEntry RE(Rel.SectionID, StubTargetAddr - Section.Address, + ELF::R_ARM_ABS32, Value.Addend); + if (Value.SymbolName) + addRelocationForSymbol(RE, Value.SymbolName); + else + addRelocationForSection(RE, Value.SectionID); + resolveRelocation(Target, (uint64_t)Target, (uint64_t)Section.Address + Section.StubOffset, RelType, 0); Section.StubOffset += getMaxStubSize(); } - } else - AddRelocation(Value, Rel.SectionID, Rel.Offset, RelType); + } else { + RelocationEntry RE(Rel.SectionID, Rel.Offset, RelType, Value.Addend); + if (Value.SymbolName) + addRelocationForSymbol(RE, Value.SymbolName); + else + addRelocationForSection(RE, Value.SectionID); + } } bool RuntimeDyldELF::isCompatibleFormat(const MemoryBuffer *InputBuffer) const { diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h index e7f6fab..e413f78 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -51,7 +51,8 @@ protected: virtual void processRelocationRef(const ObjRelocationInfo &Rel, ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, - LocalSymbolMap &Symbols, StubMap &Stubs); + const SymbolTableMap &Symbols, + StubMap &Stubs); virtual ObjectImage *createObjectImage(const MemoryBuffer *InputBuffer); virtual void handleObjectLoaded(ObjectImage *Obj); diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index 2dea13f..c38ca69 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -14,60 +14,83 @@ #ifndef LLVM_RUNTIME_DYLD_IMPL_H #define LLVM_RUNTIME_DYLD_IMPL_H +#include "ObjectImage.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" -#include "llvm/Object/ObjectFile.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/Twine.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Support/Memory.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/system_error.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Object/ObjectFile.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/ADT/Triple.h" -#include <map> #include "llvm/Support/Format.h" -#include "ObjectImage.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/system_error.h" +#include <map> using namespace llvm; using namespace llvm::object; namespace llvm { +class MemoryBuffer; +class Twine; + + +/// SectionEntry - represents a section emitted into memory by the dynamic +/// linker. class SectionEntry { public: - uint8_t* Address; + /// Address - address in the linker's memory where the section resides. + uint8_t *Address; + + /// Size - section size. size_t Size; - uint64_t LoadAddress; // For each section, the address it will be - // considered to live at for relocations. The same - // as the pointer to the above memory block for - // hosted JITs. - uintptr_t StubOffset; // It's used for architecturies with stub - // functions for far relocations like ARM. - uintptr_t ObjAddress; // Section address in object file. It's use for - // calculate MachO relocation addend - SectionEntry(uint8_t* address, size_t size, uintptr_t stubOffset, + + /// LoadAddress - the address of the section in the target process's memory. + /// Used for situations in which JIT-ed code is being executed in the address + /// space of a separate process. If the code executes in the same address + /// space where it was JIT-ed, this just equals Address. + uint64_t LoadAddress; + + /// StubOffset - used for architectures with stub functions for far + /// relocations (like ARM). + uintptr_t StubOffset; + + /// ObjAddress - address of the section in the in-memory object file. Used + /// for calculating relocations in some object formats (like MachO). + uintptr_t ObjAddress; + + SectionEntry(uint8_t *address, size_t size, uintptr_t stubOffset, uintptr_t objAddress) : Address(address), Size(size), LoadAddress((uintptr_t)address), StubOffset(stubOffset), ObjAddress(objAddress) {} }; +/// RelocationEntry - used to represent relocations internally in the dynamic +/// linker. class RelocationEntry { public: - unsigned SectionID; // Section the relocation is contained in. - uintptr_t Offset; // Offset into the section for the relocation. - uint32_t Data; // Relocatino data. Including type of relocation - // and another flags and parameners from - intptr_t Addend; // Addend encoded in the instruction itself, if any, - // plus the offset into the source section for - // the symbol once the relocation is resolvable. - RelocationEntry(unsigned id, uint64_t offset, uint32_t data, int64_t addend) - : SectionID(id), Offset(offset), Data(data), Addend(addend) {} + /// SectionID - the section this relocation points to. + unsigned SectionID; + + /// Offset - offset into the section. + uintptr_t Offset; + + /// RelType - relocation type. + uint32_t RelType; + + /// Addend - the relocation addend encoded in the instruction itself. Also + /// used to make a relocation section relative instead of symbol relative. + intptr_t Addend; + + RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend) + : SectionID(id), Offset(offset), RelType(type), Addend(addend) {} }; -// Raw relocation data from object file +/// ObjRelocationInfo - relocation information as read from the object file. +/// Used to pass around data taken from object::RelocationRef, together with +/// the section to which the relocation points (represented by a SectionID). class ObjRelocationInfo { public: unsigned SectionID; @@ -97,7 +120,8 @@ protected: // The MemoryManager to load objects into. RTDyldMemoryManager *MemMgr; - // A list of emmitted sections. + // A list of all sections emitted by the dynamic linker. These sections are + // referenced in the code by means of their index in this list - SectionID. typedef SmallVector<SectionEntry, 64> SectionList; SectionList Sections; @@ -105,11 +129,11 @@ protected: // references it. typedef std::map<SectionRef, unsigned> ObjSectionToIDMap; - // Master symbol table. As modules are loaded and external symbols are - // resolved, their addresses are stored here as a SectionID/Offset pair. + // A global symbol table for symbols from all loaded modules. Maps the + // symbol name to a (SectionID, offset in section) pair. typedef std::pair<unsigned, uintptr_t> SymbolLoc; - StringMap<SymbolLoc> SymbolTable; - typedef DenseMap<const char*, SymbolLoc> LocalSymbolMap; + typedef StringMap<SymbolLoc> SymbolTableMap; + SymbolTableMap GlobalSymbolTable; // Keep a map of common symbols to their sizes typedef std::map<SymbolRef, unsigned> CommonSymbolMap; @@ -121,12 +145,14 @@ protected: // in the relocation list where it's stored. typedef SmallVector<RelocationEntry, 64> RelocationList; // Relocations to sections already loaded. Indexed by SectionID which is the - // source of the address. The target where the address will be writen is + // source of the address. The target where the address will be written is // SectionID/Offset in the relocation itself. DenseMap<unsigned, RelocationList> Relocations; - // Relocations to external symbols that are not yet resolved. - // Indexed by symbol name. - StringMap<RelocationList> SymbolRelocations; + + // Relocations to external symbols that are not yet resolved. Symbols are + // external when they aren't found in the global symbol table of all loaded + // modules. This map is indexed by symbol name. + StringMap<RelocationList> ExternalSymbolRelocations; typedef std::map<RelocationValueRef, uintptr_t> StubMap; @@ -153,16 +179,17 @@ protected: return (uint8_t*)Sections[SectionID].Address; } - /// \brief Emits a section containing common symbols. - /// \return SectionID. - unsigned emitCommonSymbols(ObjectImage &Obj, - const CommonSymbolMap &Map, - uint64_t TotalSize, - LocalSymbolMap &Symbols); + /// \brief Given the common symbols discovered in the object file, emit a + /// new section for them and update the symbol mappings in the object and + /// symbol table. + void emitCommonSymbols(ObjectImage &Obj, + const CommonSymbolMap &CommonSymbols, + uint64_t TotalSize, + SymbolTableMap &SymbolTable); /// \brief Emits section data from the object file to the MemoryManager. /// \param IsCode if it's true then allocateCodeSection() will be - /// used for emmits, else allocateDataSection() will be used. + /// used for emits, else allocateDataSection() will be used. /// \return SectionID. unsigned emitSection(ObjectImage &Obj, const SectionRef &Section, @@ -178,10 +205,12 @@ protected: bool IsCode, ObjSectionToIDMap &LocalSections); - /// \brief If Value.SymbolName is NULL then store relocation to the - /// Relocations, else store it in the SymbolRelocations. - void AddRelocation(const RelocationValueRef &Value, unsigned SectionID, - uintptr_t Offset, uint32_t RelType); + // \brief Add a relocation entry that uses the given section. + void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID); + + // \brief Add a relocation entry that uses the given symbol. This symbol may + // be found in the global symbol table, or it may be external. + void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName); /// \brief Emits long jump instruction to Addr. /// \return Pointer to the memory area for emitting target address. @@ -203,14 +232,16 @@ protected: uint32_t Type, int64_t Addend) = 0; - /// \brief Parses the object file relocation and store it to Relocations - /// or SymbolRelocations. Its depend from object file type. + /// \brief Parses the object file relocation and stores it to Relocations + /// or SymbolRelocations (this depends on the object file type). virtual void processRelocationRef(const ObjRelocationInfo &Rel, ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, - LocalSymbolMap &Symbols, StubMap &Stubs) = 0; + const SymbolTableMap &Symbols, + StubMap &Stubs) = 0; - void resolveSymbols(); + /// \brief Resolve relocations to external symbols. + void resolveExternalSymbols(); virtual ObjectImage *createObjectImage(const MemoryBuffer *InputBuffer); virtual void handleObjectLoaded(ObjectImage *Obj) { @@ -228,9 +259,9 @@ public: void *getSymbolAddress(StringRef Name) { // FIXME: Just look up as a function for now. Overly simple of course. // Work in progress. - if (SymbolTable.find(Name) == SymbolTable.end()) + if (GlobalSymbolTable.find(Name) == GlobalSymbolTable.end()) return 0; - SymbolLoc Loc = SymbolTable.lookup(Name); + SymbolLoc Loc = GlobalSymbolTable.lookup(Name); return getSectionAddress(Loc.first) + Loc.second; } diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index b7f515d..0e3a9d4 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -30,7 +30,8 @@ void RuntimeDyldMachO::resolveRelocation(uint8_t *LocalAddress, unsigned MachoType = (Type >> 28) & 0xf; unsigned Size = 1 << ((Type >> 25) & 3); - DEBUG(dbgs() << "resolveRelocation LocalAddress: " << format("%p", LocalAddress) + DEBUG(dbgs() << "resolveRelocation LocalAddress: " + << format("%p", LocalAddress) << " FinalAddress: " << format("%p", FinalAddress) << " Value: " << format("%p", Value) << " Addend: " << Addend @@ -53,12 +54,12 @@ void RuntimeDyldMachO::resolveRelocation(uint8_t *LocalAddress, break; case Triple::x86: resolveI386Relocation(LocalAddress, - FinalAddress, - (uintptr_t)Value, - isPCRel, - Type, - Size, - Addend); + FinalAddress, + (uintptr_t)Value, + isPCRel, + Type, + Size, + Addend); break; case Triple::arm: // Fall through. case Triple::thumb: @@ -73,14 +74,13 @@ void RuntimeDyldMachO::resolveRelocation(uint8_t *LocalAddress, } } -bool RuntimeDyldMachO:: -resolveI386Relocation(uint8_t *LocalAddress, - uint64_t FinalAddress, - uint64_t Value, - bool isPCRel, - unsigned Type, - unsigned Size, - int64_t Addend) { +bool RuntimeDyldMachO::resolveI386Relocation(uint8_t *LocalAddress, + uint64_t FinalAddress, + uint64_t Value, + bool isPCRel, + unsigned Type, + unsigned Size, + int64_t Addend) { if (isPCRel) Value -= FinalAddress + 4; // see resolveX86_64Relocation @@ -102,14 +102,13 @@ resolveI386Relocation(uint8_t *LocalAddress, } } -bool RuntimeDyldMachO:: -resolveX86_64Relocation(uint8_t *LocalAddress, - uint64_t FinalAddress, - uint64_t Value, - bool isPCRel, - unsigned Type, - unsigned Size, - int64_t Addend) { +bool RuntimeDyldMachO::resolveX86_64Relocation(uint8_t *LocalAddress, + uint64_t FinalAddress, + uint64_t Value, + bool isPCRel, + unsigned Type, + unsigned Size, + int64_t Addend) { // If the relocation is PC-relative, the value to be encoded is the // pointer difference. if (isPCRel) @@ -144,14 +143,13 @@ resolveX86_64Relocation(uint8_t *LocalAddress, } } -bool RuntimeDyldMachO:: -resolveARMRelocation(uint8_t *LocalAddress, - uint64_t FinalAddress, - uint64_t Value, - bool isPCRel, - unsigned Type, - unsigned Size, - int64_t Addend) { +bool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress, + uint64_t FinalAddress, + uint64_t Value, + bool isPCRel, + unsigned Type, + unsigned Size, + int64_t Addend) { // If the relocation is PC-relative, the value to be encoded is the // pointer difference. if (isPCRel) { @@ -207,7 +205,7 @@ resolveARMRelocation(uint8_t *LocalAddress, void RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel, ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, - LocalSymbolMap &Symbols, + const SymbolTableMap &Symbols, StubMap &Stubs) { uint32_t RelType = (uint32_t) (Rel.Type & 0xffffffffL); @@ -217,18 +215,19 @@ void RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel, bool isExtern = (RelType >> 27) & 1; if (isExtern) { + // Obtain the symbol name which is referenced in the relocation StringRef TargetName; const SymbolRef &Symbol = Rel.Symbol; Symbol.getName(TargetName); - // First look the symbol in object file symbols. - LocalSymbolMap::iterator lsi = Symbols.find(TargetName.data()); + // First search for the symbol in the local symbol table + SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data()); if (lsi != Symbols.end()) { Value.SectionID = lsi->second.first; Value.Addend = lsi->second.second; } else { - // Second look the symbol in global symbol table. - StringMap<SymbolLoc>::iterator gsi = SymbolTable.find(TargetName.data()); - if (gsi != SymbolTable.end()) { + // Search for the symbol in the global symbol table + SymbolTableMap::const_iterator gsi = GlobalSymbolTable.find(TargetName.data()); + if (gsi != GlobalSymbolTable.end()) { Value.SectionID = gsi->second.first; Value.Addend = gsi->second.second; } else @@ -249,8 +248,8 @@ void RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel, Value.SectionID = findOrEmitSection(Obj, *si, true, ObjSectionToID); Value.Addend = *(const intptr_t *)Target; if (Value.Addend) { - // The MachO addend is offset from the current section, we need set it - // as offset from destination section + // The MachO addend is an offset from the current section. We need it + // to be an offset from the destination section Value.Addend += Section.ObjAddress - Sections[Value.SectionID].ObjAddress; } } @@ -269,19 +268,29 @@ void RuntimeDyldMachO::processRelocationRef(const ObjRelocationInfo &Rel, Stubs[Value] = Section.StubOffset; uint8_t *StubTargetAddr = createStubFunction(Section.Address + Section.StubOffset); - AddRelocation(Value, Rel.SectionID, StubTargetAddr - Section.Address, - macho::RIT_Vanilla); + RelocationEntry RE(Rel.SectionID, StubTargetAddr - Section.Address, + macho::RIT_Vanilla, Value.Addend); + if (Value.SymbolName) + addRelocationForSymbol(RE, Value.SymbolName); + else + addRelocationForSection(RE, Value.SectionID); resolveRelocation(Target, (uint64_t)Target, (uint64_t)Section.Address + Section.StubOffset, RelType, 0); Section.StubOffset += getMaxStubSize(); } - } else - AddRelocation(Value, Rel.SectionID, Rel.Offset, RelType); + } else { + RelocationEntry RE(Rel.SectionID, Rel.Offset, RelType, Value.Addend); + if (Value.SymbolName) + addRelocationForSymbol(RE, Value.SymbolName); + else + addRelocationForSection(RE, Value.SectionID); + } } -bool RuntimeDyldMachO::isCompatibleFormat(const MemoryBuffer *InputBuffer) const { +bool RuntimeDyldMachO::isCompatibleFormat( + const MemoryBuffer *InputBuffer) const { StringRef Magic = InputBuffer->getBuffer().slice(0, 4); if (Magic == "\xFE\xED\xFA\xCE") return true; if (Magic == "\xCE\xFA\xED\xFE") return true; diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h index 418d130..707664c 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h @@ -51,7 +51,8 @@ protected: virtual void processRelocationRef(const ObjRelocationInfo &Rel, ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, - LocalSymbolMap &Symbols, StubMap &Stubs); + const SymbolTableMap &Symbols, + StubMap &Stubs); public: virtual void resolveRelocation(uint8_t *LocalAddress, diff --git a/lib/ExecutionEngine/TargetSelect.cpp b/lib/ExecutionEngine/TargetSelect.cpp index 42364f9..7cdd669 100644 --- a/lib/ExecutionEngine/TargetSelect.cpp +++ b/lib/ExecutionEngine/TargetSelect.cpp @@ -26,11 +26,7 @@ using namespace llvm; TargetMachine *EngineBuilder::selectTarget() { - StringRef MArch = ""; - StringRef MCPU = ""; - SmallVector<std::string, 1> MAttrs; - Triple TT(M->getTargetTriple()); - + Triple TT(LLVM_HOSTTRIPLE); return selectTarget(TT, MArch, MCPU, MAttrs); } @@ -56,8 +52,9 @@ TargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple, } if (!TheTarget) { - *ErrorStr = "No available targets are compatible with this -march, " - "see -version for the available targets.\n"; + if (ErrorStr) + *ErrorStr = "No available targets are compatible with this -march, " + "see -version for the available targets.\n"; return 0; } |