diff options
Diffstat (limited to 'contrib/llvm/lib/ExecutionEngine')
38 files changed, 889 insertions, 663 deletions
diff --git a/contrib/llvm/lib/ExecutionEngine/ExecutionEngine.cpp b/contrib/llvm/lib/ExecutionEngine/ExecutionEngine.cpp index a8e68bf..b4bed32 100644 --- a/contrib/llvm/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/contrib/llvm/lib/ExecutionEngine/ExecutionEngine.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/ExecutionEngine/JITEventListener.h" +#include "llvm/ExecutionEngine/ObjectCache.h" #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" @@ -48,12 +49,13 @@ STATISTIC(NumGlobals , "Number of global vars initialized"); ExecutionEngine *(*ExecutionEngine::MCJITCtor)( std::unique_ptr<Module> M, std::string *ErrorStr, std::shared_ptr<MCJITMemoryManager> MemMgr, - std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver, + + std::shared_ptr<JITSymbolResolver> Resolver, std::unique_ptr<TargetMachine> TM) = nullptr; ExecutionEngine *(*ExecutionEngine::OrcMCJITReplacementCtor)( std::string *ErrorStr, std::shared_ptr<MCJITMemoryManager> MemMgr, - std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver, + std::shared_ptr<JITSymbolResolver> Resolver, std::unique_ptr<TargetMachine> TM) = nullptr; ExecutionEngine *(*ExecutionEngine::InterpCtor)(std::unique_ptr<Module> M, @@ -61,6 +63,8 @@ ExecutionEngine *(*ExecutionEngine::InterpCtor)(std::unique_ptr<Module> M, void JITEventListener::anchor() {} +void ObjectCache::anchor() {} + void ExecutionEngine::Init(std::unique_ptr<Module> M) { CompilingLazily = false; GVCompilationDisabled = false; @@ -151,7 +155,7 @@ bool ExecutionEngine::removeModule(Module *M) { return false; } -Function *ExecutionEngine::FindFunctionNamed(const char *FnName) { +Function *ExecutionEngine::FindFunctionNamed(StringRef FnName) { for (unsigned i = 0, e = Modules.size(); i != e; ++i) { Function *F = Modules[i]->getFunction(FnName); if (F && !F->isDeclaration()) @@ -160,7 +164,7 @@ Function *ExecutionEngine::FindFunctionNamed(const char *FnName) { return nullptr; } -GlobalVariable *ExecutionEngine::FindGlobalVariableNamed(const char *Name, bool AllowInternal) { +GlobalVariable *ExecutionEngine::FindGlobalVariableNamed(StringRef Name, bool AllowInternal) { for (unsigned i = 0, e = Modules.size(); i != e; ++i) { GlobalVariable *GV = Modules[i]->getGlobalVariable(Name,AllowInternal); if (GV && !GV->isDeclaration()) @@ -366,7 +370,7 @@ void *ArgvArray::reset(LLVMContext &C, ExecutionEngine *EE, void ExecutionEngine::runStaticConstructorsDestructors(Module &module, bool isDtors) { - const char *Name = isDtors ? "llvm.global_dtors" : "llvm.global_ctors"; + StringRef Name(isDtors ? "llvm.global_dtors" : "llvm.global_ctors"); GlobalVariable *GV = module.getNamedGlobal(Name); // If this global has internal linkage, or if it has a use, then it must be @@ -499,8 +503,8 @@ EngineBuilder::setMemoryManager(std::unique_ptr<MCJITMemoryManager> MM) { } EngineBuilder& -EngineBuilder::setSymbolResolver(std::unique_ptr<RuntimeDyld::SymbolResolver> SR) { - Resolver = std::shared_ptr<RuntimeDyld::SymbolResolver>(std::move(SR)); +EngineBuilder::setSymbolResolver(std::unique_ptr<JITSymbolResolver> SR) { + Resolver = std::shared_ptr<JITSymbolResolver>(std::move(SR)); return *this; } @@ -688,7 +692,7 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { else if (CE->getType()->isDoubleTy()) GV.DoubleVal = GV.IntVal.roundToDouble(); else if (CE->getType()->isX86_FP80Ty()) { - APFloat apf = APFloat::getZero(APFloat::x87DoubleExtended); + APFloat apf = APFloat::getZero(APFloat::x87DoubleExtended()); (void)apf.convertFromAPInt(GV.IntVal, false, APFloat::rmNearestTiesToEven); @@ -703,7 +707,7 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { else if (CE->getType()->isDoubleTy()) GV.DoubleVal = GV.IntVal.signedRoundToDouble(); else if (CE->getType()->isX86_FP80Ty()) { - APFloat apf = APFloat::getZero(APFloat::x87DoubleExtended); + APFloat apf = APFloat::getZero(APFloat::x87DoubleExtended()); (void)apf.convertFromAPInt(GV.IntVal, true, APFloat::rmNearestTiesToEven); @@ -720,7 +724,7 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { else if (Op0->getType()->isDoubleTy()) GV.IntVal = APIntOps::RoundDoubleToAPInt(GV.DoubleVal, BitWidth); else if (Op0->getType()->isX86_FP80Ty()) { - APFloat apf = APFloat(APFloat::x87DoubleExtended, GV.IntVal); + APFloat apf = APFloat(APFloat::x87DoubleExtended(), GV.IntVal); uint64_t v; bool ignored; (void)apf.convertToInteger(&v, BitWidth, diff --git a/contrib/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp b/contrib/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp index d6b209a..1d7c6e7 100644 --- a/contrib/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp +++ b/contrib/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp @@ -187,7 +187,7 @@ LLVMBool LLVMCreateMCJITCompilerForModule( // NoFramePointerElim. for (auto &F : *Mod) { auto Attrs = F.getAttributes(); - auto Value = options.NoFramePointerElim ? "true" : "false"; + StringRef Value(options.NoFramePointerElim ? "true" : "false"); Attrs = Attrs.addAttribute(F.getContext(), AttributeSet::FunctionIndex, "no-frame-pointer-elim", Value); F.setAttributes(Attrs); diff --git a/contrib/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp b/contrib/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp index 1ab6203..dad099d 100644 --- a/contrib/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp +++ b/contrib/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp @@ -69,16 +69,6 @@ struct RegisteredObjectInfo { OwningBinary<ObjectFile> Obj) : Size(Size), Entry(Entry), Obj(std::move(Obj)) {} - RegisteredObjectInfo(RegisteredObjectInfo &&Other) - : Size(Other.Size), Entry(Other.Entry), Obj(std::move(Other.Obj)) {} - - RegisteredObjectInfo& operator=(RegisteredObjectInfo &&Other) { - Size = Other.Size; - Entry = Other.Entry; - Obj = std::move(Other.Obj); - return *this; - } - std::size_t Size; jit_code_entry *Entry; OwningBinary<ObjectFile> Obj; diff --git a/contrib/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp b/contrib/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp index 1eb4f7d..923f6e7 100644 --- a/contrib/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/contrib/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -999,7 +999,7 @@ GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I, uint64_t Total = 0; for (; I != E; ++I) { - if (StructType *STy = dyn_cast<StructType>(*I)) { + if (StructType *STy = I.getStructTypeOrNull()) { const StructLayout *SLO = getDataLayout().getStructLayout(STy); const ConstantInt *CPU = cast<ConstantInt>(I.getOperand()); @@ -1007,7 +1007,6 @@ GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I, Total += SLO->getElementOffset(Index); } else { - SequentialType *ST = cast<SequentialType>(*I); // Get the index number for the array... which must be long type... GenericValue IdxGV = getOperandValue(I.getOperand(), SF); @@ -1020,7 +1019,7 @@ GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I, assert(BitWidth == 64 && "Invalid index type for getelementptr"); Idx = (int64_t)IdxGV.IntVal.getZExtValue(); } - Total += getDataLayout().getTypeAllocSize(ST->getElementType()) * Idx; + Total += getDataLayout().getTypeAllocSize(I.getIndexedType()) * Idx; } } diff --git a/contrib/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp b/contrib/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp index 441f0eb..ee75bee 100644 --- a/contrib/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp +++ b/contrib/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp @@ -20,20 +20,31 @@ //===----------------------------------------------------------------------===// #include "Interpreter.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/Config/config.h" // Detect libffi +#include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" -#include "llvm/IR/Module.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Type.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Mutex.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Support/UniqueLock.h" +#include <cassert> #include <cmath> #include <csignal> +#include <cstdint> #include <cstdio> #include <cstring> #include <map> +#include <string> +#include <utility> +#include <vector> #ifdef HAVE_FFI_CALL #ifdef HAVE_FFI_H @@ -290,7 +301,6 @@ GenericValue Interpreter::callExternalFunction(Function *F, return GenericValue(); } - //===----------------------------------------------------------------------===// // Functions "exported" to the running application... // @@ -331,7 +341,7 @@ static GenericValue lle_X_sprintf(FunctionType *FT, // close enough for now. GenericValue GV; GV.IntVal = APInt(32, strlen(FmtStr)); - while (1) { + while (true) { switch (*FmtStr) { case 0: return GV; // Null terminator... default: // Normal nonspecial character diff --git a/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp b/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp index bc7da2e..9818adf 100644 --- a/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp +++ b/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.cpp @@ -35,9 +35,13 @@ extern "C" void LLVMLinkInInterpreter() { } ExecutionEngine *Interpreter::create(std::unique_ptr<Module> M, std::string *ErrStr) { // Tell this Module to materialize everything and release the GVMaterializer. - if (std::error_code EC = M->materializeAll()) { + if (Error Err = M->materializeAll()) { + std::string Msg; + handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { + Msg = EIB.message(); + }); if (ErrStr) - *ErrStr = EC.message(); + *ErrStr = Msg; // We got an error, just return 0 return nullptr; } diff --git a/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h b/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h index 2e5a867..5c16448 100644 --- a/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h +++ b/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h @@ -41,12 +41,9 @@ class AllocaHolder { public: AllocaHolder() {} - // Make this type move-only. Define explicit move special members for MSVC. - AllocaHolder(AllocaHolder &&RHS) : Allocations(std::move(RHS.Allocations)) {} - AllocaHolder &operator=(AllocaHolder &&RHS) { - Allocations = std::move(RHS.Allocations); - return *this; - } + // Make this type move-only. + AllocaHolder(AllocaHolder &&) = default; + AllocaHolder &operator=(AllocaHolder &&RHS) = default; ~AllocaHolder() { for (void *Allocation : Allocations) @@ -72,22 +69,6 @@ struct ExecutionContext { AllocaHolder Allocas; // Track memory allocated by alloca ExecutionContext() : CurFunction(nullptr), CurBB(nullptr), CurInst(nullptr) {} - - ExecutionContext(ExecutionContext &&O) - : CurFunction(O.CurFunction), CurBB(O.CurBB), CurInst(O.CurInst), - Caller(O.Caller), Values(std::move(O.Values)), - VarArgs(std::move(O.VarArgs)), Allocas(std::move(O.Allocas)) {} - - ExecutionContext &operator=(ExecutionContext &&O) { - CurFunction = O.CurFunction; - CurBB = O.CurBB; - CurInst = O.CurInst; - Caller = O.Caller; - Values = std::move(O.Values); - VarArgs = std::move(O.VarArgs); - Allocas = std::move(O.Allocas); - return *this; - } }; // Interpreter - This class represents the entirety of the interpreter. diff --git a/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp index 7fb328b..ff8749f 100644 --- a/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -29,8 +29,6 @@ using namespace llvm; -void ObjectCache::anchor() {} - namespace { static struct RegisterJIT { @@ -46,7 +44,7 @@ ExecutionEngine* MCJIT::createJIT(std::unique_ptr<Module> M, std::string *ErrorStr, std::shared_ptr<MCJITMemoryManager> MemMgr, - std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver, + std::shared_ptr<JITSymbolResolver> Resolver, std::unique_ptr<TargetMachine> TM) { // Try to register the program as a source of symbols to resolve against. // @@ -67,7 +65,7 @@ MCJIT::createJIT(std::unique_ptr<Module> M, MCJIT::MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> TM, std::shared_ptr<MCJITMemoryManager> MemMgr, - std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver) + std::shared_ptr<JITSymbolResolver> Resolver) : ExecutionEngine(TM->createDataLayout(), std::move(M)), TM(std::move(TM)), Ctx(nullptr), MemMgr(std::move(MemMgr)), Resolver(*this, std::move(Resolver)), Dyld(*this->MemMgr, this->Resolver), @@ -276,20 +274,21 @@ void MCJIT::finalizeModule(Module *M) { finalizeLoadedModules(); } -RuntimeDyld::SymbolInfo MCJIT::findExistingSymbol(const std::string &Name) { - SmallString<128> FullName; - Mangler::getNameWithPrefix(FullName, Name, getDataLayout()); - - if (void *Addr = getPointerToGlobalIfAvailable(FullName)) - return RuntimeDyld::SymbolInfo(static_cast<uint64_t>( - reinterpret_cast<uintptr_t>(Addr)), - JITSymbolFlags::Exported); +JITSymbol MCJIT::findExistingSymbol(const std::string &Name) { + if (void *Addr = getPointerToGlobalIfAvailable(Name)) + return JITSymbol(static_cast<uint64_t>( + reinterpret_cast<uintptr_t>(Addr)), + JITSymbolFlags::Exported); - return Dyld.getSymbol(FullName); + return Dyld.getSymbol(Name); } Module *MCJIT::findModuleForSymbol(const std::string &Name, bool CheckFunctionsOnly) { + StringRef DemangledName = Name; + if (DemangledName[0] == getDataLayout().getGlobalPrefix()) + DemangledName = DemangledName.substr(1); + MutexGuard locked(lock); // If it hasn't already been generated, see if it's in one of our modules. @@ -297,11 +296,11 @@ Module *MCJIT::findModuleForSymbol(const std::string &Name, E = OwnedModules.end_added(); I != E; ++I) { Module *M = *I; - Function *F = M->getFunction(Name); + Function *F = M->getFunction(DemangledName); if (F && !F->isDeclaration()) return M; if (!CheckFunctionsOnly) { - GlobalVariable *G = M->getGlobalVariable(Name); + GlobalVariable *G = M->getGlobalVariable(DemangledName); if (G && !G->isDeclaration()) return M; // FIXME: Do we need to worry about global aliases? @@ -313,11 +312,16 @@ Module *MCJIT::findModuleForSymbol(const std::string &Name, uint64_t MCJIT::getSymbolAddress(const std::string &Name, bool CheckFunctionsOnly) { - return findSymbol(Name, CheckFunctionsOnly).getAddress(); + std::string MangledName; + { + raw_string_ostream MangledNameStream(MangledName); + Mangler::getNameWithPrefix(MangledNameStream, Name, getDataLayout()); + } + return findSymbol(MangledName, CheckFunctionsOnly).getAddress(); } -RuntimeDyld::SymbolInfo MCJIT::findSymbol(const std::string &Name, - bool CheckFunctionsOnly) { +JITSymbol MCJIT::findSymbol(const std::string &Name, + bool CheckFunctionsOnly) { MutexGuard locked(lock); // First, check to see if we already have this symbol. @@ -367,7 +371,7 @@ RuntimeDyld::SymbolInfo MCJIT::findSymbol(const std::string &Name, if (LazyFunctionCreator) { auto Addr = static_cast<uint64_t>( reinterpret_cast<uintptr_t>(LazyFunctionCreator(Name))); - return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported); + return JITSymbol(Addr, JITSymbolFlags::Exported); } return nullptr; @@ -442,7 +446,7 @@ void MCJIT::runStaticConstructorsDestructors(bool isDtors) { isDtors, OwnedModules.begin_finalized(), OwnedModules.end_finalized()); } -Function *MCJIT::FindFunctionNamedInModulePtrSet(const char *FnName, +Function *MCJIT::FindFunctionNamedInModulePtrSet(StringRef FnName, ModulePtrSet::iterator I, ModulePtrSet::iterator E) { for (; I != E; ++I) { @@ -453,7 +457,7 @@ Function *MCJIT::FindFunctionNamedInModulePtrSet(const char *FnName, return nullptr; } -GlobalVariable *MCJIT::FindGlobalVariableNamedInModulePtrSet(const char *Name, +GlobalVariable *MCJIT::FindGlobalVariableNamedInModulePtrSet(StringRef Name, bool AllowInternal, ModulePtrSet::iterator I, ModulePtrSet::iterator E) { @@ -466,7 +470,7 @@ GlobalVariable *MCJIT::FindGlobalVariableNamedInModulePtrSet(const char *Name, } -Function *MCJIT::FindFunctionNamed(const char *FnName) { +Function *MCJIT::FindFunctionNamed(StringRef FnName) { Function *F = FindFunctionNamedInModulePtrSet( FnName, OwnedModules.begin_added(), OwnedModules.end_added()); if (!F) @@ -478,7 +482,7 @@ Function *MCJIT::FindFunctionNamed(const char *FnName) { return F; } -GlobalVariable *MCJIT::FindGlobalVariableNamed(const char *Name, bool AllowInternal) { +GlobalVariable *MCJIT::FindGlobalVariableNamed(StringRef Name, bool AllowInternal) { GlobalVariable *GV = FindGlobalVariableNamedInModulePtrSet( Name, AllowInternal, OwnedModules.begin_added(), OwnedModules.end_added()); if (!GV) @@ -587,7 +591,10 @@ GenericValue MCJIT::runFunction(Function *F, ArrayRef<GenericValue> ArgValues) { } } - llvm_unreachable("Full-featured argument passing not supported yet!"); + report_fatal_error("MCJIT::runFunction does not support full-featured " + "argument passing. Please use " + "ExecutionEngine::getFunctionAddress and cast the result " + "to the desired function pointer type."); } void *MCJIT::getPointerToNamedFunction(StringRef Name, bool AbortOnFailure) { @@ -622,7 +629,7 @@ void MCJIT::UnregisterJITEventListener(JITEventListener *L) { if (!L) return; MutexGuard locked(lock); - auto I = std::find(EventListeners.rbegin(), EventListeners.rend(), L); + auto I = find(reverse(EventListeners), L); if (I != EventListeners.rend()) { std::swap(*I, EventListeners.back()); EventListeners.pop_back(); @@ -644,13 +651,9 @@ void MCJIT::NotifyFreeingObject(const object::ObjectFile& Obj) { L->NotifyFreeingObject(Obj); } -RuntimeDyld::SymbolInfo +JITSymbol LinkingSymbolResolver::findSymbol(const std::string &Name) { auto Result = ParentEngine.findSymbol(Name, false); - // If the symbols wasn't found and it begins with an underscore, try again - // without the underscore. - if (!Result && Name[0] == '_') - Result = ParentEngine.findSymbol(Name.substr(1), false); if (Result) return Result; if (ParentEngine.isSymbolSearchingDisabled()) diff --git a/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h b/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h index e25f76c..daf578f 100644 --- a/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h +++ b/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h @@ -26,23 +26,22 @@ class MCJIT; // functions across modules that it owns. It aggregates the memory manager // that is passed in to the MCJIT constructor and defers most functionality // to that object. -class LinkingSymbolResolver : public RuntimeDyld::SymbolResolver { +class LinkingSymbolResolver : public JITSymbolResolver { public: LinkingSymbolResolver(MCJIT &Parent, - std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver) + std::shared_ptr<JITSymbolResolver> Resolver) : ParentEngine(Parent), ClientResolver(std::move(Resolver)) {} - RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) override; + JITSymbol findSymbol(const std::string &Name) override; // MCJIT doesn't support logical dylibs. - RuntimeDyld::SymbolInfo - findSymbolInLogicalDylib(const std::string &Name) override { + JITSymbol findSymbolInLogicalDylib(const std::string &Name) override { return nullptr; } private: MCJIT &ParentEngine; - std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver; + std::shared_ptr<JITSymbolResolver> ClientResolver; }; // About Module states: added->loaded->finalized. @@ -68,7 +67,7 @@ private: class MCJIT : public ExecutionEngine { MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> tm, std::shared_ptr<MCJITMemoryManager> MemMgr, - std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver); + std::shared_ptr<JITSymbolResolver> Resolver); typedef llvm::SmallPtrSet<Module *, 4> ModulePtrSet; @@ -195,11 +194,11 @@ class MCJIT : public ExecutionEngine { // perform lookup of pre-compiled code to avoid re-compilation. ObjectCache *ObjCache; - Function *FindFunctionNamedInModulePtrSet(const char *FnName, + Function *FindFunctionNamedInModulePtrSet(StringRef FnName, ModulePtrSet::iterator I, ModulePtrSet::iterator E); - GlobalVariable *FindGlobalVariableNamedInModulePtrSet(const char *Name, + GlobalVariable *FindGlobalVariableNamedInModulePtrSet(StringRef Name, bool AllowInternal, ModulePtrSet::iterator I, ModulePtrSet::iterator E); @@ -222,12 +221,12 @@ public: /// FindFunctionNamed - Search all of the active modules to find the function that /// defines FnName. This is very slow operation and shouldn't be used for /// general code. - Function *FindFunctionNamed(const char *FnName) override; + Function *FindFunctionNamed(StringRef FnName) override; /// FindGlobalVariableNamed - Search all of the active modules to find the /// global variable that defines Name. This is very slow operation and /// shouldn't be used for general code. - GlobalVariable *FindGlobalVariableNamed(const char *Name, + GlobalVariable *FindGlobalVariableNamed(StringRef Name, bool AllowInternal = false) override; /// Sets the object manager that MCJIT should use to avoid compilation. @@ -305,16 +304,22 @@ public: createJIT(std::unique_ptr<Module> M, std::string *ErrorStr, std::shared_ptr<MCJITMemoryManager> MemMgr, - std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver, + std::shared_ptr<JITSymbolResolver> Resolver, std::unique_ptr<TargetMachine> TM); // @} - RuntimeDyld::SymbolInfo findSymbol(const std::string &Name, - bool CheckFunctionsOnly); + // Takes a mangled name and returns the corresponding JITSymbol (if a + // definition of that mangled name has been added to the JIT). + JITSymbol findSymbol(const std::string &Name, bool CheckFunctionsOnly); + // DEPRECATED - Please use findSymbol instead. + // // This is not directly exposed via the ExecutionEngine API, but it is // used by the LinkingMemoryManager. + // + // getSymbolAddress takes an unmangled name and returns the corresponding + // JITSymbol if a definition of the name has been added to the JIT. uint64_t getSymbolAddress(const std::string &Name, bool CheckFunctionsOnly); @@ -330,9 +335,8 @@ protected: const RuntimeDyld::LoadedObjectInfo &L); void NotifyFreeingObject(const object::ObjectFile& Obj); - RuntimeDyld::SymbolInfo findExistingSymbol(const std::string &Name); - Module *findModuleForSymbol(const std::string &Name, - bool CheckFunctionsOnly); + JITSymbol findExistingSymbol(const std::string &Name); + Module *findModuleForSymbol(const std::string &Name, bool CheckFunctionsOnly); }; } // end llvm namespace diff --git a/contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp b/contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp index 324d071..57b5d85 100644 --- a/contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp +++ b/contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp @@ -88,15 +88,15 @@ void OProfileJITEventListener::NotifyObjectEmitted( // Use symbol info to iterate functions in the object. for (const std::pair<SymbolRef, uint64_t> &P : computeSymbolSizes(DebugObj)) { SymbolRef Sym = P.first; - if (Sym.getType() != SymbolRef::ST_Function) + if (!Sym.getType() || *Sym.getType() != SymbolRef::ST_Function) continue; - ErrorOr<StringRef> NameOrErr = Sym.getName(); - if (NameOrErr.getError()) + Expected<StringRef> NameOrErr = Sym.getName(); + if (!NameOrErr) continue; StringRef Name = *NameOrErr; - ErrorOr<uint64_t> AddrOrErr = Sym.getAddress(); - if (AddrOrErr.getError()) + Expected<uint64_t> AddrOrErr = Sym.getAddress(); + if (!AddrOrErr) continue; uint64_t Addr = *AddrOrErr; uint64_t Size = P.second; @@ -128,9 +128,9 @@ void OProfileJITEventListener::NotifyFreeingObject(const ObjectFile &Obj) { for (symbol_iterator I = DebugObj.symbol_begin(), E = DebugObj.symbol_end(); I != E; ++I) { - if (I->getType() == SymbolRef::ST_Function) { - ErrorOr<uint64_t> AddrOrErr = I->getAddress(); - if (AddrOrErr.getError()) + if (I->getType() && *I->getType() == SymbolRef::ST_Function) { + Expected<uint64_t> AddrOrErr = I->getAddress(); + if (!AddrOrErr) continue; uint64_t Addr = *AddrOrErr; diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/contrib/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp index 6f7c29f..711b887 100644 --- a/contrib/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp +++ b/contrib/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp @@ -24,7 +24,7 @@ void IndirectStubsManager::anchor() {} std::unique_ptr<JITCompileCallbackManager> createLocalCompileCallbackManager(const Triple &T, - TargetAddress ErrorHandlerAddress) { + JITTargetAddress ErrorHandlerAddress) { switch (T.getArch()) { default: return nullptr; @@ -71,7 +71,7 @@ createLocalIndirectStubsManagerBuilder(const Triple &T) { } } -Constant* createIRTypedAddress(FunctionType &FT, TargetAddress Addr) { +Constant* createIRTypedAddress(FunctionType &FT, JITTargetAddress Addr) { Constant *AddrIntVal = ConstantInt::get(Type::getInt64Ty(FT.getContext()), Addr); Constant *AddrPtrVal = @@ -241,5 +241,14 @@ GlobalAlias* cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA, return NewA; } +void cloneModuleFlagsMetadata(Module &Dst, const Module &Src, + ValueToValueMapTy &VMap) { + auto *MFs = Src.getModuleFlagsMetadata(); + if (!MFs) + return; + for (auto *MF : MFs->operands()) + Dst.addModuleFlag(MapMetadata(MF, VMap)); +} + } // End namespace orc. } // End namespace llvm. diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/NullResolver.cpp b/contrib/llvm/lib/ExecutionEngine/Orc/NullResolver.cpp index 57666a9..8f2d6fd 100644 --- a/contrib/llvm/lib/ExecutionEngine/Orc/NullResolver.cpp +++ b/contrib/llvm/lib/ExecutionEngine/Orc/NullResolver.cpp @@ -14,12 +14,11 @@ namespace llvm { namespace orc { -RuntimeDyld::SymbolInfo NullResolver::findSymbol(const std::string &Name) { +JITSymbol NullResolver::findSymbol(const std::string &Name) { llvm_unreachable("Unexpected cross-object symbol reference"); } -RuntimeDyld::SymbolInfo -NullResolver::findSymbolInLogicalDylib(const std::string &Name) { +JITSymbol NullResolver::findSymbolInLogicalDylib(const std::string &Name) { llvm_unreachable("Unexpected cross-object symbol reference"); } diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h b/contrib/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h index 9ae9b20..a74fae7 100644 --- a/contrib/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h +++ b/contrib/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h @@ -44,8 +44,8 @@ private: class GenericHandle { public: virtual ~GenericHandle() {} - virtual orc::JITSymbol findSymbolIn(const std::string &Name, - bool ExportedSymbolsOnly) = 0; + virtual JITSymbol findSymbolIn(const std::string &Name, + bool ExportedSymbolsOnly) = 0; virtual void removeModule() = 0; }; @@ -54,8 +54,8 @@ private: GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle) : Layer(Layer), Handle(std::move(Handle)) {} - orc::JITSymbol findSymbolIn(const std::string &Name, - bool ExportedSymbolsOnly) override { + JITSymbol findSymbolIn(const std::string &Name, + bool ExportedSymbolsOnly) override { return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly); } @@ -109,55 +109,56 @@ public: } template <typename PtrTy> - static PtrTy fromTargetAddress(orc::TargetAddress Addr) { + static PtrTy fromTargetAddress(JITTargetAddress Addr) { return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr)); } - orc::TargetAddress + JITTargetAddress createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback, void *CallbackCtx) { auto CCInfo = CCMgr->getCompileCallback(); - CCInfo.setCompileAction([=]() -> orc::TargetAddress { + CCInfo.setCompileAction([=]() -> JITTargetAddress { return Callback(wrap(this), CallbackCtx); }); return CCInfo.getAddress(); } LLVMOrcErrorCode createIndirectStub(StringRef StubName, - orc::TargetAddress Addr) { + JITTargetAddress Addr) { return mapError( IndirectStubsMgr->createStub(StubName, Addr, JITSymbolFlags::Exported)); } LLVMOrcErrorCode setIndirectStubPointer(StringRef Name, - orc::TargetAddress Addr) { + JITTargetAddress Addr) { return mapError(IndirectStubsMgr->updatePointer(Name, Addr)); } - std::unique_ptr<RuntimeDyld::SymbolResolver> + std::unique_ptr<JITSymbolResolver> createResolver(LLVMOrcSymbolResolverFn ExternalResolver, void *ExternalResolverCtx) { return orc::createLambdaResolver( - [this, ExternalResolver, ExternalResolverCtx](const std::string &Name) { + [this, ExternalResolver, ExternalResolverCtx](const std::string &Name) + -> JITSymbol { // Search order: // 1. JIT'd symbols. // 2. Runtime overrides. // 3. External resolver (if present). if (auto Sym = CODLayer.findSymbol(Name, true)) - return Sym.toRuntimeDyldSymbol(); + return Sym; if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name)) return Sym; if (ExternalResolver) - return RuntimeDyld::SymbolInfo( + return JITSymbol( ExternalResolver(Name.c_str(), ExternalResolverCtx), llvm::JITSymbolFlags::Exported); - return RuntimeDyld::SymbolInfo(nullptr); + return JITSymbol(nullptr); }, [](const std::string &Name) { - return RuntimeDyld::SymbolInfo(nullptr); + return JITSymbol(nullptr); }); } @@ -222,14 +223,14 @@ public: FreeHandleIndexes.push_back(H); } - orc::JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { + JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly)) return Sym; return CODLayer.findSymbol(mangle(Name), ExportedSymbolsOnly); } - orc::JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name, - bool ExportedSymbolsOnly) { + JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name, + bool ExportedSymbolsOnly) { return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly); } diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/OrcError.cpp b/contrib/llvm/lib/ExecutionEngine/Orc/OrcError.cpp index 22f1303..c531fe3 100644 --- a/contrib/llvm/lib/ExecutionEngine/Orc/OrcError.cpp +++ b/contrib/llvm/lib/ExecutionEngine/Orc/OrcError.cpp @@ -25,7 +25,7 @@ namespace { // deal with the Error value directly, rather than converting to error_code. class OrcErrorCategory : public std::error_category { public: - const char *name() const LLVM_NOEXCEPT override { return "orc"; } + const char *name() const noexcept override { return "orc"; } std::string message(int condition) const override { switch (static_cast<OrcErrorCode>(condition)) { @@ -39,10 +39,14 @@ public: return "Remote indirect stubs owner does not exist"; case OrcErrorCode::RemoteIndirectStubsOwnerIdAlreadyInUse: return "Remote indirect stubs owner Id already in use"; + case OrcErrorCode::RPCResponseAbandoned: + return "RPC response abandoned"; case OrcErrorCode::UnexpectedRPCCall: return "Unexpected RPC call"; case OrcErrorCode::UnexpectedRPCResponse: return "Unexpected RPC response"; + case OrcErrorCode::UnknownRPCFunction: + return "Unknown RPC function"; } llvm_unreachable("Unhandled error code"); } diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h b/contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h index d108307..af70960 100644 --- a/contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h +++ b/contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h @@ -14,18 +14,40 @@ #ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H #define LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" +#include "llvm/ExecutionEngine/GenericValue.h" +#include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/ExecutionEngine/Orc/CompileUtils.h" #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" #include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h" #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Mangler.h" #include "llvm/Object/Archive.h" +#include "llvm/Object/Binary.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetMachine.h" +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <algorithm> +#include <map> +#include <memory> +#include <set> +#include <string> +#include <vector> namespace llvm { namespace orc { class OrcMCJITReplacement : public ExecutionEngine { - // OrcMCJITReplacement needs to do a little extra book-keeping to ensure that // Orc's automatic finalization doesn't kick in earlier than MCJIT clients are // expecting - see finalizeMemory. @@ -111,17 +133,18 @@ class OrcMCJITReplacement : public ExecutionEngine { std::shared_ptr<MCJITMemoryManager> ClientMM; }; - class LinkingResolver : public RuntimeDyld::SymbolResolver { + class LinkingResolver : public JITSymbolResolver { public: LinkingResolver(OrcMCJITReplacement &M) : M(M) {} - RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) override { - return M.findMangledSymbol(Name); + JITSymbol findSymbol(const std::string &Name) override { + return M.ClientResolver->findSymbol(Name); } - RuntimeDyld::SymbolInfo - findSymbolInLogicalDylib(const std::string &Name) override { - return M.ClientResolver->findSymbol(Name); + JITSymbol findSymbolInLogicalDylib(const std::string &Name) override { + if (auto Sym = M.findMangledSymbol(Name)) + return Sym; + return M.ClientResolver->findSymbolInLogicalDylib(Name); } private: @@ -133,7 +156,7 @@ private: static ExecutionEngine * createOrcMCJITReplacement(std::string *ErrorMsg, std::shared_ptr<MCJITMemoryManager> MemMgr, - std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver, + std::shared_ptr<JITSymbolResolver> Resolver, std::unique_ptr<TargetMachine> TM) { return new OrcMCJITReplacement(std::move(MemMgr), std::move(Resolver), std::move(TM)); @@ -146,7 +169,7 @@ public: OrcMCJITReplacement( std::shared_ptr<MCJITMemoryManager> MemMgr, - std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver, + std::shared_ptr<JITSymbolResolver> ClientResolver, std::unique_ptr<TargetMachine> TM) : ExecutionEngine(TM->createDataLayout()), TM(std::move(TM)), MemMgr(*this, std::move(MemMgr)), Resolver(*this), @@ -193,7 +216,7 @@ public: return findSymbol(Name).getAddress(); } - RuntimeDyld::SymbolInfo findSymbol(StringRef Name) { + JITSymbol findSymbol(StringRef Name) { return findMangledSymbol(Mangle(Name)); } @@ -242,14 +265,13 @@ public: } private: - - RuntimeDyld::SymbolInfo findMangledSymbol(StringRef Name) { + JITSymbol findMangledSymbol(StringRef Name) { if (auto Sym = LazyEmitLayer.findSymbol(Name, false)) - return Sym.toRuntimeDyldSymbol(); + return Sym; if (auto Sym = ClientResolver->findSymbol(Name)) return Sym; if (auto Sym = scanArchives(Name)) - return Sym.toRuntimeDyldSymbol(); + return Sym; return nullptr; } @@ -305,7 +327,6 @@ private: } private: - static const object::ObjectFile& getObject(const object::ObjectFile &Obj) { return Obj; } @@ -322,6 +343,7 @@ private: class NotifyFinalizedT { public: NotifyFinalizedT(OrcMCJITReplacement &M) : M(M) {} + void operator()(ObjectLinkingLayerBase::ObjSetHandleT H) { M.UnfinalizedSections.erase(H); } @@ -346,7 +368,7 @@ private: std::unique_ptr<TargetMachine> TM; MCJITReplacementMemMgr MemMgr; LinkingResolver Resolver; - std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver; + std::shared_ptr<JITSymbolResolver> ClientResolver; Mangler Mang; NotifyObjectLoadedT NotifyObjectLoaded; @@ -373,7 +395,7 @@ private: std::vector<object::OwningBinary<object::Archive>> Archives; }; -} // End namespace orc. -} // End namespace llvm. +} // end namespace orc +} // end namespace llvm #endif // LLVM_LIB_EXECUTIONENGINE_ORC_MCJITREPLACEMENT_H diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp b/contrib/llvm/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp deleted file mode 100644 index d1a021a..0000000 --- a/contrib/llvm/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp +++ /dev/null @@ -1,53 +0,0 @@ -//===------- OrcRemoteTargetRPCAPI.cpp - ORC Remote API utilities ---------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h" - -namespace llvm { -namespace orc { -namespace remote { - -#define FUNCNAME(X) \ - case X ## Id: \ - return #X - -const char *OrcRemoteTargetRPCAPI::getJITFuncIdName(JITFuncId Id) { - switch (Id) { - case InvalidId: - return "*** Invalid JITFuncId ***"; - FUNCNAME(CallIntVoid); - FUNCNAME(CallMain); - FUNCNAME(CallVoidVoid); - FUNCNAME(CreateRemoteAllocator); - FUNCNAME(CreateIndirectStubsOwner); - FUNCNAME(DeregisterEHFrames); - FUNCNAME(DestroyRemoteAllocator); - FUNCNAME(DestroyIndirectStubsOwner); - FUNCNAME(EmitIndirectStubs); - FUNCNAME(EmitResolverBlock); - FUNCNAME(EmitTrampolineBlock); - FUNCNAME(GetSymbolAddress); - FUNCNAME(GetRemoteInfo); - FUNCNAME(ReadMem); - FUNCNAME(RegisterEHFrames); - FUNCNAME(ReserveMem); - FUNCNAME(RequestCompile); - FUNCNAME(SetProtections); - FUNCNAME(TerminateSession); - FUNCNAME(WriteMem); - FUNCNAME(WritePtr); - }; - return nullptr; -} - -#undef FUNCNAME - -} // end namespace remote -} // end namespace orc -} // end namespace llvm diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/JITSymbol.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/JITSymbol.cpp new file mode 100644 index 0000000..8769dcf --- /dev/null +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/JITSymbol.cpp @@ -0,0 +1,41 @@ +//===----------- JITSymbol.cpp - JITSymbol class implementation -----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// JITSymbol class implementation plus helper functions. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/IR/GlobalValue.h" +#include "llvm/Object/SymbolicFile.h" + +using namespace llvm; + +JITSymbolFlags llvm::JITSymbolFlags::fromGlobalValue(const GlobalValue &GV) { + JITSymbolFlags Flags = JITSymbolFlags::None; + if (GV.hasWeakLinkage() || GV.hasLinkOnceLinkage()) + Flags |= JITSymbolFlags::Weak; + if (GV.hasCommonLinkage()) + Flags |= JITSymbolFlags::Common; + if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility()) + Flags |= JITSymbolFlags::Exported; + return Flags; +} + +JITSymbolFlags +llvm::JITSymbolFlags::fromObjectSymbol(const object::BasicSymbolRef &Symbol) { + JITSymbolFlags Flags = JITSymbolFlags::None; + if (Symbol.getFlags() & object::BasicSymbolRef::SF_Weak) + Flags |= JITSymbolFlags::Weak; + if (Symbol.getFlags() & object::BasicSymbolRef::SF_Common) + Flags |= JITSymbolFlags::Common; + if (Symbol.getFlags() & object::BasicSymbolRef::SF_Exported) + Flags |= JITSymbolFlags::Exported; + return Flags; +} diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp index e39acc7..de73fbd 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp @@ -97,7 +97,8 @@ static const char *processFDE(const char *Entry, bool isDeregister) { void RTDyldMemoryManager::registerEHFramesInProcess(uint8_t *Addr, size_t Size) { // On OS X OS X __register_frame takes a single FDE as an argument. - // See http://lists.llvm.org/pipermail/llvm-dev/2013-April/061768.html + // See http://lists.llvm.org/pipermail/llvm-dev/2013-April/061737.html + // and projects/libunwind/src/UnwindLevel1-gcc-ext.c. const char *P = (const char *)Addr; const char *End = P + Size; do { diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 1dfbe31..63b56f7 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -39,7 +39,7 @@ enum RuntimeDyldErrorCode { // deal with the Error value directly, rather than converting to error_code. class RuntimeDyldErrorCategory : public std::error_category { public: - const char *name() const LLVM_NOEXCEPT override { return "runtimedyld"; } + const char *name() const noexcept override { return "runtimedyld"; } std::string message(int Condition) const override { switch (static_cast<RuntimeDyldErrorCode>(Condition)) { @@ -205,6 +205,10 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { ++I) { uint32_t Flags = I->getFlags(); + // Skip undefined symbols. + if (Flags & SymbolRef::SF_Undefined) + continue; + if (Flags & SymbolRef::SF_Common) CommonSymbols.push_back(*I); else { @@ -224,11 +228,25 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { return NameOrErr.takeError(); // Compute JIT symbol flags. - JITSymbolFlags RTDyldSymFlags = JITSymbolFlags::None; - if (Flags & SymbolRef::SF_Weak) - RTDyldSymFlags |= JITSymbolFlags::Weak; - if (Flags & SymbolRef::SF_Exported) - RTDyldSymFlags |= JITSymbolFlags::Exported; + JITSymbolFlags JITSymFlags = JITSymbolFlags::fromObjectSymbol(*I); + + // If this is a weak definition, check to see if there's a strong one. + // If there is, skip this symbol (we won't be providing it: the strong + // definition will). If there's no strong definition, make this definition + // strong. + if (JITSymFlags.isWeak()) { + // First check whether there's already a definition in this instance. + // FIXME: Override existing weak definitions with strong ones. + if (GlobalSymbolTable.count(Name)) + continue; + // Then check the symbol resolver to see if there's a definition + // elsewhere in this logical dylib. + if (auto Sym = Resolver.findSymbolInLogicalDylib(Name)) + if (Sym.getFlags().isStrongDefinition()) + continue; + // else + JITSymFlags &= ~JITSymbolFlags::Weak; + } if (Flags & SymbolRef::SF_Absolute && SymType != object::SymbolRef::ST_File) { @@ -245,7 +263,7 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { << format("%p", (uintptr_t)Addr) << " flags: " << Flags << "\n"); GlobalSymbolTable[Name] = - SymbolTableEntry(SectionID, Addr, RTDyldSymFlags); + SymbolTableEntry(SectionID, Addr, JITSymFlags); } else if (SymType == object::SymbolRef::ST_Function || SymType == object::SymbolRef::ST_Data || SymType == object::SymbolRef::ST_Unknown || @@ -278,7 +296,7 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) { << format("%p", (uintptr_t)SectOffset) << " flags: " << Flags << "\n"); GlobalSymbolTable[Name] = - SymbolTableEntry(SectionID, SectOffset, RTDyldSymFlags); + SymbolTableEntry(SectionID, SectOffset, JITSymFlags); } } } @@ -584,13 +602,19 @@ Error RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj, return NameOrErr.takeError(); // Skip common symbols already elsewhere. - if (GlobalSymbolTable.count(Name) || - Resolver.findSymbolInLogicalDylib(Name)) { + if (GlobalSymbolTable.count(Name)) { DEBUG(dbgs() << "\tSkipping already emitted common symbol '" << Name << "'\n"); continue; } + if (auto Sym = Resolver.findSymbolInLogicalDylib(Name)) { + if (!Sym.getFlags().isCommon()) { + DEBUG(dbgs() << "\tSkipping common symbol '" << Name + << "' in favor of stronger definition.\n"); + continue; + } + } uint32_t Align = Sym.getAlignment(); uint64_t Size = Sym.getCommonSize(); @@ -628,16 +652,11 @@ Error RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj, Addr += AlignOffset; Offset += AlignOffset; } - uint32_t Flags = Sym.getFlags(); - JITSymbolFlags RTDyldSymFlags = JITSymbolFlags::None; - if (Flags & SymbolRef::SF_Weak) - RTDyldSymFlags |= JITSymbolFlags::Weak; - if (Flags & SymbolRef::SF_Exported) - RTDyldSymFlags |= JITSymbolFlags::Exported; + JITSymbolFlags JITSymFlags = JITSymbolFlags::fromObjectSymbol(Sym); DEBUG(dbgs() << "Allocating common symbol " << Name << " address " << format("%p", Addr) << "\n"); GlobalSymbolTable[Name] = - SymbolTableEntry(SectionID, Offset, RTDyldSymFlags); + SymbolTableEntry(SectionID, Offset, JITSymFlags); Offset += Size; Addr += Size; } @@ -974,10 +993,10 @@ uint64_t RuntimeDyld::LoadedObjectInfo::getSectionLoadAddress( } void RuntimeDyld::MemoryManager::anchor() {} -void RuntimeDyld::SymbolResolver::anchor() {} +void JITSymbolResolver::anchor() {} RuntimeDyld::RuntimeDyld(RuntimeDyld::MemoryManager &MemMgr, - RuntimeDyld::SymbolResolver &Resolver) + JITSymbolResolver &Resolver) : MemMgr(MemMgr), Resolver(Resolver) { // FIXME: There's a potential issue lurking here if a single instance of // RuntimeDyld is used to load multiple objects. The current implementation @@ -994,8 +1013,8 @@ RuntimeDyld::~RuntimeDyld() {} static std::unique_ptr<RuntimeDyldCOFF> createRuntimeDyldCOFF(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM, - RuntimeDyld::SymbolResolver &Resolver, - bool ProcessAllSections, RuntimeDyldCheckerImpl *Checker) { + JITSymbolResolver &Resolver, bool ProcessAllSections, + RuntimeDyldCheckerImpl *Checker) { std::unique_ptr<RuntimeDyldCOFF> Dyld = RuntimeDyldCOFF::create(Arch, MM, Resolver); Dyld->setProcessAllSections(ProcessAllSections); @@ -1004,10 +1023,11 @@ createRuntimeDyldCOFF(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM, } static std::unique_ptr<RuntimeDyldELF> -createRuntimeDyldELF(RuntimeDyld::MemoryManager &MM, - RuntimeDyld::SymbolResolver &Resolver, - bool ProcessAllSections, RuntimeDyldCheckerImpl *Checker) { - std::unique_ptr<RuntimeDyldELF> Dyld(new RuntimeDyldELF(MM, Resolver)); +createRuntimeDyldELF(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM, + JITSymbolResolver &Resolver, bool ProcessAllSections, + RuntimeDyldCheckerImpl *Checker) { + std::unique_ptr<RuntimeDyldELF> Dyld = + RuntimeDyldELF::create(Arch, MM, Resolver); Dyld->setProcessAllSections(ProcessAllSections); Dyld->setRuntimeDyldChecker(Checker); return Dyld; @@ -1015,7 +1035,7 @@ createRuntimeDyldELF(RuntimeDyld::MemoryManager &MM, static std::unique_ptr<RuntimeDyldMachO> createRuntimeDyldMachO(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM, - RuntimeDyld::SymbolResolver &Resolver, + JITSymbolResolver &Resolver, bool ProcessAllSections, RuntimeDyldCheckerImpl *Checker) { std::unique_ptr<RuntimeDyldMachO> Dyld = @@ -1029,7 +1049,9 @@ std::unique_ptr<RuntimeDyld::LoadedObjectInfo> RuntimeDyld::loadObject(const ObjectFile &Obj) { if (!Dyld) { if (Obj.isELF()) - Dyld = createRuntimeDyldELF(MemMgr, Resolver, ProcessAllSections, Checker); + Dyld = + createRuntimeDyldELF(static_cast<Triple::ArchType>(Obj.getArch()), + MemMgr, Resolver, ProcessAllSections, Checker); else if (Obj.isMachO()) Dyld = createRuntimeDyldMachO( static_cast<Triple::ArchType>(Obj.getArch()), MemMgr, Resolver, @@ -1056,7 +1078,7 @@ void *RuntimeDyld::getSymbolLocalAddress(StringRef Name) const { return Dyld->getSymbolLocalAddress(Name); } -RuntimeDyld::SymbolInfo RuntimeDyld::getSymbol(StringRef Name) const { +JITEvaluatedSymbol RuntimeDyld::getSymbol(StringRef Name) const { if (!Dyld) return nullptr; return Dyld->getSymbol(Name); diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp index 24bd9a0..1bd28ef 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp @@ -44,7 +44,7 @@ namespace llvm { std::unique_ptr<RuntimeDyldCOFF> llvm::RuntimeDyldCOFF::create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr, - RuntimeDyld::SymbolResolver &Resolver) { + JITSymbolResolver &Resolver) { switch (Arch) { default: llvm_unreachable("Unsupported target for RuntimeDyldCOFF."); case Triple::x86: diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h index 03a91f6..729a358 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h @@ -33,11 +33,11 @@ public: static std::unique_ptr<RuntimeDyldCOFF> create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr, - RuntimeDyld::SymbolResolver &Resolver); + JITSymbolResolver &Resolver); protected: RuntimeDyldCOFF(RuntimeDyld::MemoryManager &MemMgr, - RuntimeDyld::SymbolResolver &Resolver) + JITSymbolResolver &Resolver) : RuntimeDyldImpl(MemMgr, Resolver) {} uint64_t getSymbolOffset(const SymbolRef &Sym); }; diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp index 090b9a3..7bfa794 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp @@ -217,7 +217,7 @@ private: // given symbol and get the value of the requested operand. // Returns an error if the instruction cannot be decoded, or the requested // operand is not an immediate. - // On success, retuns a pair containing the value of the operand, plus + // On success, returns a pair containing the value of the operand, plus // the expression remaining to be evaluated. std::pair<EvalResult, StringRef> evalDecodeOperand(StringRef Expr) const { if (!Expr.startswith("(")) @@ -463,7 +463,7 @@ private: Expr.substr(FirstNonDigit)); } - // Evaluate a constant numeric expression (hexidecimal or decimal) and + // Evaluate a constant numeric expression (hexadecimal or decimal) and // return a pair containing the result, and the expression remaining to be // evaluated. std::pair<EvalResult, StringRef> evalNumberExpr(StringRef Expr) const { diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index 9cbdb13..05615d3 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -13,6 +13,7 @@ #include "RuntimeDyldELF.h" #include "RuntimeDyldCheckerImpl.h" +#include "Targets/RuntimeDyldELFMips.h" #include "llvm/ADT/IntervalMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" @@ -27,9 +28,34 @@ using namespace llvm; using namespace llvm::object; +using namespace llvm::support::endian; #define DEBUG_TYPE "dyld" +static void or32le(void *P, int32_t V) { write32le(P, read32le(P) | V); } + +static void or32AArch64Imm(void *L, uint64_t Imm) { + or32le(L, (Imm & 0xFFF) << 10); +} + +template <class T> static void write(bool isBE, void *P, T V) { + isBE ? write<T, support::big>(P, V) : write<T, support::little>(P, V); +} + +static void write32AArch64Addr(void *L, uint64_t Imm) { + uint32_t ImmLo = (Imm & 0x3) << 29; + uint32_t ImmHi = (Imm & 0x1FFFFC) << 3; + uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3); + write32le(L, (read32le(L) & ~Mask) | ImmLo | ImmHi); +} + +// Return the bits [Start, End] from Val shifted Start bits. +// For instance, getBits(0xF0, 4, 8) returns 0xF. +static uint64_t getBits(uint64_t Val, int Start, int End) { + uint64_t Mask = ((uint64_t)1 << (End + 1 - Start)) - 1; + return (Val >> Start) & Mask; +} + namespace { template <class ELFT> class DyldELFObject : public ELFObjectFile<ELFT> { @@ -184,7 +210,7 @@ LoadedELFObjectInfo::getObjectForDebug(const ObjectFile &Obj) const { namespace llvm { RuntimeDyldELF::RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr, - RuntimeDyld::SymbolResolver &Resolver) + JITSymbolResolver &Resolver) : RuntimeDyldImpl(MemMgr, Resolver), GOTSectionID(0), CurrentGOTIndex(0) {} RuntimeDyldELF::~RuntimeDyldELF() {} @@ -211,6 +237,21 @@ void RuntimeDyldELF::deregisterEHFrames() { RegisteredEHFrameSections.clear(); } +std::unique_ptr<RuntimeDyldELF> +llvm::RuntimeDyldELF::create(Triple::ArchType Arch, + RuntimeDyld::MemoryManager &MemMgr, + JITSymbolResolver &Resolver) { + switch (Arch) { + default: + return make_unique<RuntimeDyldELF>(MemMgr, Resolver); + case Triple::mips: + case Triple::mipsel: + case Triple::mips64: + case Triple::mips64el: + return make_unique<RuntimeDyldELFMips>(MemMgr, Resolver); + } +} + std::unique_ptr<RuntimeDyld::LoadedObjectInfo> RuntimeDyldELF::loadObject(const object::ObjectFile &O) { if (auto ObjSectionToIDOrErr = loadObjectImpl(O)) @@ -309,6 +350,8 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section, uint32_t *TargetPtr = reinterpret_cast<uint32_t *>(Section.getAddressWithOffset(Offset)); uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + // Data should use target endian. Code should always use little endian. + bool isBE = Arch == Triple::aarch64_be; DEBUG(dbgs() << "resolveAArch64Relocation, LocalAddress: 0x" << format("%llx", Section.getAddressWithOffset(Offset)) @@ -321,19 +364,19 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section, default: llvm_unreachable("Relocation type not implemented yet!"); break; - case ELF::R_AARCH64_ABS64: { - uint64_t *TargetPtr = - reinterpret_cast<uint64_t *>(Section.getAddressWithOffset(Offset)); - *TargetPtr = Value + Addend; + case ELF::R_AARCH64_ABS64: + write(isBE, TargetPtr, Value + Addend); break; - } case ELF::R_AARCH64_PREL32: { uint64_t Result = Value + Addend - FinalAddress; assert(static_cast<int64_t>(Result) >= INT32_MIN && static_cast<int64_t>(Result) <= UINT32_MAX); - *TargetPtr = static_cast<uint32_t>(Result & 0xffffffffU); + write(isBE, TargetPtr, static_cast<uint32_t>(Result & 0xffffffffU)); break; } + case ELF::R_AARCH64_PREL64: + write(isBE, TargetPtr, Value + Addend - FinalAddress); + break; case ELF::R_AARCH64_CALL26: // fallthrough case ELF::R_AARCH64_JUMP26: { // Operation: S+A-P. Set Call or B immediate value to bits fff_fffc of the @@ -342,62 +385,21 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section, // "Check that -2^27 <= result < 2^27". assert(isInt<28>(BranchImm)); - - // AArch64 code is emitted with .rela relocations. The data already in any - // bits affected by the relocation on entry is garbage. - *TargetPtr &= 0xfc000000U; - // Immediate goes in bits 25:0 of B and BL. - *TargetPtr |= static_cast<uint32_t>(BranchImm & 0xffffffcU) >> 2; + or32le(TargetPtr, (BranchImm & 0x0FFFFFFC) >> 2); break; } - case ELF::R_AARCH64_MOVW_UABS_G3: { - uint64_t Result = Value + Addend; - - // AArch64 code is emitted with .rela relocations. The data already in any - // bits affected by the relocation on entry is garbage. - *TargetPtr &= 0xffe0001fU; - // Immediate goes in bits 20:5 of MOVZ/MOVK instruction - *TargetPtr |= Result >> (48 - 5); - // Shift must be "lsl #48", in bits 22:21 - assert((*TargetPtr >> 21 & 0x3) == 3 && "invalid shift for relocation"); + case ELF::R_AARCH64_MOVW_UABS_G3: + or32le(TargetPtr, ((Value + Addend) & 0xFFFF000000000000) >> 43); break; - } - case ELF::R_AARCH64_MOVW_UABS_G2_NC: { - uint64_t Result = Value + Addend; - - // AArch64 code is emitted with .rela relocations. The data already in any - // bits affected by the relocation on entry is garbage. - *TargetPtr &= 0xffe0001fU; - // Immediate goes in bits 20:5 of MOVZ/MOVK instruction - *TargetPtr |= ((Result & 0xffff00000000ULL) >> (32 - 5)); - // Shift must be "lsl #32", in bits 22:21 - assert((*TargetPtr >> 21 & 0x3) == 2 && "invalid shift for relocation"); + case ELF::R_AARCH64_MOVW_UABS_G2_NC: + or32le(TargetPtr, ((Value + Addend) & 0xFFFF00000000) >> 27); break; - } - case ELF::R_AARCH64_MOVW_UABS_G1_NC: { - uint64_t Result = Value + Addend; - - // AArch64 code is emitted with .rela relocations. The data already in any - // bits affected by the relocation on entry is garbage. - *TargetPtr &= 0xffe0001fU; - // Immediate goes in bits 20:5 of MOVZ/MOVK instruction - *TargetPtr |= ((Result & 0xffff0000U) >> (16 - 5)); - // Shift must be "lsl #16", in bits 22:2 - assert((*TargetPtr >> 21 & 0x3) == 1 && "invalid shift for relocation"); + case ELF::R_AARCH64_MOVW_UABS_G1_NC: + or32le(TargetPtr, ((Value + Addend) & 0xFFFF0000) >> 11); break; - } - case ELF::R_AARCH64_MOVW_UABS_G0_NC: { - uint64_t Result = Value + Addend; - - // AArch64 code is emitted with .rela relocations. The data already in any - // bits affected by the relocation on entry is garbage. - *TargetPtr &= 0xffe0001fU; - // Immediate goes in bits 20:5 of MOVZ/MOVK instruction - *TargetPtr |= ((Result & 0xffffU) << 5); - // Shift must be "lsl #0", in bits 22:21. - assert((*TargetPtr >> 21 & 0x3) == 0 && "invalid shift for relocation"); + case ELF::R_AARCH64_MOVW_UABS_G0_NC: + or32le(TargetPtr, ((Value + Addend) & 0xFFFF) << 5); break; - } case ELF::R_AARCH64_ADR_PREL_PG_HI21: { // Operation: Page(S+A) - Page(P) uint64_t Result = @@ -406,40 +408,30 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section, // Check that -2^32 <= X < 2^32 assert(isInt<33>(Result) && "overflow check failed for relocation"); - // AArch64 code is emitted with .rela relocations. The data already in any - // bits affected by the relocation on entry is garbage. - *TargetPtr &= 0x9f00001fU; // Immediate goes in bits 30:29 + 5:23 of ADRP instruction, taken // from bits 32:12 of X. - *TargetPtr |= ((Result & 0x3000U) << (29 - 12)); - *TargetPtr |= ((Result & 0x1ffffc000ULL) >> (14 - 5)); + write32AArch64Addr(TargetPtr, Result >> 12); break; } - case ELF::R_AARCH64_LDST32_ABS_LO12_NC: { + case ELF::R_AARCH64_ADD_ABS_LO12_NC: + // Operation: S + A + // Immediate goes in bits 21:10 of LD/ST instruction, taken + // from bits 11:0 of X + or32AArch64Imm(TargetPtr, Value + Addend); + break; + case ELF::R_AARCH64_LDST32_ABS_LO12_NC: // Operation: S + A - uint64_t Result = Value + Addend; - - // AArch64 code is emitted with .rela relocations. The data already in any - // bits affected by the relocation on entry is garbage. - *TargetPtr &= 0xffc003ffU; // Immediate goes in bits 21:10 of LD/ST instruction, taken // from bits 11:2 of X - *TargetPtr |= ((Result & 0xffc) << (10 - 2)); + or32AArch64Imm(TargetPtr, getBits(Value + Addend, 2, 11)); break; - } - case ELF::R_AARCH64_LDST64_ABS_LO12_NC: { + case ELF::R_AARCH64_LDST64_ABS_LO12_NC: // Operation: S + A - uint64_t Result = Value + Addend; - - // AArch64 code is emitted with .rela relocations. The data already in any - // bits affected by the relocation on entry is garbage. - *TargetPtr &= 0xffc003ffU; // Immediate goes in bits 21:10 of LD/ST instruction, taken // from bits 11:3 of X - *TargetPtr |= ((Result & 0xff8) << (10 - 3)); + or32AArch64Imm(TargetPtr, getBits(Value + Addend, 3, 11)); break; } - } } void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section, @@ -463,10 +455,15 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section, case ELF::R_ARM_NONE: break; + // Write a 31bit signed offset case ELF::R_ARM_PREL31: + support::ulittle32_t::ref{TargetPtr} = + (support::ulittle32_t::ref{TargetPtr} & 0x80000000) | + ((Value - FinalAddress) & ~0x80000000); + break; case ELF::R_ARM_TARGET1: case ELF::R_ARM_ABS32: - *TargetPtr = Value; + support::ulittle32_t::ref{TargetPtr} = Value; break; // Write first 16 bit of 32 bit value to the mov instruction. // Last 4 bit should be shifted. @@ -476,9 +473,9 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section, Value = Value & 0xFFFF; else if (Type == ELF::R_ARM_MOVT_ABS) Value = (Value >> 16) & 0xFFFF; - *TargetPtr &= ~0x000F0FFF; - *TargetPtr |= Value & 0xFFF; - *TargetPtr |= ((Value >> 12) & 0xF) << 16; + support::ulittle32_t::ref{TargetPtr} = + (support::ulittle32_t::ref{TargetPtr} & ~0x000F0FFF) | (Value & 0xFFF) | + (((Value >> 12) & 0xF) << 16); break; // Write 24 bit relative value to the branch instruction. case ELF::R_ARM_PC24: // Fall through. @@ -486,298 +483,26 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section, case ELF::R_ARM_JUMP24: int32_t RelValue = static_cast<int32_t>(Value - FinalAddress - 8); RelValue = (RelValue & 0x03FFFFFC) >> 2; - assert((*TargetPtr & 0xFFFFFF) == 0xFFFFFE); - *TargetPtr &= 0xFF000000; - *TargetPtr |= RelValue; + assert((support::ulittle32_t::ref{TargetPtr} & 0xFFFFFF) == 0xFFFFFE); + support::ulittle32_t::ref{TargetPtr} = + (support::ulittle32_t::ref{TargetPtr} & 0xFF000000) | RelValue; break; } } -void RuntimeDyldELF::resolveMIPSRelocation(const SectionEntry &Section, - uint64_t Offset, uint32_t Value, - uint32_t Type, int32_t Addend) { - uint8_t *TargetPtr = Section.getAddressWithOffset(Offset); - Value += Addend; - - DEBUG(dbgs() << "resolveMIPSRelocation, LocalAddress: " - << Section.getAddressWithOffset(Offset) << " FinalAddress: " - << format("%p", Section.getLoadAddressWithOffset(Offset)) - << " Value: " << format("%x", Value) - << " Type: " << format("%x", Type) - << " Addend: " << format("%x", Addend) << "\n"); - - uint32_t Insn = readBytesUnaligned(TargetPtr, 4); - - switch (Type) { - default: - llvm_unreachable("Not implemented relocation type!"); - break; - case ELF::R_MIPS_32: - writeBytesUnaligned(Value, TargetPtr, 4); - break; - case ELF::R_MIPS_26: - Insn &= 0xfc000000; - Insn |= (Value & 0x0fffffff) >> 2; - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - case ELF::R_MIPS_HI16: - // Get the higher 16-bits. Also add 1 if bit 15 is 1. - Insn &= 0xffff0000; - Insn |= ((Value + 0x8000) >> 16) & 0xffff; - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - case ELF::R_MIPS_LO16: - Insn &= 0xffff0000; - Insn |= Value & 0xffff; - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - case ELF::R_MIPS_PC32: { - uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - writeBytesUnaligned(Value - FinalAddress, (uint8_t *)TargetPtr, 4); - break; - } - case ELF::R_MIPS_PC16: { - uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - Insn &= 0xffff0000; - Insn |= ((Value - FinalAddress) >> 2) & 0xffff; - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - } - case ELF::R_MIPS_PC19_S2: { - uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - Insn &= 0xfff80000; - Insn |= ((Value - (FinalAddress & ~0x3)) >> 2) & 0x7ffff; - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - } - case ELF::R_MIPS_PC21_S2: { - uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - Insn &= 0xffe00000; - Insn |= ((Value - FinalAddress) >> 2) & 0x1fffff; - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - } - case ELF::R_MIPS_PC26_S2: { - uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - Insn &= 0xfc000000; - Insn |= ((Value - FinalAddress) >> 2) & 0x3ffffff; - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - } - case ELF::R_MIPS_PCHI16: { - uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - Insn &= 0xffff0000; - Insn |= ((Value - FinalAddress + 0x8000) >> 16) & 0xffff; - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - } - case ELF::R_MIPS_PCLO16: { - uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - Insn &= 0xffff0000; - Insn |= (Value - FinalAddress) & 0xffff; - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - } - } -} - void RuntimeDyldELF::setMipsABI(const ObjectFile &Obj) { if (Arch == Triple::UnknownArch || !StringRef(Triple::getArchTypePrefix(Arch)).equals("mips")) { IsMipsO32ABI = false; + IsMipsN32ABI = false; IsMipsN64ABI = false; return; } unsigned AbiVariant; Obj.getPlatformFlags(AbiVariant); IsMipsO32ABI = AbiVariant & ELF::EF_MIPS_ABI_O32; + IsMipsN32ABI = AbiVariant & ELF::EF_MIPS_ABI2; IsMipsN64ABI = Obj.getFileFormatName().equals("ELF64-mips"); - if (AbiVariant & ELF::EF_MIPS_ABI2) - llvm_unreachable("Mips N32 ABI is not supported yet"); -} - -void RuntimeDyldELF::resolveMIPS64Relocation(const SectionEntry &Section, - uint64_t Offset, uint64_t Value, - uint32_t Type, int64_t Addend, - uint64_t SymOffset, - SID SectionID) { - uint32_t r_type = Type & 0xff; - uint32_t r_type2 = (Type >> 8) & 0xff; - uint32_t r_type3 = (Type >> 16) & 0xff; - - // RelType is used to keep information for which relocation type we are - // applying relocation. - uint32_t RelType = r_type; - int64_t CalculatedValue = evaluateMIPS64Relocation(Section, Offset, Value, - RelType, Addend, - SymOffset, SectionID); - if (r_type2 != ELF::R_MIPS_NONE) { - RelType = r_type2; - CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType, - CalculatedValue, SymOffset, - SectionID); - } - if (r_type3 != ELF::R_MIPS_NONE) { - RelType = r_type3; - CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType, - CalculatedValue, SymOffset, - SectionID); - } - applyMIPS64Relocation(Section.getAddressWithOffset(Offset), CalculatedValue, - RelType); -} - -int64_t -RuntimeDyldELF::evaluateMIPS64Relocation(const SectionEntry &Section, - uint64_t Offset, uint64_t Value, - uint32_t Type, int64_t Addend, - uint64_t SymOffset, SID SectionID) { - - DEBUG(dbgs() << "evaluateMIPS64Relocation, LocalAddress: 0x" - << format("%llx", Section.getAddressWithOffset(Offset)) - << " FinalAddress: 0x" - << format("%llx", Section.getLoadAddressWithOffset(Offset)) - << " Value: 0x" << format("%llx", Value) << " Type: 0x" - << format("%x", Type) << " Addend: 0x" << format("%llx", Addend) - << " SymOffset: " << format("%x", SymOffset) << "\n"); - - switch (Type) { - default: - llvm_unreachable("Not implemented relocation type!"); - break; - case ELF::R_MIPS_JALR: - case ELF::R_MIPS_NONE: - break; - case ELF::R_MIPS_32: - case ELF::R_MIPS_64: - return Value + Addend; - case ELF::R_MIPS_26: - return ((Value + Addend) >> 2) & 0x3ffffff; - case ELF::R_MIPS_GPREL16: { - uint64_t GOTAddr = getSectionLoadAddress(SectionToGOTMap[SectionID]); - return Value + Addend - (GOTAddr + 0x7ff0); - } - case ELF::R_MIPS_SUB: - return Value - Addend; - case ELF::R_MIPS_HI16: - // Get the higher 16-bits. Also add 1 if bit 15 is 1. - return ((Value + Addend + 0x8000) >> 16) & 0xffff; - case ELF::R_MIPS_LO16: - return (Value + Addend) & 0xffff; - case ELF::R_MIPS_CALL16: - case ELF::R_MIPS_GOT_DISP: - case ELF::R_MIPS_GOT_PAGE: { - uint8_t *LocalGOTAddr = - getSectionAddress(SectionToGOTMap[SectionID]) + SymOffset; - uint64_t GOTEntry = readBytesUnaligned(LocalGOTAddr, 8); - - Value += Addend; - if (Type == ELF::R_MIPS_GOT_PAGE) - Value = (Value + 0x8000) & ~0xffff; - - if (GOTEntry) - assert(GOTEntry == Value && - "GOT entry has two different addresses."); - else - writeBytesUnaligned(Value, LocalGOTAddr, 8); - - return (SymOffset - 0x7ff0) & 0xffff; - } - case ELF::R_MIPS_GOT_OFST: { - int64_t page = (Value + Addend + 0x8000) & ~0xffff; - return (Value + Addend - page) & 0xffff; - } - case ELF::R_MIPS_GPREL32: { - uint64_t GOTAddr = getSectionLoadAddress(SectionToGOTMap[SectionID]); - return Value + Addend - (GOTAddr + 0x7ff0); - } - case ELF::R_MIPS_PC16: { - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return ((Value + Addend - FinalAddress) >> 2) & 0xffff; - } - case ELF::R_MIPS_PC32: { - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return Value + Addend - FinalAddress; - } - case ELF::R_MIPS_PC18_S3: { - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return ((Value + Addend - (FinalAddress & ~0x7)) >> 3) & 0x3ffff; - } - case ELF::R_MIPS_PC19_S2: { - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return ((Value + Addend - (FinalAddress & ~0x3)) >> 2) & 0x7ffff; - } - case ELF::R_MIPS_PC21_S2: { - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return ((Value + Addend - FinalAddress) >> 2) & 0x1fffff; - } - case ELF::R_MIPS_PC26_S2: { - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return ((Value + Addend - FinalAddress) >> 2) & 0x3ffffff; - } - case ELF::R_MIPS_PCHI16: { - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return ((Value + Addend - FinalAddress + 0x8000) >> 16) & 0xffff; - } - case ELF::R_MIPS_PCLO16: { - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return (Value + Addend - FinalAddress) & 0xffff; - } - } - return 0; -} - -void RuntimeDyldELF::applyMIPS64Relocation(uint8_t *TargetPtr, - int64_t CalculatedValue, - uint32_t Type) { - uint32_t Insn = readBytesUnaligned(TargetPtr, 4); - - switch (Type) { - default: - break; - case ELF::R_MIPS_32: - case ELF::R_MIPS_GPREL32: - case ELF::R_MIPS_PC32: - writeBytesUnaligned(CalculatedValue & 0xffffffff, TargetPtr, 4); - break; - case ELF::R_MIPS_64: - case ELF::R_MIPS_SUB: - writeBytesUnaligned(CalculatedValue, TargetPtr, 8); - break; - case ELF::R_MIPS_26: - case ELF::R_MIPS_PC26_S2: - Insn = (Insn & 0xfc000000) | CalculatedValue; - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - case ELF::R_MIPS_GPREL16: - Insn = (Insn & 0xffff0000) | (CalculatedValue & 0xffff); - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - case ELF::R_MIPS_HI16: - case ELF::R_MIPS_LO16: - case ELF::R_MIPS_PCHI16: - case ELF::R_MIPS_PCLO16: - case ELF::R_MIPS_PC16: - case ELF::R_MIPS_CALL16: - case ELF::R_MIPS_GOT_DISP: - case ELF::R_MIPS_GOT_PAGE: - case ELF::R_MIPS_GOT_OFST: - Insn = (Insn & 0xffff0000) | CalculatedValue; - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - case ELF::R_MIPS_PC18_S3: - Insn = (Insn & 0xfffc0000) | CalculatedValue; - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - case ELF::R_MIPS_PC19_S2: - Insn = (Insn & 0xfff80000) | CalculatedValue; - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - case ELF::R_MIPS_PC21_S2: - Insn = (Insn & 0xffe00000) | CalculatedValue; - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - } } // Return the .TOC. section and offset. @@ -1124,19 +849,6 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section, resolveARMRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type, (uint32_t)(Addend & 0xffffffffL)); break; - case Triple::mips: // Fall through. - case Triple::mipsel: - case Triple::mips64: - case Triple::mips64el: - if (IsMipsO32ABI) - resolveMIPSRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), - Type, (uint32_t)(Addend & 0xffffffffL)); - else if (IsMipsN64ABI) - resolveMIPS64Relocation(Section, Offset, Value, Type, Addend, SymOffset, - SectionID); - else - llvm_unreachable("Mips ABI not handled"); - break; case Triple::ppc: resolvePPC32Relocation(Section, Offset, Value, Type, Addend); break; @@ -1187,6 +899,48 @@ uint32_t RuntimeDyldELF::getMatchingLoRelocation(uint32_t RelType, return ELF::R_MIPS_NONE; } +// Sometimes we don't need to create thunk for a branch. +// This typically happens when branch target is located +// in the same object file. In such case target is either +// a weak symbol or symbol in a different executable section. +// This function checks if branch target is located in the +// same object file and if distance between source and target +// fits R_AARCH64_CALL26 relocation. If both conditions are +// met, it emits direct jump to the target and returns true. +// Otherwise false is returned and thunk is created. +bool RuntimeDyldELF::resolveAArch64ShortBranch( + unsigned SectionID, relocation_iterator RelI, + const RelocationValueRef &Value) { + uint64_t Address; + if (Value.SymbolName) { + auto Loc = GlobalSymbolTable.find(Value.SymbolName); + + // Don't create direct branch for external symbols. + if (Loc == GlobalSymbolTable.end()) + return false; + + const auto &SymInfo = Loc->second; + Address = + uint64_t(Sections[SymInfo.getSectionID()].getLoadAddressWithOffset( + SymInfo.getOffset())); + } else { + Address = uint64_t(Sections[Value.SectionID].getLoadAddress()); + } + uint64_t Offset = RelI->getOffset(); + uint64_t SourceAddress = Sections[SectionID].getLoadAddressWithOffset(Offset); + + // R_AARCH64_CALL26 requires immediate to be in range -2^27 <= imm < 2^27 + // If distance between source and target is out of range then we should + // create thunk. + if (!isInt<28>(Address + Value.Addend - SourceAddress)) + return false; + + resolveRelocation(Sections[SectionID], Offset, Address, RelI->getType(), + Value.Addend); + + return true; +} + Expected<relocation_iterator> RuntimeDyldELF::processRelocationRef( unsigned SectionID, relocation_iterator RelI, const ObjectFile &O, @@ -1258,6 +1012,7 @@ RuntimeDyldELF::processRelocationRef( break; } case SymbolRef::ST_Data: + case SymbolRef::ST_Function: case SymbolRef::ST_Unknown: { Value.SymbolName = TargetName.data(); Value.Addend = Addend; @@ -1293,7 +1048,7 @@ RuntimeDyldELF::processRelocationRef( (uint64_t)Section.getAddressWithOffset(i->second), RelType, 0); DEBUG(dbgs() << " Stub function found\n"); - } else { + } else if (!resolveAArch64ShortBranch(SectionID, RelI, Value)) { // Create a new stub function. DEBUG(dbgs() << " Create a new stub function\n"); Stubs[Value] = Section.getStubOffset(); @@ -1468,7 +1223,7 @@ RuntimeDyldELF::processRelocationRef( Value.Addend += SignExtend32<28>((Opcode & 0x03ffffff) << 2); processSimpleRelocation(SectionID, Offset, RelType, Value); } - } else if (IsMipsN64ABI) { + } else if (IsMipsN32ABI || IsMipsN64ABI) { uint32_t r_type = RelType & 0xff; RelocationEntry RE(SectionID, Offset, RelType, Value.Addend); if (r_type == ELF::R_MIPS_CALL16 || r_type == ELF::R_MIPS_GOT_PAGE @@ -1805,7 +1560,7 @@ size_t RuntimeDyldELF::getGOTEntrySize() { case Triple::mipsel: case Triple::mips64: case Triple::mips64el: - if (IsMipsO32ABI) + if (IsMipsO32ABI || IsMipsN32ABI) Result = sizeof(uint32_t); else if (IsMipsN64ABI) Result = sizeof(uint64_t); @@ -1870,7 +1625,7 @@ Error RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj, // For now, initialize all GOT entries to zero. We'll fill them in as // needed when GOT-based relocations are applied. memset(Addr, 0, TotalSize); - if (IsMipsN64ABI) { + if (IsMipsN32ABI || IsMipsN64ABI) { // To correctly resolve Mips GOT relocations, we need a mapping from // object's sections to GOTs. for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end(); diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h index 82931b9..d1867d0 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -40,12 +40,12 @@ class RuntimeDyldELF : public RuntimeDyldImpl { void resolveAArch64Relocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend); + bool resolveAArch64ShortBranch(unsigned SectionID, relocation_iterator RelI, + const RelocationValueRef &Value); + void resolveARMRelocation(const SectionEntry &Section, uint64_t Offset, uint32_t Value, uint32_t Type, int32_t Addend); - void resolveMIPSRelocation(const SectionEntry &Section, uint64_t Offset, - uint32_t Value, uint32_t Type, int32_t Addend); - void resolvePPC32Relocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend); @@ -55,18 +55,6 @@ class RuntimeDyldELF : public RuntimeDyldImpl { void resolveSystemZRelocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend); - void resolveMIPS64Relocation(const SectionEntry &Section, uint64_t Offset, - uint64_t Value, uint32_t Type, int64_t Addend, - uint64_t SymOffset, SID SectionID); - - int64_t evaluateMIPS64Relocation(const SectionEntry &Section, - uint64_t Offset, uint64_t Value, - uint32_t Type, int64_t Addend, - uint64_t SymOffset, SID SectionID); - - void applyMIPS64Relocation(uint8_t *TargetPtr, int64_t CalculatedValue, - uint32_t Type); - unsigned getMaxStubSize() override { if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be) return 20; // movz; movk; movk; movk; br @@ -99,9 +87,10 @@ class RuntimeDyldELF : public RuntimeDyldImpl { Error findOPDEntrySection(const ELFObjectFileBase &Obj, ObjSectionToIDMap &LocalSections, RelocationValueRef &Rel); - +protected: size_t getGOTEntrySize(); +private: SectionEntry &getSection(unsigned SectionID) { return Sections[SectionID]; } // Allocate no GOT entries for use in the given section. @@ -138,10 +127,12 @@ class RuntimeDyldELF : public RuntimeDyldImpl { // that consume more than one slot) unsigned CurrentGOTIndex; +protected: // A map from section to a GOT section that has entries for section's GOT // relocations. (Mips64 specific) DenseMap<SID, SID> SectionToGOTMap; +private: // A map to avoid duplicate got entries (Mips64 specific) StringMap<uint64_t> GOTSymbolOffsets; @@ -159,9 +150,13 @@ class RuntimeDyldELF : public RuntimeDyldImpl { public: RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr, - RuntimeDyld::SymbolResolver &Resolver); + JITSymbolResolver &Resolver); ~RuntimeDyldELF() override; + static std::unique_ptr<RuntimeDyldELF> + create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr, + JITSymbolResolver &Resolver); + std::unique_ptr<RuntimeDyld::LoadedObjectInfo> loadObject(const object::ObjectFile &O) override; diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index 76bd3fc..279d0de 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -149,26 +149,41 @@ public: /// The size of this relocation (MachO specific). unsigned Size; + // COFF specific. + bool IsTargetThumbFunc; + RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend) : SectionID(id), Offset(offset), RelType(type), Addend(addend), - SymOffset(0), IsPCRel(false), Size(0) {} + SymOffset(0), IsPCRel(false), Size(0), IsTargetThumbFunc(false) {} RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend, uint64_t symoffset) : SectionID(id), Offset(offset), RelType(type), Addend(addend), - SymOffset(symoffset), IsPCRel(false), Size(0) {} + SymOffset(symoffset), IsPCRel(false), Size(0), + IsTargetThumbFunc(false) {} RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend, bool IsPCRel, unsigned Size) : SectionID(id), Offset(offset), RelType(type), Addend(addend), - SymOffset(0), IsPCRel(IsPCRel), Size(Size) {} + SymOffset(0), IsPCRel(IsPCRel), Size(Size), IsTargetThumbFunc(false) {} RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend, unsigned SectionA, uint64_t SectionAOffset, unsigned SectionB, uint64_t SectionBOffset, bool IsPCRel, unsigned Size) : SectionID(id), Offset(offset), RelType(type), Addend(SectionAOffset - SectionBOffset + addend), IsPCRel(IsPCRel), - Size(Size) { + Size(Size), IsTargetThumbFunc(false) { + Sections.SectionA = SectionA; + Sections.SectionB = SectionB; + } + + RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend, + unsigned SectionA, uint64_t SectionAOffset, unsigned SectionB, + uint64_t SectionBOffset, bool IsPCRel, unsigned Size, + bool IsTargetThumbFunc) + : SectionID(id), Offset(offset), RelType(type), + Addend(SectionAOffset - SectionBOffset + addend), IsPCRel(IsPCRel), + Size(Size), IsTargetThumbFunc(IsTargetThumbFunc) { Sections.SectionA = SectionA; Sections.SectionB = SectionB; } @@ -199,20 +214,23 @@ public: }; /// @brief Symbol info for RuntimeDyld. -class SymbolTableEntry : public JITSymbolBase { +class SymbolTableEntry { public: SymbolTableEntry() - : JITSymbolBase(JITSymbolFlags::None), Offset(0), SectionID(0) {} + : Offset(0), SectionID(0) {} SymbolTableEntry(unsigned SectionID, uint64_t Offset, JITSymbolFlags Flags) - : JITSymbolBase(Flags), Offset(Offset), SectionID(SectionID) {} + : Offset(Offset), SectionID(SectionID), Flags(Flags) {} unsigned getSectionID() const { return SectionID; } uint64_t getOffset() const { return Offset; } + JITSymbolFlags getFlags() const { return Flags; } + private: uint64_t Offset; unsigned SectionID; + JITSymbolFlags Flags; }; typedef StringMap<SymbolTableEntry> RTDyldSymbolTable; @@ -227,7 +245,7 @@ protected: RuntimeDyld::MemoryManager &MemMgr; // The symbol resolver to use for external symbols. - RuntimeDyld::SymbolResolver &Resolver; + JITSymbolResolver &Resolver; // Attached RuntimeDyldChecker instance. Null if no instance attached. RuntimeDyldCheckerImpl *Checker; @@ -272,6 +290,7 @@ protected: Triple::ArchType Arch; bool IsTargetLittleEndian; bool IsMipsO32ABI; + bool IsMipsN32ABI; bool IsMipsN64ABI; // True if all sections should be passed to the memory manager, false if only @@ -335,6 +354,7 @@ protected: virtual void setMipsABI(const ObjectFile &Obj) { IsMipsO32ABI = false; + IsMipsN32ABI = false; IsMipsN64ABI = false; } @@ -420,7 +440,7 @@ protected: public: RuntimeDyldImpl(RuntimeDyld::MemoryManager &MemMgr, - RuntimeDyld::SymbolResolver &Resolver) + JITSymbolResolver &Resolver) : MemMgr(MemMgr), Resolver(Resolver), Checker(nullptr), ProcessAllSections(false), HasError(false) { } @@ -451,7 +471,7 @@ public: return getSectionAddress(SymInfo.getSectionID()) + SymInfo.getOffset(); } - RuntimeDyld::SymbolInfo getSymbol(StringRef Name) const { + JITEvaluatedSymbol getSymbol(StringRef Name) const { // FIXME: Just look up as a function for now. Overly simple of course. // Work in progress. RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name); @@ -462,7 +482,7 @@ public: if (SymEntry.getSectionID() != AbsoluteSymbolSection) SectionAddr = getSectionLoadAddress(SymEntry.getSectionID()); uint64_t TargetAddr = SectionAddr + SymEntry.getOffset(); - return RuntimeDyld::SymbolInfo(TargetAddr, SymEntry.getFlags()); + return JITEvaluatedSymbol(TargetAddr, SymEntry.getFlags()); } void resolveRelocations(); diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index fd109ae..00541e8 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -343,7 +343,7 @@ void RuntimeDyldMachOCRTPBase<Impl>::registerEHFrames() { std::unique_ptr<RuntimeDyldMachO> RuntimeDyldMachO::create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr, - RuntimeDyld::SymbolResolver &Resolver) { + JITSymbolResolver &Resolver) { switch (Arch) { default: llvm_unreachable("Unsupported target for RuntimeDyldMachO."); diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h index 30f3bb3..67a5020 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h @@ -50,7 +50,7 @@ protected: SmallVector<EHFrameRelatedSections, 2> UnregisteredEHFrameSections; RuntimeDyldMachO(RuntimeDyld::MemoryManager &MemMgr, - RuntimeDyld::SymbolResolver &Resolver) + JITSymbolResolver &Resolver) : RuntimeDyldImpl(MemMgr, Resolver) {} /// This convenience method uses memcpy to extract a contiguous addend (the @@ -124,7 +124,7 @@ public: static std::unique_ptr<RuntimeDyldMachO> create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr, - RuntimeDyld::SymbolResolver &Resolver); + JITSymbolResolver &Resolver); std::unique_ptr<RuntimeDyld::LoadedObjectInfo> loadObject(const object::ObjectFile &O) override; @@ -152,7 +152,7 @@ private: public: RuntimeDyldMachOCRTPBase(RuntimeDyld::MemoryManager &MemMgr, - RuntimeDyld::SymbolResolver &Resolver) + JITSymbolResolver &Resolver) : RuntimeDyldMachO(MemMgr, Resolver) {} Error finalizeLoad(const ObjectFile &Obj, diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h index 44fda87..0398413 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h @@ -25,7 +25,7 @@ namespace llvm { class RuntimeDyldCOFFI386 : public RuntimeDyldCOFF { public: RuntimeDyldCOFFI386(RuntimeDyld::MemoryManager &MM, - RuntimeDyld::SymbolResolver &Resolver) + JITSymbolResolver &Resolver) : RuntimeDyldCOFF(MM, Resolver) {} unsigned getMaxStubSize() override { diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h index ff7d1d4..8c6af0b 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h @@ -22,10 +22,30 @@ namespace llvm { +static bool isThumbFunc(symbol_iterator Symbol, const ObjectFile &Obj, + section_iterator Section) { + Expected<SymbolRef::Type> SymTypeOrErr = Symbol->getType(); + if (!SymTypeOrErr) { + std::string Buf; + raw_string_ostream OS(Buf); + logAllUnhandledErrors(SymTypeOrErr.takeError(), OS, ""); + OS.flush(); + report_fatal_error(Buf); + } + + if (*SymTypeOrErr != SymbolRef::ST_Function) + return false; + + // We check the IMAGE_SCN_MEM_16BIT flag in the section of the symbol to tell + // if it's thumb or not + return cast<COFFObjectFile>(Obj).getCOFFSection(*Section)->Characteristics & + COFF::IMAGE_SCN_MEM_16BIT; +} + class RuntimeDyldCOFFThumb : public RuntimeDyldCOFF { public: RuntimeDyldCOFFThumb(RuntimeDyld::MemoryManager &MM, - RuntimeDyld::SymbolResolver &Resolver) + JITSymbolResolver &Resolver) : RuntimeDyldCOFF(MM, Resolver) {} unsigned getMaxStubSize() override { @@ -92,12 +112,22 @@ public: else return TargetSectionIDOrErr.takeError(); + // We need to find out if the relocation is relative to a thumb function + // so that we include the ISA selection bit when resolve the relocation + bool IsTargetThumbFunc = isThumbFunc(Symbol, Obj, Section); + switch (RelType) { default: llvm_unreachable("unsupported relocation type"); case COFF::IMAGE_REL_ARM_ABSOLUTE: // This relocation is ignored. break; - case COFF::IMAGE_REL_ARM_ADDR32: + case COFF::IMAGE_REL_ARM_ADDR32: { + RelocationEntry RE = RelocationEntry( + SectionID, Offset, RelType, Addend, TargetSectionID, + getSymbolOffset(*Symbol), 0, 0, false, 0, IsTargetThumbFunc); + addRelocationForSection(RE, TargetSectionID); + break; + } case COFF::IMAGE_REL_ARM_ADDR32NB: { RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType, Addend, TargetSectionID, @@ -118,9 +148,9 @@ public: break; } case COFF::IMAGE_REL_ARM_MOV32T: { - RelocationEntry RE = - RelocationEntry(SectionID, Offset, RelType, Addend, TargetSectionID, - getSymbolOffset(*Symbol), 0, 0, false, 0); + RelocationEntry RE = RelocationEntry( + SectionID, Offset, RelType, Addend, TargetSectionID, + getSymbolOffset(*Symbol), 0, 0, false, 0, IsTargetThumbFunc); addRelocationForSection(RE, TargetSectionID); break; } @@ -142,6 +172,7 @@ public: void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override { const auto Section = Sections[RE.SectionID]; uint8_t *Target = Section.getAddressWithOffset(RE.Offset); + int ISASelectionBit = RE.IsTargetThumbFunc ? 1 : 0; switch (RE.RelType) { default: llvm_unreachable("unsupported relocation type"); @@ -154,6 +185,7 @@ public: RE.Sections.SectionA == static_cast<uint32_t>(-1) ? Value : Sections[RE.Sections.SectionA].getLoadAddressWithOffset(RE.Addend); + Result |= ISASelectionBit; assert(static_cast<int32_t>(Result) <= INT32_MAX && "relocation overflow"); assert(static_cast<int32_t>(Result) >= INT32_MIN && @@ -178,6 +210,7 @@ public: << " RelType: IMAGE_REL_ARM_ADDR32NB" << " TargetSection: " << RE.Sections.SectionA << " Value: " << format("0x%08" PRIx32, Result) << '\n'); + Result |= ISASelectionBit; writeBytesUnaligned(Result, Target, 4); break; } @@ -225,10 +258,11 @@ public: Bytes[0] |= ((Immediate & 0xf000) >> 12); Bytes[1] |= ((Immediate & 0x0800) >> 11); Bytes[2] |= ((Immediate & 0x00ff) >> 0); - Bytes[3] |= ((Immediate & 0x0700) >> 8); + Bytes[3] |= (((Immediate & 0x0700) >> 8) << 4); }; - EncodeImmediate(&Target[0], static_cast<uint32_t>(Result) >> 00); + EncodeImmediate(&Target[0], + (static_cast<uint32_t>(Result) >> 00) | ISASelectionBit); EncodeImmediate(&Target[4], static_cast<uint32_t>(Result) >> 16); break; diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h index df8681d..109beb3 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h @@ -33,7 +33,7 @@ private: public: RuntimeDyldCOFFX86_64(RuntimeDyld::MemoryManager &MM, - RuntimeDyld::SymbolResolver &Resolver) + JITSymbolResolver &Resolver) : RuntimeDyldCOFF(MM, Resolver) {} unsigned getMaxStubSize() override { diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp new file mode 100644 index 0000000..cae4d69 --- /dev/null +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp @@ -0,0 +1,312 @@ +//===-- RuntimeDyldELFMips.cpp ---- ELF/Mips specific code. -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "RuntimeDyldELFMips.h" +#include "llvm/Support/ELF.h" + +#define DEBUG_TYPE "dyld" + +void RuntimeDyldELFMips::resolveRelocation(const RelocationEntry &RE, + uint64_t Value) { + const SectionEntry &Section = Sections[RE.SectionID]; + if (IsMipsO32ABI) + resolveMIPSO32Relocation(Section, RE.Offset, Value, RE.RelType, RE.Addend); + else if (IsMipsN32ABI) { + resolveMIPSN32Relocation(Section, RE.Offset, Value, RE.RelType, RE.Addend, + RE.SymOffset, RE.SectionID); + } else if (IsMipsN64ABI) + resolveMIPSN64Relocation(Section, RE.Offset, Value, RE.RelType, RE.Addend, + RE.SymOffset, RE.SectionID); + else + llvm_unreachable("Mips ABI not handled"); +} + +uint64_t RuntimeDyldELFMips::evaluateRelocation(const RelocationEntry &RE, + uint64_t Value, + uint64_t Addend) { + if (IsMipsN32ABI) { + const SectionEntry &Section = Sections[RE.SectionID]; + Value = evaluateMIPS64Relocation(Section, RE.Offset, Value, RE.RelType, + Addend, RE.SymOffset, RE.SectionID); + return Value; + } + llvm_unreachable("Not reachable"); +} + +void RuntimeDyldELFMips::applyRelocation(const RelocationEntry &RE, + uint64_t Value) { + if (IsMipsN32ABI) { + const SectionEntry &Section = Sections[RE.SectionID]; + applyMIPSRelocation(Section.getAddressWithOffset(RE.Offset), Value, + RE.RelType); + return; + } + llvm_unreachable("Not reachable"); +} + +int64_t +RuntimeDyldELFMips::evaluateMIPS32Relocation(const SectionEntry &Section, + uint64_t Offset, uint64_t Value, + uint32_t Type) { + + DEBUG(dbgs() << "evaluateMIPS32Relocation, LocalAddress: 0x" + << format("%llx", Section.getAddressWithOffset(Offset)) + << " FinalAddress: 0x" + << format("%llx", Section.getLoadAddressWithOffset(Offset)) + << " Value: 0x" << format("%llx", Value) << " Type: 0x" + << format("%x", Type) << "\n"); + + switch (Type) { + default: + llvm_unreachable("Unknown relocation type!"); + return Value; + case ELF::R_MIPS_32: + return Value; + case ELF::R_MIPS_26: + return Value >> 2; + case ELF::R_MIPS_HI16: + // Get the higher 16-bits. Also add 1 if bit 15 is 1. + return (Value + 0x8000) >> 16; + case ELF::R_MIPS_LO16: + return Value; + case ELF::R_MIPS_PC32: { + uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + return Value - FinalAddress; + } + case ELF::R_MIPS_PC16: { + uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + return (Value - FinalAddress) >> 2; + } + case ELF::R_MIPS_PC19_S2: { + uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + return (Value - (FinalAddress & ~0x3)) >> 2; + } + case ELF::R_MIPS_PC21_S2: { + uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + return (Value - FinalAddress) >> 2; + } + case ELF::R_MIPS_PC26_S2: { + uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + return (Value - FinalAddress) >> 2; + } + case ELF::R_MIPS_PCHI16: { + uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + return (Value - FinalAddress + 0x8000) >> 16; + } + case ELF::R_MIPS_PCLO16: { + uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + return Value - FinalAddress; + } + } +} + +int64_t RuntimeDyldELFMips::evaluateMIPS64Relocation( + const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, + int64_t Addend, uint64_t SymOffset, SID SectionID) { + + DEBUG(dbgs() << "evaluateMIPS64Relocation, LocalAddress: 0x" + << format("%llx", Section.getAddressWithOffset(Offset)) + << " FinalAddress: 0x" + << format("%llx", Section.getLoadAddressWithOffset(Offset)) + << " Value: 0x" << format("%llx", Value) << " Type: 0x" + << format("%x", Type) << " Addend: 0x" << format("%llx", Addend) + << " SymOffset: " << format("%x", SymOffset) << "\n"); + + switch (Type) { + default: + llvm_unreachable("Not implemented relocation type!"); + break; + case ELF::R_MIPS_JALR: + case ELF::R_MIPS_NONE: + break; + case ELF::R_MIPS_32: + case ELF::R_MIPS_64: + return Value + Addend; + case ELF::R_MIPS_26: + return ((Value + Addend) >> 2) & 0x3ffffff; + case ELF::R_MIPS_GPREL16: { + uint64_t GOTAddr = getSectionLoadAddress(SectionToGOTMap[SectionID]); + return Value + Addend - (GOTAddr + 0x7ff0); + } + case ELF::R_MIPS_SUB: + return Value - Addend; + case ELF::R_MIPS_HI16: + // Get the higher 16-bits. Also add 1 if bit 15 is 1. + return ((Value + Addend + 0x8000) >> 16) & 0xffff; + case ELF::R_MIPS_LO16: + return (Value + Addend) & 0xffff; + case ELF::R_MIPS_CALL16: + case ELF::R_MIPS_GOT_DISP: + case ELF::R_MIPS_GOT_PAGE: { + uint8_t *LocalGOTAddr = + getSectionAddress(SectionToGOTMap[SectionID]) + SymOffset; + uint64_t GOTEntry = readBytesUnaligned(LocalGOTAddr, getGOTEntrySize()); + + Value += Addend; + if (Type == ELF::R_MIPS_GOT_PAGE) + Value = (Value + 0x8000) & ~0xffff; + + if (GOTEntry) + assert(GOTEntry == Value && + "GOT entry has two different addresses."); + else + writeBytesUnaligned(Value, LocalGOTAddr, getGOTEntrySize()); + + return (SymOffset - 0x7ff0) & 0xffff; + } + case ELF::R_MIPS_GOT_OFST: { + int64_t page = (Value + Addend + 0x8000) & ~0xffff; + return (Value + Addend - page) & 0xffff; + } + case ELF::R_MIPS_GPREL32: { + uint64_t GOTAddr = getSectionLoadAddress(SectionToGOTMap[SectionID]); + return Value + Addend - (GOTAddr + 0x7ff0); + } + case ELF::R_MIPS_PC16: { + uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + return ((Value + Addend - FinalAddress) >> 2) & 0xffff; + } + case ELF::R_MIPS_PC32: { + uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + return Value + Addend - FinalAddress; + } + case ELF::R_MIPS_PC18_S3: { + uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + return ((Value + Addend - (FinalAddress & ~0x7)) >> 3) & 0x3ffff; + } + case ELF::R_MIPS_PC19_S2: { + uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + return ((Value + Addend - (FinalAddress & ~0x3)) >> 2) & 0x7ffff; + } + case ELF::R_MIPS_PC21_S2: { + uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + return ((Value + Addend - FinalAddress) >> 2) & 0x1fffff; + } + case ELF::R_MIPS_PC26_S2: { + uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + return ((Value + Addend - FinalAddress) >> 2) & 0x3ffffff; + } + case ELF::R_MIPS_PCHI16: { + uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + return ((Value + Addend - FinalAddress + 0x8000) >> 16) & 0xffff; + } + case ELF::R_MIPS_PCLO16: { + uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); + return (Value + Addend - FinalAddress) & 0xffff; + } + } + return 0; +} + +void RuntimeDyldELFMips::applyMIPSRelocation(uint8_t *TargetPtr, int64_t Value, + uint32_t Type) { + uint32_t Insn = readBytesUnaligned(TargetPtr, 4); + + switch (Type) { + default: + llvm_unreachable("Unknown relocation type!"); + break; + case ELF::R_MIPS_GPREL16: + case ELF::R_MIPS_HI16: + case ELF::R_MIPS_LO16: + case ELF::R_MIPS_PC16: + case ELF::R_MIPS_PCHI16: + case ELF::R_MIPS_PCLO16: + case ELF::R_MIPS_CALL16: + case ELF::R_MIPS_GOT_DISP: + case ELF::R_MIPS_GOT_PAGE: + case ELF::R_MIPS_GOT_OFST: + Insn = (Insn & 0xffff0000) | (Value & 0x0000ffff); + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + case ELF::R_MIPS_PC18_S3: + Insn = (Insn & 0xfffc0000) | (Value & 0x0003ffff); + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + case ELF::R_MIPS_PC19_S2: + Insn = (Insn & 0xfff80000) | (Value & 0x0007ffff); + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + case ELF::R_MIPS_PC21_S2: + Insn = (Insn & 0xffe00000) | (Value & 0x001fffff); + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + case ELF::R_MIPS_26: + case ELF::R_MIPS_PC26_S2: + Insn = (Insn & 0xfc000000) | (Value & 0x03ffffff); + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + case ELF::R_MIPS_32: + case ELF::R_MIPS_GPREL32: + case ELF::R_MIPS_PC32: + writeBytesUnaligned(Value & 0xffffffff, TargetPtr, 4); + break; + case ELF::R_MIPS_64: + case ELF::R_MIPS_SUB: + writeBytesUnaligned(Value, TargetPtr, 8); + break; + } +} + +void RuntimeDyldELFMips::resolveMIPSN32Relocation( + const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, + int64_t Addend, uint64_t SymOffset, SID SectionID) { + int64_t CalculatedValue = evaluateMIPS64Relocation( + Section, Offset, Value, Type, Addend, SymOffset, SectionID); + applyMIPSRelocation(Section.getAddressWithOffset(Offset), CalculatedValue, + Type); +} + +void RuntimeDyldELFMips::resolveMIPSN64Relocation( + const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, + int64_t Addend, uint64_t SymOffset, SID SectionID) { + uint32_t r_type = Type & 0xff; + uint32_t r_type2 = (Type >> 8) & 0xff; + uint32_t r_type3 = (Type >> 16) & 0xff; + + // RelType is used to keep information for which relocation type we are + // applying relocation. + uint32_t RelType = r_type; + int64_t CalculatedValue = evaluateMIPS64Relocation(Section, Offset, Value, + RelType, Addend, + SymOffset, SectionID); + if (r_type2 != ELF::R_MIPS_NONE) { + RelType = r_type2; + CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType, + CalculatedValue, SymOffset, + SectionID); + } + if (r_type3 != ELF::R_MIPS_NONE) { + RelType = r_type3; + CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType, + CalculatedValue, SymOffset, + SectionID); + } + applyMIPSRelocation(Section.getAddressWithOffset(Offset), CalculatedValue, + RelType); +} + +void RuntimeDyldELFMips::resolveMIPSO32Relocation(const SectionEntry &Section, + uint64_t Offset, + uint32_t Value, uint32_t Type, + int32_t Addend) { + uint8_t *TargetPtr = Section.getAddressWithOffset(Offset); + Value += Addend; + + DEBUG(dbgs() << "resolveMIPSO32Relocation, LocalAddress: " + << Section.getAddressWithOffset(Offset) << " FinalAddress: " + << format("%p", Section.getLoadAddressWithOffset(Offset)) + << " Value: " << format("%x", Value) + << " Type: " << format("%x", Type) + << " Addend: " << format("%x", Addend) << "\n"); + + Value = evaluateMIPS32Relocation(Section, Offset, Value, Type); + + applyMIPSRelocation(TargetPtr, Value, Type); +} diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.h new file mode 100644 index 0000000..ce54a27 --- /dev/null +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.h @@ -0,0 +1,68 @@ +//===-- RuntimeDyldELFMips.h ---- ELF/Mips specific code. -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDELFMIPS_H +#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDELFMIPS_H + +#include "../RuntimeDyldELF.h" +#include <string> + +#define DEBUG_TYPE "dyld" + +namespace llvm { + +class RuntimeDyldELFMips : public RuntimeDyldELF { +public: + + typedef uint64_t TargetPtrT; + + RuntimeDyldELFMips(RuntimeDyld::MemoryManager &MM, + JITSymbolResolver &Resolver) + : RuntimeDyldELF(MM, Resolver) {} + + void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override; + +protected: + void resolveMIPSO32Relocation(const SectionEntry &Section, uint64_t Offset, + uint32_t Value, uint32_t Type, int32_t Addend); + void resolveMIPSN32Relocation(const SectionEntry &Section, uint64_t Offset, + uint64_t Value, uint32_t Type, int64_t Addend, + uint64_t SymOffset, SID SectionID); + void resolveMIPSN64Relocation(const SectionEntry &Section, uint64_t Offset, + uint64_t Value, uint32_t Type, int64_t Addend, + uint64_t SymOffset, SID SectionID); + +private: + /// \brief A object file specific relocation resolver + /// \param RE The relocation to be resolved + /// \param Value Target symbol address to apply the relocation action + uint64_t evaluateRelocation(const RelocationEntry &RE, uint64_t Value, + uint64_t Addend); + + /// \brief A object file specific relocation resolver + /// \param RE The relocation to be resolved + /// \param Value Target symbol address to apply the relocation action + void applyRelocation(const RelocationEntry &RE, uint64_t Value); + + int64_t evaluateMIPS32Relocation(const SectionEntry &Section, uint64_t Offset, + uint64_t Value, uint32_t Type); + int64_t evaluateMIPS64Relocation(const SectionEntry &Section, + uint64_t Offset, uint64_t Value, + uint32_t Type, int64_t Addend, + uint64_t SymOffset, SID SectionID); + + void applyMIPSRelocation(uint8_t *TargetPtr, int64_t CalculatedValue, + uint32_t Type); + +}; +} + +#undef DEBUG_TYPE + +#endif diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h index 63598f1..97cbc15 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h @@ -24,7 +24,7 @@ public: typedef uint64_t TargetPtrT; RuntimeDyldMachOAArch64(RuntimeDyld::MemoryManager &MM, - RuntimeDyld::SymbolResolver &Resolver) + JITSymbolResolver &Resolver) : RuntimeDyldMachOCRTPBase(MM, Resolver) {} unsigned getMaxStubSize() override { return 8; } @@ -97,7 +97,8 @@ public: (void)p; assert((*p & 0x3B000000) == 0x39000000 && "Only expected load / store instructions."); - } // fall-through + LLVM_FALLTHROUGH; + } case MachO::ARM64_RELOC_PAGEOFF12: { // Verify that the relocation points to one of the expected load / store // or add / sub instructions. @@ -196,7 +197,8 @@ public: assert((*p & 0x3B000000) == 0x39000000 && "Only expected load / store instructions."); (void)p; - } // fall-through + LLVM_FALLTHROUGH; + } case MachO::ARM64_RELOC_PAGEOFF12: { // Verify that the relocation points to one of the expected load / store // or add / sub instructions. diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h index 0abf9da..adca0ee 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h @@ -27,7 +27,7 @@ public: typedef uint32_t TargetPtrT; RuntimeDyldMachOARM(RuntimeDyld::MemoryManager &MM, - RuntimeDyld::SymbolResolver &Resolver) + JITSymbolResolver &Resolver) : RuntimeDyldMachOCRTPBase(MM, Resolver) {} unsigned getMaxStubSize() override { return 8; } diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h index 2c79b3f..c42f175 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h @@ -24,7 +24,7 @@ public: typedef uint32_t TargetPtrT; RuntimeDyldMachOI386(RuntimeDyld::MemoryManager &MM, - RuntimeDyld::SymbolResolver &Resolver) + JITSymbolResolver &Resolver) : RuntimeDyldMachOCRTPBase(MM, Resolver) {} unsigned getMaxStubSize() override { return 0; } diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h index bc48229..32fd3ef 100644 --- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h +++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h @@ -24,7 +24,7 @@ public: typedef uint64_t TargetPtrT; RuntimeDyldMachOX86_64(RuntimeDyld::MemoryManager &MM, - RuntimeDyld::SymbolResolver &Resolver) + JITSymbolResolver &Resolver) : RuntimeDyldMachOCRTPBase(MM, Resolver) {} unsigned getMaxStubSize() override { return 8; } diff --git a/contrib/llvm/lib/ExecutionEngine/SectionMemoryManager.cpp b/contrib/llvm/lib/ExecutionEngine/SectionMemoryManager.cpp index 1ad5f17..50478ea 100644 --- a/contrib/llvm/lib/ExecutionEngine/SectionMemoryManager.cpp +++ b/contrib/llvm/lib/ExecutionEngine/SectionMemoryManager.cpp @@ -196,8 +196,8 @@ SectionMemoryManager::applyMemoryGroupPermissions(MemoryGroup &MemGroup, // Remove all blocks which are now empty MemGroup.FreeMem.erase( - std::remove_if(MemGroup.FreeMem.begin(), MemGroup.FreeMem.end(), - [](FreeMemBlock &FreeMB) { return FreeMB.Free.size() == 0; }), + remove_if(MemGroup.FreeMem, + [](FreeMemBlock &FreeMB) { return FreeMB.Free.size() == 0; }), MemGroup.FreeMem.end()); return std::error_code(); diff --git a/contrib/llvm/lib/ExecutionEngine/TargetSelect.cpp b/contrib/llvm/lib/ExecutionEngine/TargetSelect.cpp index b45f0c8..6e2973c 100644 --- a/contrib/llvm/lib/ExecutionEngine/TargetSelect.cpp +++ b/contrib/llvm/lib/ExecutionEngine/TargetSelect.cpp @@ -48,9 +48,8 @@ TargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple, // Adjust the triple to match what the user requested. const Target *TheTarget = nullptr; if (!MArch.empty()) { - auto I = std::find_if( - TargetRegistry::targets().begin(), TargetRegistry::targets().end(), - [&](const Target &T) { return MArch == T.getName(); }); + auto I = find_if(TargetRegistry::targets(), + [&](const Target &T) { return MArch == T.getName(); }); if (I == TargetRegistry::targets().end()) { if (ErrorStr) |