aboutsummaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ExecutionEngine')
-rw-r--r--lib/ExecutionEngine/ExecutionEngine.cpp17
-rw-r--r--lib/ExecutionEngine/ExecutionEngineBindings.cpp3
-rw-r--r--lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt6
-rw-r--r--lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp23
-rw-r--r--lib/ExecutionEngine/IntelJITEvents/Makefile18
-rw-r--r--lib/ExecutionEngine/Interpreter/Makefile13
-rw-r--r--lib/ExecutionEngine/MCJIT/MCJIT.cpp41
-rw-r--r--lib/ExecutionEngine/MCJIT/MCJIT.h1
-rw-r--r--lib/ExecutionEngine/MCJIT/Makefile13
-rw-r--r--lib/ExecutionEngine/Makefile24
-rw-r--r--lib/ExecutionEngine/OProfileJIT/Makefile18
-rw-r--r--lib/ExecutionEngine/OProfileJIT/OProfileWrapper.cpp1
-rw-r--r--lib/ExecutionEngine/Orc/CMakeLists.txt3
-rw-r--r--lib/ExecutionEngine/Orc/IndirectionUtils.cpp57
-rw-r--r--lib/ExecutionEngine/Orc/Makefile13
-rw-r--r--lib/ExecutionEngine/Orc/OrcABISupport.cpp542
-rw-r--r--lib/ExecutionEngine/Orc/OrcArchitectureSupport.cpp171
-rw-r--r--lib/ExecutionEngine/Orc/OrcCBindings.cpp34
-rw-r--r--lib/ExecutionEngine/Orc/OrcCBindingsStack.cpp43
-rw-r--r--lib/ExecutionEngine/Orc/OrcCBindingsStack.h140
-rw-r--r--lib/ExecutionEngine/Orc/OrcError.cpp10
-rw-r--r--lib/ExecutionEngine/Orc/OrcMCJITReplacement.h50
-rw-r--r--lib/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.cpp96
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/Makefile13
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp34
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp249
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp16
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h1
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp14
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h1
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp147
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h21
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h52
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp90
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h27
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h63
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h291
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h38
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h73
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h65
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h77
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h99
-rw-r--r--lib/ExecutionEngine/TargetSelect.cpp3
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"