diff options
Diffstat (limited to 'lib/ExecutionEngine')
43 files changed, 1836 insertions, 875 deletions
| diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index 41c8da40346a..a8e68bf49abc 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -103,12 +103,10 @@ public:    /// \brief Returns the address the GlobalVariable should be written into.  The    /// GVMemoryBlock object prefixes that.    static char *Create(const GlobalVariable *GV, const DataLayout& TD) { -    Type *ElTy = GV->getType()->getElementType(); +    Type *ElTy = GV->getValueType();      size_t GVSize = (size_t)TD.getTypeAllocSize(ElTy);      void *RawMemory = ::operator new( -      RoundUpToAlignment(sizeof(GVMemoryBlock), -                         TD.getPreferredAlignment(GV)) -      + GVSize); +        alignTo(sizeof(GVMemoryBlock), TD.getPreferredAlignment(GV)) + GVSize);      new(RawMemory) GVMemoryBlock(GV);      return static_cast<char*>(RawMemory) + sizeof(GVMemoryBlock);    } @@ -237,10 +235,8 @@ void ExecutionEngine::clearAllGlobalMappings() {  void ExecutionEngine::clearGlobalMappingsFromModule(Module *M) {    MutexGuard locked(lock); -  for (Function &FI : *M) -    EEState.RemoveMapping(getMangledName(&FI)); -  for (GlobalVariable &GI : M->globals()) -    EEState.RemoveMapping(getMangledName(&GI)); +  for (GlobalObject &GO : M->global_objects()) +    EEState.RemoveMapping(getMangledName(&GO));  }  uint64_t ExecutionEngine::updateGlobalMapping(const GlobalValue *GV, @@ -476,8 +472,7 @@ EngineBuilder::EngineBuilder() : EngineBuilder(nullptr) {}  EngineBuilder::EngineBuilder(std::unique_ptr<Module> M)      : M(std::move(M)), WhichEngine(EngineKind::Either), ErrorStr(nullptr),        OptLevel(CodeGenOpt::Default), MemMgr(nullptr), Resolver(nullptr), -      RelocModel(Reloc::Default), CMModel(CodeModel::JITDefault), -      UseOrcMCJITReplacement(false) { +      CMModel(CodeModel::JITDefault), UseOrcMCJITReplacement(false) {  // IR module verification is enabled by default in debug builds, and disabled  // by default in release builds.  #ifndef NDEBUG @@ -1355,7 +1350,7 @@ void ExecutionEngine::EmitGlobalVariable(const GlobalVariable *GV) {    if (!GV->isThreadLocal())      InitializeMemory(GV->getInitializer(), GA); -  Type *ElTy = GV->getType()->getElementType(); +  Type *ElTy = GV->getValueType();    size_t GVSize = (size_t)getDataLayout().getTypeAllocSize(ElTy);    NumInitBytes += (unsigned)GVSize;    ++NumGlobals; diff --git a/lib/ExecutionEngine/ExecutionEngineBindings.cpp b/lib/ExecutionEngine/ExecutionEngineBindings.cpp index ff7c4dce0d5d..d6b209a91d76 100644 --- a/lib/ExecutionEngine/ExecutionEngineBindings.cpp +++ b/lib/ExecutionEngine/ExecutionEngineBindings.cpp @@ -17,6 +17,7 @@  #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"  #include "llvm/IR/DerivedTypes.h"  #include "llvm/IR/Module.h" +#include "llvm/Support/CodeGenCWrappers.h"  #include "llvm/Support/ErrorHandling.h"  #include "llvm/Target/TargetOptions.h"  #include <cstring> @@ -215,10 +216,12 @@ void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE) {  }  void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE) { +  unwrap(EE)->finalizeObject();    unwrap(EE)->runStaticConstructorsDestructors(false);  }  void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE) { +  unwrap(EE)->finalizeObject();    unwrap(EE)->runStaticConstructorsDestructors(true);  } diff --git a/lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt b/lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt index 65f2a2f51f9b..3b8c4b973e68 100644 --- a/lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt +++ b/lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt @@ -3,9 +3,9 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. )  if( HAVE_LIBDL )      set(LLVM_INTEL_JIT_LIBS ${CMAKE_DL_LIBS})  endif() -if( HAVE_LIBPTHREAD ) -    set(LLVM_INTEL_JIT_LIBS pthread ${LLVM_INTEL_JIT_LIBS}) -endif() + +set(LLVM_INTEL_JIT_LIBS ${PTHREAD_LIB} ${LLVM_INTEL_JIT_LIBS}) +  add_llvm_library(LLVMIntelJITEvents    IntelJITEventListener.cpp diff --git a/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp b/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp index a131763193c0..0051c69efb7d 100644 --- a/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp +++ b/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp @@ -113,16 +113,29 @@ void IntelJITEventListener::NotifyObjectEmitted(      std::vector<LineNumberInfo> LineInfo;      std::string SourceFileName; -    if (Sym.getType() != SymbolRef::ST_Function) +    Expected<SymbolRef::Type> SymTypeOrErr = Sym.getType(); +    if (!SymTypeOrErr) { +      // TODO: Actually report errors helpfully. +      consumeError(SymTypeOrErr.takeError()); +      continue; +    } +    SymbolRef::Type SymType = *SymTypeOrErr; +    if (SymType != SymbolRef::ST_Function)        continue; -    ErrorOr<StringRef> Name = Sym.getName(); -    if (!Name) +    Expected<StringRef> Name = Sym.getName(); +    if (!Name) { +      // TODO: Actually report errors helpfully. +      consumeError(Name.takeError());        continue; +    } -    ErrorOr<uint64_t> AddrOrErr = Sym.getAddress(); -    if (AddrOrErr.getError()) +    Expected<uint64_t> AddrOrErr = Sym.getAddress(); +    if (!AddrOrErr) { +      // TODO: Actually report errors helpfully. +      consumeError(AddrOrErr.takeError());        continue; +    }      uint64_t Addr = *AddrOrErr;      uint64_t Size = P.second; diff --git a/lib/ExecutionEngine/IntelJITEvents/Makefile b/lib/ExecutionEngine/IntelJITEvents/Makefile deleted file mode 100644 index dcf3126cc529..000000000000 --- a/lib/ExecutionEngine/IntelJITEvents/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -##===- lib/ExecutionEngine/JITProfile/Makefile -------------*- Makefile -*-===## -# -#                     The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../../.. -LIBRARYNAME = LLVMIntelJITEvents - -include $(LEVEL)/Makefile.config - -SOURCES := IntelJITEventListener.cpp \ -  jitprofiling.c -CPPFLAGS += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. - -include $(LLVM_SRC_ROOT)/Makefile.rules diff --git a/lib/ExecutionEngine/Interpreter/Makefile b/lib/ExecutionEngine/Interpreter/Makefile deleted file mode 100644 index 5def1365c61a..000000000000 --- a/lib/ExecutionEngine/Interpreter/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -##===- lib/ExecutionEngine/Interpreter/Makefile ------------*- Makefile -*-===## -# -#                     The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../../.. -LIBRARYNAME = LLVMInterpreter - -include $(LEVEL)/Makefile.common diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp index 6cbebe98e7c9..7fb328babfe8 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -85,6 +85,9 @@ MCJIT::MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> TM,    std::unique_ptr<Module> First = std::move(Modules[0]);    Modules.clear(); +  if (First->getDataLayout().isDefault()) +    First->setDataLayout(getDataLayout()); +    OwnedModules.addModule(std::move(First));    RegisterJITEventListener(JITEventListener::createGDBRegistrationListener());  } @@ -103,6 +106,10 @@ MCJIT::~MCJIT() {  void MCJIT::addModule(std::unique_ptr<Module> M) {    MutexGuard locked(lock); + +  if (M->getDataLayout().isDefault()) +    M->setDataLayout(getDataLayout()); +    OwnedModules.addModule(std::move(M));  } @@ -192,11 +199,7 @@ void MCJIT::generateCodeForModule(Module *M) {    if (ObjCache)      ObjectToLoad = ObjCache->getObject(M); -  if (M->getDataLayout().isDefault()) { -    M->setDataLayout(getDataLayout()); -  } else { -    assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch"); -  } +  assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch");    // If the cache did not contain a suitable object, compile the object    if (!ObjectToLoad) { @@ -206,8 +209,15 @@ void MCJIT::generateCodeForModule(Module *M) {    // Load the object into the dynamic linker.    // MCJIT now owns the ObjectImage pointer (via its LoadedObjects list). -  ErrorOr<std::unique_ptr<object::ObjectFile>> LoadedObject = +  Expected<std::unique_ptr<object::ObjectFile>> LoadedObject =      object::ObjectFile::createObjectFile(ObjectToLoad->getMemBufferRef()); +  if (!LoadedObject) { +    std::string Buf; +    raw_string_ostream OS(Buf); +    logAllUnhandledErrors(LoadedObject.takeError(), OS, ""); +    OS.flush(); +    report_fatal_error(Buf); +  }    std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L =      Dyld.loadObject(*LoadedObject.get()); @@ -317,15 +327,19 @@ RuntimeDyld::SymbolInfo MCJIT::findSymbol(const std::string &Name,    for (object::OwningBinary<object::Archive> &OB : Archives) {      object::Archive *A = OB.getBinary();      // Look for our symbols in each Archive -    object::Archive::child_iterator ChildIt = A->findSym(Name); -    if (std::error_code EC = ChildIt->getError()) -      report_fatal_error(EC.message()); -    if (ChildIt != A->child_end()) { +    auto OptionalChildOrErr = A->findSym(Name); +    if (!OptionalChildOrErr) +      report_fatal_error(OptionalChildOrErr.takeError()); +    auto &OptionalChild = *OptionalChildOrErr; +    if (OptionalChild) {        // FIXME: Support nested archives? -      ErrorOr<std::unique_ptr<object::Binary>> ChildBinOrErr = -          (*ChildIt)->getAsBinary(); -      if (ChildBinOrErr.getError()) +      Expected<std::unique_ptr<object::Binary>> ChildBinOrErr = +          OptionalChild->getAsBinary(); +      if (!ChildBinOrErr) { +        // TODO: Actually report errors helpfully. +        consumeError(ChildBinOrErr.takeError());          continue; +      }        std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();        if (ChildBin->isObject()) {          std::unique_ptr<object::ObjectFile> OF( @@ -480,6 +494,7 @@ GenericValue MCJIT::runFunction(Function *F, ArrayRef<GenericValue> ArgValues) {    assert(F && "Function *F was null at entry to run()");    void *FPtr = getPointerToFunction(F); +  finalizeModule(F->getParent());    assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");    FunctionType *FTy = F->getFunctionType();    Type *RetTy = FTy->getReturnType(); diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.h b/lib/ExecutionEngine/MCJIT/MCJIT.h index 3c9d2fd50336..e25f76cd57f3 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.h +++ b/lib/ExecutionEngine/MCJIT/MCJIT.h @@ -10,7 +10,6 @@  #ifndef LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H  #define LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H -#include "llvm/ADT/DenseMap.h"  #include "llvm/ADT/SmallPtrSet.h"  #include "llvm/ADT/SmallVector.h"  #include "llvm/ExecutionEngine/ExecutionEngine.h" diff --git a/lib/ExecutionEngine/MCJIT/Makefile b/lib/ExecutionEngine/MCJIT/Makefile deleted file mode 100644 index 967efbc0efa4..000000000000 --- a/lib/ExecutionEngine/MCJIT/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -##===- lib/ExecutionEngine/MCJIT/Makefile ------------------*- Makefile -*-===## -# -#                     The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../../.. -LIBRARYNAME = LLVMMCJIT - -include $(LEVEL)/Makefile.common diff --git a/lib/ExecutionEngine/Makefile b/lib/ExecutionEngine/Makefile deleted file mode 100644 index e9a5b79ddf62..000000000000 --- a/lib/ExecutionEngine/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -##===- lib/ExecutionEngine/Makefile ------------------------*- Makefile -*-===## -# -#                     The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../.. -LIBRARYNAME = LLVMExecutionEngine - -include $(LEVEL)/Makefile.config - -PARALLEL_DIRS = Interpreter MCJIT Orc RuntimeDyld - -ifeq ($(USE_INTEL_JITEVENTS), 1) -PARALLEL_DIRS += IntelJITEvents -endif - -ifeq ($(USE_OPROFILE), 1) -PARALLEL_DIRS += OProfileJIT -endif - -include $(LLVM_SRC_ROOT)/Makefile.rules diff --git a/lib/ExecutionEngine/OProfileJIT/Makefile b/lib/ExecutionEngine/OProfileJIT/Makefile deleted file mode 100644 index fd3adce26c1f..000000000000 --- a/lib/ExecutionEngine/OProfileJIT/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -##===- lib/ExecutionEngine/OProfileJIT/Makefile ------------*- Makefile -*-===## -# -#                     The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../../.. -LIBRARYNAME = LLVMOProfileJIT - -include $(LEVEL)/Makefile.config - -SOURCES += OProfileJITEventListener.cpp \ -  OProfileWrapper.cpp -CPPFLAGS += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. - -include $(LLVM_SRC_ROOT)/Makefile.rules diff --git a/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp b/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp index 04edbd2a300e..d96278a8137b 100644 --- a/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp +++ b/lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp @@ -23,7 +23,6 @@  #include <cstring>  #include <dirent.h>  #include <fcntl.h> -#include <sstream>  #include <stddef.h>  #include <sys/stat.h>  #include <unistd.h> diff --git a/lib/ExecutionEngine/Orc/CMakeLists.txt b/lib/ExecutionEngine/Orc/CMakeLists.txt index d26f212e00c9..76720a7c52ec 100644 --- a/lib/ExecutionEngine/Orc/CMakeLists.txt +++ b/lib/ExecutionEngine/Orc/CMakeLists.txt @@ -2,9 +2,8 @@ add_llvm_library(LLVMOrcJIT    ExecutionUtils.cpp    IndirectionUtils.cpp    NullResolver.cpp -  OrcArchitectureSupport.cpp +  OrcABISupport.cpp    OrcCBindings.cpp -  OrcCBindingsStack.cpp    OrcError.cpp    OrcMCJITReplacement.cpp    OrcRemoteTargetRPCAPI.cpp diff --git a/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/lib/ExecutionEngine/Orc/IndirectionUtils.cpp index 34564e42b10f..6f7c29feef0d 100644 --- a/lib/ExecutionEngine/Orc/IndirectionUtils.cpp +++ b/lib/ExecutionEngine/Orc/IndirectionUtils.cpp @@ -10,10 +10,10 @@  #include "llvm/ADT/STLExtras.h"  #include "llvm/ADT/Triple.h"  #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h" +#include "llvm/ExecutionEngine/Orc/OrcABISupport.h"  #include "llvm/IR/CallSite.h"  #include "llvm/IR/IRBuilder.h"  #include "llvm/Transforms/Utils/Cloning.h" -#include <set>  #include <sstream>  namespace llvm { @@ -22,6 +22,55 @@ namespace orc {  void JITCompileCallbackManager::anchor() {}  void IndirectStubsManager::anchor() {} +std::unique_ptr<JITCompileCallbackManager> +createLocalCompileCallbackManager(const Triple &T, +                                  TargetAddress ErrorHandlerAddress) { +  switch (T.getArch()) { +    default: return nullptr; + +    case Triple::x86: { +      typedef orc::LocalJITCompileCallbackManager<orc::OrcI386> CCMgrT; +      return llvm::make_unique<CCMgrT>(ErrorHandlerAddress); +    } + +    case Triple::x86_64: { +      if ( T.getOS() == Triple::OSType::Win32 ) { +        typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64_Win32> CCMgrT; +        return llvm::make_unique<CCMgrT>(ErrorHandlerAddress); +      } else { +        typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64_SysV> CCMgrT; +        return llvm::make_unique<CCMgrT>(ErrorHandlerAddress); +      } +    } +  } +} + +std::function<std::unique_ptr<IndirectStubsManager>()> +createLocalIndirectStubsManagerBuilder(const Triple &T) { +  switch (T.getArch()) { +    default: return nullptr; + +    case Triple::x86: +      return [](){ +        return llvm::make_unique< +                       orc::LocalIndirectStubsManager<orc::OrcI386>>(); +      }; + +    case Triple::x86_64: +      if (T.getOS() == Triple::OSType::Win32) { +        return [](){ +          return llvm::make_unique< +                     orc::LocalIndirectStubsManager<orc::OrcX86_64_Win32>>(); +        }; +      } else { +        return [](){ +          return llvm::make_unique< +                     orc::LocalIndirectStubsManager<orc::OrcX86_64_SysV>>(); +        }; +      } +  } +} +  Constant* createIRTypedAddress(FunctionType &FT, TargetAddress Addr) {    Constant *AddrIntVal =      ConstantInt::get(Type::getInt64Ty(FT.getContext()), Addr); @@ -95,7 +144,7 @@ static void raiseVisibilityOnValue(GlobalValue &V, GlobalRenamer &R) {      V.setLinkage(GlobalValue::ExternalLinkage);      V.setVisibility(GlobalValue::HiddenVisibility);    } -  V.setUnnamedAddr(false); +  V.setUnnamedAddr(GlobalValue::UnnamedAddr::None);    assert(!R.needsRenaming(V) && "Invalid global name.");  } @@ -116,7 +165,7 @@ Function* cloneFunctionDecl(Module &Dst, const Function &F,                              ValueToValueMapTy *VMap) {    assert(F.getParent() != &Dst && "Can't copy decl over existing function.");    Function *NewF = -    Function::Create(cast<FunctionType>(F.getType()->getElementType()), +    Function::Create(cast<FunctionType>(F.getValueType()),                       F.getLinkage(), F.getName(), &Dst);    NewF->copyAttributesFrom(&F); @@ -154,7 +203,7 @@ GlobalVariable* cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV,                                          ValueToValueMapTy *VMap) {    assert(GV.getParent() != &Dst && "Can't copy decl over existing global var.");    GlobalVariable *NewGV = new GlobalVariable( -      Dst, GV.getType()->getElementType(), GV.isConstant(), +      Dst, GV.getValueType(), GV.isConstant(),        GV.getLinkage(), nullptr, GV.getName(), nullptr,        GV.getThreadLocalMode(), GV.getType()->getAddressSpace());    NewGV->copyAttributesFrom(&GV); diff --git a/lib/ExecutionEngine/Orc/Makefile b/lib/ExecutionEngine/Orc/Makefile deleted file mode 100644 index ac302348ee7e..000000000000 --- a/lib/ExecutionEngine/Orc/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -##===- lib/ExecutionEngine/OrcJIT/Makefile -----------------*- Makefile -*-===## -# -#                     The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../../.. -LIBRARYNAME = LLVMOrcJIT - -include $(LEVEL)/Makefile.common diff --git a/lib/ExecutionEngine/Orc/OrcABISupport.cpp b/lib/ExecutionEngine/Orc/OrcABISupport.cpp new file mode 100644 index 000000000000..9869b6c7050c --- /dev/null +++ b/lib/ExecutionEngine/Orc/OrcABISupport.cpp @@ -0,0 +1,542 @@ +//===------------- OrcABISupport.cpp - ABI specific support code ----------===// +// +//                     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/OrcABISupport.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Support/Process.h" + +namespace llvm { +namespace orc { + +void OrcAArch64::writeResolverCode(uint8_t *ResolverMem, JITReentryFn ReentryFn, +                                   void *CallbackMgr) { + +  const uint32_t ResolverCode[] = { +    // resolver_entry: +    0xa9bf47fd,        // 0x000:  stp  x29, x17, [sp, #-16]! +    0x910003fd,        // 0x004:  mov  x29, sp +    0xa9bf73fb,        // 0x008:  stp  x27, x28, [sp, #-16]! +    0xa9bf6bf9,        // 0x00c:  stp  x25, x26, [sp, #-16]! +    0xa9bf63f7,        // 0x010:  stp  x23, x24, [sp, #-16]! +    0xa9bf5bf5,        // 0x014:  stp  x21, x22, [sp, #-16]! +    0xa9bf53f3,        // 0x018:  stp  x19, x20, [sp, #-16]! +    0xa9bf3fee,        // 0x01c:  stp  x14, x15, [sp, #-16]! +    0xa9bf37ec,        // 0x020:  stp  x12, x13, [sp, #-16]! +    0xa9bf2fea,        // 0x024:  stp  x10, x11, [sp, #-16]! +    0xa9bf27e8,        // 0x028:  stp   x8,  x9, [sp, #-16]! +    0xa9bf1fe6,        // 0x02c:  stp   x6,  x7, [sp, #-16]! +    0xa9bf17e4,        // 0x030:  stp   x4,  x5, [sp, #-16]! +    0xa9bf0fe2,        // 0x034:  stp   x2,  x3, [sp, #-16]! +    0xa9bf07e0,        // 0x038:  stp   x0,  x1, [sp, #-16]! +    0xadbf7ffe,        // 0x03c:  stp  q30, q31, [sp, #-32]! +    0xadbf77fc,        // 0x040:  stp  q28, q29, [sp, #-32]! +    0xadbf6ffa,        // 0x044:  stp  q26, q27, [sp, #-32]! +    0xadbf67f8,        // 0x048:  stp  q24, q25, [sp, #-32]! +    0xadbf5ff6,        // 0x04c:  stp  q22, q23, [sp, #-32]! +    0xadbf57f4,        // 0x050:  stp  q20, q21, [sp, #-32]! +    0xadbf4ff2,        // 0x054:  stp  q18, q19, [sp, #-32]! +    0xadbf47f0,        // 0x058:  stp  q16, q17, [sp, #-32]! +    0xadbf3fee,        // 0x05c:  stp  q14, q15, [sp, #-32]! +    0xadbf37ec,        // 0x060:  stp  q12, q13, [sp, #-32]! +    0xadbf2fea,        // 0x064:  stp  q10, q11, [sp, #-32]! +    0xadbf27e8,        // 0x068:  stp   q8,  q9, [sp, #-32]! +    0xadbf1fe6,        // 0x06c:  stp   q6,  q7, [sp, #-32]! +    0xadbf17e4,        // 0x070:  stp   q4,  q5, [sp, #-32]! +    0xadbf0fe2,        // 0x074:  stp   q2,  q3, [sp, #-32]! +    0xadbf07e0,        // 0x078:  stp   q0,  q1, [sp, #-32]! +    0x580004e0,        // 0x07c:  ldr   x0, Lcallbackmgr +    0xaa1e03e1,        // 0x080:  mov   x1, x30 +    0xd1003021,        // 0x084:  sub   x1,  x1, #12 +    0x58000442,        // 0x088:  ldr   x2, Lreentry_fn_ptr +    0xd63f0040,        // 0x08c:  blr   x2 +    0xaa0003f1,        // 0x090:  mov   x17, x0 +    0xacc107e0,        // 0x094:  ldp   q0,  q1, [sp], #32 +    0xacc10fe2,        // 0x098:  ldp   q2,  q3, [sp], #32 +    0xacc117e4,        // 0x09c:  ldp   q4,  q5, [sp], #32 +    0xacc11fe6,        // 0x0a0:  ldp   q6,  q7, [sp], #32 +    0xacc127e8,        // 0x0a4:  ldp   q8,  q9, [sp], #32 +    0xacc12fea,        // 0x0a8:  ldp  q10, q11, [sp], #32 +    0xacc137ec,        // 0x0ac:  ldp  q12, q13, [sp], #32 +    0xacc13fee,        // 0x0b0:  ldp  q14, q15, [sp], #32 +    0xacc147f0,        // 0x0b4:  ldp  q16, q17, [sp], #32 +    0xacc14ff2,        // 0x0b8:  ldp  q18, q19, [sp], #32 +    0xacc157f4,        // 0x0bc:  ldp  q20, q21, [sp], #32 +    0xacc15ff6,        // 0x0c0:  ldp  q22, q23, [sp], #32 +    0xacc167f8,        // 0x0c4:  ldp  q24, q25, [sp], #32 +    0xacc16ffa,        // 0x0c8:  ldp  q26, q27, [sp], #32 +    0xacc177fc,        // 0x0cc:  ldp  q28, q29, [sp], #32 +    0xacc17ffe,        // 0x0d0:  ldp  q30, q31, [sp], #32 +    0xa8c107e0,        // 0x0d4:  ldp   x0,  x1, [sp], #16 +    0xa8c10fe2,        // 0x0d8:  ldp   x2,  x3, [sp], #16 +    0xa8c117e4,        // 0x0dc:  ldp   x4,  x5, [sp], #16 +    0xa8c11fe6,        // 0x0e0:  ldp   x6,  x7, [sp], #16 +    0xa8c127e8,        // 0x0e4:  ldp   x8,  x9, [sp], #16 +    0xa8c12fea,        // 0x0e8:  ldp  x10, x11, [sp], #16 +    0xa8c137ec,        // 0x0ec:  ldp  x12, x13, [sp], #16 +    0xa8c13fee,        // 0x0f0:  ldp  x14, x15, [sp], #16 +    0xa8c153f3,        // 0x0f4:  ldp  x19, x20, [sp], #16 +    0xa8c15bf5,        // 0x0f8:  ldp  x21, x22, [sp], #16 +    0xa8c163f7,        // 0x0fc:  ldp  x23, x24, [sp], #16 +    0xa8c16bf9,        // 0x100:  ldp  x25, x26, [sp], #16 +    0xa8c173fb,        // 0x104:  ldp  x27, x28, [sp], #16 +    0xa8c17bfd,        // 0x108:  ldp  x29, x30, [sp], #16 +    0xd65f0220,        // 0x10c:  ret  x17 +    0x01234567,        // 0x110:  Lreentry_fn_ptr: +    0xdeadbeef,        // 0x114:      .quad 0 +    0x98765432,        // 0x118:  Lcallbackmgr: +    0xcafef00d         // 0x11c:      .quad 0 +  }; + +  const unsigned ReentryFnAddrOffset = 0x110; +  const unsigned CallbackMgrAddrOffset = 0x118; + +  memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode)); +  memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn, sizeof(ReentryFn)); +  memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr, +         sizeof(CallbackMgr)); +} + +void OrcAArch64::writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr, +                                  unsigned NumTrampolines) { + +  unsigned OffsetToPtr = alignTo(NumTrampolines * TrampolineSize, 8); + +  memcpy(TrampolineMem + OffsetToPtr, &ResolverAddr, sizeof(void *)); + +  // OffsetToPtr is actually the offset from the PC for the 2nd instruction, so +  // subtract 32-bits. +  OffsetToPtr -= 4; + +  uint32_t *Trampolines = reinterpret_cast<uint32_t *>(TrampolineMem); + +  for (unsigned I = 0; I < NumTrampolines; ++I, OffsetToPtr -= TrampolineSize) { +    Trampolines[3 * I + 0] = 0xaa1e03f1;                      // mov x17, x30 +    Trampolines[3 * I + 1] = 0x58000010 | (OffsetToPtr << 3); // mov x16, Lptr +    Trampolines[3 * I + 2] = 0xd63f0200;                      // blr x16 +  } + +} + +Error OrcAArch64::emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo, +                                         unsigned MinStubs, +                                         void *InitialPtrVal) { +  // Stub format is: +  // +  // .section __orc_stubs +  // stub1: +  //                 ldr     x0, ptr1       ; PC-rel load of ptr1 +  //                 br      x0             ; Jump to resolver +  // stub2: +  //                 ldr     x0, ptr2       ; PC-rel load of ptr2 +  //                 br      x0             ; Jump to resolver +  // +  // ... +  // +  // .section __orc_ptrs +  // ptr1: +  //                 .quad 0x0 +  // ptr2: +  //                 .quad 0x0 +  // +  // ... + +  const unsigned StubSize = IndirectStubsInfo::StubSize; + +  // Emit at least MinStubs, rounded up to fill the pages allocated. +  unsigned PageSize = sys::Process::getPageSize(); +  unsigned NumPages = ((MinStubs * StubSize) + (PageSize - 1)) / PageSize; +  unsigned NumStubs = (NumPages * PageSize) / StubSize; + +  // Allocate memory for stubs and pointers in one call. +  std::error_code EC; +  auto StubsMem = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory( +      2 * NumPages * PageSize, nullptr, +      sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC)); + +  if (EC) +    return errorCodeToError(EC); + +  // Create separate MemoryBlocks representing the stubs and pointers. +  sys::MemoryBlock StubsBlock(StubsMem.base(), NumPages * PageSize); +  sys::MemoryBlock PtrsBlock(static_cast<char *>(StubsMem.base()) + +                                 NumPages * PageSize, +                             NumPages * PageSize); + +  // Populate the stubs page stubs and mark it executable. +  uint64_t *Stub = reinterpret_cast<uint64_t *>(StubsBlock.base()); +  uint64_t PtrOffsetField = static_cast<uint64_t>(NumPages * PageSize) +                            << 3; + +  for (unsigned I = 0; I < NumStubs; ++I) +    Stub[I] = 0xd61f020058000010 | PtrOffsetField; + +  if (auto EC = sys::Memory::protectMappedMemory( +          StubsBlock, sys::Memory::MF_READ | sys::Memory::MF_EXEC)) +    return errorCodeToError(EC); + +  // Initialize all pointers to point at FailureAddress. +  void **Ptr = reinterpret_cast<void **>(PtrsBlock.base()); +  for (unsigned I = 0; I < NumStubs; ++I) +    Ptr[I] = InitialPtrVal; + +  StubsInfo = IndirectStubsInfo(NumStubs, std::move(StubsMem)); + +  return Error::success(); +} + +void OrcX86_64_Base::writeTrampolines(uint8_t *TrampolineMem, +                                      void *ResolverAddr, +                                      unsigned NumTrampolines) { + +  unsigned OffsetToPtr = NumTrampolines * TrampolineSize; + +  memcpy(TrampolineMem + OffsetToPtr, &ResolverAddr, sizeof(void *)); + +  uint64_t *Trampolines = reinterpret_cast<uint64_t *>(TrampolineMem); +  uint64_t CallIndirPCRel = 0xf1c40000000015ff; + +  for (unsigned I = 0; I < NumTrampolines; ++I, OffsetToPtr -= TrampolineSize) +    Trampolines[I] = CallIndirPCRel | ((OffsetToPtr - 6) << 16); +} + +Error OrcX86_64_Base::emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo, +                                             unsigned MinStubs, +                                             void *InitialPtrVal) { +  // Stub format is: +  // +  // .section __orc_stubs +  // stub1: +  //                 jmpq    *ptr1(%rip) +  //                 .byte   0xC4         ; <- Invalid opcode padding. +  //                 .byte   0xF1 +  // stub2: +  //                 jmpq    *ptr2(%rip) +  // +  // ... +  // +  // .section __orc_ptrs +  // ptr1: +  //                 .quad 0x0 +  // ptr2: +  //                 .quad 0x0 +  // +  // ... + +  const unsigned StubSize = IndirectStubsInfo::StubSize; + +  // Emit at least MinStubs, rounded up to fill the pages allocated. +  unsigned PageSize = sys::Process::getPageSize(); +  unsigned NumPages = ((MinStubs * StubSize) + (PageSize - 1)) / PageSize; +  unsigned NumStubs = (NumPages * PageSize) / StubSize; + +  // Allocate memory for stubs and pointers in one call. +  std::error_code EC; +  auto StubsMem = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory( +      2 * NumPages * PageSize, nullptr, +      sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC)); + +  if (EC) +    return errorCodeToError(EC); + +  // Create separate MemoryBlocks representing the stubs and pointers. +  sys::MemoryBlock StubsBlock(StubsMem.base(), NumPages * PageSize); +  sys::MemoryBlock PtrsBlock(static_cast<char *>(StubsMem.base()) + +                                 NumPages * PageSize, +                             NumPages * PageSize); + +  // Populate the stubs page stubs and mark it executable. +  uint64_t *Stub = reinterpret_cast<uint64_t *>(StubsBlock.base()); +  uint64_t PtrOffsetField = static_cast<uint64_t>(NumPages * PageSize - 6) +                            << 16; +  for (unsigned I = 0; I < NumStubs; ++I) +    Stub[I] = 0xF1C40000000025ff | PtrOffsetField; + +  if (auto EC = sys::Memory::protectMappedMemory( +          StubsBlock, sys::Memory::MF_READ | sys::Memory::MF_EXEC)) +    return errorCodeToError(EC); + +  // Initialize all pointers to point at FailureAddress. +  void **Ptr = reinterpret_cast<void **>(PtrsBlock.base()); +  for (unsigned I = 0; I < NumStubs; ++I) +    Ptr[I] = InitialPtrVal; + +  StubsInfo = IndirectStubsInfo(NumStubs, std::move(StubsMem)); + +  return Error::success(); +} + +void OrcX86_64_SysV::writeResolverCode(uint8_t *ResolverMem, +                                       JITReentryFn ReentryFn, +                                       void *CallbackMgr) { + +  const uint8_t ResolverCode[] = { +      // resolver_entry: +      0x55,                                     // 0x00: pushq     %rbp +      0x48, 0x89, 0xe5,                         // 0x01: movq      %rsp, %rbp +      0x50,                                     // 0x04: pushq     %rax +      0x53,                                     // 0x05: pushq     %rbx +      0x51,                                     // 0x06: pushq     %rcx +      0x52,                                     // 0x07: pushq     %rdx +      0x56,                                     // 0x08: pushq     %rsi +      0x57,                                     // 0x09: pushq     %rdi +      0x41, 0x50,                               // 0x0a: pushq     %r8 +      0x41, 0x51,                               // 0x0c: pushq     %r9 +      0x41, 0x52,                               // 0x0e: pushq     %r10 +      0x41, 0x53,                               // 0x10: pushq     %r11 +      0x41, 0x54,                               // 0x12: pushq     %r12 +      0x41, 0x55,                               // 0x14: pushq     %r13 +      0x41, 0x56,                               // 0x16: pushq     %r14 +      0x41, 0x57,                               // 0x18: pushq     %r15 +      0x48, 0x81, 0xec, 0x08, 0x02, 0x00, 0x00, // 0x1a: subq      0x208, %rsp +      0x48, 0x0f, 0xae, 0x04, 0x24,             // 0x21: fxsave64  (%rsp) +      0x48, 0xbf,                               // 0x26: movabsq   <CBMgr>, %rdi + +      // 0x28: Callback manager addr. +      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + +      0x48, 0x8b, 0x75, 0x08,                   // 0x30: movq      8(%rbp), %rsi +      0x48, 0x83, 0xee, 0x06,                   // 0x34: subq      $6, %rsi +      0x48, 0xb8,                               // 0x38: movabsq   <REntry>, %rax + +      // 0x3a: JIT re-entry fn addr: +      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + +      0xff, 0xd0,                               // 0x42: callq     *%rax +      0x48, 0x89, 0x45, 0x08,                   // 0x44: movq      %rax, 8(%rbp) +      0x48, 0x0f, 0xae, 0x0c, 0x24,             // 0x48: fxrstor64 (%rsp) +      0x48, 0x81, 0xc4, 0x08, 0x02, 0x00, 0x00, // 0x4d: addq      0x208, %rsp +      0x41, 0x5f,                               // 0x54: popq      %r15 +      0x41, 0x5e,                               // 0x56: popq      %r14 +      0x41, 0x5d,                               // 0x58: popq      %r13 +      0x41, 0x5c,                               // 0x5a: popq      %r12 +      0x41, 0x5b,                               // 0x5c: popq      %r11 +      0x41, 0x5a,                               // 0x5e: popq      %r10 +      0x41, 0x59,                               // 0x60: popq      %r9 +      0x41, 0x58,                               // 0x62: popq      %r8 +      0x5f,                                     // 0x64: popq      %rdi +      0x5e,                                     // 0x65: popq      %rsi +      0x5a,                                     // 0x66: popq      %rdx +      0x59,                                     // 0x67: popq      %rcx +      0x5b,                                     // 0x68: popq      %rbx +      0x58,                                     // 0x69: popq      %rax +      0x5d,                                     // 0x6a: popq      %rbp +      0xc3,                                     // 0x6b: retq +  }; + +  const unsigned ReentryFnAddrOffset = 0x3a; +  const unsigned CallbackMgrAddrOffset = 0x28; + +  memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode)); +  memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn, sizeof(ReentryFn)); +  memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr, +         sizeof(CallbackMgr)); +} + +void OrcX86_64_Win32::writeResolverCode(uint8_t *ResolverMem, +                                        JITReentryFn ReentryFn, +                                        void *CallbackMgr) { + +  // resolverCode is similar to OrcX86_64 with differences specific to windows x64 calling convention: +  // arguments go into rcx, rdx and come in reverse order, shadow space allocation on stack +  const uint8_t ResolverCode[] = { +      // resolver_entry: +      0x55,                                      // 0x00: pushq     %rbp +      0x48, 0x89, 0xe5,                          // 0x01: movq      %rsp, %rbp +      0x50,                                      // 0x04: pushq     %rax +      0x53,                                      // 0x05: pushq     %rbx +      0x51,                                      // 0x06: pushq     %rcx +      0x52,                                      // 0x07: pushq     %rdx +      0x56,                                      // 0x08: pushq     %rsi +      0x57,                                      // 0x09: pushq     %rdi +      0x41, 0x50,                                // 0x0a: pushq     %r8 +      0x41, 0x51,                                // 0x0c: pushq     %r9 +      0x41, 0x52,                                // 0x0e: pushq     %r10 +      0x41, 0x53,                                // 0x10: pushq     %r11 +      0x41, 0x54,                                // 0x12: pushq     %r12 +      0x41, 0x55,                                // 0x14: pushq     %r13 +      0x41, 0x56,                                // 0x16: pushq     %r14 +      0x41, 0x57,                                // 0x18: pushq     %r15 +      0x48, 0x81, 0xec, 0x08, 0x02, 0x00, 0x00,  // 0x1a: subq      0x208, %rsp +      0x48, 0x0f, 0xae, 0x04, 0x24,              // 0x21: fxsave64  (%rsp) + +      0x48, 0xb9,                                // 0x26: movabsq   <CBMgr>, %rcx +      // 0x28: Callback manager addr. +      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + +      0x48, 0x8B, 0x55, 0x08,                    // 0x30: mov       rdx, [rbp+0x8] +      0x48, 0x83, 0xea, 0x06,                    // 0x34: sub       rdx, 0x6 + +      0x48, 0xb8,                                // 0x38: movabsq   <REntry>, %rax +      // 0x3a: JIT re-entry fn addr: +      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + +      // 0x42: sub       rsp, 0x20 (Allocate shadow space) +      0x48, 0x83, 0xEC, 0x20, +      0xff, 0xd0,                                // 0x46: callq     *%rax + +      // 0x48: add       rsp, 0x20 (Free shadow space) +      0x48, 0x83, 0xC4, 0x20, + +      0x48, 0x89, 0x45, 0x08,                    // 0x4C: movq      %rax, 8(%rbp) +      0x48, 0x0f, 0xae, 0x0c, 0x24,              // 0x50: fxrstor64 (%rsp) +      0x48, 0x81, 0xc4, 0x08, 0x02, 0x00, 0x00,  // 0x55: addq      0x208, %rsp +      0x41, 0x5f,                                // 0x5C: popq      %r15 +      0x41, 0x5e,                                // 0x5E: popq      %r14 +      0x41, 0x5d,                                // 0x60: popq      %r13 +      0x41, 0x5c,                                // 0x62: popq      %r12 +      0x41, 0x5b,                                // 0x64: popq      %r11 +      0x41, 0x5a,                                // 0x66: popq      %r10 +      0x41, 0x59,                                // 0x68: popq      %r9 +      0x41, 0x58,                                // 0x6a: popq      %r8 +      0x5f,                                      // 0x6c: popq      %rdi +      0x5e,                                      // 0x6d: popq      %rsi +      0x5a,                                      // 0x6e: popq      %rdx +      0x59,                                      // 0x6f: popq      %rcx +      0x5b,                                      // 0x70: popq      %rbx +      0x58,                                      // 0x71: popq      %rax +      0x5d,                                      // 0x72: popq      %rbp +      0xc3,                                      // 0x73: retq +  }; + + +  const unsigned ReentryFnAddrOffset = 0x3a; +  const unsigned CallbackMgrAddrOffset = 0x28; + +  memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode)); +  memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn, sizeof(ReentryFn)); +  memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr, +         sizeof(CallbackMgr)); +} + +void OrcI386::writeResolverCode(uint8_t *ResolverMem, JITReentryFn ReentryFn, +                                void *CallbackMgr) { + +  const uint8_t ResolverCode[] = { +      // resolver_entry: +      0x55,                               // 0x00: pushl    %ebp +      0x89, 0xe5,                         // 0x01: movl     %esp, %ebp +      0x54,                               // 0x03: pushl    %esp +      0x83, 0xe4, 0xf0,                   // 0x04: andl     $-0x10, %esp +      0x50,                               // 0x07: pushl    %eax +      0x53,                               // 0x08: pushl    %ebx +      0x51,                               // 0x09: pushl    %ecx +      0x52,                               // 0x0a: pushl    %edx +      0x56,                               // 0x0b: pushl    %esi +      0x57,                               // 0x0c: pushl    %edi +      0x81, 0xec, 0x18, 0x02, 0x00, 0x00, // 0x0d: subl     $0x218, %esp +      0x0f, 0xae, 0x44, 0x24, 0x10,       // 0x13: fxsave   0x10(%esp) +      0x8b, 0x75, 0x04,                   // 0x18: movl     0x4(%ebp), %esi +      0x83, 0xee, 0x05,                   // 0x1b: subl     $0x5, %esi +      0x89, 0x74, 0x24, 0x04,             // 0x1e: movl     %esi, 0x4(%esp) +      0xc7, 0x04, 0x24, 0x00, 0x00, 0x00, +      0x00,                               // 0x22: movl     <cbmgr>, (%esp) +      0xb8, 0x00, 0x00, 0x00, 0x00,       // 0x29: movl     <reentry>, %eax +      0xff, 0xd0,                         // 0x2e: calll    *%eax +      0x89, 0x45, 0x04,                   // 0x30: movl     %eax, 0x4(%ebp) +      0x0f, 0xae, 0x4c, 0x24, 0x10,       // 0x33: fxrstor  0x10(%esp) +      0x81, 0xc4, 0x18, 0x02, 0x00, 0x00, // 0x38: addl     $0x218, %esp +      0x5f,                               // 0x3e: popl     %edi +      0x5e,                               // 0x3f: popl     %esi +      0x5a,                               // 0x40: popl     %edx +      0x59,                               // 0x41: popl     %ecx +      0x5b,                               // 0x42: popl     %ebx +      0x58,                               // 0x43: popl     %eax +      0x8b, 0x65, 0xfc,                   // 0x44: movl     -0x4(%ebp), %esp +      0x5d,                               // 0x48: popl     %ebp +      0xc3                                // 0x49: retl +  }; + +  const unsigned ReentryFnAddrOffset = 0x2a; +  const unsigned CallbackMgrAddrOffset = 0x25; + +  memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode)); +  memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn, sizeof(ReentryFn)); +  memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr, +         sizeof(CallbackMgr)); +} + +void OrcI386::writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr, +                               unsigned NumTrampolines) { + +  uint64_t CallRelImm = 0xF1C4C400000000e8; +  uint64_t Resolver = reinterpret_cast<uint64_t>(ResolverAddr); +  uint64_t ResolverRel = +      Resolver - reinterpret_cast<uint64_t>(TrampolineMem) - 5; + +  uint64_t *Trampolines = reinterpret_cast<uint64_t *>(TrampolineMem); +  for (unsigned I = 0; I < NumTrampolines; ++I, ResolverRel -= TrampolineSize) +    Trampolines[I] = CallRelImm | (ResolverRel << 8); +} + +Error OrcI386::emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo, +                                      unsigned MinStubs, void *InitialPtrVal) { +  // Stub format is: +  // +  // .section __orc_stubs +  // stub1: +  //                 jmpq    *ptr1 +  //                 .byte   0xC4         ; <- Invalid opcode padding. +  //                 .byte   0xF1 +  // stub2: +  //                 jmpq    *ptr2 +  // +  // ... +  // +  // .section __orc_ptrs +  // ptr1: +  //                 .quad 0x0 +  // ptr2: +  //                 .quad 0x0 +  // +  // ... + +  const unsigned StubSize = IndirectStubsInfo::StubSize; + +  // Emit at least MinStubs, rounded up to fill the pages allocated. +  unsigned PageSize = sys::Process::getPageSize(); +  unsigned NumPages = ((MinStubs * StubSize) + (PageSize - 1)) / PageSize; +  unsigned NumStubs = (NumPages * PageSize) / StubSize; + +  // Allocate memory for stubs and pointers in one call. +  std::error_code EC; +  auto StubsMem = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory( +      2 * NumPages * PageSize, nullptr, +      sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC)); + +  if (EC) +    return errorCodeToError(EC); + +  // Create separate MemoryBlocks representing the stubs and pointers. +  sys::MemoryBlock StubsBlock(StubsMem.base(), NumPages * PageSize); +  sys::MemoryBlock PtrsBlock(static_cast<char *>(StubsMem.base()) + +                                 NumPages * PageSize, +                             NumPages * PageSize); + +  // Populate the stubs page stubs and mark it executable. +  uint64_t *Stub = reinterpret_cast<uint64_t *>(StubsBlock.base()); +  uint64_t PtrAddr = reinterpret_cast<uint64_t>(PtrsBlock.base()); +  for (unsigned I = 0; I < NumStubs; ++I, PtrAddr += 4) +    Stub[I] = 0xF1C40000000025ff | (PtrAddr << 16); + +  if (auto EC = sys::Memory::protectMappedMemory( +          StubsBlock, sys::Memory::MF_READ | sys::Memory::MF_EXEC)) +    return errorCodeToError(EC); + +  // Initialize all pointers to point at FailureAddress. +  void **Ptr = reinterpret_cast<void **>(PtrsBlock.base()); +  for (unsigned I = 0; I < NumStubs; ++I) +    Ptr[I] = InitialPtrVal; + +  StubsInfo = IndirectStubsInfo(NumStubs, std::move(StubsMem)); + +  return Error::success(); +} + +} // End namespace orc. +} // End namespace llvm. diff --git a/lib/ExecutionEngine/Orc/OrcArchitectureSupport.cpp b/lib/ExecutionEngine/Orc/OrcArchitectureSupport.cpp deleted file mode 100644 index 01e829f7909e..000000000000 --- a/lib/ExecutionEngine/Orc/OrcArchitectureSupport.cpp +++ /dev/null @@ -1,171 +0,0 @@ -//===------ OrcArchSupport.cpp - Architecture specific support code -------===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ADT/Triple.h" -#include "llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h" -#include "llvm/Support/Process.h" -#include <array> - -namespace llvm { -namespace orc { - -void OrcX86_64::writeResolverCode(uint8_t *ResolverMem, JITReentryFn ReentryFn, -                                  void *CallbackMgr) { - -  const uint8_t ResolverCode[] = { -                                               // resolver_entry: -    0x55,                                      // 0x00: pushq     %rbp -    0x48, 0x89, 0xe5,                          // 0x01: movq      %rsp, %rbp -    0x50,                                      // 0x04: pushq     %rax -    0x53,                                      // 0x05: pushq     %rbx -    0x51,                                      // 0x06: pushq     %rcx -    0x52,                                      // 0x07: pushq     %rdx -    0x56,                                      // 0x08: pushq     %rsi -    0x57,                                      // 0x09: pushq     %rdi -    0x41, 0x50,                                // 0x0a: pushq     %r8 -    0x41, 0x51,                                // 0x0c: pushq     %r9 -    0x41, 0x52,                                // 0x0e: pushq     %r10 -    0x41, 0x53,                                // 0x10: pushq     %r11 -    0x41, 0x54,                                // 0x12: pushq     %r12 -    0x41, 0x55,                                // 0x14: pushq     %r13 -    0x41, 0x56,                                // 0x16: pushq     %r14 -    0x41, 0x57,                                // 0x18: pushq     %r15 -    0x48, 0x81, 0xec, 0x08, 0x02, 0x00, 0x00,  // 0x1a: subq      20, %rsp -    0x48, 0x0f, 0xae, 0x04, 0x24,              // 0x21: fxsave64  (%rsp) -    0x48, 0x8d, 0x3d, 0x43, 0x00, 0x00, 0x00,  // 0x26: leaq      67(%rip), %rdi -    0x48, 0x8b, 0x3f,                          // 0x2d: movq      (%rdi), %rdi -    0x48, 0x8b, 0x75, 0x08,                    // 0x30: movq      8(%rbp), %rsi -    0x48, 0x83, 0xee, 0x06,                    // 0x34: subq      $6, %rsi -    0x48, 0xb8,                                // 0x38: movabsq   $0, %rax - -    // 0x3a: JIT re-entry fn addr: -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - -    0xff, 0xd0,                                // 0x42: callq     *%rax -    0x48, 0x89, 0x45, 0x08,                    // 0x44: movq      %rax, 8(%rbp) -    0x48, 0x0f, 0xae, 0x0c, 0x24,              // 0x48: fxrstor64 (%rsp) -    0x48, 0x81, 0xc4, 0x08, 0x02, 0x00, 0x00,  // 0x4d: addq      20, %rsp -    0x41, 0x5f,                                // 0x54: popq      %r15 -    0x41, 0x5e,                                // 0x56: popq      %r14 -    0x41, 0x5d,                                // 0x58: popq      %r13 -    0x41, 0x5c,                                // 0x5a: popq      %r12 -    0x41, 0x5b,                                // 0x5c: popq      %r11 -    0x41, 0x5a,                                // 0x5e: popq      %r10 -    0x41, 0x59,                                // 0x60: popq      %r9 -    0x41, 0x58,                                // 0x62: popq      %r8 -    0x5f,                                      // 0x64: popq      %rdi -    0x5e,                                      // 0x65: popq      %rsi -    0x5a,                                      // 0x66: popq      %rdx -    0x59,                                      // 0x67: popq      %rcx -    0x5b,                                      // 0x68: popq      %rbx -    0x58,                                      // 0x69: popq      %rax -    0x5d,                                      // 0x6a: popq      %rbp -    0xc3,                                      // 0x6b: retq -    0x00, 0x00, 0x00, 0x00,                    // 0x6c: <padding> - -    // 0x70: Callback mgr address. -    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -  }; - -  const unsigned ReentryFnAddrOffset = 0x3a; -  const unsigned CallbackMgrAddrOffset = 0x70; -   -  memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode)); -  memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn, sizeof(ReentryFn)); -  memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr, -         sizeof(CallbackMgr)); -} - -void OrcX86_64::writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr, -				 unsigned NumTrampolines) { - -  unsigned OffsetToPtr = NumTrampolines * TrampolineSize; - -  memcpy(TrampolineMem + OffsetToPtr, &ResolverAddr, sizeof(void*)); - -  uint64_t *Trampolines = reinterpret_cast<uint64_t*>(TrampolineMem); -  uint64_t CallIndirPCRel = 0xf1c40000000015ff; - -  for (unsigned I = 0; I < NumTrampolines; ++I, OffsetToPtr -= TrampolineSize) -    Trampolines[I] = CallIndirPCRel | ((OffsetToPtr - 6) << 16); -} - -std::error_code OrcX86_64::emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo, -                                                  unsigned MinStubs, -                                                  void *InitialPtrVal) { -  // Stub format is: -  // -  // .section __orc_stubs -  // stub1: -  //                 jmpq    *ptr1(%rip) -  //                 .byte   0xC4         ; <- Invalid opcode padding. -  //                 .byte   0xF1 -  // stub2: -  //                 jmpq    *ptr2(%rip) -  // -  // ... -  // -  // .section __orc_ptrs -  // ptr1: -  //                 .quad 0x0 -  // ptr2: -  //                 .quad 0x0 -  // -  // ... - -  const unsigned StubSize = IndirectStubsInfo::StubSize; - -  // Emit at least MinStubs, rounded up to fill the pages allocated. -  unsigned PageSize = sys::Process::getPageSize(); -  unsigned NumPages = ((MinStubs * StubSize) + (PageSize - 1)) / PageSize; -  unsigned NumStubs = (NumPages * PageSize) / StubSize; - -  // Allocate memory for stubs and pointers in one call. -  std::error_code EC; -  auto StubsMem = -    sys::OwningMemoryBlock( -      sys::Memory::allocateMappedMemory(2 * NumPages * PageSize, nullptr, -                                        sys::Memory::MF_READ | -                                        sys::Memory::MF_WRITE, -                                        EC)); - -  if (EC) -    return EC; - -  // Create separate MemoryBlocks representing the stubs and pointers. -  sys::MemoryBlock StubsBlock(StubsMem.base(), NumPages * PageSize); -  sys::MemoryBlock PtrsBlock(static_cast<char*>(StubsMem.base()) + -                               NumPages * PageSize, -                             NumPages * PageSize); - -  // Populate the stubs page stubs and mark it executable. -  uint64_t *Stub = reinterpret_cast<uint64_t*>(StubsBlock.base()); -  uint64_t PtrOffsetField = -    static_cast<uint64_t>(NumPages * PageSize - 6) << 16; -  for (unsigned I = 0; I < NumStubs; ++I) -    Stub[I] = 0xF1C40000000025ff | PtrOffsetField; - -  if (auto EC = sys::Memory::protectMappedMemory(StubsBlock, -                                                 sys::Memory::MF_READ | -                                                 sys::Memory::MF_EXEC)) -    return EC; - -  // Initialize all pointers to point at FailureAddress. -  void **Ptr = reinterpret_cast<void**>(PtrsBlock.base()); -  for (unsigned I = 0; I < NumStubs; ++I) -    Ptr[I] = InitialPtrVal; - -  StubsInfo.NumStubs = NumStubs; -  StubsInfo.StubsMem = std::move(StubsMem); - -  return std::error_code(); -} - -} // End namespace orc. -} // End namespace llvm. diff --git a/lib/ExecutionEngine/Orc/OrcCBindings.cpp b/lib/ExecutionEngine/Orc/OrcCBindings.cpp index d2379cd441d5..8dcd49aaab5b 100644 --- a/lib/ExecutionEngine/Orc/OrcCBindings.cpp +++ b/lib/ExecutionEngine/Orc/OrcCBindings.cpp @@ -17,17 +17,21 @@ LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM) {    Triple T(TM2->getTargetTriple()); -  auto CompileCallbackMgr = OrcCBindingsStack::createCompileCallbackMgr(T); +  auto CompileCallbackMgr = orc::createLocalCompileCallbackManager(T, 0);    auto IndirectStubsMgrBuilder = -    OrcCBindingsStack::createIndirectStubsMgrBuilder(T); +      orc::createLocalIndirectStubsManagerBuilder(T); -  OrcCBindingsStack *JITStack = -    new OrcCBindingsStack(*TM2, std::move(CompileCallbackMgr), -			  IndirectStubsMgrBuilder); +  OrcCBindingsStack *JITStack = new OrcCBindingsStack( +      *TM2, std::move(CompileCallbackMgr), IndirectStubsMgrBuilder);    return wrap(JITStack);  } +const char *LLVMOrcGetErrorMsg(LLVMOrcJITStackRef JITStack) { +  OrcCBindingsStack &J = *unwrap(JITStack); +  return J.getErrorMessage().c_str(); +} +  void LLVMOrcGetMangledSymbol(LLVMOrcJITStackRef JITStack, char **MangledName,                               const char *SymbolName) {    OrcCBindingsStack &J = *unwrap(JITStack); @@ -36,9 +40,7 @@ void LLVMOrcGetMangledSymbol(LLVMOrcJITStackRef JITStack, char **MangledName,    strcpy(*MangledName, Mangled.c_str());  } -void LLVMOrcDisposeMangledSymbol(char *MangledName) { -  delete[] MangledName; -} +void LLVMOrcDisposeMangledSymbol(char *MangledName) { delete[] MangledName; }  LLVMOrcTargetAddress  LLVMOrcCreateLazyCompileCallback(LLVMOrcJITStackRef JITStack, @@ -48,18 +50,18 @@ LLVMOrcCreateLazyCompileCallback(LLVMOrcJITStackRef JITStack,    return J.createLazyCompileCallback(Callback, CallbackCtx);  } -void LLVMOrcCreateIndirectStub(LLVMOrcJITStackRef JITStack, -                               const char *StubName, -                               LLVMOrcTargetAddress InitAddr) { +LLVMOrcErrorCode LLVMOrcCreateIndirectStub(LLVMOrcJITStackRef JITStack, +                                           const char *StubName, +                                           LLVMOrcTargetAddress InitAddr) {    OrcCBindingsStack &J = *unwrap(JITStack); -  J.createIndirectStub(StubName, InitAddr); +  return J.createIndirectStub(StubName, InitAddr);  } -void LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack, -                                   const char *StubName, -                                   LLVMOrcTargetAddress NewAddr) { +LLVMOrcErrorCode LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack, +                                               const char *StubName, +                                               LLVMOrcTargetAddress NewAddr) {    OrcCBindingsStack &J = *unwrap(JITStack); -  J.setIndirectStubPointer(StubName, NewAddr); +  return J.setIndirectStubPointer(StubName, NewAddr);  }  LLVMOrcModuleHandle diff --git a/lib/ExecutionEngine/Orc/OrcCBindingsStack.cpp b/lib/ExecutionEngine/Orc/OrcCBindingsStack.cpp deleted file mode 100644 index 956daae372da..000000000000 --- a/lib/ExecutionEngine/Orc/OrcCBindingsStack.cpp +++ /dev/null @@ -1,43 +0,0 @@ -//===-------- OrcCBindingsStack.cpp - Orc JIT stack for C bindings --------===// -// -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "OrcCBindingsStack.h" - -#include "llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/DynamicLibrary.h" -#include <cstdio> -#include <system_error> - -using namespace llvm; - -std::unique_ptr<OrcCBindingsStack::CompileCallbackMgr> -OrcCBindingsStack::createCompileCallbackMgr(Triple T) { -  switch (T.getArch()) { -    default: return nullptr; - -    case Triple::x86_64: { -      typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64> CCMgrT; -      return llvm::make_unique<CCMgrT>(0); -    } -  } -} - -OrcCBindingsStack::IndirectStubsManagerBuilder -OrcCBindingsStack::createIndirectStubsMgrBuilder(Triple T) { -  switch (T.getArch()) { -    default: return nullptr; - -    case Triple::x86_64: -      return [](){ -        return llvm::make_unique< -                 orc::LocalIndirectStubsManager<orc::OrcX86_64>>(); -      }; -  } -} diff --git a/lib/ExecutionEngine/Orc/OrcCBindingsStack.h b/lib/ExecutionEngine/Orc/OrcCBindingsStack.h index aae6a99432bc..9ae9b20feb0a 100644 --- a/lib/ExecutionEngine/Orc/OrcCBindingsStack.h +++ b/lib/ExecutionEngine/Orc/OrcCBindingsStack.h @@ -10,6 +10,7 @@  #ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H  #define LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H +#include "llvm-c/OrcBindings.h"  #include "llvm/ADT/Triple.h"  #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"  #include "llvm/ExecutionEngine/Orc/CompileUtils.h" @@ -17,7 +18,7 @@  #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"  #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"  #include "llvm/IR/LLVMContext.h" -#include "llvm-c/OrcBindings.h" +#include "llvm/Support/Error.h"  namespace llvm { @@ -28,19 +29,18 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)  class OrcCBindingsStack {  public: -    typedef orc::JITCompileCallbackManager CompileCallbackMgr;    typedef orc::ObjectLinkingLayer<> ObjLayerT;    typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT; -  typedef orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr> CODLayerT; +  typedef orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr> +      CODLayerT;    typedef std::function<std::unique_ptr<CompileCallbackMgr>()> -    CallbackManagerBuilder; +      CallbackManagerBuilder;    typedef CODLayerT::IndirectStubsManagerBuilderT IndirectStubsManagerBuilder;  private: -    class GenericHandle {    public:      virtual ~GenericHandle() {} @@ -49,20 +49,17 @@ private:      virtual void removeModule() = 0;    }; -  template <typename LayerT> -  class GenericHandleImpl : public GenericHandle { +  template <typename LayerT> class GenericHandleImpl : public GenericHandle {    public:      GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle) -      : Layer(Layer), Handle(std::move(Handle)) {} +        : Layer(Layer), Handle(std::move(Handle)) {}      orc::JITSymbol findSymbolIn(const std::string &Name,                                  bool ExportedSymbolsOnly) override {        return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);      } -    void removeModule() override { -      return Layer.removeModuleSet(Handle); -    } +    void removeModule() override { return Layer.removeModuleSet(Handle); }    private:      LayerT &Layer; @@ -77,26 +74,22 @@ private:    }  public: -    // We need a 'ModuleSetHandleT' to conform to the layer concept.    typedef unsigned ModuleSetHandleT;    typedef unsigned ModuleHandleT; -  static std::unique_ptr<CompileCallbackMgr> createCompileCallbackMgr(Triple T); -  static IndirectStubsManagerBuilder createIndirectStubsMgrBuilder(Triple T); -    OrcCBindingsStack(TargetMachine &TM, -		    std::unique_ptr<CompileCallbackMgr> CCMgr,  +                    std::unique_ptr<CompileCallbackMgr> CCMgr,                      IndirectStubsManagerBuilder IndirectStubsMgrBuilder) -    : DL(TM.createDataLayout()), CCMgr(std::move(CCMgr)), -      ObjectLayer(), -      CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)), -      CODLayer(CompileLayer, -               [](Function &F) { std::set<Function*> S; S.insert(&F); return S; }, -               *this->CCMgr, std::move(IndirectStubsMgrBuilder), false), -      IndirectStubsMgr(IndirectStubsMgrBuilder()), -      CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {} +      : DL(TM.createDataLayout()), IndirectStubsMgr(IndirectStubsMgrBuilder()), +        CCMgr(std::move(CCMgr)), ObjectLayer(), +        CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)), +        CODLayer(CompileLayer, +                 [](Function &F) { return std::set<Function *>({&F}); }, +                 *this->CCMgr, std::move(IndirectStubsMgrBuilder), false), +        CXXRuntimeOverrides( +            [this](const std::string &S) { return mangle(S); }) {}    ~OrcCBindingsStack() {      // Run any destructors registered with __cxa_atexit. @@ -124,55 +117,52 @@ public:    createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback,                              void *CallbackCtx) {      auto CCInfo = CCMgr->getCompileCallback(); -    CCInfo.setCompileAction( -      [=]() -> orc::TargetAddress { -        return Callback(wrap(this), CallbackCtx); -      }); +    CCInfo.setCompileAction([=]() -> orc::TargetAddress { +      return Callback(wrap(this), CallbackCtx); +    });      return CCInfo.getAddress();    } -  void createIndirectStub(StringRef StubName, orc::TargetAddress Addr) { -    IndirectStubsMgr->createStub(StubName, Addr, JITSymbolFlags::Exported); +  LLVMOrcErrorCode createIndirectStub(StringRef StubName, +                                      orc::TargetAddress Addr) { +    return mapError( +        IndirectStubsMgr->createStub(StubName, Addr, JITSymbolFlags::Exported));    } -  void setIndirectStubPointer(StringRef Name, orc::TargetAddress Addr) { -    IndirectStubsMgr->updatePointer(Name, Addr); +  LLVMOrcErrorCode setIndirectStubPointer(StringRef Name, +                                          orc::TargetAddress Addr) { +    return mapError(IndirectStubsMgr->updatePointer(Name, Addr));    } -  std::shared_ptr<RuntimeDyld::SymbolResolver> +  std::unique_ptr<RuntimeDyld::SymbolResolver>    createResolver(LLVMOrcSymbolResolverFn ExternalResolver,                   void *ExternalResolverCtx) { -    auto Resolver = orc::createLambdaResolver( -      [this, ExternalResolver, ExternalResolverCtx](const std::string &Name) { -        // Search order: -        // 1. JIT'd symbols. -        // 2. Runtime overrides. -        // 3. External resolver (if present). - -        if (auto Sym = CODLayer.findSymbol(Name, true)) -          return RuntimeDyld::SymbolInfo(Sym.getAddress(), -                                         Sym.getFlags()); -        if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name)) -          return Sym; - -        if (ExternalResolver) -          return RuntimeDyld::SymbolInfo(ExternalResolver(Name.c_str(), -                                                          ExternalResolverCtx), -                                         llvm::JITSymbolFlags::Exported); - -        return RuntimeDyld::SymbolInfo(nullptr); -      }, -      [](const std::string &Name) { -        return RuntimeDyld::SymbolInfo(nullptr); -      } -    ); - -    return std::shared_ptr<RuntimeDyld::SymbolResolver>(std::move(Resolver)); +    return orc::createLambdaResolver( +        [this, ExternalResolver, ExternalResolverCtx](const std::string &Name) { +          // Search order: +          // 1. JIT'd symbols. +          // 2. Runtime overrides. +          // 3. External resolver (if present). + +          if (auto Sym = CODLayer.findSymbol(Name, true)) +            return Sym.toRuntimeDyldSymbol(); +          if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name)) +            return Sym; + +          if (ExternalResolver) +            return RuntimeDyld::SymbolInfo( +                ExternalResolver(Name.c_str(), ExternalResolverCtx), +                llvm::JITSymbolFlags::Exported); + +          return RuntimeDyld::SymbolInfo(nullptr); +        }, +        [](const std::string &Name) { +          return RuntimeDyld::SymbolInfo(nullptr); +        });    }    template <typename LayerT> -  ModuleHandleT addIRModule(LayerT &Layer, -                            Module *M, +  ModuleHandleT addIRModule(LayerT &Layer, Module *M,                              std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,                              LLVMOrcSymbolResolverFn ExternalResolver,                              void *ExternalResolverCtx) { @@ -193,7 +183,7 @@ public:      auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);      // Add the module to the JIT. -    std::vector<Module*> S; +    std::vector<Module *> S;      S.push_back(std::move(M));      auto LH = Layer.addModuleSet(std::move(S), std::move(MemMgr), @@ -210,7 +200,7 @@ public:      return H;    } -  ModuleHandleT addIRModuleEager(Module* M, +  ModuleHandleT addIRModuleEager(Module *M,                                   LLVMOrcSymbolResolverFn ExternalResolver,                                   void *ExternalResolverCtx) {      return addIRModule(CompileLayer, std::move(M), @@ -218,11 +208,11 @@ public:                         std::move(ExternalResolver), ExternalResolverCtx);    } -  ModuleHandleT addIRModuleLazy(Module* M, +  ModuleHandleT addIRModuleLazy(Module *M,                                  LLVMOrcSymbolResolverFn ExternalResolver,                                  void *ExternalResolverCtx) {      return addIRModule(CODLayer, std::move(M), -		       llvm::make_unique<SectionMemoryManager>(), +                       llvm::make_unique<SectionMemoryManager>(),                         std::move(ExternalResolver), ExternalResolverCtx);    } @@ -243,8 +233,9 @@ public:      return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly);    } -private: +  const std::string &getErrorMessage() const { return ErrMsg; } +private:    template <typename LayerT>    unsigned createHandle(LayerT &Layer,                          typename LayerT::ModuleSetHandleT Handle) { @@ -261,21 +252,34 @@ private:      return NewHandle;    } +  LLVMOrcErrorCode mapError(Error Err) { +    LLVMOrcErrorCode Result = LLVMOrcErrSuccess; +    handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { +      // Handler of last resort. +      Result = LLVMOrcErrGeneric; +      ErrMsg = ""; +      raw_string_ostream ErrStream(ErrMsg); +      EIB.log(ErrStream); +    }); +    return Result; +  } +    DataLayout DL;    SectionMemoryManager CCMgrMemMgr; +  std::unique_ptr<orc::IndirectStubsManager> IndirectStubsMgr; +    std::unique_ptr<CompileCallbackMgr> CCMgr;    ObjLayerT ObjectLayer;    CompileLayerT CompileLayer;    CODLayerT CODLayer; -  std::unique_ptr<orc::IndirectStubsManager> IndirectStubsMgr; -    std::vector<std::unique_ptr<GenericHandle>> GenericHandles;    std::vector<unsigned> FreeHandleIndexes;    orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;    std::vector<orc::CtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners; +  std::string ErrMsg;  };  } // end namespace llvm diff --git a/lib/ExecutionEngine/Orc/OrcError.cpp b/lib/ExecutionEngine/Orc/OrcError.cpp index e95115ec6fed..22f1303f4330 100644 --- a/lib/ExecutionEngine/Orc/OrcError.cpp +++ b/lib/ExecutionEngine/Orc/OrcError.cpp @@ -20,6 +20,9 @@ using namespace llvm::orc;  namespace { +// FIXME: This class is only here to support the transition to llvm::Error. It +// will be removed once this transition is complete. Clients should prefer to +// 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"; } @@ -38,6 +41,8 @@ public:        return "Remote indirect stubs owner Id already in use";      case OrcErrorCode::UnexpectedRPCCall:        return "Unexpected RPC call"; +    case OrcErrorCode::UnexpectedRPCResponse: +      return "Unexpected RPC response";      }      llvm_unreachable("Unhandled error code");    } @@ -49,9 +54,10 @@ static ManagedStatic<OrcErrorCategory> OrcErrCat;  namespace llvm {  namespace orc { -std::error_code orcError(OrcErrorCode ErrCode) { +Error orcError(OrcErrorCode ErrCode) {    typedef std::underlying_type<OrcErrorCode>::type UT; -  return std::error_code(static_cast<UT>(ErrCode), *OrcErrCat); +  return errorCodeToError( +      std::error_code(static_cast<UT>(ErrCode), *OrcErrCat));  }  }  } diff --git a/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h b/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h index 2ab70a9fee86..d1083072c98b 100644 --- a/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h +++ b/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h @@ -121,7 +121,7 @@ class OrcMCJITReplacement : public ExecutionEngine {      RuntimeDyld::SymbolInfo      findSymbolInLogicalDylib(const std::string &Name) override { -      return M.ClientResolver->findSymbolInLogicalDylib(Name); +      return M.ClientResolver->findSymbol(Name);      }    private: @@ -178,11 +178,10 @@ public:    }    void addObjectFile(object::OwningBinary<object::ObjectFile> O) override { -    std::unique_ptr<object::ObjectFile> Obj; -    std::unique_ptr<MemoryBuffer> Buf; -    std::tie(Obj, Buf) = O.takeBinary(); -    std::vector<std::unique_ptr<object::ObjectFile>> Objs; -    Objs.push_back(std::move(Obj)); +    std::vector<std::unique_ptr<object::OwningBinary<object::ObjectFile>>> Objs; +    Objs.push_back( +      llvm::make_unique<object::OwningBinary<object::ObjectFile>>( +        std::move(O)));      ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);    } @@ -246,11 +245,11 @@ private:    RuntimeDyld::SymbolInfo findMangledSymbol(StringRef Name) {      if (auto Sym = LazyEmitLayer.findSymbol(Name, false)) -      return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags()); +      return Sym.toRuntimeDyldSymbol();      if (auto Sym = ClientResolver->findSymbol(Name)) -      return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags()); +      return Sym;      if (auto Sym = scanArchives(Name)) -      return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags()); +      return Sym.toRuntimeDyldSymbol();      return nullptr;    } @@ -259,15 +258,19 @@ private:      for (object::OwningBinary<object::Archive> &OB : Archives) {        object::Archive *A = OB.getBinary();        // Look for our symbols in each Archive -      object::Archive::child_iterator ChildIt = A->findSym(Name); -      if (std::error_code EC = ChildIt->getError()) -        report_fatal_error(EC.message()); -      if (ChildIt != A->child_end()) { +      auto OptionalChildOrErr = A->findSym(Name); +      if (!OptionalChildOrErr) +        report_fatal_error(OptionalChildOrErr.takeError()); +      auto &OptionalChild = *OptionalChildOrErr; +      if (OptionalChild) {          // FIXME: Support nested archives? -        ErrorOr<std::unique_ptr<object::Binary>> ChildBinOrErr = -            (*ChildIt)->getAsBinary(); -        if (ChildBinOrErr.getError()) +        Expected<std::unique_ptr<object::Binary>> ChildBinOrErr = +            OptionalChild->getAsBinary(); +        if (!ChildBinOrErr) { +          // TODO: Actually report errors helpfully. +          consumeError(ChildBinOrErr.takeError());            continue; +        }          std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();          if (ChildBin->isObject()) {            std::vector<std::unique_ptr<object::ObjectFile>> ObjSet; @@ -284,12 +287,12 @@ private:    class NotifyObjectLoadedT {    public: -    typedef std::vector<std::unique_ptr<object::ObjectFile>> ObjListT;      typedef std::vector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>          LoadedObjInfoListT;      NotifyObjectLoadedT(OrcMCJITReplacement &M) : M(M) {} +    template <typename ObjListT>      void operator()(ObjectLinkingLayerBase::ObjSetHandleT H,                      const ObjListT &Objects,                      const LoadedObjInfoListT &Infos) const { @@ -298,10 +301,21 @@ private:        assert(Objects.size() == Infos.size() &&               "Incorrect number of Infos for Objects.");        for (unsigned I = 0; I < Objects.size(); ++I) -        M.MemMgr.notifyObjectLoaded(&M, *Objects[I]); +        M.MemMgr.notifyObjectLoaded(&M, getObject(*Objects[I]));      }    private: + +    static const object::ObjectFile& getObject(const object::ObjectFile &Obj) { +      return Obj; +    } + +    template <typename ObjT> +    static const object::ObjectFile& +    getObject(const object::OwningBinary<ObjT> &Obj) { +      return *Obj.getBinary(); +    } +      OrcMCJITReplacement &M;    }; diff --git a/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp b/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp index 064633b4e490..d1a021aee3ab 100644 --- a/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp +++ b/lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp @@ -13,71 +13,41 @@ namespace llvm {  namespace orc {  namespace remote { -const char *OrcRemoteTargetRPCAPI::getJITProcIdName(JITProcId Id) { +#define FUNCNAME(X) \ +  case X ## Id: \ +  return #X + +const char *OrcRemoteTargetRPCAPI::getJITFuncIdName(JITFuncId Id) {    switch (Id) {    case InvalidId: -    return "*** Invalid JITProcId ***"; -  case CallIntVoidId: -    return "CallIntVoid"; -  case CallIntVoidResponseId: -    return "CallIntVoidResponse"; -  case CallMainId: -    return "CallMain"; -  case CallMainResponseId: -    return "CallMainResponse"; -  case CallVoidVoidId: -    return "CallVoidVoid"; -  case CallVoidVoidResponseId: -    return "CallVoidVoidResponse"; -  case CreateRemoteAllocatorId: -    return "CreateRemoteAllocator"; -  case CreateIndirectStubsOwnerId: -    return "CreateIndirectStubsOwner"; -  case DestroyRemoteAllocatorId: -    return "DestroyRemoteAllocator"; -  case DestroyIndirectStubsOwnerId: -    return "DestroyIndirectStubsOwner"; -  case EmitIndirectStubsId: -    return "EmitIndirectStubs"; -  case EmitIndirectStubsResponseId: -    return "EmitIndirectStubsResponse"; -  case EmitResolverBlockId: -    return "EmitResolverBlock"; -  case EmitTrampolineBlockId: -    return "EmitTrampolineBlock"; -  case EmitTrampolineBlockResponseId: -    return "EmitTrampolineBlockResponse"; -  case GetSymbolAddressId: -    return "GetSymbolAddress"; -  case GetSymbolAddressResponseId: -    return "GetSymbolAddressResponse"; -  case GetRemoteInfoId: -    return "GetRemoteInfo"; -  case GetRemoteInfoResponseId: -    return "GetRemoteInfoResponse"; -  case ReadMemId: -    return "ReadMem"; -  case ReadMemResponseId: -    return "ReadMemResponse"; -  case ReserveMemId: -    return "ReserveMem"; -  case ReserveMemResponseId: -    return "ReserveMemResponse"; -  case RequestCompileId: -    return "RequestCompile"; -  case RequestCompileResponseId: -    return "RequestCompileResponse"; -  case SetProtectionsId: -    return "SetProtections"; -  case TerminateSessionId: -    return "TerminateSession"; -  case WriteMemId: -    return "WriteMem"; -  case WritePtrId: -    return "WritePtr"; +    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/lib/ExecutionEngine/RuntimeDyld/Makefile b/lib/ExecutionEngine/RuntimeDyld/Makefile deleted file mode 100644 index 5d6f26d950fe..000000000000 --- a/lib/ExecutionEngine/RuntimeDyld/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -##===- lib/ExecutionEngine/MCJIT/Makefile ------------------*- Makefile -*-===## -# -#                     The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../../.. -LIBRARYNAME = LLVMRuntimeDyld - -include $(LEVEL)/Makefile.common diff --git a/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp b/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp index ecd99004bade..e39acc7ee144 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp @@ -94,9 +94,8 @@ static const char *processFDE(const char *Entry, bool isDeregister) {  // This implementation handles frame registration for local targets.  // Memory managers for remote targets should re-implement this function  // and use the LoadAddr parameter. -void RTDyldMemoryManager::registerEHFrames(uint8_t *Addr, -                                           uint64_t LoadAddr, -                                           size_t Size) { +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    const char *P = (const char *)Addr; @@ -106,9 +105,8 @@ void RTDyldMemoryManager::registerEHFrames(uint8_t *Addr,    } while(P != End);  } -void RTDyldMemoryManager::deregisterEHFrames(uint8_t *Addr, -                                           uint64_t LoadAddr, -                                           size_t Size) { +void RTDyldMemoryManager::deregisterEHFramesInProcess(uint8_t *Addr, +                                                      size_t Size) {    const char *P = (const char *)Addr;    const char *End = P + Size;    do  { @@ -118,9 +116,8 @@ void RTDyldMemoryManager::deregisterEHFrames(uint8_t *Addr,  #else -void RTDyldMemoryManager::registerEHFrames(uint8_t *Addr, -                                           uint64_t LoadAddr, -                                           size_t Size) { +void RTDyldMemoryManager::registerEHFramesInProcess(uint8_t *Addr, +                                                    size_t Size) {    // On Linux __register_frame takes a single argument:     // a pointer to the start of the .eh_frame section. @@ -129,9 +126,8 @@ void RTDyldMemoryManager::registerEHFrames(uint8_t *Addr,    __register_frame(Addr);  } -void RTDyldMemoryManager::deregisterEHFrames(uint8_t *Addr, -                                           uint64_t LoadAddr, -                                           size_t Size) { +void RTDyldMemoryManager::deregisterEHFramesInProcess(uint8_t *Addr, +                                                      size_t Size) {    __deregister_frame(Addr);  } @@ -266,18 +262,15 @@ RTDyldMemoryManager::getSymbolAddressInProcess(const std::string &Name) {    // is called before ExecutionEngine::runFunctionAsMain() is called.    if (Name == "__main") return (uint64_t)&jit_noop; -  // Try to demangle Name before looking it up in the process, otherwise symbol -  // '_<Name>' (if present) will shadow '<Name>', and there will be no way to -  // refer to the latter. -    const char *NameStr = Name.c_str(); +  // DynamicLibrary::SearchForAddresOfSymbol expects an unmangled 'C' symbol +  // name so ff we're on Darwin, strip the leading '_' off. +#ifdef __APPLE__    if (NameStr[0] == '_') -    if (void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr + 1)) -      return (uint64_t)Ptr; +    ++NameStr; +#endif -  // If we Name did not require demangling, or we failed to find the demangled -  // name, try again without demangling.    return (uint64_t)sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr);  } @@ -288,6 +281,7 @@ void *RTDyldMemoryManager::getPointerToNamedFunction(const std::string &Name,    if (!Addr && AbortOnFailure)      report_fatal_error("Program used external function '" + Name +                         "' which could not be resolved!"); +    return (void*)Addr;  } diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index d16b2db24e1a..1dfbe31f2717 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -19,6 +19,7 @@  #include "RuntimeDyldMachO.h"  #include "llvm/Object/ELFObjectFile.h"  #include "llvm/Object/COFF.h" +#include "llvm/Support/ManagedStatic.h"  #include "llvm/Support/MathExtras.h"  #include "llvm/Support/MutexGuard.h" @@ -27,6 +28,41 @@ using namespace llvm::object;  #define DEBUG_TYPE "dyld" +namespace { + +enum RuntimeDyldErrorCode { +  GenericRTDyldError = 1 +}; + +// FIXME: This class is only here to support the transition to llvm::Error. It +// will be removed once this transition is complete. Clients should prefer to +// 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"; } + +  std::string message(int Condition) const override { +    switch (static_cast<RuntimeDyldErrorCode>(Condition)) { +      case GenericRTDyldError: return "Generic RuntimeDyld error"; +    } +    llvm_unreachable("Unrecognized RuntimeDyldErrorCode"); +  } +}; + +static ManagedStatic<RuntimeDyldErrorCategory> RTDyldErrorCategory; + +} + +char RuntimeDyldError::ID = 0; + +void RuntimeDyldError::log(raw_ostream &OS) const { +  OS << ErrMsg << "\n"; +} + +std::error_code RuntimeDyldError::convertToErrorCode() const { +  return std::error_code(GenericRTDyldError, *RTDyldErrorCategory); +} +  // Empty out-of-line virtual destructor as the key function.  RuntimeDyldImpl::~RuntimeDyldImpl() {} @@ -125,16 +161,16 @@ void RuntimeDyldImpl::mapSectionAddress(const void *LocalAddress,    llvm_unreachable("Attempting to remap address of unknown section!");  } -static std::error_code getOffset(const SymbolRef &Sym, SectionRef Sec, -                                 uint64_t &Result) { -  ErrorOr<uint64_t> AddressOrErr = Sym.getAddress(); -  if (std::error_code EC = AddressOrErr.getError()) -    return EC; +static Error getOffset(const SymbolRef &Sym, SectionRef Sec, +                       uint64_t &Result) { +  Expected<uint64_t> AddressOrErr = Sym.getAddress(); +  if (!AddressOrErr) +    return AddressOrErr.takeError();    Result = *AddressOrErr - Sec.getAddress(); -  return std::error_code(); +  return Error::success();  } -RuntimeDyldImpl::ObjSectionToIDMap +Expected<RuntimeDyldImpl::ObjSectionToIDMap>  RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {    MutexGuard locked(lock); @@ -148,8 +184,11 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {    if (MemMgr.needsToReserveAllocationSpace()) {      uint64_t CodeSize = 0, RODataSize = 0, RWDataSize = 0;      uint32_t CodeAlign = 1, RODataAlign = 1, RWDataAlign = 1; -    computeTotalAllocSize(Obj, CodeSize, CodeAlign, RODataSize, RODataAlign, -                          RWDataSize, RWDataAlign); +    if (auto Err = computeTotalAllocSize(Obj, +                                         CodeSize, CodeAlign, +                                         RODataSize, RODataAlign, +                                         RWDataSize, RWDataAlign)) +      return std::move(Err);      MemMgr.reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign,                                    RWDataSize, RWDataAlign);    } @@ -169,13 +208,21 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {      if (Flags & SymbolRef::SF_Common)        CommonSymbols.push_back(*I);      else { -      object::SymbolRef::Type SymType = I->getType(); + +      // Get the symbol type. +      object::SymbolRef::Type SymType; +      if (auto SymTypeOrErr = I->getType()) +        SymType =  *SymTypeOrErr; +      else +        return SymTypeOrErr.takeError();        // Get symbol name. -      ErrorOr<StringRef> NameOrErr = I->getName(); -      Check(NameOrErr.getError()); -      StringRef Name = *NameOrErr; -   +      StringRef Name; +      if (auto NameOrErr = I->getName()) +        Name = *NameOrErr; +      else +        return NameOrErr.takeError(); +        // Compute JIT symbol flags.        JITSymbolFlags RTDyldSymFlags = JITSymbolFlags::None;        if (Flags & SymbolRef::SF_Weak) @@ -185,32 +232,46 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {        if (Flags & SymbolRef::SF_Absolute &&            SymType != object::SymbolRef::ST_File) { -        auto Addr = I->getAddress(); -        Check(Addr.getError()); -        uint64_t SectOffset = *Addr; +        uint64_t Addr = 0; +        if (auto AddrOrErr = I->getAddress()) +          Addr = *AddrOrErr; +        else +          return AddrOrErr.takeError(); +          unsigned SectionID = AbsoluteSymbolSection;          DEBUG(dbgs() << "\tType: " << SymType << " (absolute) Name: " << Name                       << " SID: " << SectionID << " Offset: " -                     << format("%p", (uintptr_t)SectOffset) +                     << format("%p", (uintptr_t)Addr)                       << " flags: " << Flags << "\n");          GlobalSymbolTable[Name] = -          SymbolTableEntry(SectionID, SectOffset, RTDyldSymFlags); +          SymbolTableEntry(SectionID, Addr, RTDyldSymFlags);        } else if (SymType == object::SymbolRef::ST_Function ||                   SymType == object::SymbolRef::ST_Data ||                   SymType == object::SymbolRef::ST_Unknown ||                   SymType == object::SymbolRef::ST_Other) { -        ErrorOr<section_iterator> SIOrErr = I->getSection(); -        Check(SIOrErr.getError()); -        section_iterator SI = *SIOrErr; +        section_iterator SI = Obj.section_end(); +        if (auto SIOrErr = I->getSection()) +          SI = *SIOrErr; +        else +          return SIOrErr.takeError(); +          if (SI == Obj.section_end())            continue; +          // Get symbol offset.          uint64_t SectOffset; -        Check(getOffset(*I, *SI, SectOffset)); +        if (auto Err = getOffset(*I, *SI, SectOffset)) +          return std::move(Err); +          bool IsCode = SI->isText(); -        unsigned SectionID = findOrEmitSection(Obj, *SI, IsCode, LocalSections); +        unsigned SectionID; +        if (auto SectionIDOrErr = findOrEmitSection(Obj, *SI, IsCode, +                                                    LocalSections)) +          SectionID = *SectionIDOrErr; +        else +          return SectionIDOrErr.takeError();          DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name                       << " SID: " << SectionID << " Offset: " @@ -223,13 +284,13 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {    }    // Allocate common symbols -  emitCommonSymbols(Obj, CommonSymbols); +  if (auto Err = emitCommonSymbols(Obj, CommonSymbols)) +    return std::move(Err);    // Parse and process relocations    DEBUG(dbgs() << "Parse relocations:\n");    for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();         SI != SE; ++SI) { -    unsigned SectionID = 0;      StubMap Stubs;      section_iterator RelocatedSection = SI->getRelocatedSection(); @@ -243,12 +304,20 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {        continue;      bool IsCode = RelocatedSection->isText(); -    SectionID = -        findOrEmitSection(Obj, *RelocatedSection, IsCode, LocalSections); +    unsigned SectionID = 0; +    if (auto SectionIDOrErr = findOrEmitSection(Obj, *RelocatedSection, IsCode, +                                                LocalSections)) +      SectionID = *SectionIDOrErr; +    else +      return SectionIDOrErr.takeError(); +      DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");      for (; I != E;) -      I = processRelocationRef(SectionID, I, Obj, LocalSections, Stubs); +      if (auto IOrErr = processRelocationRef(SectionID, I, Obj, LocalSections, Stubs)) +        I = *IOrErr; +      else +        return IOrErr.takeError();      // If there is an attached checker, notify it about the stubs for this      // section so that they can be verified. @@ -257,7 +326,8 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {    }    // Give the subclasses a chance to tie-up any loose ends. -  finalizeLoad(Obj, LocalSections); +  if (auto Err = finalizeLoad(Obj, LocalSections)) +    return std::move(Err);  //   for (auto E : LocalSections)  //     llvm::dbgs() << "Added: " << E.first.getRawDataRefImpl() << " -> " << E.second << "\n"; @@ -288,16 +358,17 @@ static bool isRequiredForExecution(const SectionRef Section) {      const coff_section *CoffSection = COFFObj->getCOFFSection(Section);      // Avoid loading zero-sized COFF sections.      // In PE files, VirtualSize gives the section size, and SizeOfRawData -    // may be zero for sections with content. In Obj files, SizeOfRawData  +    // may be zero for sections with content. In Obj files, SizeOfRawData      // gives the section size, and VirtualSize is always zero. Hence      // the need to check for both cases below. -    bool HasContent = (CoffSection->VirtualSize > 0)  -      || (CoffSection->SizeOfRawData > 0); -    bool IsDiscardable = CoffSection->Characteristics & -      (COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_LNK_INFO); +    bool HasContent = +        (CoffSection->VirtualSize > 0) || (CoffSection->SizeOfRawData > 0); +    bool IsDiscardable = +        CoffSection->Characteristics & +        (COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_LNK_INFO);      return HasContent && !IsDiscardable;    } -   +    assert(isa<MachOObjectFile>(Obj));    return true;  } @@ -336,13 +407,13 @@ static bool isZeroInit(const SectionRef Section) {  // Compute an upper bound of the memory size that is required to load all  // sections -void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj, -                                            uint64_t &CodeSize, -                                            uint32_t &CodeAlign, -                                            uint64_t &RODataSize, -                                            uint32_t &RODataAlign, -                                            uint64_t &RWDataSize, -                                            uint32_t &RWDataAlign) { +Error RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj, +                                             uint64_t &CodeSize, +                                             uint32_t &CodeAlign, +                                             uint64_t &RODataSize, +                                             uint32_t &RODataAlign, +                                             uint64_t &RWDataSize, +                                             uint32_t &RWDataAlign) {    // Compute the size of all sections required for execution    std::vector<uint64_t> CodeSectionSizes;    std::vector<uint64_t> ROSectionSizes; @@ -358,13 +429,15 @@ void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,      // Consider only the sections that are required to be loaded for execution      if (IsRequired) { -      StringRef Name;        uint64_t DataSize = Section.getSize();        uint64_t Alignment64 = Section.getAlignment(); +      unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;        bool IsCode = Section.isText();        bool IsReadOnly = isReadOnlyData(Section); -      Check(Section.getName(Name)); -      unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL; + +      StringRef Name; +      if (auto EC = Section.getName(Name)) +        return errorCodeToError(EC);        uint64_t StubBufSize = computeSectionStubBufSize(Obj, Section);        uint64_t SectionSize = DataSize + StubBufSize; @@ -395,17 +468,24 @@ void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,    // Compute the size of all common symbols    uint64_t CommonSize = 0; +  uint32_t CommonAlign = 1;    for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E;         ++I) {      uint32_t Flags = I->getFlags();      if (Flags & SymbolRef::SF_Common) {        // Add the common symbols to a list.  We'll allocate them all below.        uint64_t Size = I->getCommonSize(); -      CommonSize += Size; +      uint32_t Align = I->getAlignment(); +      // If this is the first common symbol, use its alignment as the alignment +      // for the common symbols section. +      if (CommonSize == 0) +        CommonAlign = Align; +      CommonSize = alignTo(CommonSize, Align) + Size;      }    }    if (CommonSize != 0) {      RWSectionSizes.push_back(CommonSize); +    RWDataAlign = std::max(RWDataAlign, CommonAlign);    }    // Compute the required allocation space for each different type of sections @@ -416,6 +496,8 @@ void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,    CodeSize = computeAllocationSizeForSections(CodeSectionSizes, CodeAlign);    RODataSize = computeAllocationSizeForSections(ROSectionSizes, RODataAlign);    RWDataSize = computeAllocationSizeForSections(RWSectionSizes, RWDataAlign); + +  return Error::success();  }  // compute stub buffer size for the given section @@ -483,20 +565,23 @@ void RuntimeDyldImpl::writeBytesUnaligned(uint64_t Value, uint8_t *Dst,    }  } -void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj, -                                        CommonSymbolList &CommonSymbols) { +Error RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj, +                                         CommonSymbolList &CommonSymbols) {    if (CommonSymbols.empty()) -    return; +    return Error::success();    uint64_t CommonSize = 0; +  uint32_t CommonAlign = CommonSymbols.begin()->getAlignment();    CommonSymbolList SymbolsToAllocate;    DEBUG(dbgs() << "Processing common symbols...\n");    for (const auto &Sym : CommonSymbols) { -    ErrorOr<StringRef> NameOrErr = Sym.getName(); -    Check(NameOrErr.getError()); -    StringRef Name = *NameOrErr; +    StringRef Name; +    if (auto NameOrErr = Sym.getName()) +      Name = *NameOrErr; +    else +      return NameOrErr.takeError();      // Skip common symbols already elsewhere.      if (GlobalSymbolTable.count(Name) || @@ -509,14 +594,15 @@ void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,      uint32_t Align = Sym.getAlignment();      uint64_t Size = Sym.getCommonSize(); -    CommonSize += Align + Size; +    CommonSize = alignTo(CommonSize, Align) + Size; +      SymbolsToAllocate.push_back(Sym);    }    // Allocate memory for the section    unsigned SectionID = Sections.size(); -  uint8_t *Addr = MemMgr.allocateDataSection(CommonSize, sizeof(void *), -                                             SectionID, StringRef(), false); +  uint8_t *Addr = MemMgr.allocateDataSection(CommonSize, CommonAlign, SectionID, +                                             "<common symbols>", false);    if (!Addr)      report_fatal_error("Unable to allocate memory for common symbols!");    uint64_t Offset = 0; @@ -531,9 +617,11 @@ void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,    for (auto &Sym : SymbolsToAllocate) {      uint32_t Align = Sym.getAlignment();      uint64_t Size = Sym.getCommonSize(); -    ErrorOr<StringRef> NameOrErr = Sym.getName(); -    Check(NameOrErr.getError()); -    StringRef Name = *NameOrErr; +    StringRef Name; +    if (auto NameOrErr = Sym.getName()) +      Name = *NameOrErr; +    else +      return NameOrErr.takeError();      if (Align) {        // This symbol has an alignment requirement.        uint64_t AlignOffset = OffsetToAlignment((uint64_t)Addr, Align); @@ -556,24 +644,29 @@ void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,    if (Checker)      Checker->registerSection(Obj.getFileName(), SectionID); -} -unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj, -                                      const SectionRef &Section, bool IsCode) { +  return Error::success(); +} +Expected<unsigned> +RuntimeDyldImpl::emitSection(const ObjectFile &Obj, +                             const SectionRef &Section, +                             bool IsCode) {    StringRef data;    uint64_t Alignment64 = Section.getAlignment();    unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;    unsigned PaddingSize = 0;    unsigned StubBufSize = 0; -  StringRef Name;    bool IsRequired = isRequiredForExecution(Section);    bool IsVirtual = Section.isVirtual();    bool IsZeroInit = isZeroInit(Section);    bool IsReadOnly = isReadOnlyData(Section);    uint64_t DataSize = Section.getSize(); -  Check(Section.getName(Name)); + +  StringRef Name; +  if (auto EC = Section.getName(Name)) +    return errorCodeToError(EC);    StubBufSize = computeSectionStubBufSize(Obj, Section); @@ -593,7 +686,8 @@ unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj,    if (!IsVirtual && !IsZeroInit) {      // In either case, set the location of the unrelocated section in memory,      // since we still process relocations for it even if we're not applying them. -    Check(Section.getContents(data)); +    if (auto EC = Section.getContents(data)) +      return errorCodeToError(EC);      pData = data.data();    } @@ -655,17 +749,21 @@ unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj,    return SectionID;  } -unsigned RuntimeDyldImpl::findOrEmitSection(const ObjectFile &Obj, -                                            const SectionRef &Section, -                                            bool IsCode, -                                            ObjSectionToIDMap &LocalSections) { +Expected<unsigned> +RuntimeDyldImpl::findOrEmitSection(const ObjectFile &Obj, +                                   const SectionRef &Section, +                                   bool IsCode, +                                   ObjSectionToIDMap &LocalSections) {    unsigned SectionID = 0;    ObjSectionToIDMap::iterator i = LocalSections.find(Section);    if (i != LocalSections.end())      SectionID = i->second;    else { -    SectionID = emitSection(Obj, Section, IsCode); +    if (auto SectionIDOrErr = emitSection(Obj, Section, IsCode)) +      SectionID = *SectionIDOrErr; +    else +      return SectionIDOrErr.takeError();      LocalSections[Section] = SectionID;    }    return SectionID; @@ -718,7 +816,10 @@ uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr,      // 8:   03200008        jr      t9.      // c:   00000000        nop.      const unsigned LuiT9Instr = 0x3c190000, AdduiT9Instr = 0x27390000; -    const unsigned JrT9Instr = 0x03200008, NopInstr = 0x0; +    const unsigned NopInstr = 0x0; +    unsigned JrT9Instr = 0x03200008; +    if ((AbiVariant & ELF::EF_MIPS_ARCH) == ELF::EF_MIPS_ARCH_32R6) +        JrT9Instr = 0x03200009;      writeBytesUnaligned(LuiT9Instr, Addr, 4);      writeBytesUnaligned(AdduiT9Instr, Addr+4, 4); @@ -818,7 +919,11 @@ void RuntimeDyldImpl::resolveExternalSymbols() {        if (Loc == GlobalSymbolTable.end()) {          // This is an external symbol, try to get its address from the symbol          // resolver. -        Addr = Resolver.findSymbol(Name.data()).getAddress(); +        // First search for the symbol in this logical dylib. +        Addr = Resolver.findSymbolInLogicalDylib(Name.data()).getAddress(); +        // If that fails, try searching for an external symbol. +        if (!Addr) +          Addr = Resolver.findSymbol(Name.data()).getAddress();          // The call to getSymbolAddress may have caused additional modules to          // be loaded, which may have added new entries to the          // ExternalSymbolRelocations map.  Consquently, we need to update our diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp index e5fab929ea29..24bd9a002c20 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp @@ -13,6 +13,7 @@  #include "RuntimeDyldCOFF.h"  #include "Targets/RuntimeDyldCOFFI386.h" +#include "Targets/RuntimeDyldCOFFThumb.h"  #include "Targets/RuntimeDyldCOFFX86_64.h"  #include "llvm/ADT/STLExtras.h"  #include "llvm/ADT/Triple.h" @@ -45,11 +46,11 @@ llvm::RuntimeDyldCOFF::create(Triple::ArchType Arch,                                RuntimeDyld::MemoryManager &MemMgr,                                RuntimeDyld::SymbolResolver &Resolver) {    switch (Arch) { -  default: -    llvm_unreachable("Unsupported target for RuntimeDyldCOFF."); -    break; +  default: llvm_unreachable("Unsupported target for RuntimeDyldCOFF.");    case Triple::x86:      return make_unique<RuntimeDyldCOFFI386>(MemMgr, Resolver); +  case Triple::thumb: +    return make_unique<RuntimeDyldCOFFThumb>(MemMgr, Resolver);    case Triple::x86_64:      return make_unique<RuntimeDyldCOFFX86_64>(MemMgr, Resolver);    } @@ -57,7 +58,14 @@ llvm::RuntimeDyldCOFF::create(Triple::ArchType Arch,  std::unique_ptr<RuntimeDyld::LoadedObjectInfo>  RuntimeDyldCOFF::loadObject(const object::ObjectFile &O) { -  return llvm::make_unique<LoadedCOFFObjectInfo>(*this, loadObjectImpl(O)); +  if (auto ObjSectionToIDOrErr = loadObjectImpl(O)) { +    return llvm::make_unique<LoadedCOFFObjectInfo>(*this, *ObjSectionToIDOrErr); +  } else { +    HasError = true; +    raw_string_ostream ErrStream(ErrorStr); +    logAllUnhandledErrors(ObjSectionToIDOrErr.takeError(), ErrStream, ""); +    return nullptr; +  }  }  uint64_t RuntimeDyldCOFF::getSymbolOffset(const SymbolRef &Sym) { diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h index 32b8fa269be0..03a91f6cf690 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h @@ -15,7 +15,6 @@  #define LLVM_RUNTIME_DYLD_COFF_H  #include "RuntimeDyldImpl.h" -#include "llvm/ADT/DenseMap.h"  #define DEBUG_TYPE "dyld" diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp index 58ce88a68f23..090b9a3857e3 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp @@ -7,16 +7,17 @@  //  //===----------------------------------------------------------------------===// -#include "llvm/ADT/STLExtras.h" +#include "llvm/ExecutionEngine/RuntimeDyldChecker.h"  #include "RuntimeDyldCheckerImpl.h"  #include "RuntimeDyldImpl.h" -#include "llvm/ExecutionEngine/RuntimeDyldChecker.h" +#include "llvm/ADT/STLExtras.h"  #include "llvm/MC/MCContext.h" -#include "llvm/MC/MCDisassembler.h" +#include "llvm/MC/MCDisassembler/MCDisassembler.h"  #include "llvm/MC/MCInst.h"  #include "llvm/Support/Path.h"  #include <cctype>  #include <memory> +#include <utility>  #define DEBUG_TYPE "rtdyld" @@ -97,7 +98,8 @@ private:    public:      EvalResult() : Value(0), ErrorMsg("") {}      EvalResult(uint64_t Value) : Value(Value), ErrorMsg("") {} -    EvalResult(std::string ErrorMsg) : Value(0), ErrorMsg(ErrorMsg) {} +    EvalResult(std::string ErrorMsg) +        : Value(0), ErrorMsg(std::move(ErrorMsg)) {}      uint64_t getValue() const { return Value; }      bool hasError() const { return ErrorMsg != ""; }      const std::string &getErrorMsg() const { return ErrorMsg; } @@ -582,7 +584,7 @@ private:    // Returns a pair containing the result of the slice operation, plus the    // expression remaining to be parsed.    std::pair<EvalResult, StringRef> -  evalSliceExpr(std::pair<EvalResult, StringRef> Ctx) const { +  evalSliceExpr(const std::pair<EvalResult, StringRef> &Ctx) const {      EvalResult SubExprResult;      StringRef RemainingExpr;      std::tie(SubExprResult, RemainingExpr) = Ctx; @@ -626,7 +628,7 @@ private:    // Returns a pair containing the ultimate result of evaluating the    // expression, plus the expression remaining to be evaluated.    std::pair<EvalResult, StringRef> -  evalComplexExpr(std::pair<EvalResult, StringRef> LHSAndRemaining, +  evalComplexExpr(const std::pair<EvalResult, StringRef> &LHSAndRemaining,                    ParseContext PCtx) const {      EvalResult LHSResult;      StringRef RemainingExpr; diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h index 69d2a7d6b668..b7263be09934 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h @@ -11,7 +11,6 @@  #define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDCHECKERIMPL_H  #include "RuntimeDyldImpl.h" -#include <set>  namespace llvm { diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index e09b71af18a5..9cbdb13a3572 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -30,13 +30,6 @@ using namespace llvm::object;  #define DEBUG_TYPE "dyld" -static inline std::error_code check(std::error_code Err) { -  if (Err) { -    report_fatal_error(Err.message()); -  } -  return Err; -} -  namespace {  template <class ELFT> class DyldELFObject : public ELFObjectFile<ELFT> { @@ -220,7 +213,14 @@ void RuntimeDyldELF::deregisterEHFrames() {  std::unique_ptr<RuntimeDyld::LoadedObjectInfo>  RuntimeDyldELF::loadObject(const object::ObjectFile &O) { -  return llvm::make_unique<LoadedELFObjectInfo>(*this, loadObjectImpl(O)); +  if (auto ObjSectionToIDOrErr = loadObjectImpl(O)) +    return llvm::make_unique<LoadedELFObjectInfo>(*this, *ObjSectionToIDOrErr); +  else { +    HasError = true; +    raw_string_ostream ErrStream(ErrorStr); +    logAllUnhandledErrors(ObjSectionToIDOrErr.takeError(), ErrStream, ""); +    return nullptr; +  }  }  void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section, @@ -781,9 +781,9 @@ void RuntimeDyldELF::applyMIPS64Relocation(uint8_t *TargetPtr,  }  // Return the .TOC. section and offset. -void RuntimeDyldELF::findPPC64TOCSection(const ELFObjectFileBase &Obj, -                                         ObjSectionToIDMap &LocalSections, -                                         RelocationValueRef &Rel) { +Error RuntimeDyldELF::findPPC64TOCSection(const ELFObjectFileBase &Obj, +                                          ObjSectionToIDMap &LocalSections, +                                          RelocationValueRef &Rel) {    // Set a default SectionID in case we do not find a TOC section below.    // This may happen for references to TOC base base (sym@toc, .odp    // relocation) without a .toc directive.  In this case just use the @@ -796,13 +796,18 @@ void RuntimeDyldELF::findPPC64TOCSection(const ELFObjectFileBase &Obj,    // order. The TOC starts where the first of these sections starts.    for (auto &Section: Obj.sections()) {      StringRef SectionName; -    check(Section.getName(SectionName)); +    if (auto EC = Section.getName(SectionName)) +      return errorCodeToError(EC);      if (SectionName == ".got"          || SectionName == ".toc"          || SectionName == ".tocbss"          || SectionName == ".plt") { -      Rel.SectionID = findOrEmitSection(Obj, Section, false, LocalSections); +      if (auto SectionIDOrErr = +            findOrEmitSection(Obj, Section, false, LocalSections)) +        Rel.SectionID = *SectionIDOrErr; +      else +        return SectionIDOrErr.takeError();        break;      }    } @@ -810,13 +815,15 @@ void RuntimeDyldELF::findPPC64TOCSection(const ELFObjectFileBase &Obj,    // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000    // thus permitting a full 64 Kbytes segment.    Rel.Addend = 0x8000; + +  return Error::success();  }  // Returns the sections and offset associated with the ODP entry referenced  // by Symbol. -void RuntimeDyldELF::findOPDEntrySection(const ELFObjectFileBase &Obj, -                                         ObjSectionToIDMap &LocalSections, -                                         RelocationValueRef &Rel) { +Error RuntimeDyldELF::findOPDEntrySection(const ELFObjectFileBase &Obj, +                                          ObjSectionToIDMap &LocalSections, +                                          RelocationValueRef &Rel) {    // Get the ELF symbol value (st_value) to compare with Relocation offset in    // .opd entries    for (section_iterator si = Obj.section_begin(), se = Obj.section_end(); @@ -826,7 +833,9 @@ void RuntimeDyldELF::findOPDEntrySection(const ELFObjectFileBase &Obj,        continue;      StringRef RelSectionName; -    check(RelSecI->getName(RelSectionName)); +    if (auto EC = RelSecI->getName(RelSectionName)) +      return errorCodeToError(EC); +      if (RelSectionName != ".opd")        continue; @@ -843,9 +852,11 @@ void RuntimeDyldELF::findOPDEntrySection(const ELFObjectFileBase &Obj,        uint64_t TargetSymbolOffset = i->getOffset();        symbol_iterator TargetSymbol = i->getSymbol(); -      ErrorOr<int64_t> AddendOrErr = i->getAddend(); -      Check(AddendOrErr.getError()); -      int64_t Addend = *AddendOrErr; +      int64_t Addend; +      if (auto AddendOrErr = i->getAddend()) +        Addend = *AddendOrErr; +      else +        return errorCodeToError(AddendOrErr.getError());        ++i;        if (i == e) @@ -862,13 +873,21 @@ void RuntimeDyldELF::findOPDEntrySection(const ELFObjectFileBase &Obj,        if (Rel.Addend != (int64_t)TargetSymbolOffset)          continue; -      ErrorOr<section_iterator> TSIOrErr = TargetSymbol->getSection(); -      check(TSIOrErr.getError()); -      section_iterator tsi = *TSIOrErr; -      bool IsCode = tsi->isText(); -      Rel.SectionID = findOrEmitSection(Obj, (*tsi), IsCode, LocalSections); +      section_iterator TSI = Obj.section_end(); +      if (auto TSIOrErr = TargetSymbol->getSection()) +        TSI = *TSIOrErr; +      else +        return TSIOrErr.takeError(); +      assert(TSI != Obj.section_end() && "TSI should refer to a valid section"); + +      bool IsCode = TSI->isText(); +      if (auto SectionIDOrErr = findOrEmitSection(Obj, *TSI, IsCode, +                                                  LocalSections)) +        Rel.SectionID = *SectionIDOrErr; +      else +        return SectionIDOrErr.takeError();        Rel.Addend = (intptr_t)Addend; -      return; +      return Error::success();      }    }    llvm_unreachable("Attempting to get address of ODP entry!"); @@ -1047,6 +1066,11 @@ void RuntimeDyldELF::resolveSystemZRelocation(const SectionEntry &Section,    case ELF::R_390_64:      writeInt64BE(LocalAddress, Value + Addend);      break; +  case ELF::R_390_PC64: { +    int64_t Delta = (Value + Addend) - Section.getLoadAddressWithOffset(Offset); +    writeInt64BE(LocalAddress, Delta); +    break; +  }    }  } @@ -1163,7 +1187,8 @@ uint32_t RuntimeDyldELF::getMatchingLoRelocation(uint32_t RelType,    return ELF::R_MIPS_NONE;  } -relocation_iterator RuntimeDyldELF::processRelocationRef( +Expected<relocation_iterator> +RuntimeDyldELF::processRelocationRef(      unsigned SectionID, relocation_iterator RelI, const ObjectFile &O,      ObjSectionToIDMap &ObjSectionToID, StubMap &Stubs) {    const auto &Obj = cast<ELFObjectFileBase>(O); @@ -1175,10 +1200,10 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(    // Obtain the symbol name which is referenced in the relocation    StringRef TargetName;    if (Symbol != Obj.symbol_end()) { -    ErrorOr<StringRef> TargetNameOrErr = Symbol->getName(); -    if (std::error_code EC = TargetNameOrErr.getError()) -      report_fatal_error(EC.message()); -    TargetName = *TargetNameOrErr; +    if (auto TargetNameOrErr = Symbol->getName()) +      TargetName = *TargetNameOrErr; +    else +      return TargetNameOrErr.takeError();    }    DEBUG(dbgs() << "\t\tRelType: " << RelType << " Addend: " << Addend                 << " TargetName: " << TargetName << "\n"); @@ -1190,7 +1215,15 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(    RTDyldSymbolTable::const_iterator gsi = GlobalSymbolTable.end();    if (Symbol != Obj.symbol_end()) {      gsi = GlobalSymbolTable.find(TargetName.data()); -    SymType = Symbol->getType(); +    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); +    } +    SymType = *SymTypeOrErr;    }    if (gsi != GlobalSymbolTable.end()) {      const auto &SymInfo = gsi->second; @@ -1203,12 +1236,24 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(        // TODO: Now ELF SymbolRef::ST_Debug = STT_SECTION, it's not obviously        // and can be changed by another developers. Maybe best way is add        // a new symbol type ST_Section to SymbolRef and use it. -      section_iterator si = *Symbol->getSection(); +      auto SectionOrErr = Symbol->getSection(); +      if (!SectionOrErr) { +        std::string Buf; +        raw_string_ostream OS(Buf); +        logAllUnhandledErrors(SectionOrErr.takeError(), OS, ""); +        OS.flush(); +        report_fatal_error(Buf); +      } +      section_iterator si = *SectionOrErr;        if (si == Obj.section_end())          llvm_unreachable("Symbol section not found, bad object file format!");        DEBUG(dbgs() << "\t\tThis is section symbol\n");        bool isCode = si->isText(); -      Value.SectionID = findOrEmitSection(Obj, (*si), isCode, ObjSectionToID); +      if (auto SectionIDOrErr = findOrEmitSection(Obj, (*si), isCode, +                                                  ObjSectionToID)) +        Value.SectionID = *SectionIDOrErr; +      else +        return SectionIDOrErr.takeError();        Value.Addend = Addend;        break;      } @@ -1289,7 +1334,7 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(      if (RelType == ELF::R_ARM_PC24 || RelType == ELF::R_ARM_CALL ||        RelType == ELF::R_ARM_JUMP24) {        // This is an ARM branch relocation, need to use a stub function. -      DEBUG(dbgs() << "\t\tThis is an ARM branch relocation."); +      DEBUG(dbgs() << "\t\tThis is an ARM branch relocation.\n");        SectionEntry &Section = Sections[SectionID];        // Look for an existing stub. @@ -1357,8 +1402,12 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(          // Create a new stub function.          DEBUG(dbgs() << " Create a new stub function\n");          Stubs[Value] = Section.getStubOffset(); + +        unsigned AbiVariant; +        O.getPlatformFlags(AbiVariant); +          uint8_t *StubTargetAddr = createStubFunction( -            Section.getAddressWithOffset(Section.getStubOffset())); +            Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);          // Creating Hi and Lo relocations for the filled stub instructions.          RelocationEntry REHi(SectionID, StubTargetAddr - Section.getAddress(), @@ -1453,7 +1502,8 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(            // In the ELFv1 ABI, a function call may point to the .opd entry,            // so the final symbol value is calculated based on the relocation            // values in the .opd section. -          findOPDEntrySection(Obj, ObjSectionToID, Value); +          if (auto Err = findOPDEntrySection(Obj, ObjSectionToID, Value)) +            return std::move(Err);          } else {            // In the ELFv2 ABI, a function symbol may provide a local entry            // point, which must be used for direct calls. @@ -1565,7 +1615,8 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(        }        RelocationValueRef TOCValue; -      findPPC64TOCSection(Obj, ObjSectionToID, TOCValue); +      if (auto Err = findPPC64TOCSection(Obj, ObjSectionToID, TOCValue)) +        return std::move(Err);        if (Value.SymbolName || Value.SectionID != TOCValue.SectionID)          llvm_unreachable("Unsupported TOC relocation.");        Value.Addend -= TOCValue.Addend; @@ -1577,9 +1628,11 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(        // symbols (in which case the addend is respected).        if (RelType == ELF::R_PPC64_TOC) {          RelType = ELF::R_PPC64_ADDR64; -        findPPC64TOCSection(Obj, ObjSectionToID, Value); +        if (auto Err = findPPC64TOCSection(Obj, ObjSectionToID, Value)) +          return std::move(Err);        } else if (TargetName == ".TOC.") { -        findPPC64TOCSection(Obj, ObjSectionToID, Value); +        if (auto Err = findPPC64TOCSection(Obj, ObjSectionToID, Value)) +          return std::move(Err);          Value.Addend += Addend;        } @@ -1700,7 +1753,9 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(                    Value.Offset);          addRelocationForSection(RE, Value.SectionID);        } -    } else if (RelType == ELF::R_X86_64_GOTPCREL) { +    } else if (RelType == ELF::R_X86_64_GOTPCREL || +               RelType == ELF::R_X86_64_GOTPCRELX || +               RelType == ELF::R_X86_64_REX_GOTPCRELX) {        uint64_t GOTOffset = allocateGOTEntries(SectionID, 1);        resolveGOTOffsetRelocation(SectionID, Offset, GOTOffset + Addend); @@ -1791,11 +1846,11 @@ RelocationEntry RuntimeDyldELF::computeGOTOffsetRE(unsigned SectionID, uint64_t    return RelocationEntry(GOTSectionID, GOTOffset, Type, SymbolOffset);  } -void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj, +Error RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,                                    ObjSectionToIDMap &SectionMap) {    if (IsMipsO32ABI)      if (!PendingRelocs.empty()) -      report_fatal_error("Can't find matching LO16 reloc"); +      return make_error<RuntimeDyldError>("Can't find matching LO16 reloc");    // If necessary, allocate the global offset table    if (GOTSectionID != 0) { @@ -1804,7 +1859,7 @@ void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,      uint8_t *Addr = MemMgr.allocateDataSection(TotalSize, getGOTEntrySize(),                                                  GOTSectionID, ".got", false);      if (!Addr) -      report_fatal_error("Unable to allocate memory for GOT!"); +      return make_error<RuntimeDyldError>("Unable to allocate memory for GOT!");      Sections[GOTSectionID] =          SectionEntry(".got", Addr, TotalSize, TotalSize, 0); @@ -1845,6 +1900,8 @@ void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,    GOTSectionID = 0;    CurrentGOTIndex = 0; + +  return Error::success();  }  bool RuntimeDyldELF::isCompatibleFile(const object::ObjectFile &Obj) const { @@ -1861,6 +1918,8 @@ bool RuntimeDyldELF::relocationNeedsStub(const RelocationRef &R) const {    case ELF::R_X86_64_GOTPCREL: +  case ELF::R_X86_64_GOTPCRELX: +  case ELF::R_X86_64_REX_GOTPCRELX:    case ELF::R_X86_64_PC32:    case ELF::R_X86_64_PC64:    case ELF::R_X86_64_64: diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h index 041811d3e285..82931b9f45a6 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -20,6 +20,9 @@  using namespace llvm;  namespace llvm { +namespace object { +class ELFObjectFileBase; +}  class RuntimeDyldELF : public RuntimeDyldImpl { @@ -90,12 +93,12 @@ class RuntimeDyldELF : public RuntimeDyldImpl {    void setMipsABI(const ObjectFile &Obj) override; -  void findPPC64TOCSection(const ELFObjectFileBase &Obj, -                           ObjSectionToIDMap &LocalSections, -                           RelocationValueRef &Rel); -  void findOPDEntrySection(const ELFObjectFileBase &Obj, -                           ObjSectionToIDMap &LocalSections, -                           RelocationValueRef &Rel); +  Error findPPC64TOCSection(const ELFObjectFileBase &Obj, +                            ObjSectionToIDMap &LocalSections, +                            RelocationValueRef &Rel); +  Error findOPDEntrySection(const ELFObjectFileBase &Obj, +                            ObjSectionToIDMap &LocalSections, +                            RelocationValueRef &Rel);    size_t getGOTEntrySize(); @@ -163,7 +166,7 @@ public:    loadObject(const object::ObjectFile &O) override;    void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override; -  relocation_iterator +  Expected<relocation_iterator>    processRelocationRef(unsigned SectionID, relocation_iterator RelI,                         const ObjectFile &Obj,                         ObjSectionToIDMap &ObjSectionToID, @@ -171,8 +174,8 @@ public:    bool isCompatibleFile(const object::ObjectFile &Obj) const override;    void registerEHFrames() override;    void deregisterEHFrames() override; -  void finalizeLoad(const ObjectFile &Obj, -                    ObjSectionToIDMap &SectionMap) override; +  Error finalizeLoad(const ObjectFile &Obj, +                     ObjSectionToIDMap &SectionMap) override;  };  } // end namespace llvm diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index ab732c69ee2f..76bd3fc295b8 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -14,7 +14,6 @@  #ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDIMPL_H  #define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDIMPL_H -#include "llvm/ADT/DenseMap.h"  #include "llvm/ADT/SmallVector.h"  #include "llvm/ADT/StringMap.h"  #include "llvm/ADT/Triple.h" @@ -28,7 +27,6 @@  #include "llvm/Support/Host.h"  #include "llvm/Support/Mutex.h"  #include "llvm/Support/SwapByteOrder.h" -#include "llvm/Support/raw_ostream.h"  #include <map>  #include <unordered_map>  #include <system_error> @@ -38,16 +36,12 @@ using namespace llvm::object;  namespace llvm { -  // Helper for extensive error checking in debug builds. -inline std::error_code Check(std::error_code Err) { -  if (Err) { -    report_fatal_error(Err.message()); -  } -  return Err; -} -  class Twine; +#define UNIMPLEMENTED_RELOC(RelType) \ +  case RelType: \ +    return make_error<RuntimeDyldError>("Unimplemented relocation: " #RelType) +  /// SectionEntry - represents a section emitted into memory by the dynamic  /// linker.  class SectionEntry { @@ -302,13 +296,6 @@ protected:    bool HasError;    std::string ErrorStr; -  // Set the error state and record an error string. -  bool Error(const Twine &Msg) { -    ErrorStr = Msg.str(); -    HasError = true; -    return true; -  } -    uint64_t getSectionLoadAddress(unsigned SectionID) const {      return Sections[SectionID].getLoadAddress();    } @@ -361,22 +348,25 @@ protected:    /// \brief Given the common symbols discovered in the object file, emit a    /// new section for them and update the symbol mappings in the object and    /// symbol table. -  void emitCommonSymbols(const ObjectFile &Obj, CommonSymbolList &CommonSymbols); +  Error emitCommonSymbols(const ObjectFile &Obj, +                          CommonSymbolList &CommonSymbols);    /// \brief Emits section data from the object file to the MemoryManager.    /// \param IsCode if it's true then allocateCodeSection() will be    ///        used for emits, else allocateDataSection() will be used.    /// \return SectionID. -  unsigned emitSection(const ObjectFile &Obj, const SectionRef &Section, -                       bool IsCode); +  Expected<unsigned> emitSection(const ObjectFile &Obj, +                                 const SectionRef &Section, +                                 bool IsCode);    /// \brief Find Section in LocalSections. If the secton is not found - emit    ///        it and store in LocalSections.    /// \param IsCode if it's true then allocateCodeSection() will be    ///        used for emmits, else allocateDataSection() will be used.    /// \return SectionID. -  unsigned findOrEmitSection(const ObjectFile &Obj, const SectionRef &Section, -                             bool IsCode, ObjSectionToIDMap &LocalSections); +  Expected<unsigned> findOrEmitSection(const ObjectFile &Obj, +                                       const SectionRef &Section, bool IsCode, +                                       ObjSectionToIDMap &LocalSections);    // \brief Add a relocation entry that uses the given section.    void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID); @@ -401,7 +391,7 @@ protected:    ///        relocation pairs) and stores it to Relocations or SymbolRelocations    ///        (this depends on the object file type).    /// \return Iterator to the next relocation that needs to be parsed. -  virtual relocation_iterator +  virtual Expected<relocation_iterator>    processRelocationRef(unsigned SectionID, relocation_iterator RelI,                         const ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID,                         StubMap &Stubs) = 0; @@ -411,17 +401,17 @@ protected:    // \brief Compute an upper bound of the memory that is required to load all    // sections -  void computeTotalAllocSize(const ObjectFile &Obj, -                             uint64_t &CodeSize, uint32_t &CodeAlign, -                             uint64_t &RODataSize, uint32_t &RODataAlign, -                             uint64_t &RWDataSize, uint32_t &RWDataAlign); +  Error computeTotalAllocSize(const ObjectFile &Obj, +                              uint64_t &CodeSize, uint32_t &CodeAlign, +                              uint64_t &RODataSize, uint32_t &RODataAlign, +                              uint64_t &RWDataSize, uint32_t &RWDataAlign);    // \brief Compute the stub buffer size required for a section    unsigned computeSectionStubBufSize(const ObjectFile &Obj,                                       const SectionRef &Section);    // \brief Implementation of the generic part of the loadObject algorithm. -  ObjSectionToIDMap loadObjectImpl(const object::ObjectFile &Obj); +  Expected<ObjSectionToIDMap> loadObjectImpl(const object::ObjectFile &Obj);    // \brief Return true if the relocation R may require allocating a stub.    virtual bool relocationNeedsStub(const RelocationRef &R) const { @@ -496,8 +486,10 @@ public:    virtual void deregisterEHFrames(); -  virtual void finalizeLoad(const ObjectFile &ObjImg, -                            ObjSectionToIDMap &SectionMap) {} +  virtual Error finalizeLoad(const ObjectFile &ObjImg, +                             ObjSectionToIDMap &SectionMap) { +    return Error::success(); +  }  };  } // end namespace llvm diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index 739e8d65dbf4..fd109aea91d4 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -50,7 +50,8 @@ int64_t RuntimeDyldMachO::memcpyAddend(const RelocationEntry &RE) const {    return static_cast<int64_t>(readBytesUnaligned(Src, NumBytes));  } -relocation_iterator RuntimeDyldMachO::processScatteredVANILLA( +Expected<relocation_iterator> +RuntimeDyldMachO::processScatteredVANILLA(                            unsigned SectionID, relocation_iterator RelI,                            const ObjectFile &BaseObjT,                            RuntimeDyldMachO::ObjSectionToIDMap &ObjSectionToID) { @@ -74,8 +75,12 @@ relocation_iterator RuntimeDyldMachO::processScatteredVANILLA(    uint64_t SectionBaseAddr = TargetSI->getAddress();    SectionRef TargetSection = *TargetSI;    bool IsCode = TargetSection.isText(); -  uint32_t TargetSectionID = -    findOrEmitSection(Obj, TargetSection, IsCode, ObjSectionToID); +  uint32_t TargetSectionID = ~0U; +  if (auto TargetSectionIDOrErr = +        findOrEmitSection(Obj, TargetSection, IsCode, ObjSectionToID)) +    TargetSectionID = *TargetSectionIDOrErr; +  else +    return TargetSectionIDOrErr.takeError();    Addend -= SectionBaseAddr;    RelocationEntry R(SectionID, Offset, RelocType, Addend, IsPCRel, Size); @@ -86,7 +91,8 @@ relocation_iterator RuntimeDyldMachO::processScatteredVANILLA(  } -RelocationValueRef RuntimeDyldMachO::getRelocationValueRef( +Expected<RelocationValueRef> +RuntimeDyldMachO::getRelocationValueRef(      const ObjectFile &BaseTObj, const relocation_iterator &RI,      const RelocationEntry &RE, ObjSectionToIDMap &ObjSectionToID) { @@ -99,10 +105,11 @@ RelocationValueRef RuntimeDyldMachO::getRelocationValueRef(    bool IsExternal = Obj.getPlainRelocationExternal(RelInfo);    if (IsExternal) {      symbol_iterator Symbol = RI->getSymbol(); -    ErrorOr<StringRef> TargetNameOrErr = Symbol->getName(); -    if (std::error_code EC = TargetNameOrErr.getError()) -      report_fatal_error(EC.message()); -    StringRef TargetName = *TargetNameOrErr; +    StringRef TargetName; +    if (auto TargetNameOrErr = Symbol->getName()) +      TargetName = *TargetNameOrErr; +    else +      return TargetNameOrErr.takeError();      RTDyldSymbolTable::const_iterator SI =        GlobalSymbolTable.find(TargetName.data());      if (SI != GlobalSymbolTable.end()) { @@ -116,7 +123,11 @@ RelocationValueRef RuntimeDyldMachO::getRelocationValueRef(    } else {      SectionRef Sec = Obj.getAnyRelocationSection(RelInfo);      bool IsCode = Sec.isText(); -    Value.SectionID = findOrEmitSection(Obj, Sec, IsCode, ObjSectionToID); +    if (auto SectionIDOrErr = findOrEmitSection(Obj, Sec, IsCode, +                                                ObjSectionToID)) +      Value.SectionID = *SectionIDOrErr; +    else +      return SectionIDOrErr.takeError();      uint64_t Addr = Sec.getAddress();      Value.Offset = RE.Addend - Addr;    } @@ -164,7 +175,7 @@ RuntimeDyldMachO::getSectionByAddress(const MachOObjectFile &Obj,  // Populate __pointers section. -void RuntimeDyldMachO::populateIndirectSymbolPointersSection( +Error RuntimeDyldMachO::populateIndirectSymbolPointersSection(                                                      const MachOObjectFile &Obj,                                                      const SectionRef &PTSection,                                                      unsigned PTSectionID) { @@ -191,10 +202,11 @@ void RuntimeDyldMachO::populateIndirectSymbolPointersSection(      unsigned SymbolIndex =        Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i);      symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex); -    ErrorOr<StringRef> IndirectSymbolNameOrErr = SI->getName(); -    if (std::error_code EC = IndirectSymbolNameOrErr.getError()) -      report_fatal_error(EC.message()); -    StringRef IndirectSymbolName = *IndirectSymbolNameOrErr; +    StringRef IndirectSymbolName; +    if (auto IndirectSymbolNameOrErr = SI->getName()) +      IndirectSymbolName = *IndirectSymbolNameOrErr; +    else +      return IndirectSymbolNameOrErr.takeError();      DEBUG(dbgs() << "  " << IndirectSymbolName << ": index " << SymbolIndex            << ", PT offset: " << PTEntryOffset << "\n");      RelocationEntry RE(PTSectionID, PTEntryOffset, @@ -202,6 +214,7 @@ void RuntimeDyldMachO::populateIndirectSymbolPointersSection(      addRelocationForSymbol(RE, IndirectSymbolName);      PTEntryOffset += PTEntrySize;    } +  return Error::success();  }  bool RuntimeDyldMachO::isCompatibleFile(const object::ObjectFile &Obj) const { @@ -209,8 +222,9 @@ bool RuntimeDyldMachO::isCompatibleFile(const object::ObjectFile &Obj) const {  }  template <typename Impl> -void RuntimeDyldMachOCRTPBase<Impl>::finalizeLoad(const ObjectFile &Obj, -                                                  ObjSectionToIDMap &SectionMap) { +Error +RuntimeDyldMachOCRTPBase<Impl>::finalizeLoad(const ObjectFile &Obj, +                                             ObjSectionToIDMap &SectionMap) {    unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID;    unsigned TextSID = RTDYLD_INVALID_SECTION_ID;    unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID; @@ -222,20 +236,34 @@ void RuntimeDyldMachOCRTPBase<Impl>::finalizeLoad(const ObjectFile &Obj,      // Force emission of the __text, __eh_frame, and __gcc_except_tab sections      // if they're present. Otherwise call down to the impl to handle other      // sections that have already been emitted. -    if (Name == "__text") -      TextSID = findOrEmitSection(Obj, Section, true, SectionMap); -    else if (Name == "__eh_frame") -      EHFrameSID = findOrEmitSection(Obj, Section, false, SectionMap); -    else if (Name == "__gcc_except_tab") -      ExceptTabSID = findOrEmitSection(Obj, Section, true, SectionMap); -    else { +    if (Name == "__text") { +      if (auto TextSIDOrErr = findOrEmitSection(Obj, Section, true, SectionMap)) +        TextSID = *TextSIDOrErr; +      else +        return TextSIDOrErr.takeError(); +    } else if (Name == "__eh_frame") { +      if (auto EHFrameSIDOrErr = findOrEmitSection(Obj, Section, false, +                                                   SectionMap)) +        EHFrameSID = *EHFrameSIDOrErr; +      else +        return EHFrameSIDOrErr.takeError(); +    } else if (Name == "__gcc_except_tab") { +      if (auto ExceptTabSIDOrErr = findOrEmitSection(Obj, Section, true, +                                                     SectionMap)) +        ExceptTabSID = *ExceptTabSIDOrErr; +      else +        return ExceptTabSIDOrErr.takeError(); +    } else {        auto I = SectionMap.find(Section);        if (I != SectionMap.end()) -        impl().finalizeSection(Obj, I->second, Section); +        if (auto Err = impl().finalizeSection(Obj, I->second, Section)) +          return Err;      }    }    UnregisteredEHFrameSections.push_back(      EHFrameRelatedSections(EHFrameSID, TextSID, ExceptTabSID)); + +  return Error::success();  }  template <typename Impl> @@ -302,9 +330,9 @@ void RuntimeDyldMachOCRTPBase<Impl>::registerEHFrames() {      uint8_t *P = EHFrame->getAddress();      uint8_t *End = P + EHFrame->getSize(); -    do { +    while (P != End) {        P = processFDE(P, DeltaForText, DeltaForEH); -    } while (P != End); +    }      MemMgr.registerEHFrames(EHFrame->getAddress(), EHFrame->getLoadAddress(),                              EHFrame->getSize()); @@ -333,7 +361,15 @@ RuntimeDyldMachO::create(Triple::ArchType Arch,  std::unique_ptr<RuntimeDyld::LoadedObjectInfo>  RuntimeDyldMachO::loadObject(const object::ObjectFile &O) { -  return llvm::make_unique<LoadedMachOObjectInfo>(*this, loadObjectImpl(O)); +  if (auto ObjSectionToIDOrErr = loadObjectImpl(O)) +    return llvm::make_unique<LoadedMachOObjectInfo>(*this, +                                                    *ObjSectionToIDOrErr); +  else { +    HasError = true; +    raw_string_ostream ErrStream(ErrorStr); +    logAllUnhandledErrors(ObjSectionToIDOrErr.takeError(), ErrStream, ""); +    return nullptr; +  }  }  } // end namespace llvm diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h index c8ae47b0db22..30f3bb3bf07d 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h @@ -80,10 +80,10 @@ protected:    }    /// Process a scattered vanilla relocation. -  relocation_iterator processScatteredVANILLA( -                           unsigned SectionID, relocation_iterator RelI, -                           const ObjectFile &BaseObjT, -                           RuntimeDyldMachO::ObjSectionToIDMap &ObjSectionToID); +  Expected<relocation_iterator> +  processScatteredVANILLA(unsigned SectionID, relocation_iterator RelI, +                          const ObjectFile &BaseObjT, +                          RuntimeDyldMachO::ObjSectionToIDMap &ObjSectionToID);    /// Construct a RelocationValueRef representing the relocation target.    /// For Symbols in known sections, this will return a RelocationValueRef @@ -94,10 +94,11 @@ protected:    /// In both cases the Addend field is *NOT* fixed up to be PC-relative. That    /// should be done by the caller where appropriate by calling makePCRel on    /// the RelocationValueRef. -  RelocationValueRef getRelocationValueRef(const ObjectFile &BaseTObj, -                                           const relocation_iterator &RI, -                                           const RelocationEntry &RE, -                                           ObjSectionToIDMap &ObjSectionToID); +  Expected<RelocationValueRef> +  getRelocationValueRef(const ObjectFile &BaseTObj, +                        const relocation_iterator &RI, +                        const RelocationEntry &RE, +                        ObjSectionToIDMap &ObjSectionToID);    /// Make the RelocationValueRef addend PC-relative.    void makeValueAddendPCRel(RelocationValueRef &Value, @@ -113,9 +114,9 @@ protected:    // Populate __pointers section. -  void populateIndirectSymbolPointersSection(const MachOObjectFile &Obj, -                                             const SectionRef &PTSection, -                                             unsigned PTSectionID); +  Error populateIndirectSymbolPointersSection(const MachOObjectFile &Obj, +                                              const SectionRef &PTSection, +                                              unsigned PTSectionID);  public: @@ -154,8 +155,8 @@ public:                             RuntimeDyld::SymbolResolver &Resolver)      : RuntimeDyldMachO(MemMgr, Resolver) {} -  void finalizeLoad(const ObjectFile &Obj, -                    ObjSectionToIDMap &SectionMap) override; +  Error finalizeLoad(const ObjectFile &Obj, +                     ObjSectionToIDMap &SectionMap) override;    void registerEHFrames() override;  }; diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h index fbfbb3285233..44fda87e0f94 100644 --- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h +++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h @@ -34,40 +34,66 @@ public:    unsigned getStubAlignment() override { return 1; } -  relocation_iterator processRelocationRef(unsigned SectionID, -                                           relocation_iterator RelI, -                                           const ObjectFile &Obj, -                                           ObjSectionToIDMap &ObjSectionToID, -                                           StubMap &Stubs) override { +  Expected<relocation_iterator> +  processRelocationRef(unsigned SectionID, +                       relocation_iterator RelI, +                       const ObjectFile &Obj, +                       ObjSectionToIDMap &ObjSectionToID, +                       StubMap &Stubs) override { +      auto Symbol = RelI->getSymbol();      if (Symbol == Obj.symbol_end())        report_fatal_error("Unknown symbol in relocation"); -    ErrorOr<StringRef> TargetNameOrErr = Symbol->getName(); -    if (auto EC = TargetNameOrErr.getError()) -      report_fatal_error(EC.message()); +    Expected<StringRef> TargetNameOrErr = Symbol->getName(); +    if (!TargetNameOrErr) +      return TargetNameOrErr.takeError();      StringRef TargetName = *TargetNameOrErr; -    auto Section = *Symbol->getSection(); +    auto SectionOrErr = Symbol->getSection(); +    if (!SectionOrErr) +      return SectionOrErr.takeError(); +    auto Section = *SectionOrErr;      uint64_t RelType = RelI->getType();      uint64_t Offset = RelI->getOffset(); +    // Determine the Addend used to adjust the relocation value. +    uint64_t Addend = 0; +    SectionEntry &AddendSection = Sections[SectionID]; +    uintptr_t ObjTarget = AddendSection.getObjAddress() + Offset; +    uint8_t *Displacement = (uint8_t *)ObjTarget; + +    switch (RelType) { +    case COFF::IMAGE_REL_I386_DIR32: +    case COFF::IMAGE_REL_I386_DIR32NB: +    case COFF::IMAGE_REL_I386_SECREL: +    case COFF::IMAGE_REL_I386_REL32: { +      Addend = readBytesUnaligned(Displacement, 4); +      break; +    } +    default: +      break; +    } +  #if !defined(NDEBUG)      SmallString<32> RelTypeName;      RelI->getTypeName(RelTypeName);  #endif      DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset                   << " RelType: " << RelTypeName << " TargetName: " << TargetName -                 << "\n"); +                 << " Addend " << Addend << "\n");      unsigned TargetSectionID = -1;      if (Section == Obj.section_end()) {        RelocationEntry RE(SectionID, Offset, RelType, 0, -1, 0, 0, 0, false, 0);        addRelocationForSymbol(RE, TargetName);      } else { -      TargetSectionID = -          findOrEmitSection(Obj, *Section, Section->isText(), ObjSectionToID); +      if (auto TargetSectionIDOrErr = +          findOrEmitSection(Obj, *Section, Section->isText(), ObjSectionToID)) +        TargetSectionID = *TargetSectionIDOrErr; +      else +        return TargetSectionIDOrErr.takeError();        switch (RelType) {        case COFF::IMAGE_REL_I386_ABSOLUTE: @@ -77,7 +103,7 @@ public:        case COFF::IMAGE_REL_I386_DIR32NB:        case COFF::IMAGE_REL_I386_REL32: {          RelocationEntry RE = -            RelocationEntry(SectionID, Offset, RelType, 0, TargetSectionID, +            RelocationEntry(SectionID, Offset, RelType, Addend, TargetSectionID,                              getSymbolOffset(*Symbol), 0, 0, false, 0);          addRelocationForSection(RE, TargetSectionID);          break; @@ -90,7 +116,7 @@ public:        }        case COFF::IMAGE_REL_I386_SECREL: {          RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType, -                                             getSymbolOffset(*Symbol)); +                                             getSymbolOffset(*Symbol) + Addend);          addRelocationForSection(RE, TargetSectionID);          break;        } @@ -148,8 +174,10 @@ public:      }      case COFF::IMAGE_REL_I386_REL32: {        // 32-bit relative displacement to the target. -      uint64_t Result = Sections[RE.Sections.SectionA].getLoadAddress() - -                        Section.getLoadAddress() + RE.Addend - 4 - RE.Offset; +      uint64_t Result = RE.Sections.SectionA == static_cast<uint32_t>(-1) +                            ? Value +                            : Sections[RE.Sections.SectionA].getLoadAddress(); +      Result = Result - Section.getLoadAddress() + RE.Addend - 4 - RE.Offset;        assert(static_cast<int32_t>(Result) <= INT32_MAX &&               "relocation overflow");        assert(static_cast<int32_t>(Result) >= INT32_MIN && @@ -190,9 +218,6 @@ public:    void registerEHFrames() override {}    void deregisterEHFrames() override {} - -  void finalizeLoad(const ObjectFile &Obj, -                    ObjSectionToIDMap &SectionMap) override {}  };  } diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h new file mode 100644 index 000000000000..ff7d1d439252 --- /dev/null +++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h @@ -0,0 +1,291 @@ +//===--- RuntimeDyldCOFFThumb.h --- COFF/Thumb specific code ---*- C++ --*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// COFF thumb support for MC-JIT runtime dynamic linker. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFTHUMB_H +#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFTHUMB_H + +#include "llvm/Object/COFF.h" +#include "llvm/Support/COFF.h" +#include "../RuntimeDyldCOFF.h" + +#define DEBUG_TYPE "dyld" + +namespace llvm { + +class RuntimeDyldCOFFThumb : public RuntimeDyldCOFF { +public: +  RuntimeDyldCOFFThumb(RuntimeDyld::MemoryManager &MM, +                       RuntimeDyld::SymbolResolver &Resolver) +      : RuntimeDyldCOFF(MM, Resolver) {} + +  unsigned getMaxStubSize() override { +    return 16; // 8-byte load instructions, 4-byte jump, 4-byte padding +  } + +  unsigned getStubAlignment() override { return 1; } + +  Expected<relocation_iterator> +  processRelocationRef(unsigned SectionID, +                       relocation_iterator RelI, +                       const ObjectFile &Obj, +                       ObjSectionToIDMap &ObjSectionToID, +                       StubMap &Stubs) override { +    auto Symbol = RelI->getSymbol(); +    if (Symbol == Obj.symbol_end()) +      report_fatal_error("Unknown symbol in relocation"); + +    Expected<StringRef> TargetNameOrErr = Symbol->getName(); +    if (!TargetNameOrErr) +      return TargetNameOrErr.takeError(); +    StringRef TargetName = *TargetNameOrErr; + +    auto SectionOrErr = Symbol->getSection(); +    if (!SectionOrErr) +      return SectionOrErr.takeError(); +    auto Section = *SectionOrErr; + +    uint64_t RelType = RelI->getType(); +    uint64_t Offset = RelI->getOffset(); + +    // Determine the Addend used to adjust the relocation value. +    uint64_t Addend = 0; +    SectionEntry &AddendSection = Sections[SectionID]; +    uintptr_t ObjTarget = AddendSection.getObjAddress() + Offset; +    uint8_t *Displacement = (uint8_t *)ObjTarget; + +    switch (RelType) { +    case COFF::IMAGE_REL_ARM_ADDR32: +    case COFF::IMAGE_REL_ARM_ADDR32NB: +    case COFF::IMAGE_REL_ARM_SECREL: +      Addend = readBytesUnaligned(Displacement, 4); +      break; +    default: +      break; +    } + +#if !defined(NDEBUG) +    SmallString<32> RelTypeName; +    RelI->getTypeName(RelTypeName); +#endif +    DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset +                 << " RelType: " << RelTypeName << " TargetName: " << TargetName +                 << " Addend " << Addend << "\n"); + +    unsigned TargetSectionID = -1; +    if (Section == Obj.section_end()) { +      RelocationEntry RE(SectionID, Offset, RelType, 0, -1, 0, 0, 0, false, 0); +      addRelocationForSymbol(RE, TargetName); +    } else { +      if (auto TargetSectionIDOrErr = +          findOrEmitSection(Obj, *Section, Section->isText(), ObjSectionToID)) +        TargetSectionID = *TargetSectionIDOrErr; +      else +        return TargetSectionIDOrErr.takeError(); + +      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_ADDR32NB: { +        RelocationEntry RE = +            RelocationEntry(SectionID, Offset, RelType, Addend, TargetSectionID, +                            getSymbolOffset(*Symbol), 0, 0, false, 0); +        addRelocationForSection(RE, TargetSectionID); +        break; +      } +      case COFF::IMAGE_REL_ARM_SECTION: { +        RelocationEntry RE = +            RelocationEntry(TargetSectionID, Offset, RelType, 0); +        addRelocationForSection(RE, TargetSectionID); +        break; +      } +      case COFF::IMAGE_REL_ARM_SECREL: { +        RelocationEntry RE = RelocationEntry(SectionID, Offset, RelType, +                                             getSymbolOffset(*Symbol) + Addend); +        addRelocationForSection(RE, TargetSectionID); +        break; +      } +      case COFF::IMAGE_REL_ARM_MOV32T: { +        RelocationEntry RE = +            RelocationEntry(SectionID, Offset, RelType, Addend, TargetSectionID, +                            getSymbolOffset(*Symbol), 0, 0, false, 0); +        addRelocationForSection(RE, TargetSectionID); +        break; +      } +      case COFF::IMAGE_REL_ARM_BRANCH20T: +      case COFF::IMAGE_REL_ARM_BRANCH24T: +      case COFF::IMAGE_REL_ARM_BLX23T: { +        RelocationEntry RE = +            RelocationEntry(SectionID, Offset, RelType, +                            getSymbolOffset(*Symbol) + Addend, true, 0); +        addRelocationForSection(RE, TargetSectionID); +        break; +      } +      } +    } + +    return ++RelI; +  } + +  void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override { +    const auto Section = Sections[RE.SectionID]; +    uint8_t *Target = Section.getAddressWithOffset(RE.Offset); + +    switch (RE.RelType) { +    default: llvm_unreachable("unsupported relocation type"); +    case COFF::IMAGE_REL_ARM_ABSOLUTE: +      // This relocation is ignored. +      break; +    case COFF::IMAGE_REL_ARM_ADDR32: { +      // The target's 32-bit VA. +      uint64_t Result = +          RE.Sections.SectionA == static_cast<uint32_t>(-1) +              ? Value +              : Sections[RE.Sections.SectionA].getLoadAddressWithOffset(RE.Addend); +      assert(static_cast<int32_t>(Result) <= INT32_MAX && +             "relocation overflow"); +      assert(static_cast<int32_t>(Result) >= INT32_MIN && +             "relocation underflow"); +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset +                   << " RelType: IMAGE_REL_ARM_ADDR32" +                   << " TargetSection: " << RE.Sections.SectionA +                   << " Value: " << format("0x%08" PRIx32, Result) << '\n'); +      writeBytesUnaligned(Result, Target, 4); +      break; +    } +    case COFF::IMAGE_REL_ARM_ADDR32NB: { +      // The target's 32-bit RVA. +      // NOTE: use Section[0].getLoadAddress() as an approximation of ImageBase +      uint64_t Result = Sections[RE.Sections.SectionA].getLoadAddress() - +                        Sections[0].getLoadAddress() + RE.Addend; +      assert(static_cast<int32_t>(Result) <= INT32_MAX && +             "relocation overflow"); +      assert(static_cast<int32_t>(Result) >= INT32_MIN && +             "relocation underflow"); +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset +                   << " RelType: IMAGE_REL_ARM_ADDR32NB" +                   << " TargetSection: " << RE.Sections.SectionA +                   << " Value: " << format("0x%08" PRIx32, Result) << '\n'); +      writeBytesUnaligned(Result, Target, 4); +      break; +    } +    case COFF::IMAGE_REL_ARM_SECTION: +      // 16-bit section index of the section that contains the target. +      assert(static_cast<int32_t>(RE.SectionID) <= INT16_MAX && +             "relocation overflow"); +      assert(static_cast<int32_t>(RE.SectionID) >= INT16_MIN && +             "relocation underflow"); +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset +                   << " RelType: IMAGE_REL_ARM_SECTION Value: " << RE.SectionID +                   << '\n'); +      writeBytesUnaligned(RE.SectionID, Target, 2); +      break; +    case COFF::IMAGE_REL_ARM_SECREL: +      // 32-bit offset of the target from the beginning of its section. +      assert(static_cast<int32_t>(RE.Addend) <= INT32_MAX && +             "relocation overflow"); +      assert(static_cast<int32_t>(RE.Addend) >= INT32_MIN && +             "relocation underflow"); +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset +                   << " RelType: IMAGE_REL_ARM_SECREL Value: " << RE.Addend +                   << '\n'); +      writeBytesUnaligned(RE.Addend, Target, 2); +      break; +    case COFF::IMAGE_REL_ARM_MOV32T: { +      // 32-bit VA of the target applied to a contiguous MOVW+MOVT pair. +      uint64_t Result = +          Sections[RE.Sections.SectionA].getLoadAddressWithOffset(RE.Addend); +      assert(static_cast<int32_t>(Result) <= INT32_MAX && +             "relocation overflow"); +      assert(static_cast<int32_t>(Result) >= INT32_MIN && +             "relocation underflow"); +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset +                   << " RelType: IMAGE_REL_ARM_MOV32T" +                   << " TargetSection: " << RE.Sections.SectionA +                   << " Value: " << format("0x%08" PRIx32, Result) << '\n'); + +      // MOVW(T3): |11110|i|10|0|1|0|0|imm4|0|imm3|Rd|imm8| +      //            imm32 = zext imm4:i:imm3:imm8 +      // MOVT(T1): |11110|i|10|1|1|0|0|imm4|0|imm3|Rd|imm8| +      //            imm16 =      imm4:i:imm3:imm8 + +      auto EncodeImmediate = [](uint8_t *Bytes, uint16_t Immediate)  { +        Bytes[0] |= ((Immediate & 0xf000) >> 12); +        Bytes[1] |= ((Immediate & 0x0800) >> 11); +        Bytes[2] |= ((Immediate & 0x00ff) >>  0); +        Bytes[3] |= ((Immediate & 0x0700) >>  8); +      }; + +      EncodeImmediate(&Target[0], static_cast<uint32_t>(Result) >> 00); +      EncodeImmediate(&Target[4], static_cast<uint32_t>(Result) >> 16); + +      break; +    } +    case COFF::IMAGE_REL_ARM_BRANCH20T: { +      // The most significant 20-bits of the signed 21-bit relative displacement +      uint64_t Value = +          RE.Addend - (Sections[RE.SectionID].getLoadAddress() + RE.Offset) - 4; +      assert(static_cast<int32_t>(RE.Addend) <= INT32_MAX && +             "relocation overflow"); +      assert(static_cast<int32_t>(RE.Addend) >= INT32_MIN && +             "relocation underflow"); +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset +                   << " RelType: IMAGE_REL_ARM_BRANCH20T" +                   << " Value: " << static_cast<int32_t>(Value) << '\n'); +      static_cast<void>(Value); +      llvm_unreachable("unimplemented relocation"); +      break; +    } +    case COFF::IMAGE_REL_ARM_BRANCH24T: { +      // The most significant 24-bits of the signed 25-bit relative displacement +      uint64_t Value = +          RE.Addend - (Sections[RE.SectionID].getLoadAddress() + RE.Offset) - 4; +      assert(static_cast<int32_t>(RE.Addend) <= INT32_MAX && +             "relocation overflow"); +      assert(static_cast<int32_t>(RE.Addend) >= INT32_MIN && +             "relocation underflow"); +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset +                   << " RelType: IMAGE_REL_ARM_BRANCH24T" +                   << " Value: " << static_cast<int32_t>(Value) << '\n'); +      static_cast<void>(Value); +      llvm_unreachable("unimplemented relocation"); +      break; +    } +    case COFF::IMAGE_REL_ARM_BLX23T: { +      // The most significant 24-bits of the signed 25-bit relative displacement +      uint64_t Value = +          RE.Addend - (Sections[RE.SectionID].getLoadAddress() + RE.Offset) - 4; +      assert(static_cast<int32_t>(RE.Addend) <= INT32_MAX && +             "relocation overflow"); +      assert(static_cast<int32_t>(RE.Addend) >= INT32_MIN && +             "relocation underflow"); +      DEBUG(dbgs() << "\t\tOffset: " << RE.Offset +                   << " RelType: IMAGE_REL_ARM_BLX23T" +                   << " Value: " << static_cast<int32_t>(Value) << '\n'); +      static_cast<void>(Value); +      llvm_unreachable("unimplemented relocation"); +      break; +    } +    } +  } + +  void registerEHFrames() override {} +  void deregisterEHFrames() override {} +}; + +} + +#endif + diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h index 25f538d8f3da..df8681da24d1 100644 --- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h +++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h @@ -106,17 +106,21 @@ public:      }    } -  relocation_iterator processRelocationRef(unsigned SectionID, -                                           relocation_iterator RelI, -                                           const ObjectFile &Obj, -                                           ObjSectionToIDMap &ObjSectionToID, -                                           StubMap &Stubs) override { +  Expected<relocation_iterator> +  processRelocationRef(unsigned SectionID, +                       relocation_iterator RelI, +                       const ObjectFile &Obj, +                       ObjSectionToIDMap &ObjSectionToID, +                       StubMap &Stubs) override {      // If possible, find the symbol referred to in the relocation,      // and the section that contains it.      symbol_iterator Symbol = RelI->getSymbol();      if (Symbol == Obj.symbol_end())        report_fatal_error("Unknown symbol in relocation"); -    section_iterator SecI = *Symbol->getSection(); +    auto SectionOrError = Symbol->getSection(); +    if (!SectionOrError) +      return SectionOrError.takeError(); +    section_iterator SecI = *SectionOrError;      // If there is no section, this must be an external reference.      const bool IsExtern = SecI == Obj.section_end(); @@ -151,9 +155,9 @@ public:        break;      } -    ErrorOr<StringRef> TargetNameOrErr = Symbol->getName(); -    if (std::error_code EC = TargetNameOrErr.getError()) -      report_fatal_error(EC.message()); +    Expected<StringRef> TargetNameOrErr = Symbol->getName(); +    if (!TargetNameOrErr) +      return TargetNameOrErr.takeError();      StringRef TargetName = *TargetNameOrErr;      DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset @@ -165,8 +169,12 @@ public:        addRelocationForSymbol(RE, TargetName);      } else {        bool IsCode = SecI->isText(); -      unsigned TargetSectionID = -          findOrEmitSection(Obj, *SecI, IsCode, ObjSectionToID); +      unsigned TargetSectionID; +      if (auto TargetSectionIDOrErr = +          findOrEmitSection(Obj, *SecI, IsCode, ObjSectionToID)) +        TargetSectionID = *TargetSectionIDOrErr; +      else +        return TargetSectionIDOrErr.takeError();        uint64_t TargetOffset = getSymbolOffset(*Symbol);        RelocationEntry RE(SectionID, Offset, RelType, TargetOffset + Addend);        addRelocationForSection(RE, TargetSectionID); @@ -189,19 +197,21 @@ public:    void deregisterEHFrames() override {      // Stub    } -  void finalizeLoad(const ObjectFile &Obj, -                    ObjSectionToIDMap &SectionMap) override { +  Error finalizeLoad(const ObjectFile &Obj, +                     ObjSectionToIDMap &SectionMap) override {      // Look for and record the EH frame section IDs.      for (const auto &SectionPair : SectionMap) {        const SectionRef &Section = SectionPair.first;        StringRef Name; -      Check(Section.getName(Name)); +      if (auto EC = Section.getName(Name)) +        return errorCodeToError(EC);        // Note unwind info is split across .pdata and .xdata, so this        // may not be sufficiently general for all users.        if (Name == ".xdata") {          UnregisteredEHFrameSections.push_back(SectionPair.second);        }      } +    return Error::success();    }  }; diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h index dbca37747ce8..63598f197070 100644 --- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h +++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h @@ -242,7 +242,7 @@ public:      }    } -  relocation_iterator +  Expected<relocation_iterator>    processRelocationRef(unsigned SectionID, relocation_iterator RelI,                         const ObjectFile &BaseObjT,                         ObjSectionToIDMap &ObjSectionToID, @@ -252,7 +252,9 @@ public:      MachO::any_relocation_info RelInfo =          Obj.getRelocation(RelI->getRawDataRefImpl()); -    assert(!Obj.isRelocationScattered(RelInfo) && ""); +    if (Obj.isRelocationScattered(RelInfo)) +      return make_error<RuntimeDyldError>("Scattered relocations not supported " +                                          "for MachO AArch64");      // ARM64 has an ARM64_RELOC_ADDEND relocation type that carries an explicit      // addend for the following relocation. If found: (1) store the associated @@ -270,6 +272,9 @@ public:        RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl());      } +    if (Obj.getAnyRelocationType(RelInfo) == MachO::ARM64_RELOC_SUBTRACTOR) +      return processSubtractRelocation(SectionID, RelI, Obj, ObjSectionToID); +      RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));      RE.Addend = decodeAddend(RE); @@ -278,8 +283,11 @@ public:      if (ExplicitAddend)        RE.Addend = ExplicitAddend; -    RelocationValueRef Value( -        getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)); +    RelocationValueRef Value; +    if (auto ValueOrErr = getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)) +      Value = *ValueOrErr; +    else +      return ValueOrErr.takeError();      bool IsExtern = Obj.getPlainRelocationExternal(RelInfo);      if (!IsExtern && RE.IsPCRel) @@ -349,7 +357,15 @@ public:        encodeAddend(LocalAddress, /*Size=*/4, RelType, Value);        break;      } -    case MachO::ARM64_RELOC_SUBTRACTOR: +    case MachO::ARM64_RELOC_SUBTRACTOR: { +      uint64_t SectionABase = Sections[RE.Sections.SectionA].getLoadAddress(); +      uint64_t SectionBBase = Sections[RE.Sections.SectionB].getLoadAddress(); +      assert((Value == SectionABase || Value == SectionBBase) && +             "Unexpected SUBTRACTOR relocation value."); +      Value = SectionABase - SectionBBase + RE.Addend; +      writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size); +      break; +    }      case MachO::ARM64_RELOC_POINTER_TO_GOT:      case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:      case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12: @@ -360,8 +376,10 @@ public:      }    } -  void finalizeSection(const ObjectFile &Obj, unsigned SectionID, -                       const SectionRef &Section) {} +  Error finalizeSection(const ObjectFile &Obj, unsigned SectionID, +                       const SectionRef &Section) { +    return Error::success(); +  }  private:    void processGOTRelocation(const RelocationEntry &RE, @@ -398,6 +416,47 @@ private:                               RE.IsPCRel, RE.Size);      addRelocationForSection(TargetRE, RE.SectionID);    } + +  Expected<relocation_iterator> +  processSubtractRelocation(unsigned SectionID, relocation_iterator RelI, +                            const ObjectFile &BaseObjT, +                            ObjSectionToIDMap &ObjSectionToID) { +    const MachOObjectFile &Obj = +        static_cast<const MachOObjectFile&>(BaseObjT); +    MachO::any_relocation_info RE = +        Obj.getRelocation(RelI->getRawDataRefImpl()); + +    unsigned Size = Obj.getAnyRelocationLength(RE); +    uint64_t Offset = RelI->getOffset(); +    uint8_t *LocalAddress = Sections[SectionID].getAddressWithOffset(Offset); +    unsigned NumBytes = 1 << Size; + +    Expected<StringRef> SubtrahendNameOrErr = RelI->getSymbol()->getName(); +    if (!SubtrahendNameOrErr) +      return SubtrahendNameOrErr.takeError(); +    auto SubtrahendI = GlobalSymbolTable.find(*SubtrahendNameOrErr); +    unsigned SectionBID = SubtrahendI->second.getSectionID(); +    uint64_t SectionBOffset = SubtrahendI->second.getOffset(); +    int64_t Addend = +      SignExtend64(readBytesUnaligned(LocalAddress, NumBytes), NumBytes * 8); + +    ++RelI; +    Expected<StringRef> MinuendNameOrErr = RelI->getSymbol()->getName(); +    if (!MinuendNameOrErr) +      return MinuendNameOrErr.takeError(); +    auto MinuendI = GlobalSymbolTable.find(*MinuendNameOrErr); +    unsigned SectionAID = MinuendI->second.getSectionID(); +    uint64_t SectionAOffset = MinuendI->second.getOffset(); + +    RelocationEntry R(SectionID, Offset, MachO::ARM64_RELOC_SUBTRACTOR, (uint64_t)Addend, +                      SectionAID, SectionAOffset, SectionBID, SectionBOffset, +                      false, Size); + +    addRelocationForSection(R, SectionAID); + +    return ++RelI; +  } +  };  } diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h index 7731df09bd21..0abf9daba505 100644 --- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h +++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h @@ -11,6 +11,7 @@  #define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDMACHOARM_H  #include "../RuntimeDyldMachO.h" +#include <string>  #define DEBUG_TYPE "dyld" @@ -49,7 +50,7 @@ public:      }    } -  relocation_iterator +  Expected<relocation_iterator>    processRelocationRef(unsigned SectionID, relocation_iterator RelI,                         const ObjectFile &BaseObjT,                         ObjSectionToIDMap &ObjSectionToID, @@ -70,10 +71,30 @@ public:          return ++RelI;      } +    // Sanity check relocation type. +    switch (RelType) { +    UNIMPLEMENTED_RELOC(MachO::ARM_RELOC_PAIR); +    UNIMPLEMENTED_RELOC(MachO::ARM_RELOC_SECTDIFF); +    UNIMPLEMENTED_RELOC(MachO::ARM_RELOC_LOCAL_SECTDIFF); +    UNIMPLEMENTED_RELOC(MachO::ARM_RELOC_PB_LA_PTR); +    UNIMPLEMENTED_RELOC(MachO::ARM_THUMB_RELOC_BR22); +    UNIMPLEMENTED_RELOC(MachO::ARM_THUMB_32BIT_BRANCH); +    UNIMPLEMENTED_RELOC(MachO::ARM_RELOC_HALF); +    default: +      if (RelType > MachO::ARM_RELOC_HALF_SECTDIFF) +        return make_error<RuntimeDyldError>(("MachO ARM relocation type " + +                                             Twine(RelType) + +                                             " is out of range").str()); +      break; +    } +      RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));      RE.Addend = decodeAddend(RE); -    RelocationValueRef Value( -        getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)); +    RelocationValueRef Value; +    if (auto ValueOrErr = getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)) +      Value = *ValueOrErr; +    else +      return ValueOrErr.takeError();      if (RE.IsPCRel)        makeValueAddendPCRel(Value, RelI, 8); @@ -108,8 +129,6 @@ public:      }      switch (RE.RelType) { -    default: -      llvm_unreachable("Invalid relocation type!");      case MachO::ARM_RELOC_VANILLA:        writeBytesUnaligned(Value + RE.Addend, LocalAddress, 1 << RE.Size);        break; @@ -147,26 +166,20 @@ public:        break;      } -    case MachO::ARM_THUMB_RELOC_BR22: -    case MachO::ARM_THUMB_32BIT_BRANCH: -    case MachO::ARM_RELOC_HALF: -    case MachO::ARM_RELOC_PAIR: -    case MachO::ARM_RELOC_SECTDIFF: -    case MachO::ARM_RELOC_LOCAL_SECTDIFF: -    case MachO::ARM_RELOC_PB_LA_PTR: -      Error("Relocation type not implemented yet!"); -      return; +    default: +      llvm_unreachable("Invalid relocation type");      }    } -  void finalizeSection(const ObjectFile &Obj, unsigned SectionID, +  Error finalizeSection(const ObjectFile &Obj, unsigned SectionID,                         const SectionRef &Section) {      StringRef Name;      Section.getName(Name);      if (Name == "__nl_symbol_ptr") -      populateIndirectSymbolPointersSection(cast<MachOObjectFile>(Obj), -                                            Section, SectionID); +      return populateIndirectSymbolPointersSection(cast<MachOObjectFile>(Obj), +                                                   Section, SectionID); +    return Error::success();    }  private: @@ -201,7 +214,7 @@ private:      resolveRelocation(TargetRE, (uint64_t)Addr);    } -  relocation_iterator +  Expected<relocation_iterator>    processHALFSECTDIFFRelocation(unsigned SectionID, relocation_iterator RelI,                                  const ObjectFile &BaseTObj,                                  ObjSectionToIDMap &ObjSectionToID) { @@ -237,8 +250,12 @@ private:      uint64_t SectionAOffset = AddrA - SectionABase;      SectionRef SectionA = *SAI;      bool IsCode = SectionA.isText(); -    uint32_t SectionAID = -        findOrEmitSection(MachO, SectionA, IsCode, ObjSectionToID); +    uint32_t SectionAID = ~0U; +    if (auto SectionAIDOrErr = +          findOrEmitSection(MachO, SectionA, IsCode, ObjSectionToID)) +      SectionAID = *SectionAIDOrErr; +    else +      return SectionAIDOrErr.takeError();      uint32_t AddrB = MachO.getScatteredRelocationValue(RE2);      section_iterator SBI = getSectionByAddress(MachO, AddrB); @@ -246,8 +263,12 @@ private:      uint64_t SectionBBase = SBI->getAddress();      uint64_t SectionBOffset = AddrB - SectionBBase;      SectionRef SectionB = *SBI; -    uint32_t SectionBID = -        findOrEmitSection(MachO, SectionB, IsCode, ObjSectionToID); +    uint32_t SectionBID = ~0U; +    if (auto SectionBIDOrErr = +          findOrEmitSection(MachO, SectionB, IsCode, ObjSectionToID)) +      SectionBID = *SectionBIDOrErr; +    else +      return SectionBIDOrErr.takeError();      uint32_t OtherHalf = MachO.getAnyRelocationAddress(RE2) & 0xffff;      unsigned Shift = (HalfDiffKindBits & 0x1) ? 16 : 0; diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h index 85059d70a3eb..2c79b3f7c819 100644 --- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h +++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h @@ -11,6 +11,7 @@  #define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDMACHOI386_H  #include "../RuntimeDyldMachO.h" +#include <string>  #define DEBUG_TYPE "dyld" @@ -30,7 +31,7 @@ public:    unsigned getStubAlignment() override { return 1; } -  relocation_iterator +  Expected<relocation_iterator>    processRelocationRef(unsigned SectionID, relocation_iterator RelI,                         const ObjectFile &BaseObjT,                         ObjSectionToIDMap &ObjSectionToID, @@ -48,13 +49,29 @@ public:                                           ObjSectionToID);        else if (RelType == MachO::GENERIC_RELOC_VANILLA)          return processScatteredVANILLA(SectionID, RelI, Obj, ObjSectionToID); -      llvm_unreachable("Unhandled scattered relocation."); +      return make_error<RuntimeDyldError>(("Unhandled I386 scattered relocation " +                                           "type: " + Twine(RelType)).str()); +    } + +    switch (RelType) { +    UNIMPLEMENTED_RELOC(MachO::GENERIC_RELOC_PAIR); +    UNIMPLEMENTED_RELOC(MachO::GENERIC_RELOC_PB_LA_PTR); +    UNIMPLEMENTED_RELOC(MachO::GENERIC_RELOC_TLV); +    default: +      if (RelType > MachO::GENERIC_RELOC_TLV) +        return make_error<RuntimeDyldError>(("MachO I386 relocation type " + +                                             Twine(RelType) + +                                             " is out of range").str()); +      break;      }      RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));      RE.Addend = memcpyAddend(RE); -    RelocationValueRef Value( -        getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)); +    RelocationValueRef Value; +    if (auto ValueOrErr = getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)) +      Value = *ValueOrErr; +    else +      return ValueOrErr.takeError();      // Addends for external, PC-rel relocations on i386 point back to the zero      // offset. Calculate the final offset from the relocation target instead. @@ -91,8 +108,6 @@ public:      }      switch (RE.RelType) { -    default: -      llvm_unreachable("Invalid relocation type!");      case MachO::GENERIC_RELOC_VANILLA:        writeBytesUnaligned(Value + RE.Addend, LocalAddress, 1 << RE.Size);        break; @@ -106,25 +121,26 @@ public:        writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size);        break;      } -    case MachO::GENERIC_RELOC_PB_LA_PTR: -      Error("Relocation type not implemented yet!"); +    default: +      llvm_unreachable("Invalid relocation type!");      }    } -  void finalizeSection(const ObjectFile &Obj, unsigned SectionID, +  Error finalizeSection(const ObjectFile &Obj, unsigned SectionID,                         const SectionRef &Section) {      StringRef Name;      Section.getName(Name);      if (Name == "__jump_table") -      populateJumpTable(cast<MachOObjectFile>(Obj), Section, SectionID); +      return populateJumpTable(cast<MachOObjectFile>(Obj), Section, SectionID);      else if (Name == "__pointers") -      populateIndirectSymbolPointersSection(cast<MachOObjectFile>(Obj), -                                            Section, SectionID); +      return populateIndirectSymbolPointersSection(cast<MachOObjectFile>(Obj), +                                                   Section, SectionID); +    return Error::success();    }  private: -  relocation_iterator +  Expected<relocation_iterator>    processSECTDIFFRelocation(unsigned SectionID, relocation_iterator RelI,                              const ObjectFile &BaseObjT,                              ObjSectionToIDMap &ObjSectionToID) { @@ -153,8 +169,12 @@ private:      uint64_t SectionAOffset = AddrA - SectionABase;      SectionRef SectionA = *SAI;      bool IsCode = SectionA.isText(); -    uint32_t SectionAID = -        findOrEmitSection(Obj, SectionA, IsCode, ObjSectionToID); +    uint32_t SectionAID = ~0U; +    if (auto SectionAIDOrErr = +        findOrEmitSection(Obj, SectionA, IsCode, ObjSectionToID)) +      SectionAID = *SectionAIDOrErr; +    else +      return SectionAIDOrErr.takeError();      uint32_t AddrB = Obj.getScatteredRelocationValue(RE2);      section_iterator SBI = getSectionByAddress(Obj, AddrB); @@ -162,8 +182,12 @@ private:      uint64_t SectionBBase = SBI->getAddress();      uint64_t SectionBOffset = AddrB - SectionBBase;      SectionRef SectionB = *SBI; -    uint32_t SectionBID = -        findOrEmitSection(Obj, SectionB, IsCode, ObjSectionToID); +    uint32_t SectionBID = ~0U; +    if (auto SectionBIDOrErr = +        findOrEmitSection(Obj, SectionB, IsCode, ObjSectionToID)) +      SectionBID = *SectionBIDOrErr; +    else +      return SectionBIDOrErr.takeError();      // Compute the addend 'C' from the original expression 'A - B + C'.      Addend -= AddrA - AddrB; @@ -183,11 +207,9 @@ private:    }    // Populate stubs in __jump_table section. -  void populateJumpTable(const MachOObjectFile &Obj, const SectionRef &JTSection, +  Error populateJumpTable(const MachOObjectFile &Obj, +                          const SectionRef &JTSection,                           unsigned JTSectionID) { -    assert(!Obj.is64Bit() && -           "__jump_table section not supported in 64-bit MachO."); -      MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand();      MachO::section Sec32 = Obj.getSection(JTSection.getRawDataRefImpl());      uint32_t JTSectionSize = Sec32.size; @@ -197,16 +219,17 @@ private:      uint8_t *JTSectionAddr = getSectionAddress(JTSectionID);      unsigned JTEntryOffset = 0; -    assert((JTSectionSize % JTEntrySize) == 0 && -           "Jump-table section does not contain a whole number of stubs?"); +    if (JTSectionSize % JTEntrySize != 0) +      return make_error<RuntimeDyldError>("Jump-table section does not contain " +                                          "a whole number of stubs?");      for (unsigned i = 0; i < NumJTEntries; ++i) {        unsigned SymbolIndex =            Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i);        symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex); -      ErrorOr<StringRef> IndirectSymbolName = SI->getName(); -      if (std::error_code EC = IndirectSymbolName.getError()) -        report_fatal_error(EC.message()); +      Expected<StringRef> IndirectSymbolName = SI->getName(); +      if (!IndirectSymbolName) +        return IndirectSymbolName.takeError();        uint8_t *JTEntryAddr = JTSectionAddr + JTEntryOffset;        createStubFunction(JTEntryAddr);        RelocationEntry RE(JTSectionID, JTEntryOffset + 1, @@ -214,6 +237,8 @@ private:        addRelocationForSymbol(RE, *IndirectSymbolName);        JTEntryOffset += JTEntrySize;      } + +    return Error::success();    }  }; diff --git a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h index 2242295bc1ee..bc4822983244 100644 --- a/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h +++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h @@ -11,6 +11,7 @@  #define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDMACHOX86_64_H  #include "../RuntimeDyldMachO.h" +#include <string>  #define DEBUG_TYPE "dyld" @@ -30,7 +31,7 @@ public:    unsigned getStubAlignment() override { return 1; } -  relocation_iterator +  Expected<relocation_iterator>    processRelocationRef(unsigned SectionID, relocation_iterator RelI,                         const ObjectFile &BaseObjT,                         ObjSectionToIDMap &ObjSectionToID, @@ -49,13 +50,26 @@ public:      RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));      RE.Addend = memcpyAddend(RE); -    RelocationValueRef Value( -        getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)); +    RelocationValueRef Value; +    if (auto ValueOrErr = getRelocationValueRef(Obj, RelI, RE, ObjSectionToID)) +      Value = *ValueOrErr; +    else +      return ValueOrErr.takeError();      bool IsExtern = Obj.getPlainRelocationExternal(RelInfo);      if (!IsExtern && RE.IsPCRel)        makeValueAddendPCRel(Value, RelI, 1 << RE.Size); +    switch (RelType) { +    UNIMPLEMENTED_RELOC(MachO::X86_64_RELOC_TLV); +    default: +      if (RelType > MachO::X86_64_RELOC_TLV) +        return make_error<RuntimeDyldError>(("MachO X86_64 relocation type " + +                                             Twine(RelType) + +                                             " is out of range").str()); +      break; +    } +      if (RE.RelType == MachO::X86_64_RELOC_GOT ||          RE.RelType == MachO::X86_64_RELOC_GOT_LOAD)        processGOTRelocation(RE, Value, Stubs); @@ -104,15 +118,13 @@ public:        writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size);        break;      } -    case MachO::X86_64_RELOC_GOT_LOAD: -    case MachO::X86_64_RELOC_GOT: -    case MachO::X86_64_RELOC_TLV: -      Error("Relocation type not implemented yet!");      }    } -  void finalizeSection(const ObjectFile &Obj, unsigned SectionID, -                       const SectionRef &Section) {} +  Error finalizeSection(const ObjectFile &Obj, unsigned SectionID, +                        const SectionRef &Section) { +    return Error::success(); +  }  private:    void processGOTRelocation(const RelocationEntry &RE, @@ -143,12 +155,12 @@ private:      resolveRelocation(TargetRE, (uint64_t)Addr);    } -  relocation_iterator +  Expected<relocation_iterator>    processSubtractRelocation(unsigned SectionID, relocation_iterator RelI, -                            const ObjectFile &BaseObjT, +                            const MachOObjectFile &BaseObj,                              ObjSectionToIDMap &ObjSectionToID) {      const MachOObjectFile &Obj = -        static_cast<const MachOObjectFile&>(BaseObjT); +        static_cast<const MachOObjectFile&>(BaseObj);      MachO::any_relocation_info RE =          Obj.getRelocation(RelI->getRawDataRefImpl()); @@ -156,23 +168,60 @@ private:      uint64_t Offset = RelI->getOffset();      uint8_t *LocalAddress = Sections[SectionID].getAddressWithOffset(Offset);      unsigned NumBytes = 1 << Size; - -    ErrorOr<StringRef> SubtrahendNameOrErr = RelI->getSymbol()->getName(); -    if (auto EC = SubtrahendNameOrErr.getError()) -      report_fatal_error(EC.message()); -    auto SubtrahendI = GlobalSymbolTable.find(*SubtrahendNameOrErr); -    unsigned SectionBID = SubtrahendI->second.getSectionID(); -    uint64_t SectionBOffset = SubtrahendI->second.getOffset();      int64_t Addend =        SignExtend64(readBytesUnaligned(LocalAddress, NumBytes), NumBytes * 8); +    unsigned SectionBID = ~0U; +    uint64_t SectionBOffset = 0; + +    MachO::any_relocation_info RelInfo = +      Obj.getRelocation(RelI->getRawDataRefImpl()); + +    bool AIsExternal = BaseObj.getPlainRelocationExternal(RelInfo); + +    if (AIsExternal) { +      Expected<StringRef> SubtrahendNameOrErr = RelI->getSymbol()->getName(); +      if (!SubtrahendNameOrErr) +        return SubtrahendNameOrErr.takeError(); +      auto SubtrahendI = GlobalSymbolTable.find(*SubtrahendNameOrErr); +      SectionBID = SubtrahendI->second.getSectionID(); +      SectionBOffset = SubtrahendI->second.getOffset(); +    } else { +      SectionRef SecB = Obj.getAnyRelocationSection(RelInfo); +      bool IsCode = SecB.isText(); +      Expected<unsigned> SectionBIDOrErr = +        findOrEmitSection(Obj, SecB, IsCode, ObjSectionToID); +      if (!SectionBIDOrErr) +        return SectionBIDOrErr.takeError(); +      SectionBID = *SectionBIDOrErr; +      Addend += SecB.getAddress(); +    } +      ++RelI; -    ErrorOr<StringRef> MinuendNameOrErr = RelI->getSymbol()->getName(); -    if (auto EC = MinuendNameOrErr.getError()) -      report_fatal_error(EC.message()); -    auto MinuendI = GlobalSymbolTable.find(*MinuendNameOrErr); -    unsigned SectionAID = MinuendI->second.getSectionID(); -    uint64_t SectionAOffset = MinuendI->second.getOffset(); + +    unsigned SectionAID = ~0U; +    uint64_t SectionAOffset = 0; + +    RelInfo = Obj.getRelocation(RelI->getRawDataRefImpl()); + +    bool BIsExternal = BaseObj.getPlainRelocationExternal(RelInfo); +    if (BIsExternal) { +      Expected<StringRef> MinuendNameOrErr = RelI->getSymbol()->getName(); +      if (!MinuendNameOrErr) +        return MinuendNameOrErr.takeError(); +      auto MinuendI = GlobalSymbolTable.find(*MinuendNameOrErr); +      SectionAID = MinuendI->second.getSectionID(); +      SectionAOffset = MinuendI->second.getOffset(); +    } else { +      SectionRef SecA = Obj.getAnyRelocationSection(RelInfo); +      bool IsCode = SecA.isText(); +      Expected<unsigned> SectionAIDOrErr = +        findOrEmitSection(Obj, SecA, IsCode, ObjSectionToID); +      if (!SectionAIDOrErr) +        return SectionAIDOrErr.takeError(); +      SectionAID = *SectionAIDOrErr; +      Addend -= SecA.getAddress(); +    }      RelocationEntry R(SectionID, Offset, MachO::X86_64_RELOC_SUBTRACTOR, (uint64_t)Addend,                        SectionAID, SectionAOffset, SectionBID, SectionBOffset, diff --git a/lib/ExecutionEngine/TargetSelect.cpp b/lib/ExecutionEngine/TargetSelect.cpp index 57f6e0804143..b45f0c89de8b 100644 --- a/lib/ExecutionEngine/TargetSelect.cpp +++ b/lib/ExecutionEngine/TargetSelect.cpp @@ -14,11 +14,10 @@  //  //===----------------------------------------------------------------------===// -#include "llvm/ExecutionEngine/ExecutionEngine.h"  #include "llvm/ADT/Triple.h" +#include "llvm/ExecutionEngine/ExecutionEngine.h"  #include "llvm/IR/Module.h"  #include "llvm/MC/SubtargetFeature.h" -#include "llvm/Support/CommandLine.h"  #include "llvm/Support/Host.h"  #include "llvm/Support/TargetRegistry.h"  #include "llvm/Target/TargetMachine.h" | 
