summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/ExecutionEngine
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2015-05-27 20:26:41 +0000
committerdim <dim@FreeBSD.org>2015-05-27 20:26:41 +0000
commit5ef8fd3549d38e883a31881636be3dc2a275de20 (patch)
treebd13a22d9db57ccf3eddbc07b32c18109521d050 /contrib/llvm/lib/ExecutionEngine
parent77794ebe2d5718eb502c93ec32f8ccae4d8a0b7b (diff)
parent782067d0278612ee75d024b9b135c221c327e9e8 (diff)
downloadFreeBSD-src-5ef8fd3549d38e883a31881636be3dc2a275de20.zip
FreeBSD-src-5ef8fd3549d38e883a31881636be3dc2a275de20.tar.gz
Merge llvm trunk r238337 from ^/vendor/llvm/dist, resolve conflicts, and
preserve our customizations, where necessary.
Diffstat (limited to 'contrib/llvm/lib/ExecutionEngine')
-rw-r--r--contrib/llvm/lib/ExecutionEngine/EventListenerCommon.h68
-rw-r--r--contrib/llvm/lib/ExecutionEngine/ExecutionEngine.cpp212
-rw-r--r--contrib/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp17
-rw-r--r--contrib/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp2
-rw-r--r--contrib/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp6
-rw-r--r--contrib/llvm/lib/ExecutionEngine/IntelJITEvents/jitprofiling.c5
-rw-r--r--contrib/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp33
-rw-r--r--contrib/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp9
-rw-r--r--contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h2
-rw-r--r--contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp104
-rw-r--r--contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h86
-rw-r--r--contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp2
-rw-r--r--contrib/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp102
-rw-r--r--contrib/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp183
-rw-r--r--contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp128
-rw-r--r--contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h356
-rw-r--r--contrib/llvm/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp138
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp281
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp88
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h50
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp47
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h3
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp548
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h52
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h82
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp36
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h14
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h216
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h5
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h4
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h5
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h5
-rw-r--r--contrib/llvm/lib/ExecutionEngine/SectionMemoryManager.cpp (renamed from contrib/llvm/lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp)0
-rw-r--r--contrib/llvm/lib/ExecutionEngine/TargetSelect.cpp14
34 files changed, 2112 insertions, 791 deletions
diff --git a/contrib/llvm/lib/ExecutionEngine/EventListenerCommon.h b/contrib/llvm/lib/ExecutionEngine/EventListenerCommon.h
deleted file mode 100644
index 6f17427..0000000
--- a/contrib/llvm/lib/ExecutionEngine/EventListenerCommon.h
+++ /dev/null
@@ -1,68 +0,0 @@
-//===-- JIT.h - Abstract Execution Engine Interface -------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Common functionality for JITEventListener implementations
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef EVENT_LISTENER_COMMON_H
-#define EVENT_LISTENER_COMMON_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/IR/DebugInfo.h"
-#include "llvm/IR/Metadata.h"
-#include "llvm/IR/ValueHandle.h"
-#include "llvm/Support/Path.h"
-
-namespace llvm {
-
-namespace jitprofiling {
-
-class FilenameCache {
- // Holds the filename of each Scope, so that we can pass a null-terminated
- // string into oprofile.
- DenseMap<const MDNode *, std::string> Filenames;
- DenseMap<const MDNode *, std::string> Paths;
-
- public:
- const char *getFilename(MDNode *Scope) {
- assert(Scope->isResolved() && "Expected Scope to be resolved");
- std::string &Filename = Filenames[Scope];
- if (Filename.empty()) {
- DIScope DIScope(Scope);
- Filename = DIScope.getFilename();
- }
- return Filename.c_str();
- }
-
- const char *getFullPath(MDNode *Scope) {
- assert(Scope->isResolved() && "Expected Scope to be resolved");
- std::string &P = Paths[Scope];
- if (P.empty()) {
- DIScope DIScope(Scope);
- StringRef DirName = DIScope.getDirectory();
- StringRef FileName = DIScope.getFilename();
- SmallString<256> FullPath;
- if (DirName != "." && DirName != "") {
- FullPath = DirName;
- }
- if (FileName != "") {
- sys::path::append(FullPath, FileName);
- }
- P = FullPath.str();
- }
- return P.c_str();
- }
-};
-
-} // namespace jitprofiling
-
-} // namespace llvm
-
-#endif //EVENT_LISTENER_COMMON_H
diff --git a/contrib/llvm/lib/ExecutionEngine/ExecutionEngine.cpp b/contrib/llvm/lib/ExecutionEngine/ExecutionEngine.cpp
index 32d20ea..d7038fd 100644
--- a/contrib/llvm/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -13,13 +13,16 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
+#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/ValueHandle.h"
@@ -44,16 +47,22 @@ STATISTIC(NumGlobals , "Number of global vars initialized");
ExecutionEngine *(*ExecutionEngine::MCJITCtor)(
std::unique_ptr<Module> M, std::string *ErrorStr,
- std::unique_ptr<RTDyldMemoryManager> MCJMM,
+ std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver,
std::unique_ptr<TargetMachine> TM) = nullptr;
+
+ExecutionEngine *(*ExecutionEngine::OrcMCJITReplacementCtor)(
+ std::string *ErrorStr, std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver,
+ std::unique_ptr<TargetMachine> TM) = nullptr;
+
ExecutionEngine *(*ExecutionEngine::InterpCtor)(std::unique_ptr<Module> M,
std::string *ErrorStr) =nullptr;
void JITEventListener::anchor() {}
ExecutionEngine::ExecutionEngine(std::unique_ptr<Module> M)
- : EEState(*this),
- LazyFunctionCreator(nullptr) {
+ : LazyFunctionCreator(nullptr) {
CompilingLazily = false;
GVCompilationDisabled = false;
SymbolSearchingDisabled = false;
@@ -137,45 +146,60 @@ bool ExecutionEngine::removeModule(Module *M) {
Function *ExecutionEngine::FindFunctionNamed(const char *FnName) {
for (unsigned i = 0, e = Modules.size(); i != e; ++i) {
- if (Function *F = Modules[i]->getFunction(FnName))
+ Function *F = Modules[i]->getFunction(FnName);
+ if (F && !F->isDeclaration())
return F;
}
return nullptr;
}
-void *ExecutionEngineState::RemoveMapping(const GlobalValue *ToUnmap) {
- GlobalAddressMapTy::iterator I = GlobalAddressMap.find(ToUnmap);
- void *OldVal;
+uint64_t ExecutionEngineState::RemoveMapping(StringRef Name) {
+ GlobalAddressMapTy::iterator I = GlobalAddressMap.find(Name);
+ uint64_t OldVal;
// FIXME: This is silly, we shouldn't end up with a mapping -> 0 in the
// GlobalAddressMap.
if (I == GlobalAddressMap.end())
- OldVal = nullptr;
+ OldVal = 0;
else {
+ GlobalAddressReverseMap.erase(I->second);
OldVal = I->second;
GlobalAddressMap.erase(I);
}
- GlobalAddressReverseMap.erase(OldVal);
return OldVal;
}
+std::string ExecutionEngine::getMangledName(const GlobalValue *GV) {
+ MutexGuard locked(lock);
+ Mangler Mang(DL);
+ SmallString<128> FullName;
+ Mang.getNameWithPrefix(FullName, GV->getName());
+ return FullName.str();
+}
+
void ExecutionEngine::addGlobalMapping(const GlobalValue *GV, void *Addr) {
MutexGuard locked(lock);
+ addGlobalMapping(getMangledName(GV), (uint64_t) Addr);
+}
+
+void ExecutionEngine::addGlobalMapping(StringRef Name, uint64_t Addr) {
+ MutexGuard locked(lock);
+
+ assert(!Name.empty() && "Empty GlobalMapping symbol name!");
- DEBUG(dbgs() << "JIT: Map \'" << GV->getName()
- << "\' to [" << Addr << "]\n";);
- void *&CurVal = EEState.getGlobalAddressMap()[GV];
+ DEBUG(dbgs() << "JIT: Map \'" << Name << "\' to [" << Addr << "]\n";);
+ uint64_t &CurVal = EEState.getGlobalAddressMap()[Name];
assert((!CurVal || !Addr) && "GlobalMapping already established!");
CurVal = Addr;
// If we are using the reverse mapping, add it too.
if (!EEState.getGlobalAddressReverseMap().empty()) {
- AssertingVH<const GlobalValue> &V =
- EEState.getGlobalAddressReverseMap()[Addr];
- assert((!V || !GV) && "GlobalMapping already established!");
- V = GV;
+ std::string &V = EEState.getGlobalAddressReverseMap()[CurVal];
+ assert((!V.empty() || !Name.empty()) &&
+ "GlobalMapping already established!");
+ V = Name;
}
}
@@ -190,13 +214,19 @@ void ExecutionEngine::clearGlobalMappingsFromModule(Module *M) {
MutexGuard locked(lock);
for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI)
- EEState.RemoveMapping(FI);
+ EEState.RemoveMapping(getMangledName(FI));
for (Module::global_iterator GI = M->global_begin(), GE = M->global_end();
GI != GE; ++GI)
- EEState.RemoveMapping(GI);
+ EEState.RemoveMapping(getMangledName(GI));
}
-void *ExecutionEngine::updateGlobalMapping(const GlobalValue *GV, void *Addr) {
+uint64_t ExecutionEngine::updateGlobalMapping(const GlobalValue *GV,
+ void *Addr) {
+ MutexGuard locked(lock);
+ return updateGlobalMapping(getMangledName(GV), (uint64_t) Addr);
+}
+
+uint64_t ExecutionEngine::updateGlobalMapping(StringRef Name, uint64_t Addr) {
MutexGuard locked(lock);
ExecutionEngineState::GlobalAddressMapTy &Map =
@@ -204,10 +234,10 @@ void *ExecutionEngine::updateGlobalMapping(const GlobalValue *GV, void *Addr) {
// Deleting from the mapping?
if (!Addr)
- return EEState.RemoveMapping(GV);
+ return EEState.RemoveMapping(Name);
- void *&CurVal = Map[GV];
- void *OldVal = CurVal;
+ uint64_t &CurVal = Map[Name];
+ uint64_t OldVal = CurVal;
if (CurVal && !EEState.getGlobalAddressReverseMap().empty())
EEState.getGlobalAddressReverseMap().erase(CurVal);
@@ -215,20 +245,35 @@ void *ExecutionEngine::updateGlobalMapping(const GlobalValue *GV, void *Addr) {
// If we are using the reverse mapping, add it too.
if (!EEState.getGlobalAddressReverseMap().empty()) {
- AssertingVH<const GlobalValue> &V =
- EEState.getGlobalAddressReverseMap()[Addr];
- assert((!V || !GV) && "GlobalMapping already established!");
- V = GV;
+ std::string &V = EEState.getGlobalAddressReverseMap()[CurVal];
+ assert((!V.empty() || !Name.empty()) &&
+ "GlobalMapping already established!");
+ V = Name;
}
return OldVal;
}
-void *ExecutionEngine::getPointerToGlobalIfAvailable(const GlobalValue *GV) {
+uint64_t ExecutionEngine::getAddressToGlobalIfAvailable(StringRef S) {
MutexGuard locked(lock);
-
+ uint64_t Address = 0;
ExecutionEngineState::GlobalAddressMapTy::iterator I =
- EEState.getGlobalAddressMap().find(GV);
- return I != EEState.getGlobalAddressMap().end() ? I->second : nullptr;
+ EEState.getGlobalAddressMap().find(S);
+ if (I != EEState.getGlobalAddressMap().end())
+ Address = I->second;
+ return Address;
+}
+
+
+void *ExecutionEngine::getPointerToGlobalIfAvailable(StringRef S) {
+ MutexGuard locked(lock);
+ if (void* Address = (void *) getAddressToGlobalIfAvailable(S))
+ return Address;
+ return nullptr;
+}
+
+void *ExecutionEngine::getPointerToGlobalIfAvailable(const GlobalValue *GV) {
+ MutexGuard locked(lock);
+ return getPointerToGlobalIfAvailable(getMangledName(GV));
}
const GlobalValue *ExecutionEngine::getGlobalValueAtAddress(void *Addr) {
@@ -237,15 +282,25 @@ const GlobalValue *ExecutionEngine::getGlobalValueAtAddress(void *Addr) {
// If we haven't computed the reverse mapping yet, do so first.
if (EEState.getGlobalAddressReverseMap().empty()) {
for (ExecutionEngineState::GlobalAddressMapTy::iterator
- I = EEState.getGlobalAddressMap().begin(),
- E = EEState.getGlobalAddressMap().end(); I != E; ++I)
+ I = EEState.getGlobalAddressMap().begin(),
+ E = EEState.getGlobalAddressMap().end(); I != E; ++I) {
+ StringRef Name = I->first();
+ uint64_t Addr = I->second;
EEState.getGlobalAddressReverseMap().insert(std::make_pair(
- I->second, I->first));
+ Addr, Name));
+ }
}
- std::map<void *, AssertingVH<const GlobalValue> >::iterator I =
- EEState.getGlobalAddressReverseMap().find(Addr);
- return I != EEState.getGlobalAddressReverseMap().end() ? I->second : nullptr;
+ std::map<uint64_t, std::string>::iterator I =
+ EEState.getGlobalAddressReverseMap().find((uint64_t) Addr);
+
+ if (I != EEState.getGlobalAddressReverseMap().end()) {
+ StringRef Name = I->second;
+ for (unsigned i = 0, e = Modules.size(); i != e; ++i)
+ if (GlobalValue *GV = Modules[i]->getNamedValue(Name))
+ return GV;
+ }
+ return nullptr;
}
namespace {
@@ -393,35 +448,42 @@ int ExecutionEngine::runFunctionAsMain(Function *Fn,
return runFunction(Fn, GVArgs).IntVal.getZExtValue();
}
+EngineBuilder::EngineBuilder() : EngineBuilder(nullptr) {}
+
EngineBuilder::EngineBuilder(std::unique_ptr<Module> M)
- : M(std::move(M)), MCJMM(nullptr) {
- InitEngine();
+ : M(std::move(M)), WhichEngine(EngineKind::Either), ErrorStr(nullptr),
+ OptLevel(CodeGenOpt::Default), MemMgr(nullptr), Resolver(nullptr),
+ RelocModel(Reloc::Default), CMModel(CodeModel::JITDefault),
+ UseOrcMCJITReplacement(false) {
+// IR module verification is enabled by default in debug builds, and disabled
+// by default in release builds.
+#ifndef NDEBUG
+ VerifyModules = true;
+#else
+ VerifyModules = false;
+#endif
}
-EngineBuilder::~EngineBuilder() {}
+EngineBuilder::~EngineBuilder() = default;
EngineBuilder &EngineBuilder::setMCJITMemoryManager(
std::unique_ptr<RTDyldMemoryManager> mcjmm) {
- MCJMM = std::move(mcjmm);
+ auto SharedMM = std::shared_ptr<RTDyldMemoryManager>(std::move(mcjmm));
+ MemMgr = SharedMM;
+ Resolver = SharedMM;
return *this;
}
-void EngineBuilder::InitEngine() {
- WhichEngine = EngineKind::Either;
- ErrorStr = nullptr;
- OptLevel = CodeGenOpt::Default;
- MCJMM = nullptr;
- Options = TargetOptions();
- RelocModel = Reloc::Default;
- CMModel = CodeModel::JITDefault;
+EngineBuilder&
+EngineBuilder::setMemoryManager(std::unique_ptr<MCJITMemoryManager> MM) {
+ MemMgr = std::shared_ptr<MCJITMemoryManager>(std::move(MM));
+ return *this;
+}
-// IR module verification is enabled by default in debug builds, and disabled
-// by default in release builds.
-#ifndef NDEBUG
- VerifyModules = true;
-#else
- VerifyModules = false;
-#endif
+EngineBuilder&
+EngineBuilder::setSymbolResolver(std::unique_ptr<RuntimeDyld::SymbolResolver> SR) {
+ Resolver = std::shared_ptr<RuntimeDyld::SymbolResolver>(std::move(SR));
+ return *this;
}
ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
@@ -435,7 +497,7 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
// If the user specified a memory manager but didn't specify which engine to
// create, we assume they only want the JIT, and we fail if they only want
// the interpreter.
- if (MCJMM) {
+ if (MemMgr) {
if (WhichEngine & EngineKind::JIT)
WhichEngine = EngineKind::JIT;
else {
@@ -456,9 +518,15 @@ ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
}
ExecutionEngine *EE = nullptr;
- if (ExecutionEngine::MCJITCtor)
- EE = ExecutionEngine::MCJITCtor(std::move(M), ErrorStr, std::move(MCJMM),
- std::move(TheTM));
+ if (ExecutionEngine::OrcMCJITReplacementCtor && UseOrcMCJITReplacement) {
+ EE = ExecutionEngine::OrcMCJITReplacementCtor(ErrorStr, std::move(MemMgr),
+ std::move(Resolver),
+ std::move(TheTM));
+ EE->addModule(std::move(M));
+ } else if (ExecutionEngine::MCJITCtor)
+ EE = ExecutionEngine::MCJITCtor(std::move(M), ErrorStr, std::move(MemMgr),
+ std::move(Resolver), std::move(TheTM));
+
if (EE) {
EE->setVerifyModules(VerifyModules);
return EE;
@@ -488,7 +556,7 @@ void *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) {
return getPointerToFunction(F);
MutexGuard locked(lock);
- if (void *P = EEState.getGlobalAddressMap()[GV])
+ if (void* P = getPointerToGlobalIfAvailable(GV))
return P;
// Global variable might have been added since interpreter started.
@@ -498,7 +566,7 @@ void *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) {
else
llvm_unreachable("Global hasn't had an address allocated yet!");
- return EEState.getGlobalAddressMap()[GV];
+ return getPointerToGlobalIfAvailable(GV);
}
/// \brief Converts a Constant* into a GenericValue, including handling of
@@ -1270,25 +1338,3 @@ void ExecutionEngine::EmitGlobalVariable(const GlobalVariable *GV) {
NumInitBytes += (unsigned)GVSize;
++NumGlobals;
}
-
-ExecutionEngineState::ExecutionEngineState(ExecutionEngine &EE)
- : EE(EE), GlobalAddressMap(this) {
-}
-
-sys::Mutex *
-ExecutionEngineState::AddressMapConfig::getMutex(ExecutionEngineState *EES) {
- return &EES->EE.lock;
-}
-
-void ExecutionEngineState::AddressMapConfig::onDelete(ExecutionEngineState *EES,
- const GlobalValue *Old) {
- void *OldVal = EES->GlobalAddressMap.lookup(Old);
- EES->GlobalAddressReverseMap.erase(OldVal);
-}
-
-void ExecutionEngineState::AddressMapConfig::onRAUW(ExecutionEngineState *,
- const GlobalValue *,
- const GlobalValue *) {
- llvm_unreachable("The ExecutionEngine doesn't know how to handle a"
- " RAUW on a value it has a global mapping for.");
-}
diff --git a/contrib/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp b/contrib/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp
index aaa53f0..ce1ab59 100644
--- a/contrib/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp
@@ -177,11 +177,22 @@ LLVMBool LLVMCreateMCJITCompilerForModule(
memcpy(&options, PassedOptions, SizeOfPassedOptions);
TargetOptions targetOptions;
- targetOptions.NoFramePointerElim = options.NoFramePointerElim;
targetOptions.EnableFastISel = options.EnableFastISel;
+ std::unique_ptr<Module> Mod(unwrap(M));
+
+ if (Mod)
+ // Set function attribute "no-frame-pointer-elim" based on
+ // NoFramePointerElim.
+ for (auto &F : *Mod) {
+ auto Attrs = F.getAttributes();
+ auto Value = options.NoFramePointerElim ? "true" : "false";
+ Attrs = Attrs.addAttribute(F.getContext(), AttributeSet::FunctionIndex,
+ "no-frame-pointer-elim", Value);
+ F.setAttributes(Attrs);
+ }
std::string Error;
- EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
+ EngineBuilder builder(std::move(Mod));
builder.setEngineKind(EngineKind::JIT)
.setErrorStr(&Error)
.setOptLevel((CodeGenOpt::Level)options.OptLevel)
@@ -351,7 +362,7 @@ class SimpleBindingMemoryManager : public RTDyldMemoryManager {
public:
SimpleBindingMemoryManager(const SimpleBindingMMFunctions& Functions,
void *Opaque);
- virtual ~SimpleBindingMemoryManager();
+ ~SimpleBindingMemoryManager() override;
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
unsigned SectionID,
diff --git a/contrib/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp b/contrib/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp
index 8ef878c..1ab6203 100644
--- a/contrib/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp
@@ -103,7 +103,7 @@ public:
/// Unregisters each object that was previously registered and releases all
/// internal resources.
- virtual ~GDBJITRegistrationListener();
+ ~GDBJITRegistrationListener() override;
/// Creates an entry in the JIT registry for the buffer @p Object,
/// which must contain an object file in executable memory with any
diff --git a/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp b/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp
index ee9096b..ec67019 100644
--- a/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/IntelJITEventListener.cpp
@@ -13,11 +13,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/Config/config.h"
-#include "EventListenerCommon.h"
#include "IntelJITEventsWrapper.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Function.h"
@@ -29,7 +29,6 @@
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
-using namespace llvm::jitprofiling;
using namespace llvm::object;
#define DEBUG_TYPE "amplifier-jit-event-listener"
@@ -41,7 +40,6 @@ class IntelJITEventListener : public JITEventListener {
std::unique_ptr<IntelJITEventsWrapper> Wrapper;
MethodIDMap MethodIDs;
- FilenameCache Filenames;
typedef SmallVector<const void *, 64> MethodAddressVector;
typedef DenseMap<const void *, MethodAddressVector> ObjectMap;
@@ -105,7 +103,7 @@ void IntelJITEventListener::NotifyObjectEmitted(
// Get the address of the object image for use as a unique identifier
const void* ObjData = DebugObj.getData().data();
- DIContext* Context = DIContext::getDWARFContext(DebugObj);
+ DIContext* Context = new DWARFContextInMemory(DebugObj);
MethodAddressVector Functions;
// Use symbol info to iterate functions in the object.
diff --git a/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/jitprofiling.c b/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/jitprofiling.c
index 7b507de..e966889 100644
--- a/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/jitprofiling.c
+++ b/contrib/llvm/lib/ExecutionEngine/IntelJITEvents/jitprofiling.c
@@ -24,6 +24,7 @@
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
#include <pthread.h>
#include <dlfcn.h>
+#include <stdint.h>
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
#include <malloc.h>
#include <stdlib.h>
@@ -371,7 +372,7 @@ static int loadiJIT_Funcs()
#if ITT_PLATFORM==ITT_PLATFORM_WIN
FUNC_NotifyEvent = (TPNotify)GetProcAddress(m_libHandle, "NotifyEvent");
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
- FUNC_NotifyEvent = (TPNotify)dlsym(m_libHandle, "NotifyEvent");
+ FUNC_NotifyEvent = (TPNotify)(intptr_t)dlsym(m_libHandle, "NotifyEvent");
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
if (!FUNC_NotifyEvent)
{
@@ -382,7 +383,7 @@ static int loadiJIT_Funcs()
#if ITT_PLATFORM==ITT_PLATFORM_WIN
FUNC_Initialize = (TPInitialize)GetProcAddress(m_libHandle, "Initialize");
#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
- FUNC_Initialize = (TPInitialize)dlsym(m_libHandle, "Initialize");
+ FUNC_Initialize = (TPInitialize)(intptr_t)dlsym(m_libHandle, "Initialize");
#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
if (!FUNC_Initialize)
{
diff --git a/contrib/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp b/contrib/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp
index 93bb2d1..a26740b 100644
--- a/contrib/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/Interpreter/Execution.cpp
@@ -23,6 +23,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cmath>
using namespace llvm;
@@ -315,7 +316,7 @@ void Interpreter::visitICmpInst(ICmpInst &I) {
#define IMPLEMENT_VECTOR_FCMP(OP) \
case Type::VectorTyID: \
- if(dyn_cast<VectorType>(Ty)->getElementType()->isFloatTy()) { \
+ if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) { \
IMPLEMENT_VECTOR_FCMP_T(OP, Float); \
} else { \
IMPLEMENT_VECTOR_FCMP_T(OP, Double); \
@@ -362,7 +363,7 @@ static GenericValue executeFCMP_OEQ(GenericValue Src1, GenericValue Src2,
#define MASK_VECTOR_NANS(TY, X,Y, FLAG) \
if (TY->isVectorTy()) { \
- if (dyn_cast<VectorType>(TY)->getElementType()->isFloatTy()) { \
+ if (cast<VectorType>(TY)->getElementType()->isFloatTy()) { \
MASK_VECTOR_NANS_T(X, Y, Float, FLAG) \
} else { \
MASK_VECTOR_NANS_T(X, Y, Double, FLAG) \
@@ -464,14 +465,14 @@ static GenericValue executeFCMP_OGT(GenericValue Src1, GenericValue Src2,
return Dest; \
}
-#define IMPLEMENT_VECTOR_UNORDERED(TY, X,Y, _FUNC) \
- if (TY->isVectorTy()) { \
- GenericValue DestMask = Dest; \
- Dest = _FUNC(Src1, Src2, Ty); \
- for( size_t _i=0; _i<Src1.AggregateVal.size(); _i++) \
- if (DestMask.AggregateVal[_i].IntVal == true) \
- Dest.AggregateVal[_i].IntVal = APInt(1,true); \
- return Dest; \
+#define IMPLEMENT_VECTOR_UNORDERED(TY, X, Y, FUNC) \
+ if (TY->isVectorTy()) { \
+ GenericValue DestMask = Dest; \
+ Dest = FUNC(Src1, Src2, Ty); \
+ for (size_t _i = 0; _i < Src1.AggregateVal.size(); _i++) \
+ if (DestMask.AggregateVal[_i].IntVal == true) \
+ Dest.AggregateVal[_i].IntVal = APInt(1, true); \
+ return Dest; \
}
static GenericValue executeFCMP_UEQ(GenericValue Src1, GenericValue Src2,
@@ -535,7 +536,7 @@ static GenericValue executeFCMP_ORD(GenericValue Src1, GenericValue Src2,
if(Ty->isVectorTy()) {
assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
Dest.AggregateVal.resize( Src1.AggregateVal.size() );
- if(dyn_cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
+ if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
Dest.AggregateVal[_i].IntVal = APInt(1,
( (Src1.AggregateVal[_i].FloatVal ==
@@ -566,7 +567,7 @@ static GenericValue executeFCMP_UNO(GenericValue Src1, GenericValue Src2,
if(Ty->isVectorTy()) {
assert(Src1.AggregateVal.size() == Src2.AggregateVal.size());
Dest.AggregateVal.resize( Src1.AggregateVal.size() );
- if(dyn_cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
+ if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) {
for( size_t _i=0;_i<Src1.AggregateVal.size();_i++)
Dest.AggregateVal[_i].IntVal = APInt(1,
( (Src1.AggregateVal[_i].FloatVal !=
@@ -712,10 +713,10 @@ void Interpreter::visitBinaryOperator(BinaryOperator &I) {
// Macros to choose appropriate TY: float or double and run operation
// execution
#define FLOAT_VECTOR_OP(OP) { \
- if (dyn_cast<VectorType>(Ty)->getElementType()->isFloatTy()) \
+ if (cast<VectorType>(Ty)->getElementType()->isFloatTy()) \
FLOAT_VECTOR_FUNCTION(OP, FloatVal) \
else { \
- if (dyn_cast<VectorType>(Ty)->getElementType()->isDoubleTy()) \
+ if (cast<VectorType>(Ty)->getElementType()->isDoubleTy()) \
FLOAT_VECTOR_FUNCTION(OP, DoubleVal) \
else { \
dbgs() << "Unhandled type for OP instruction: " << *Ty << "\n"; \
@@ -744,12 +745,12 @@ void Interpreter::visitBinaryOperator(BinaryOperator &I) {
case Instruction::FMul: FLOAT_VECTOR_OP(*) break;
case Instruction::FDiv: FLOAT_VECTOR_OP(/) break;
case Instruction::FRem:
- if (dyn_cast<VectorType>(Ty)->getElementType()->isFloatTy())
+ if (cast<VectorType>(Ty)->getElementType()->isFloatTy())
for (unsigned i = 0; i < R.AggregateVal.size(); ++i)
R.AggregateVal[i].FloatVal =
fmod(Src1.AggregateVal[i].FloatVal, Src2.AggregateVal[i].FloatVal);
else {
- if (dyn_cast<VectorType>(Ty)->getElementType()->isDoubleTy())
+ if (cast<VectorType>(Ty)->getElementType()->isDoubleTy())
for (unsigned i = 0; i < R.AggregateVal.size(); ++i)
R.AggregateVal[i].DoubleVal =
fmod(Src1.AggregateVal[i].DoubleVal, Src2.AggregateVal[i].DoubleVal);
diff --git a/contrib/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp b/contrib/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
index b022101..e2fe065 100644
--- a/contrib/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp
@@ -95,16 +95,15 @@ static ExFunc lookupFunction(const Function *F) {
FunctionType *FT = F->getFunctionType();
for (unsigned i = 0, e = FT->getNumContainedTypes(); i != e; ++i)
ExtName += getTypeID(FT->getContainedType(i));
- ExtName += "_" + F->getName().str();
+ ExtName += ("_" + F->getName()).str();
sys::ScopedLock Writer(*FunctionsLock);
ExFunc FnPtr = (*FuncNames)[ExtName];
if (!FnPtr)
- FnPtr = (*FuncNames)["lle_X_" + F->getName().str()];
+ FnPtr = (*FuncNames)[("lle_X_" + F->getName()).str()];
if (!FnPtr) // Try calling a generic function... if it exists...
- FnPtr = (ExFunc)(intptr_t)
- sys::DynamicLibrary::SearchForAddressOfSymbol("lle_X_" +
- F->getName().str());
+ FnPtr = (ExFunc)(intptr_t)sys::DynamicLibrary::SearchForAddressOfSymbol(
+ ("lle_X_" + F->getName()).str());
if (FnPtr)
ExportedFunctions->insert(std::make_pair(F, FnPtr)); // Cache for later
return FnPtr;
diff --git a/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h b/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h
index 2be9c59..0dc0463 100644
--- a/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h
+++ b/contrib/llvm/lib/ExecutionEngine/Interpreter/Interpreter.h
@@ -108,7 +108,7 @@ class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
public:
explicit Interpreter(std::unique_ptr<Module> M);
- ~Interpreter();
+ ~Interpreter() override;
/// runAtExitHandlers - Run any functions registered by the program's calls to
/// atexit(3), which we intercept and store in AtExitHandlers.
diff --git a/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
index f2d53f5..7e37afe 100644
--- a/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "MCJIT.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/MCJIT.h"
@@ -15,18 +16,16 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/ObjectFile.h"
-#include "llvm/PassManager.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MutexGuard.h"
-#include "llvm/Target/TargetLowering.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm;
@@ -43,26 +42,35 @@ static struct RegisterJIT {
extern "C" void LLVMLinkInMCJIT() {
}
-ExecutionEngine *MCJIT::createJIT(std::unique_ptr<Module> M,
- std::string *ErrorStr,
- std::unique_ptr<RTDyldMemoryManager> MemMgr,
- std::unique_ptr<TargetMachine> TM) {
+ExecutionEngine*
+MCJIT::createJIT(std::unique_ptr<Module> M,
+ std::string *ErrorStr,
+ std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver,
+ std::unique_ptr<TargetMachine> TM) {
// Try to register the program as a source of symbols to resolve against.
//
// FIXME: Don't do this here.
sys::DynamicLibrary::LoadLibraryPermanently(nullptr, nullptr);
- std::unique_ptr<RTDyldMemoryManager> MM = std::move(MemMgr);
- if (!MM)
- MM = std::unique_ptr<SectionMemoryManager>(new SectionMemoryManager());
+ if (!MemMgr || !Resolver) {
+ auto RTDyldMM = std::make_shared<SectionMemoryManager>();
+ if (!MemMgr)
+ MemMgr = RTDyldMM;
+ if (!Resolver)
+ Resolver = RTDyldMM;
+ }
- return new MCJIT(std::move(M), std::move(TM), std::move(MM));
+ return new MCJIT(std::move(M), std::move(TM), std::move(MemMgr),
+ std::move(Resolver));
}
MCJIT::MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> tm,
- std::unique_ptr<RTDyldMemoryManager> MM)
+ std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver)
: ExecutionEngine(std::move(M)), TM(std::move(tm)), Ctx(nullptr),
- MemMgr(this, std::move(MM)), Dyld(&MemMgr), ObjCache(nullptr) {
+ MemMgr(std::move(MemMgr)), Resolver(*this, std::move(Resolver)),
+ Dyld(*this->MemMgr, this->Resolver), ObjCache(nullptr) {
// FIXME: We are managing our modules, so we do not want the base class
// ExecutionEngine to manage them as well. To avoid double destruction
// of the first (and only) module added in ExecutionEngine constructor
@@ -77,7 +85,7 @@ MCJIT::MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> tm,
Modules.clear();
OwnedModules.addModule(std::move(First));
- setDataLayout(TM->getSubtargetImpl()->getDataLayout());
+ setDataLayout(TM->getDataLayout());
RegisterJITEventListener(JITEventListener::createGDBRegistrationListener());
}
@@ -137,10 +145,9 @@ std::unique_ptr<MemoryBuffer> MCJIT::emitObject(Module *M) {
// MCJIT instance, since these conditions are tested by our caller,
// generateCodeForModule.
- PassManager PM;
+ legacy::PassManager PM;
- M->setDataLayout(TM->getSubtargetImpl()->getDataLayout());
- PM.add(new DataLayoutPass());
+ M->setDataLayout(*TM->getDataLayout());
// The RuntimeDyld will take ownership of this shortly
SmallVector<char, 4096> ObjBufferSV;
@@ -224,7 +231,7 @@ void MCJIT::finalizeLoadedModules() {
Dyld.registerEHFrames();
// Set page permissions.
- MemMgr.finalizeMemory();
+ MemMgr->finalizeMemory();
}
// FIXME: Rename this.
@@ -256,11 +263,11 @@ void MCJIT::finalizeModule(Module *M) {
finalizeLoadedModules();
}
-uint64_t MCJIT::getExistingSymbolAddress(const std::string &Name) {
- Mangler Mang(TM->getSubtargetImpl()->getDataLayout());
+RuntimeDyld::SymbolInfo MCJIT::findExistingSymbol(const std::string &Name) {
+ Mangler Mang(TM->getDataLayout());
SmallString<128> FullName;
Mang.getNameWithPrefix(FullName, Name);
- return Dyld.getSymbolLoadAddress(FullName);
+ return Dyld.getSymbol(FullName);
}
Module *MCJIT::findModuleForSymbol(const std::string &Name,
@@ -287,14 +294,17 @@ Module *MCJIT::findModuleForSymbol(const std::string &Name,
}
uint64_t MCJIT::getSymbolAddress(const std::string &Name,
- bool CheckFunctionsOnly)
-{
+ bool CheckFunctionsOnly) {
+ return findSymbol(Name, CheckFunctionsOnly).getAddress();
+}
+
+RuntimeDyld::SymbolInfo MCJIT::findSymbol(const std::string &Name,
+ bool CheckFunctionsOnly) {
MutexGuard locked(lock);
// First, check to see if we already have this symbol.
- uint64_t Addr = getExistingSymbolAddress(Name);
- if (Addr)
- return Addr;
+ if (auto Sym = findExistingSymbol(Name))
+ return Sym;
for (object::OwningBinary<object::Archive> &OB : Archives) {
object::Archive *A = OB.getBinary();
@@ -313,9 +323,8 @@ uint64_t MCJIT::getSymbolAddress(const std::string &Name,
// This causes the object file to be loaded.
addObjectFile(std::move(OF));
// The address should be here now.
- Addr = getExistingSymbolAddress(Name);
- if (Addr)
- return Addr;
+ if (auto Sym = findExistingSymbol(Name))
+ return Sym;
}
}
}
@@ -326,15 +335,18 @@ uint64_t MCJIT::getSymbolAddress(const std::string &Name,
generateCodeForModule(M);
// Check the RuntimeDyld table again, it should be there now.
- return getExistingSymbolAddress(Name);
+ return findExistingSymbol(Name);
}
// If a LazyFunctionCreator is installed, use it to get/create the function.
// FIXME: Should we instead have a LazySymbolCreator callback?
- if (LazyFunctionCreator)
- Addr = (uint64_t)LazyFunctionCreator(Name);
+ if (LazyFunctionCreator) {
+ auto Addr = static_cast<uint64_t>(
+ reinterpret_cast<uintptr_t>(LazyFunctionCreator(Name)));
+ return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported);
+ }
- return Addr;
+ return nullptr;
}
uint64_t MCJIT::getGlobalValueAddress(const std::string &Name) {
@@ -357,7 +369,7 @@ uint64_t MCJIT::getFunctionAddress(const std::string &Name) {
void *MCJIT::getPointerToFunction(Function *F) {
MutexGuard locked(lock);
- Mangler Mang(TM->getSubtargetImpl()->getDataLayout());
+ Mangler Mang(TM->getDataLayout());
SmallString<128> Name;
TM->getNameWithPrefix(Name, F, Mang);
@@ -386,7 +398,7 @@ void *MCJIT::getPointerToFunction(Function *F) {
//
// This is the accessor for the target address, so make sure to check the
// load address of the symbol, not the local address.
- return (void*)Dyld.getSymbolLoadAddress(Name);
+ return (void*)Dyld.getSymbol(Name).getAddress();
}
void MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
@@ -410,7 +422,8 @@ Function *MCJIT::FindFunctionNamedInModulePtrSet(const char *FnName,
ModulePtrSet::iterator I,
ModulePtrSet::iterator E) {
for (; I != E; ++I) {
- if (Function *F = (*I)->getFunction(FnName))
+ Function *F = (*I)->getFunction(FnName);
+ if (F && !F->isDeclaration())
return F;
}
return nullptr;
@@ -530,7 +543,9 @@ GenericValue MCJIT::runFunction(Function *F,
void *MCJIT::getPointerToNamedFunction(StringRef Name, bool AbortOnFailure) {
if (!isSymbolSearchingDisabled()) {
- void *ptr = MemMgr.getPointerToNamedFunction(Name, false);
+ void *ptr =
+ reinterpret_cast<void*>(
+ static_cast<uintptr_t>(Resolver.findSymbol(Name).getAddress()));
if (ptr)
return ptr;
}
@@ -568,7 +583,7 @@ void MCJIT::UnregisterJITEventListener(JITEventListener *L) {
void MCJIT::NotifyObjectEmitted(const object::ObjectFile& Obj,
const RuntimeDyld::LoadedObjectInfo &L) {
MutexGuard locked(lock);
- MemMgr.notifyObjectLoaded(this, Obj);
+ MemMgr->notifyObjectLoaded(this, Obj);
for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) {
EventListeners[I]->NotifyObjectEmitted(Obj, L);
}
@@ -580,15 +595,16 @@ void MCJIT::NotifyFreeingObject(const object::ObjectFile& Obj) {
L->NotifyFreeingObject(Obj);
}
-uint64_t LinkingMemoryManager::getSymbolAddress(const std::string &Name) {
- uint64_t Result = ParentEngine->getSymbolAddress(Name, false);
+RuntimeDyld::SymbolInfo
+LinkingSymbolResolver::findSymbol(const std::string &Name) {
+ auto Result = ParentEngine.findSymbol(Name, false);
// If the symbols wasn't found and it begins with an underscore, try again
// without the underscore.
if (!Result && Name[0] == '_')
- Result = ParentEngine->getSymbolAddress(Name.substr(1), false);
+ Result = ParentEngine.findSymbol(Name.substr(1), false);
if (Result)
return Result;
- if (ParentEngine->isSymbolSearchingDisabled())
- return 0;
- return ClientMM->getSymbolAddress(Name);
+ if (ParentEngine.isSymbolSearchingDisabled())
+ return nullptr;
+ return ClientResolver->findSymbol(Name);
}
diff --git a/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h b/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h
index f55dd60..59e9949 100644
--- a/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h
+++ b/contrib/llvm/lib/ExecutionEngine/MCJIT/MCJIT.h
@@ -10,12 +10,13 @@
#ifndef LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H
#define LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H
-#include "ObjectBuffer.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
+#include "llvm/ExecutionEngine/ObjectMemoryBuffer.h"
+#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/IR/Module.h"
@@ -26,59 +27,23 @@ class MCJIT;
// functions across modules that it owns. It aggregates the memory manager
// that is passed in to the MCJIT constructor and defers most functionality
// to that object.
-class LinkingMemoryManager : public RTDyldMemoryManager {
+class LinkingSymbolResolver : public RuntimeDyld::SymbolResolver {
public:
- LinkingMemoryManager(MCJIT *Parent,
- std::unique_ptr<RTDyldMemoryManager> MM)
- : ParentEngine(Parent), ClientMM(std::move(MM)) {}
+ LinkingSymbolResolver(MCJIT &Parent,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver)
+ : ParentEngine(Parent), ClientResolver(std::move(Resolver)) {}
- uint64_t getSymbolAddress(const std::string &Name) override;
+ RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) override;
- // Functions deferred to client memory manager
- uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID,
- StringRef SectionName) override {
- return ClientMM->allocateCodeSection(Size, Alignment, SectionID, SectionName);
- }
-
- uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID, StringRef SectionName,
- bool IsReadOnly) override {
- return ClientMM->allocateDataSection(Size, Alignment,
- SectionID, SectionName, IsReadOnly);
- }
-
- void reserveAllocationSpace(uintptr_t CodeSize, uintptr_t DataSizeRO,
- uintptr_t DataSizeRW) override {
- return ClientMM->reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW);
- }
-
- bool needsToReserveAllocationSpace() override {
- return ClientMM->needsToReserveAllocationSpace();
- }
-
- void notifyObjectLoaded(ExecutionEngine *EE,
- const object::ObjectFile &Obj) override {
- ClientMM->notifyObjectLoaded(EE, Obj);
- }
-
- void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
- size_t Size) override {
- ClientMM->registerEHFrames(Addr, LoadAddr, Size);
- }
-
- void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,
- size_t Size) override {
- ClientMM->deregisterEHFrames(Addr, LoadAddr, Size);
- }
-
- bool finalizeMemory(std::string *ErrMsg = nullptr) override {
- return ClientMM->finalizeMemory(ErrMsg);
+ // MCJIT doesn't support logical dylibs.
+ RuntimeDyld::SymbolInfo
+ findSymbolInLogicalDylib(const std::string &Name) override {
+ return nullptr;
}
private:
- MCJIT *ParentEngine;
- std::unique_ptr<RTDyldMemoryManager> ClientMM;
+ MCJIT &ParentEngine;
+ std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver;
};
// About Module states: added->loaded->finalized.
@@ -103,7 +68,8 @@ private:
class MCJIT : public ExecutionEngine {
MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> tm,
- std::unique_ptr<RTDyldMemoryManager> MemMgr);
+ std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver);
typedef llvm::SmallPtrSet<Module *, 4> ModulePtrSet;
@@ -214,7 +180,8 @@ class MCJIT : public ExecutionEngine {
std::unique_ptr<TargetMachine> TM;
MCContext *Ctx;
- LinkingMemoryManager MemMgr;
+ std::shared_ptr<MCJITMemoryManager> MemMgr;
+ LinkingSymbolResolver Resolver;
RuntimeDyld Dyld;
std::vector<JITEventListener*> EventListeners;
@@ -238,7 +205,7 @@ class MCJIT : public ExecutionEngine {
ModulePtrSet::iterator E);
public:
- ~MCJIT();
+ ~MCJIT() override;
/// @name ExecutionEngine interface implementation
/// @{
@@ -324,17 +291,22 @@ public:
MCJITCtor = createJIT;
}
- static ExecutionEngine *createJIT(std::unique_ptr<Module> M,
- std::string *ErrorStr,
- std::unique_ptr<RTDyldMemoryManager> MemMgr,
- std::unique_ptr<TargetMachine> TM);
+ static ExecutionEngine*
+ createJIT(std::unique_ptr<Module> M,
+ std::string *ErrorStr,
+ std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver,
+ std::unique_ptr<TargetMachine> TM);
// @}
+ RuntimeDyld::SymbolInfo findSymbol(const std::string &Name,
+ bool CheckFunctionsOnly);
+ // DEPRECATED - Please use findSymbol instead.
// This is not directly exposed via the ExecutionEngine API, but it is
// used by the LinkingMemoryManager.
uint64_t getSymbolAddress(const std::string &Name,
- bool CheckFunctionsOnly);
+ bool CheckFunctionsOnly);
protected:
/// emitObject -- Generate a JITed object in memory from the specified module
@@ -348,7 +320,7 @@ protected:
const RuntimeDyld::LoadedObjectInfo &L);
void NotifyFreeingObject(const object::ObjectFile& Obj);
- uint64_t getExistingSymbolAddress(const std::string &Name);
+ RuntimeDyld::SymbolInfo findExistingSymbol(const std::string &Name);
Module *findModuleForSymbol(const std::string &Name,
bool CheckFunctionsOnly);
};
diff --git a/contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp b/contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp
index 9ab4003..23e7662 100644
--- a/contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/OProfileJIT/OProfileJITEventListener.cpp
@@ -13,7 +13,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/Config/config.h"
-#include "EventListenerCommon.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/OProfileWrapper.h"
@@ -28,7 +27,6 @@
#include <fcntl.h>
using namespace llvm;
-using namespace llvm::jitprofiling;
using namespace llvm::object;
#define DEBUG_TYPE "oprofile-jit-event-listener"
diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/contrib/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
new file mode 100644
index 0000000..b7220db
--- /dev/null
+++ b/contrib/llvm/lib/ExecutionEngine/Orc/ExecutionUtils.cpp
@@ -0,0 +1,102 @@
+//===---- ExecutionUtils.cpp - Utilities for executing functions in Orc ---===//
+//
+// 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/ExecutionUtils.h"
+
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Module.h"
+
+namespace llvm {
+namespace orc {
+
+CtorDtorIterator::CtorDtorIterator(const GlobalVariable *GV, bool End)
+ : InitList(
+ GV ? dyn_cast_or_null<ConstantArray>(GV->getInitializer()) : nullptr),
+ I((InitList && End) ? InitList->getNumOperands() : 0) {
+}
+
+bool CtorDtorIterator::operator==(const CtorDtorIterator &Other) const {
+ assert(InitList == Other.InitList && "Incomparable iterators.");
+ return I == Other.I;
+}
+
+bool CtorDtorIterator::operator!=(const CtorDtorIterator &Other) const {
+ return !(*this == Other);
+}
+
+CtorDtorIterator& CtorDtorIterator::operator++() {
+ ++I;
+ return *this;
+}
+
+CtorDtorIterator CtorDtorIterator::operator++(int) {
+ CtorDtorIterator Temp = *this;
+ ++I;
+ return Temp;
+}
+
+CtorDtorIterator::Element CtorDtorIterator::operator*() const {
+ ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(I));
+ assert(CS && "Unrecognized type in llvm.global_ctors/llvm.global_dtors");
+
+ Constant *FuncC = CS->getOperand(1);
+ Function *Func = nullptr;
+
+ // Extract function pointer, pulling off any casts.
+ while (FuncC) {
+ if (Function *F = dyn_cast_or_null<Function>(FuncC)) {
+ Func = F;
+ break;
+ } else if (ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(FuncC)) {
+ if (CE->isCast())
+ FuncC = dyn_cast_or_null<ConstantExpr>(CE->getOperand(0));
+ else
+ break;
+ } else {
+ // This isn't anything we recognize. Bail out with Func left set to null.
+ break;
+ }
+ }
+
+ ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));
+ Value *Data = CS->getOperand(2);
+ return Element(Priority->getZExtValue(), Func, Data);
+}
+
+iterator_range<CtorDtorIterator> getConstructors(const Module &M) {
+ const GlobalVariable *CtorsList = M.getNamedGlobal("llvm.global_ctors");
+ return make_range(CtorDtorIterator(CtorsList, false),
+ CtorDtorIterator(CtorsList, true));
+}
+
+iterator_range<CtorDtorIterator> getDestructors(const Module &M) {
+ const GlobalVariable *DtorsList = M.getNamedGlobal("llvm.global_dtors");
+ return make_range(CtorDtorIterator(DtorsList, false),
+ CtorDtorIterator(DtorsList, true));
+}
+
+void LocalCXXRuntimeOverrides::runDestructors() {
+ auto& CXXDestructorDataPairs = DSOHandleOverride;
+ for (auto &P : CXXDestructorDataPairs)
+ P.first(P.second);
+ CXXDestructorDataPairs.clear();
+}
+
+int LocalCXXRuntimeOverrides::CXAAtExitOverride(DestructorPtr Destructor,
+ void *Arg, void *DSOHandle) {
+ auto& CXXDestructorDataPairs =
+ *reinterpret_cast<CXXDestructorDataPairList*>(DSOHandle);
+ CXXDestructorDataPairs.push_back(std::make_pair(Destructor, Arg));
+ return 0;
+}
+
+} // End namespace orc.
+} // End namespace llvm.
diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/contrib/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
new file mode 100644
index 0000000..4ed8730
--- /dev/null
+++ b/contrib/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
@@ -0,0 +1,183 @@
+//===---- IndirectionUtils.cpp - Utilities for call indirection in Orc ----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include <set>
+#include <sstream>
+
+namespace llvm {
+namespace orc {
+
+Constant* createIRTypedAddress(FunctionType &FT, TargetAddress Addr) {
+ Constant *AddrIntVal =
+ ConstantInt::get(Type::getInt64Ty(FT.getContext()), Addr);
+ Constant *AddrPtrVal =
+ ConstantExpr::getCast(Instruction::IntToPtr, AddrIntVal,
+ PointerType::get(&FT, 0));
+ return AddrPtrVal;
+}
+
+GlobalVariable* createImplPointer(PointerType &PT, Module &M,
+ const Twine &Name, Constant *Initializer) {
+ if (!Initializer)
+ Initializer = Constant::getNullValue(&PT);
+ auto IP = new GlobalVariable(M, &PT, false, GlobalValue::ExternalLinkage,
+ Initializer, Name, nullptr,
+ GlobalValue::NotThreadLocal, 0, true);
+ IP->setVisibility(GlobalValue::HiddenVisibility);
+ return IP;
+}
+
+void makeStub(Function &F, GlobalVariable &ImplPointer) {
+ assert(F.isDeclaration() && "Can't turn a definition into a stub.");
+ assert(F.getParent() && "Function isn't in a module.");
+ Module &M = *F.getParent();
+ BasicBlock *EntryBlock = BasicBlock::Create(M.getContext(), "entry", &F);
+ IRBuilder<> Builder(EntryBlock);
+ LoadInst *ImplAddr = Builder.CreateLoad(&ImplPointer);
+ std::vector<Value*> CallArgs;
+ for (auto &A : F.args())
+ CallArgs.push_back(&A);
+ CallInst *Call = Builder.CreateCall(ImplAddr, CallArgs);
+ Call->setTailCall();
+ Call->setAttributes(F.getAttributes());
+ if (F.getReturnType()->isVoidTy())
+ Builder.CreateRetVoid();
+ else
+ Builder.CreateRet(Call);
+}
+
+// Utility class for renaming global values and functions during partitioning.
+class GlobalRenamer {
+public:
+
+ static bool needsRenaming(const Value &New) {
+ if (!New.hasName() || New.getName().startswith("\01L"))
+ return true;
+ return false;
+ }
+
+ const std::string& getRename(const Value &Orig) {
+ // See if we have a name for this global.
+ {
+ auto I = Names.find(&Orig);
+ if (I != Names.end())
+ return I->second;
+ }
+
+ // Nope. Create a new one.
+ // FIXME: Use a more robust uniquing scheme. (This may blow up if the user
+ // writes a "__orc_anon[[:digit:]]* method).
+ unsigned ID = Names.size();
+ std::ostringstream NameStream;
+ NameStream << "__orc_anon" << ID++;
+ auto I = Names.insert(std::make_pair(&Orig, NameStream.str()));
+ return I.first->second;
+ }
+private:
+ DenseMap<const Value*, std::string> Names;
+};
+
+static void raiseVisibilityOnValue(GlobalValue &V, GlobalRenamer &R) {
+ if (V.hasLocalLinkage()) {
+ if (R.needsRenaming(V))
+ V.setName(R.getRename(V));
+ V.setLinkage(GlobalValue::ExternalLinkage);
+ V.setVisibility(GlobalValue::HiddenVisibility);
+ }
+ V.setUnnamedAddr(false);
+ assert(!R.needsRenaming(V) && "Invalid global name.");
+}
+
+void makeAllSymbolsExternallyAccessible(Module &M) {
+ GlobalRenamer Renamer;
+
+ for (auto &F : M)
+ raiseVisibilityOnValue(F, Renamer);
+
+ for (auto &GV : M.globals())
+ raiseVisibilityOnValue(GV, Renamer);
+}
+
+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()),
+ F.getLinkage(), F.getName(), &Dst);
+ NewF->copyAttributesFrom(&F);
+
+ if (VMap) {
+ (*VMap)[&F] = NewF;
+ auto NewArgI = NewF->arg_begin();
+ for (auto ArgI = F.arg_begin(), ArgE = F.arg_end(); ArgI != ArgE;
+ ++ArgI, ++NewArgI)
+ (*VMap)[ArgI] = NewArgI;
+ }
+
+ return NewF;
+}
+
+void moveFunctionBody(Function &OrigF, ValueToValueMapTy &VMap,
+ ValueMaterializer *Materializer,
+ Function *NewF) {
+ assert(!OrigF.isDeclaration() && "Nothing to move");
+ if (!NewF)
+ NewF = cast<Function>(VMap[&OrigF]);
+ else
+ assert(VMap[&OrigF] == NewF && "Incorrect function mapping in VMap.");
+ assert(NewF && "Function mapping missing from VMap.");
+ assert(NewF->getParent() != OrigF.getParent() &&
+ "moveFunctionBody should only be used to move bodies between "
+ "modules.");
+
+ SmallVector<ReturnInst *, 8> Returns; // Ignore returns cloned.
+ CloneFunctionInto(NewF, &OrigF, VMap, /*ModuleLevelChanges=*/true, Returns,
+ "", nullptr, nullptr, Materializer);
+ OrigF.deleteBody();
+}
+
+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(),
+ GV.getLinkage(), nullptr, GV.getName(), nullptr,
+ GV.getThreadLocalMode(), GV.getType()->getAddressSpace());
+ NewGV->copyAttributesFrom(&GV);
+ if (VMap)
+ (*VMap)[&GV] = NewGV;
+ return NewGV;
+}
+
+void moveGlobalVariableInitializer(GlobalVariable &OrigGV,
+ ValueToValueMapTy &VMap,
+ ValueMaterializer *Materializer,
+ GlobalVariable *NewGV) {
+ assert(OrigGV.hasInitializer() && "Nothing to move");
+ if (!NewGV)
+ NewGV = cast<GlobalVariable>(VMap[&OrigGV]);
+ else
+ assert(VMap[&OrigGV] == NewGV &&
+ "Incorrect global variable mapping in VMap.");
+ assert(NewGV->getParent() != OrigGV.getParent() &&
+ "moveGlobalVariable should only be used to move initializers between "
+ "modules");
+
+ NewGV->setInitializer(MapValue(OrigGV.getInitializer(), VMap, RF_None,
+ nullptr, Materializer));
+}
+
+} // End namespace orc.
+} // End namespace llvm.
diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp b/contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp
new file mode 100644
index 0000000..48fd31e
--- /dev/null
+++ b/contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.cpp
@@ -0,0 +1,128 @@
+//===-------- OrcMCJITReplacement.cpp - Orc-based MCJIT replacement -------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "OrcMCJITReplacement.h"
+#include "llvm/ExecutionEngine/GenericValue.h"
+
+namespace {
+
+static struct RegisterJIT {
+ RegisterJIT() { llvm::orc::OrcMCJITReplacement::Register(); }
+} JITRegistrator;
+
+}
+
+extern "C" void LLVMLinkInOrcMCJITReplacement() {}
+
+namespace llvm {
+namespace orc {
+
+GenericValue
+OrcMCJITReplacement::runFunction(Function *F,
+ const std::vector<GenericValue> &ArgValues) {
+ assert(F && "Function *F was null at entry to run()");
+
+ void *FPtr = getPointerToFunction(F);
+ assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
+ FunctionType *FTy = F->getFunctionType();
+ Type *RetTy = FTy->getReturnType();
+
+ assert((FTy->getNumParams() == ArgValues.size() ||
+ (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&
+ "Wrong number of arguments passed into function!");
+ assert(FTy->getNumParams() == ArgValues.size() &&
+ "This doesn't support passing arguments through varargs (yet)!");
+
+ // Handle some common cases first. These cases correspond to common `main'
+ // prototypes.
+ if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
+ switch (ArgValues.size()) {
+ case 3:
+ if (FTy->getParamType(0)->isIntegerTy(32) &&
+ FTy->getParamType(1)->isPointerTy() &&
+ FTy->getParamType(2)->isPointerTy()) {
+ int (*PF)(int, char **, const char **) =
+ (int (*)(int, char **, const char **))(intptr_t)FPtr;
+
+ // Call the function.
+ GenericValue rv;
+ rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
+ (char **)GVTOP(ArgValues[1]),
+ (const char **)GVTOP(ArgValues[2])));
+ return rv;
+ }
+ break;
+ case 2:
+ if (FTy->getParamType(0)->isIntegerTy(32) &&
+ FTy->getParamType(1)->isPointerTy()) {
+ int (*PF)(int, char **) = (int (*)(int, char **))(intptr_t)FPtr;
+
+ // Call the function.
+ GenericValue rv;
+ rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
+ (char **)GVTOP(ArgValues[1])));
+ return rv;
+ }
+ break;
+ case 1:
+ if (FTy->getNumParams() == 1 && FTy->getParamType(0)->isIntegerTy(32)) {
+ GenericValue rv;
+ int (*PF)(int) = (int (*)(int))(intptr_t)FPtr;
+ rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
+ return rv;
+ }
+ break;
+ }
+ }
+
+ // Handle cases where no arguments are passed first.
+ if (ArgValues.empty()) {
+ GenericValue rv;
+ switch (RetTy->getTypeID()) {
+ default:
+ llvm_unreachable("Unknown return type for function call!");
+ case Type::IntegerTyID: {
+ unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
+ if (BitWidth == 1)
+ rv.IntVal = APInt(BitWidth, ((bool (*)())(intptr_t)FPtr)());
+ else if (BitWidth <= 8)
+ rv.IntVal = APInt(BitWidth, ((char (*)())(intptr_t)FPtr)());
+ else if (BitWidth <= 16)
+ rv.IntVal = APInt(BitWidth, ((short (*)())(intptr_t)FPtr)());
+ else if (BitWidth <= 32)
+ rv.IntVal = APInt(BitWidth, ((int (*)())(intptr_t)FPtr)());
+ else if (BitWidth <= 64)
+ rv.IntVal = APInt(BitWidth, ((int64_t (*)())(intptr_t)FPtr)());
+ else
+ llvm_unreachable("Integer types > 64 bits not supported");
+ return rv;
+ }
+ case Type::VoidTyID:
+ rv.IntVal = APInt(32, ((int (*)())(intptr_t)FPtr)());
+ return rv;
+ case Type::FloatTyID:
+ rv.FloatVal = ((float (*)())(intptr_t)FPtr)();
+ return rv;
+ case Type::DoubleTyID:
+ rv.DoubleVal = ((double (*)())(intptr_t)FPtr)();
+ return rv;
+ case Type::X86_FP80TyID:
+ case Type::FP128TyID:
+ case Type::PPC_FP128TyID:
+ llvm_unreachable("long double not supported yet");
+ case Type::PointerTyID:
+ return PTOGV(((void *(*)())(intptr_t)FPtr)());
+ }
+ }
+
+ llvm_unreachable("Full-featured argument passing not supported yet!");
+}
+
+} // End namespace orc.
+} // End namespace llvm.
diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h b/contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
new file mode 100644
index 0000000..4023344
--- /dev/null
+++ b/contrib/llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
@@ -0,0 +1,356 @@
+//===---- OrcMCJITReplacement.h - Orc based MCJIT replacement ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Orc based MCJIT replacement.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H
+#define LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H
+
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
+#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
+#include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
+#include "llvm/Object/Archive.h"
+
+namespace llvm {
+namespace orc {
+
+class OrcMCJITReplacement : public ExecutionEngine {
+
+ // OrcMCJITReplacement needs to do a little extra book-keeping to ensure that
+ // Orc's automatic finalization doesn't kick in earlier than MCJIT clients are
+ // expecting - see finalizeMemory.
+ class MCJITReplacementMemMgr : public MCJITMemoryManager {
+ public:
+ MCJITReplacementMemMgr(OrcMCJITReplacement &M,
+ std::shared_ptr<MCJITMemoryManager> ClientMM)
+ : M(M), ClientMM(std::move(ClientMM)) {}
+
+ uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID,
+ StringRef SectionName) override {
+ uint8_t *Addr =
+ ClientMM->allocateCodeSection(Size, Alignment, SectionID,
+ SectionName);
+ M.SectionsAllocatedSinceLastLoad.insert(Addr);
+ return Addr;
+ }
+
+ uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID, StringRef SectionName,
+ bool IsReadOnly) override {
+ uint8_t *Addr = ClientMM->allocateDataSection(Size, Alignment, SectionID,
+ SectionName, IsReadOnly);
+ M.SectionsAllocatedSinceLastLoad.insert(Addr);
+ return Addr;
+ }
+
+ void reserveAllocationSpace(uintptr_t CodeSize, uintptr_t DataSizeRO,
+ uintptr_t DataSizeRW) override {
+ return ClientMM->reserveAllocationSpace(CodeSize, DataSizeRO,
+ DataSizeRW);
+ }
+
+ bool needsToReserveAllocationSpace() override {
+ return ClientMM->needsToReserveAllocationSpace();
+ }
+
+ void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
+ size_t Size) override {
+ return ClientMM->registerEHFrames(Addr, LoadAddr, Size);
+ }
+
+ void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,
+ size_t Size) override {
+ return ClientMM->deregisterEHFrames(Addr, LoadAddr, Size);
+ }
+
+ void notifyObjectLoaded(ExecutionEngine *EE,
+ const object::ObjectFile &O) override {
+ return ClientMM->notifyObjectLoaded(EE, O);
+ }
+
+ bool finalizeMemory(std::string *ErrMsg = nullptr) override {
+ // Each set of objects loaded will be finalized exactly once, but since
+ // symbol lookup during relocation may recursively trigger the
+ // loading/relocation of other modules, and since we're forwarding all
+ // finalizeMemory calls to a single underlying memory manager, we need to
+ // defer forwarding the call on until all necessary objects have been
+ // loaded. Otherwise, during the relocation of a leaf object, we will end
+ // up finalizing memory, causing a crash further up the stack when we
+ // attempt to apply relocations to finalized memory.
+ // To avoid finalizing too early, look at how many objects have been
+ // loaded but not yet finalized. This is a bit of a hack that relies on
+ // the fact that we're lazily emitting object files: The only way you can
+ // get more than one set of objects loaded but not yet finalized is if
+ // they were loaded during relocation of another set.
+ if (M.UnfinalizedSections.size() == 1)
+ return ClientMM->finalizeMemory(ErrMsg);
+ return false;
+ }
+
+ private:
+ OrcMCJITReplacement &M;
+ std::shared_ptr<MCJITMemoryManager> ClientMM;
+ };
+
+ class LinkingResolver : public RuntimeDyld::SymbolResolver {
+ public:
+ LinkingResolver(OrcMCJITReplacement &M) : M(M) {}
+
+ RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) override {
+ return M.findMangledSymbol(Name);
+ }
+
+ RuntimeDyld::SymbolInfo
+ findSymbolInLogicalDylib(const std::string &Name) override {
+ return M.ClientResolver->findSymbolInLogicalDylib(Name);
+ }
+
+ private:
+ OrcMCJITReplacement &M;
+ };
+
+private:
+
+ static ExecutionEngine *
+ createOrcMCJITReplacement(std::string *ErrorMsg,
+ std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver,
+ std::unique_ptr<TargetMachine> TM) {
+ return new OrcMCJITReplacement(std::move(MemMgr), std::move(Resolver),
+ std::move(TM));
+ }
+
+public:
+ static void Register() {
+ OrcMCJITReplacementCtor = createOrcMCJITReplacement;
+ }
+
+ OrcMCJITReplacement(
+ std::shared_ptr<MCJITMemoryManager> MemMgr,
+ std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver,
+ std::unique_ptr<TargetMachine> TM)
+ : TM(std::move(TM)), MemMgr(*this, std::move(MemMgr)),
+ Resolver(*this), ClientResolver(std::move(ClientResolver)),
+ Mang(this->TM->getDataLayout()),
+ NotifyObjectLoaded(*this), NotifyFinalized(*this),
+ ObjectLayer(NotifyObjectLoaded, NotifyFinalized),
+ CompileLayer(ObjectLayer, SimpleCompiler(*this->TM)),
+ LazyEmitLayer(CompileLayer) {
+ setDataLayout(this->TM->getDataLayout());
+ }
+
+ void addModule(std::unique_ptr<Module> M) override {
+
+ // If this module doesn't have a DataLayout attached then attach the
+ // default.
+ if (M->getDataLayout().isDefault())
+ M->setDataLayout(*getDataLayout());
+
+ Modules.push_back(std::move(M));
+ std::vector<Module *> Ms;
+ Ms.push_back(&*Modules.back());
+ LazyEmitLayer.addModuleSet(std::move(Ms), &MemMgr, &Resolver);
+ }
+
+ void addObjectFile(std::unique_ptr<object::ObjectFile> O) override {
+ std::vector<std::unique_ptr<object::ObjectFile>> Objs;
+ Objs.push_back(std::move(O));
+ ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);
+ }
+
+ 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));
+ auto H =
+ ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);
+
+ std::vector<std::unique_ptr<MemoryBuffer>> Bufs;
+ Bufs.push_back(std::move(Buf));
+ ObjectLayer.takeOwnershipOfBuffers(H, std::move(Bufs));
+ }
+
+ void addArchive(object::OwningBinary<object::Archive> A) override {
+ Archives.push_back(std::move(A));
+ }
+
+ uint64_t getSymbolAddress(StringRef Name) {
+ return findSymbol(Name).getAddress();
+ }
+
+ RuntimeDyld::SymbolInfo findSymbol(StringRef Name) {
+ return findMangledSymbol(Mangle(Name));
+ }
+
+ void finalizeObject() override {
+ // This is deprecated - Aim to remove in ExecutionEngine.
+ // REMOVE IF POSSIBLE - Doesn't make sense for New JIT.
+ }
+
+ void mapSectionAddress(const void *LocalAddress,
+ uint64_t TargetAddress) override {
+ for (auto &P : UnfinalizedSections)
+ if (P.second.count(LocalAddress))
+ ObjectLayer.mapSectionAddress(P.first, LocalAddress, TargetAddress);
+ }
+
+ uint64_t getGlobalValueAddress(const std::string &Name) override {
+ return getSymbolAddress(Name);
+ }
+
+ uint64_t getFunctionAddress(const std::string &Name) override {
+ return getSymbolAddress(Name);
+ }
+
+ void *getPointerToFunction(Function *F) override {
+ uint64_t FAddr = getSymbolAddress(F->getName());
+ return reinterpret_cast<void *>(static_cast<uintptr_t>(FAddr));
+ }
+
+ void *getPointerToNamedFunction(StringRef Name,
+ bool AbortOnFailure = true) override {
+ uint64_t Addr = getSymbolAddress(Name);
+ if (!Addr && AbortOnFailure)
+ llvm_unreachable("Missing symbol!");
+ return reinterpret_cast<void *>(static_cast<uintptr_t>(Addr));
+ }
+
+ GenericValue runFunction(Function *F,
+ const std::vector<GenericValue> &ArgValues) override;
+
+ void setObjectCache(ObjectCache *NewCache) override {
+ CompileLayer.setObjectCache(NewCache);
+ }
+
+private:
+
+ RuntimeDyld::SymbolInfo findMangledSymbol(StringRef Name) {
+ if (auto Sym = LazyEmitLayer.findSymbol(Name, false))
+ return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
+ if (auto Sym = ClientResolver->findSymbol(Name))
+ return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
+ if (auto Sym = scanArchives(Name))
+ return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
+
+ return nullptr;
+ }
+
+ JITSymbol scanArchives(StringRef 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 (ChildIt != A->child_end()) {
+ // FIXME: Support nested archives?
+ ErrorOr<std::unique_ptr<object::Binary>> ChildBinOrErr =
+ ChildIt->getAsBinary();
+ if (ChildBinOrErr.getError())
+ continue;
+ std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
+ if (ChildBin->isObject()) {
+ std::vector<std::unique_ptr<object::ObjectFile>> ObjSet;
+ ObjSet.push_back(std::unique_ptr<object::ObjectFile>(
+ static_cast<object::ObjectFile *>(ChildBin.release())));
+ ObjectLayer.addObjectSet(std::move(ObjSet), &MemMgr, &Resolver);
+ if (auto Sym = ObjectLayer.findSymbol(Name, true))
+ return Sym;
+ }
+ }
+ }
+ return nullptr;
+ }
+
+ 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) {}
+
+ void operator()(ObjectLinkingLayerBase::ObjSetHandleT H,
+ const ObjListT &Objects,
+ const LoadedObjInfoListT &Infos) const {
+ M.UnfinalizedSections[H] = std::move(M.SectionsAllocatedSinceLastLoad);
+ M.SectionsAllocatedSinceLastLoad = SectionAddrSet();
+ 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]);
+ };
+
+ private:
+ OrcMCJITReplacement &M;
+ };
+
+ class NotifyFinalizedT {
+ public:
+ NotifyFinalizedT(OrcMCJITReplacement &M) : M(M) {}
+ void operator()(ObjectLinkingLayerBase::ObjSetHandleT H) {
+ M.UnfinalizedSections.erase(H);
+ }
+
+ private:
+ OrcMCJITReplacement &M;
+ };
+
+ std::string Mangle(StringRef Name) {
+ std::string MangledName;
+ {
+ raw_string_ostream MangledNameStream(MangledName);
+ Mang.getNameWithPrefix(MangledNameStream, Name);
+ }
+ return MangledName;
+ }
+
+ typedef ObjectLinkingLayer<NotifyObjectLoadedT> ObjectLayerT;
+ typedef IRCompileLayer<ObjectLayerT> CompileLayerT;
+ typedef LazyEmittingLayer<CompileLayerT> LazyEmitLayerT;
+
+ std::unique_ptr<TargetMachine> TM;
+ MCJITReplacementMemMgr MemMgr;
+ LinkingResolver Resolver;
+ std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver;
+ Mangler Mang;
+
+ NotifyObjectLoadedT NotifyObjectLoaded;
+ NotifyFinalizedT NotifyFinalized;
+
+ ObjectLayerT ObjectLayer;
+ CompileLayerT CompileLayer;
+ LazyEmitLayerT LazyEmitLayer;
+
+ // We need to store ObjLayerT::ObjSetHandles for each of the object sets
+ // that have been emitted but not yet finalized so that we can forward the
+ // mapSectionAddress calls appropriately.
+ typedef std::set<const void *> SectionAddrSet;
+ struct ObjSetHandleCompare {
+ bool operator()(ObjectLayerT::ObjSetHandleT H1,
+ ObjectLayerT::ObjSetHandleT H2) const {
+ return &*H1 < &*H2;
+ }
+ };
+ SectionAddrSet SectionsAllocatedSinceLastLoad;
+ std::map<ObjectLayerT::ObjSetHandleT, SectionAddrSet, ObjSetHandleCompare>
+ UnfinalizedSections;
+
+ std::vector<object::OwningBinary<object::Archive>> Archives;
+};
+
+} // End namespace orc.
+} // End namespace llvm.
+
+#endif // LLVM_LIB_EXECUTIONENGINE_ORC_MCJITREPLACEMENT_H
diff --git a/contrib/llvm/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp b/contrib/llvm/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp
new file mode 100644
index 0000000..258868a
--- /dev/null
+++ b/contrib/llvm/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp
@@ -0,0 +1,138 @@
+#include "llvm/ADT/Triple.h"
+#include "llvm/ExecutionEngine/Orc/OrcTargetSupport.h"
+#include <array>
+
+using namespace llvm::orc;
+
+namespace {
+
+uint64_t executeCompileCallback(JITCompileCallbackManagerBase *JCBM,
+ TargetAddress CallbackID) {
+ return JCBM->executeCompileCallback(CallbackID);
+}
+
+}
+
+namespace llvm {
+namespace orc {
+
+const char* OrcX86_64::ResolverBlockName = "orc_resolver_block";
+
+void OrcX86_64::insertResolverBlock(
+ Module &M, JITCompileCallbackManagerBase &JCBM) {
+
+ // Trampoline code-sequence length, used to get trampoline address from return
+ // address.
+ const unsigned X86_64_TrampolineLength = 6;
+
+ // List of x86-64 GPRs to save. Note - RBP saved separately below.
+ std::array<const char *, 14> GPRs = {{
+ "rax", "rbx", "rcx", "rdx",
+ "rsi", "rdi", "r8", "r9",
+ "r10", "r11", "r12", "r13",
+ "r14", "r15"
+ }};
+
+ // Address of the executeCompileCallback function.
+ uint64_t CallbackAddr =
+ static_cast<uint64_t>(
+ reinterpret_cast<uintptr_t>(executeCompileCallback));
+
+ std::ostringstream AsmStream;
+ Triple TT(M.getTargetTriple());
+
+ // Switch to text section.
+ if (TT.getOS() == Triple::Darwin)
+ AsmStream << ".section __TEXT,__text,regular,pure_instructions\n"
+ << ".align 4, 0x90\n";
+ else
+ AsmStream << ".text\n"
+ << ".align 16, 0x90\n";
+
+ // Bake in a pointer to the callback manager immediately before the
+ // start of the resolver function.
+ AsmStream << "jit_callback_manager_addr:\n"
+ << " .quad " << &JCBM << "\n";
+
+ // Start the resolver function.
+ AsmStream << ResolverBlockName << ":\n"
+ << " pushq %rbp\n"
+ << " movq %rsp, %rbp\n";
+
+ // Store the GPRs.
+ for (const auto &GPR : GPRs)
+ AsmStream << " pushq %" << GPR << "\n";
+
+ // Store floating-point state with FXSAVE.
+ // Note: We need to keep the stack 16-byte aligned, so if we've emitted an odd
+ // number of 64-bit pushes so far (GPRs.size() plus 1 for RBP) then add
+ // an extra 64 bits of padding to the FXSave area.
+ unsigned Padding = (GPRs.size() + 1) % 2 ? 8 : 0;
+ unsigned FXSaveSize = 512 + Padding;
+ AsmStream << " subq $" << FXSaveSize << ", %rsp\n"
+ << " fxsave64 (%rsp)\n"
+
+ // Load callback manager address, compute trampoline address, call JIT.
+ << " lea jit_callback_manager_addr(%rip), %rdi\n"
+ << " movq (%rdi), %rdi\n"
+ << " movq 0x8(%rbp), %rsi\n"
+ << " subq $" << X86_64_TrampolineLength << ", %rsi\n"
+ << " movabsq $" << CallbackAddr << ", %rax\n"
+ << " callq *%rax\n"
+
+ // Replace the return to the trampoline with the return address of the
+ // compiled function body.
+ << " movq %rax, 0x8(%rbp)\n"
+
+ // Restore the floating point state.
+ << " fxrstor64 (%rsp)\n"
+ << " addq $" << FXSaveSize << ", %rsp\n";
+
+ for (const auto &GPR : make_range(GPRs.rbegin(), GPRs.rend()))
+ AsmStream << " popq %" << GPR << "\n";
+
+ // Restore original RBP and return to compiled function body.
+ AsmStream << " popq %rbp\n"
+ << " retq\n";
+
+ M.appendModuleInlineAsm(AsmStream.str());
+}
+
+OrcX86_64::LabelNameFtor
+OrcX86_64::insertCompileCallbackTrampolines(Module &M,
+ TargetAddress ResolverBlockAddr,
+ unsigned NumCalls,
+ unsigned StartIndex) {
+ const char *ResolverBlockPtrName = "Lorc_resolve_block_addr";
+
+ std::ostringstream AsmStream;
+ Triple TT(M.getTargetTriple());
+
+ if (TT.getOS() == Triple::Darwin)
+ AsmStream << ".section __TEXT,__text,regular,pure_instructions\n"
+ << ".align 4, 0x90\n";
+ else
+ AsmStream << ".text\n"
+ << ".align 16, 0x90\n";
+
+ AsmStream << ResolverBlockPtrName << ":\n"
+ << " .quad " << ResolverBlockAddr << "\n";
+
+ auto GetLabelName =
+ [=](unsigned I) {
+ std::ostringstream LabelStream;
+ LabelStream << "orc_jcc_" << (StartIndex + I);
+ return LabelStream.str();
+ };
+
+ for (unsigned I = 0; I < NumCalls; ++I)
+ AsmStream << GetLabelName(I) << ":\n"
+ << " callq *" << ResolverBlockPtrName << "(%rip)\n";
+
+ M.appendModuleInlineAsm(AsmStream.str());
+
+ return GetLabelName;
+}
+
+} // End namespace orc.
+} // End namespace llvm.
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index 304014e..24a3ec1 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -13,10 +13,12 @@
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "RuntimeDyldCheckerImpl.h"
+#include "RuntimeDyldCOFF.h"
#include "RuntimeDyldELF.h"
#include "RuntimeDyldImpl.h"
#include "RuntimeDyldMachO.h"
#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/COFF.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MutexGuard.h"
@@ -55,7 +57,8 @@ static void dumpSectionMemory(const SectionEntry &S, StringRef State) {
unsigned BytesRemaining = S.Size;
if (StartPadding) {
- dbgs() << "\n" << format("0x%016" PRIx64, LoadAddr & ~(ColsPerRow - 1)) << ":";
+ dbgs() << "\n" << format("0x%016" PRIx64,
+ LoadAddr & ~(uint64_t)(ColsPerRow - 1)) << ":";
while (StartPadding--)
dbgs() << " ";
}
@@ -90,7 +93,7 @@ void RuntimeDyldImpl::resolveRelocations() {
// entry provides the section to which the relocation will be applied.
uint64_t Addr = Sections[i].LoadAddress;
DEBUG(dbgs() << "Resolving relocations Section #" << i << "\t"
- << format("0x%x", Addr) << "\n");
+ << format("%p", (uintptr_t)Addr) << "\n");
DEBUG(dumpSectionMemory(Sections[i], "before relocations"));
resolveRelocationList(Relocations[i], Addr);
DEBUG(dumpSectionMemory(Sections[i], "after relocations"));
@@ -149,68 +152,65 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
// Compute the memory size required to load all sections to be loaded
// and pass this information to the memory manager
- if (MemMgr->needsToReserveAllocationSpace()) {
+ if (MemMgr.needsToReserveAllocationSpace()) {
uint64_t CodeSize = 0, DataSizeRO = 0, DataSizeRW = 0;
computeTotalAllocSize(Obj, CodeSize, DataSizeRO, DataSizeRW);
- MemMgr->reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW);
+ MemMgr.reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW);
}
// Used sections from the object file
ObjSectionToIDMap LocalSections;
// Common symbols requiring allocation, with their sizes and alignments
- CommonSymbolMap CommonSymbols;
- // Maximum required total memory to allocate all common symbols
- uint64_t CommonSize = 0;
+ CommonSymbolList CommonSymbols;
// Parse symbols
DEBUG(dbgs() << "Parse symbols:\n");
for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E;
++I) {
- object::SymbolRef::Type SymType;
- StringRef Name;
- Check(I->getType(SymType));
- Check(I->getName(Name));
-
uint32_t Flags = I->getFlags();
bool IsCommon = Flags & SymbolRef::SF_Common;
- if (IsCommon) {
- // Add the common symbols to a list. We'll allocate them all below.
- if (!GlobalSymbolTable.count(Name)) {
- uint32_t Align;
- Check(I->getAlignment(Align));
- uint64_t Size = 0;
- Check(I->getSize(Size));
- CommonSize += Size + Align;
- CommonSymbols[*I] = CommonSymbolInfo(Size, Align);
- }
- } else {
+ if (IsCommon)
+ CommonSymbols.push_back(*I);
+ else {
+ object::SymbolRef::Type SymType;
+ Check(I->getType(SymType));
+
if (SymType == object::SymbolRef::ST_Function ||
SymType == object::SymbolRef::ST_Data ||
SymType == object::SymbolRef::ST_Unknown) {
+
+ StringRef Name;
uint64_t SectOffset;
- StringRef SectionData;
- section_iterator SI = Obj.section_end();
+ Check(I->getName(Name));
Check(getOffset(*I, SectOffset));
+ section_iterator SI = Obj.section_end();
Check(I->getSection(SI));
if (SI == Obj.section_end())
continue;
+ StringRef SectionData;
Check(SI->getContents(SectionData));
bool IsCode = SI->isText();
unsigned SectionID =
findOrEmitSection(Obj, *SI, IsCode, LocalSections);
- DEBUG(dbgs() << "\tOffset: " << format("%p", (uintptr_t)SectOffset)
- << " flags: " << Flags << " SID: " << SectionID);
- GlobalSymbolTable[Name] = SymbolLoc(SectionID, SectOffset);
+ DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name
+ << " SID: " << SectionID << " Offset: "
+ << format("%p", (uintptr_t)SectOffset)
+ << " flags: " << Flags << "\n");
+ JITSymbolFlags RTDyldSymFlags = JITSymbolFlags::None;
+ if (Flags & SymbolRef::SF_Weak)
+ RTDyldSymFlags |= JITSymbolFlags::Weak;
+ if (Flags & SymbolRef::SF_Exported)
+ RTDyldSymFlags |= JITSymbolFlags::Exported;
+ GlobalSymbolTable[Name] =
+ SymbolTableEntry(SectionID, SectOffset, RTDyldSymFlags);
}
}
- DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name << "\n");
}
// Allocate common symbols
- if (CommonSize != 0)
- emitCommonSymbols(Obj, CommonSymbols, CommonSize, GlobalSymbolTable);
+ emitCommonSymbols(Obj, CommonSymbols);
// Parse and process relocations
DEBUG(dbgs() << "Parse relocations:\n");
@@ -220,6 +220,9 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
StubMap Stubs;
section_iterator RelocatedSection = SI->getRelocatedSection();
+ if (RelocatedSection == SE)
+ continue;
+
relocation_iterator I = SI->relocation_begin();
relocation_iterator E = SI->relocation_end();
@@ -267,6 +270,20 @@ static bool isRequiredForExecution(const SectionRef &Section) {
const ObjectFile *Obj = Section.getObject();
if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj))
return ELFObj->getSectionFlags(Section) & ELF::SHF_ALLOC;
+ if (auto *COFFObj = dyn_cast<object::COFFObjectFile>(Obj)) {
+ 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
+ // 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);
+ return HasContent && !IsDiscardable;
+ }
+
assert(isa<MachOObjectFile>(Obj));
return true;
}
@@ -276,6 +293,15 @@ static bool isReadOnlyData(const SectionRef &Section) {
if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj))
return !(ELFObj->getSectionFlags(Section) &
(ELF::SHF_WRITE | ELF::SHF_EXECINSTR));
+ if (auto *COFFObj = dyn_cast<object::COFFObjectFile>(Obj))
+ return ((COFFObj->getCOFFSection(Section)->Characteristics &
+ (COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
+ | COFF::IMAGE_SCN_MEM_READ
+ | COFF::IMAGE_SCN_MEM_WRITE))
+ ==
+ (COFF::IMAGE_SCN_CNT_INITIALIZED_DATA
+ | COFF::IMAGE_SCN_MEM_READ));
+
assert(isa<MachOObjectFile>(Obj));
return false;
}
@@ -284,6 +310,9 @@ static bool isZeroInit(const SectionRef &Section) {
const ObjectFile *Obj = Section.getObject();
if (auto *ELFObj = dyn_cast<object::ELFObjectFileBase>(Obj))
return ELFObj->getSectionType(Section) == ELF::SHT_NOBITS;
+ if (auto *COFFObj = dyn_cast<object::COFFObjectFile>(Obj))
+ return COFFObj->getCOFFSection(Section)->Characteristics &
+ COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
auto *MachO = cast<MachOObjectFile>(Obj);
unsigned SectionType = MachO->getSectionType(Section);
@@ -332,19 +361,20 @@ void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,
if (Name == ".eh_frame")
SectionSize += 4;
- if (SectionSize > 0) {
- // save the total size of the section
- if (IsCode) {
- CodeSectionSizes.push_back(SectionSize);
- } else if (IsReadOnly) {
- ROSectionSizes.push_back(SectionSize);
- } else {
- RWSectionSizes.push_back(SectionSize);
- }
- // update the max alignment
- if (Alignment > MaxAlignment) {
- MaxAlignment = Alignment;
- }
+ if (!SectionSize)
+ SectionSize = 1;
+
+ if (IsCode) {
+ CodeSectionSizes.push_back(SectionSize);
+ } else if (IsReadOnly) {
+ ROSectionSizes.push_back(SectionSize);
+ } else {
+ RWSectionSizes.push_back(SectionSize);
+ }
+
+ // update the max alignment
+ if (Alignment > MaxAlignment) {
+ MaxAlignment = Alignment;
}
}
}
@@ -442,38 +472,73 @@ void RuntimeDyldImpl::writeBytesUnaligned(uint64_t Value, uint8_t *Dst,
}
void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
- const CommonSymbolMap &CommonSymbols,
- uint64_t TotalSize,
- SymbolTableMap &SymbolTable) {
+ CommonSymbolList &CommonSymbols) {
+ if (CommonSymbols.empty())
+ return;
+
+ uint64_t CommonSize = 0;
+ CommonSymbolList SymbolsToAllocate;
+
+ DEBUG(dbgs() << "Processing common symbols...\n");
+
+ for (const auto &Sym : CommonSymbols) {
+ StringRef Name;
+ Check(Sym.getName(Name));
+
+ // Skip common symbols already elsewhere.
+ if (GlobalSymbolTable.count(Name) ||
+ Resolver.findSymbolInLogicalDylib(Name)) {
+ DEBUG(dbgs() << "\tSkipping already emitted common symbol '" << Name
+ << "'\n");
+ continue;
+ }
+
+ uint32_t Align = 0;
+ uint64_t Size = 0;
+ Check(Sym.getAlignment(Align));
+ Check(Sym.getSize(Size));
+
+ CommonSize += Align + Size;
+ SymbolsToAllocate.push_back(Sym);
+ }
+
// Allocate memory for the section
unsigned SectionID = Sections.size();
- uint8_t *Addr = MemMgr->allocateDataSection(TotalSize, sizeof(void *),
- SectionID, StringRef(), false);
+ uint8_t *Addr = MemMgr.allocateDataSection(CommonSize, sizeof(void *),
+ SectionID, StringRef(), false);
if (!Addr)
report_fatal_error("Unable to allocate memory for common symbols!");
uint64_t Offset = 0;
- Sections.push_back(SectionEntry("<common symbols>", Addr, TotalSize, 0));
- memset(Addr, 0, TotalSize);
+ Sections.push_back(SectionEntry("<common symbols>", Addr, CommonSize, 0));
+ memset(Addr, 0, CommonSize);
DEBUG(dbgs() << "emitCommonSection SectionID: " << SectionID << " new addr: "
- << format("%p", Addr) << " DataSize: " << TotalSize << "\n");
+ << format("%p", Addr) << " DataSize: " << CommonSize << "\n");
// Assign the address of each symbol
- for (CommonSymbolMap::const_iterator it = CommonSymbols.begin(),
- itEnd = CommonSymbols.end(); it != itEnd; ++it) {
- uint64_t Size = it->second.first;
- uint64_t Align = it->second.second;
+ for (auto &Sym : SymbolsToAllocate) {
+ uint32_t Align;
+ uint64_t Size;
StringRef Name;
- it->first.getName(Name);
+ Check(Sym.getAlignment(Align));
+ Check(Sym.getSize(Size));
+ Check(Sym.getName(Name));
if (Align) {
// This symbol has an alignment requirement.
uint64_t AlignOffset = OffsetToAlignment((uint64_t)Addr, Align);
Addr += AlignOffset;
Offset += AlignOffset;
- DEBUG(dbgs() << "Allocating common symbol " << Name << " address "
- << format("%p\n", Addr));
}
- SymbolTable[Name.data()] = SymbolLoc(SectionID, Offset);
+ uint32_t Flags = Sym.getFlags();
+ JITSymbolFlags RTDyldSymFlags = JITSymbolFlags::None;
+ if (Flags & SymbolRef::SF_Weak)
+ RTDyldSymFlags |= JITSymbolFlags::Weak;
+ if (Flags & SymbolRef::SF_Exported)
+ RTDyldSymFlags |= JITSymbolFlags::Exported;
+ DEBUG(dbgs() << "Allocating common symbol " << Name << " address "
+ << format("%p", Addr) << "\n");
+ GlobalSymbolTable[Name] =
+ SymbolTableEntry(SectionID, Offset, RTDyldSymFlags);
Offset += Size;
Addr += Size;
}
@@ -483,7 +548,6 @@ unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
const SectionRef &Section, bool IsCode) {
StringRef data;
- Check(Section.getContents(data));
uint64_t Alignment64 = Section.getAlignment();
unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;
@@ -510,21 +574,26 @@ unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
uint8_t *Addr;
const char *pData = nullptr;
+ // 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));
+ // Virtual sections have no data in the object image, so leave pData = 0
+ if (!IsVirtual)
+ pData = data.data();
+
// Some sections, such as debug info, don't need to be loaded for execution.
// Leave those where they are.
if (IsRequired) {
Allocate = DataSize + PaddingSize + StubBufSize;
- Addr = IsCode ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID,
- Name)
- : MemMgr->allocateDataSection(Allocate, Alignment, SectionID,
- Name, IsReadOnly);
+ if (!Allocate)
+ Allocate = 1;
+ Addr = IsCode ? MemMgr.allocateCodeSection(Allocate, Alignment, SectionID,
+ Name)
+ : MemMgr.allocateDataSection(Allocate, Alignment, SectionID,
+ Name, IsReadOnly);
if (!Addr)
report_fatal_error("Unable to allocate section memory!");
- // Virtual sections have no data in the object image, so leave pData = 0
- if (!IsVirtual)
- pData = data.data();
-
// Zero-initialize or copy the data from the image
if (IsZeroInit || IsVirtual)
memset(Addr, 0, DataSize);
@@ -589,14 +658,15 @@ void RuntimeDyldImpl::addRelocationForSymbol(const RelocationEntry &RE,
// Relocation by symbol. If the symbol is found in the global symbol table,
// create an appropriate section relocation. Otherwise, add it to
// ExternalSymbolRelocations.
- SymbolTableMap::const_iterator Loc = GlobalSymbolTable.find(SymbolName);
+ RTDyldSymbolTable::const_iterator Loc = GlobalSymbolTable.find(SymbolName);
if (Loc == GlobalSymbolTable.end()) {
ExternalSymbolRelocations[SymbolName].push_back(RE);
} else {
// Copy the RE since we want to modify its addend.
RelocationEntry RECopy = RE;
- RECopy.Addend += Loc->second.second;
- Relocations[Loc->second.first].push_back(RECopy);
+ const auto &SymInfo = Loc->second;
+ RECopy.Addend += SymInfo.getOffset();
+ Relocations[SymInfo.getSectionID()].push_back(RECopy);
}
}
@@ -721,11 +791,11 @@ void RuntimeDyldImpl::resolveExternalSymbols() {
resolveRelocationList(Relocs, 0);
} else {
uint64_t Addr = 0;
- SymbolTableMap::const_iterator Loc = GlobalSymbolTable.find(Name);
+ RTDyldSymbolTable::const_iterator Loc = GlobalSymbolTable.find(Name);
if (Loc == GlobalSymbolTable.end()) {
- // This is an external symbol, try to get its address from
- // MemoryManager.
- Addr = MemMgr->getSymbolAddress(Name.data());
+ // This is an external symbol, try to get its address from the symbol
+ // resolver.
+ 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
@@ -736,8 +806,9 @@ void RuntimeDyldImpl::resolveExternalSymbols() {
} else {
// We found the symbol in our global table. It was probably in a
// Module that we loaded previously.
- SymbolLoc SymLoc = Loc->second;
- Addr = getSectionLoadAddress(SymLoc.first) + SymLoc.second;
+ const auto &SymInfo = Loc->second;
+ Addr = getSectionLoadAddress(SymInfo.getSectionID()) +
+ SymInfo.getOffset();
}
// FIXME: Implement error handling that doesn't kill the host program!
@@ -745,7 +816,6 @@ void RuntimeDyldImpl::resolveExternalSymbols() {
report_fatal_error("Program used external function '" + Name +
"' which could not be resolved!");
- updateGOTEntries(Name, Addr);
DEBUG(dbgs() << "Resolving relocations Name: " << Name << "\t"
<< format("0x%lx", Addr) << "\n");
// This list may have been updated when we called getSymbolAddress, so
@@ -770,7 +840,12 @@ uint64_t RuntimeDyld::LoadedObjectInfo::getSectionLoadAddress(
return 0;
}
-RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
+void RuntimeDyld::MemoryManager::anchor() {}
+void RuntimeDyld::SymbolResolver::anchor() {}
+
+RuntimeDyld::RuntimeDyld(RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : MemMgr(MemMgr), Resolver(Resolver) {
// FIXME: There's a potential issue lurking here if a single instance of
// RuntimeDyld is used to load multiple objects. The current implementation
// associates a single memory manager with a RuntimeDyld instance. Even
@@ -778,26 +853,40 @@ RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
// they share a single memory manager. This can become a problem when page
// permissions are applied.
Dyld = nullptr;
- MM = mm;
ProcessAllSections = false;
Checker = nullptr;
}
RuntimeDyld::~RuntimeDyld() {}
+static std::unique_ptr<RuntimeDyldCOFF>
+createRuntimeDyldCOFF(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM,
+ RuntimeDyld::SymbolResolver &Resolver,
+ bool ProcessAllSections, RuntimeDyldCheckerImpl *Checker) {
+ std::unique_ptr<RuntimeDyldCOFF> Dyld =
+ RuntimeDyldCOFF::create(Arch, MM, Resolver);
+ Dyld->setProcessAllSections(ProcessAllSections);
+ Dyld->setRuntimeDyldChecker(Checker);
+ return Dyld;
+}
+
static std::unique_ptr<RuntimeDyldELF>
-createRuntimeDyldELF(RTDyldMemoryManager *MM, bool ProcessAllSections,
- RuntimeDyldCheckerImpl *Checker) {
- std::unique_ptr<RuntimeDyldELF> Dyld(new RuntimeDyldELF(MM));
+createRuntimeDyldELF(RuntimeDyld::MemoryManager &MM,
+ RuntimeDyld::SymbolResolver &Resolver,
+ bool ProcessAllSections, RuntimeDyldCheckerImpl *Checker) {
+ std::unique_ptr<RuntimeDyldELF> Dyld(new RuntimeDyldELF(MM, Resolver));
Dyld->setProcessAllSections(ProcessAllSections);
Dyld->setRuntimeDyldChecker(Checker);
return Dyld;
}
static std::unique_ptr<RuntimeDyldMachO>
-createRuntimeDyldMachO(Triple::ArchType Arch, RTDyldMemoryManager *MM,
- bool ProcessAllSections, RuntimeDyldCheckerImpl *Checker) {
- std::unique_ptr<RuntimeDyldMachO> Dyld(RuntimeDyldMachO::create(Arch, MM));
+createRuntimeDyldMachO(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM,
+ RuntimeDyld::SymbolResolver &Resolver,
+ bool ProcessAllSections,
+ RuntimeDyldCheckerImpl *Checker) {
+ std::unique_ptr<RuntimeDyldMachO> Dyld =
+ RuntimeDyldMachO::create(Arch, MM, Resolver);
Dyld->setProcessAllSections(ProcessAllSections);
Dyld->setRuntimeDyldChecker(Checker);
return Dyld;
@@ -807,10 +896,14 @@ std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
RuntimeDyld::loadObject(const ObjectFile &Obj) {
if (!Dyld) {
if (Obj.isELF())
- Dyld = createRuntimeDyldELF(MM, ProcessAllSections, Checker);
+ Dyld = createRuntimeDyldELF(MemMgr, Resolver, ProcessAllSections, Checker);
else if (Obj.isMachO())
Dyld = createRuntimeDyldMachO(
- static_cast<Triple::ArchType>(Obj.getArch()), MM,
+ static_cast<Triple::ArchType>(Obj.getArch()), MemMgr, Resolver,
+ ProcessAllSections, Checker);
+ else if (Obj.isCOFF())
+ Dyld = createRuntimeDyldCOFF(
+ static_cast<Triple::ArchType>(Obj.getArch()), MemMgr, Resolver,
ProcessAllSections, Checker);
else
report_fatal_error("Incompatible object format!");
@@ -822,16 +915,16 @@ RuntimeDyld::loadObject(const ObjectFile &Obj) {
return Dyld->loadObject(Obj);
}
-void *RuntimeDyld::getSymbolAddress(StringRef Name) const {
+void *RuntimeDyld::getSymbolLocalAddress(StringRef Name) const {
if (!Dyld)
return nullptr;
- return Dyld->getSymbolAddress(Name);
+ return Dyld->getSymbolLocalAddress(Name);
}
-uint64_t RuntimeDyld::getSymbolLoadAddress(StringRef Name) const {
+RuntimeDyld::SymbolInfo RuntimeDyld::getSymbol(StringRef Name) const {
if (!Dyld)
- return 0;
- return Dyld->getSymbolLoadAddress(Name);
+ return nullptr;
+ return Dyld->getSymbol(Name);
}
void RuntimeDyld::resolveRelocations() { Dyld->resolveRelocations(); }
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp
new file mode 100644
index 0000000..c8d3d22
--- /dev/null
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp
@@ -0,0 +1,88 @@
+//===-- RuntimeDyldCOFF.cpp - Run-time dynamic linker for MC-JIT -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation of COFF support for the MC-JIT runtime dynamic linker.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RuntimeDyldCOFF.h"
+#include "Targets/RuntimeDyldCOFFX86_64.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Object/ObjectFile.h"
+
+using namespace llvm;
+using namespace llvm::object;
+
+#define DEBUG_TYPE "dyld"
+
+namespace {
+
+class LoadedCOFFObjectInfo
+ : public RuntimeDyld::LoadedObjectInfoHelper<LoadedCOFFObjectInfo> {
+public:
+ LoadedCOFFObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx,
+ unsigned EndIdx)
+ : LoadedObjectInfoHelper(RTDyld, BeginIdx, EndIdx) {}
+
+ OwningBinary<ObjectFile>
+ getObjectForDebug(const ObjectFile &Obj) const override {
+ return OwningBinary<ObjectFile>();
+ }
+};
+}
+
+namespace llvm {
+
+std::unique_ptr<RuntimeDyldCOFF>
+llvm::RuntimeDyldCOFF::create(Triple::ArchType Arch,
+ RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver) {
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported target for RuntimeDyldCOFF.");
+ break;
+ case Triple::x86_64:
+ return make_unique<RuntimeDyldCOFFX86_64>(MemMgr, Resolver);
+ }
+}
+
+std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
+RuntimeDyldCOFF::loadObject(const object::ObjectFile &O) {
+ unsigned SectionStartIdx, SectionEndIdx;
+ std::tie(SectionStartIdx, SectionEndIdx) = loadObjectImpl(O);
+ return llvm::make_unique<LoadedCOFFObjectInfo>(*this, SectionStartIdx,
+ SectionEndIdx);
+}
+
+uint64_t RuntimeDyldCOFF::getSymbolOffset(const SymbolRef &Sym) {
+ uint64_t Address;
+ if (Sym.getAddress(Address))
+ return UnknownAddressOrSize;
+
+ if (Address == UnknownAddressOrSize)
+ return UnknownAddressOrSize;
+
+ const ObjectFile *Obj = Sym.getObject();
+ section_iterator SecI(Obj->section_end());
+ if (Sym.getSection(SecI))
+ return UnknownAddressOrSize;
+
+ if (SecI == Obj->section_end())
+ return UnknownAddressOrSize;
+
+ uint64_t SectionAddress = SecI->getAddress();
+ return Address - SectionAddress;
+}
+
+bool RuntimeDyldCOFF::isCompatibleFile(const object::ObjectFile &Obj) const {
+ return Obj.isCOFF();
+}
+
+} // namespace llvm
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h
new file mode 100644
index 0000000..32b8fa2
--- /dev/null
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h
@@ -0,0 +1,50 @@
+//===-- RuntimeDyldCOFF.h - Run-time dynamic linker for MC-JIT ---*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// COFF support for MC-JIT runtime dynamic linker.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_RUNTIME_DYLD_COFF_H
+#define LLVM_RUNTIME_DYLD_COFF_H
+
+#include "RuntimeDyldImpl.h"
+#include "llvm/ADT/DenseMap.h"
+
+#define DEBUG_TYPE "dyld"
+
+using namespace llvm;
+
+namespace llvm {
+
+// Common base class for COFF dynamic linker support.
+// Concrete subclasses for each target can be found in ./Targets.
+class RuntimeDyldCOFF : public RuntimeDyldImpl {
+
+public:
+ std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
+ loadObject(const object::ObjectFile &Obj) override;
+ bool isCompatibleFile(const object::ObjectFile &Obj) const override;
+
+ static std::unique_ptr<RuntimeDyldCOFF>
+ create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver);
+
+protected:
+ RuntimeDyldCOFF(RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldImpl(MemMgr, Resolver) {}
+ uint64_t getSymbolOffset(const SymbolRef &Sym);
+};
+
+} // end namespace llvm
+
+#undef DEBUG_TYPE
+
+#endif
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
index f3e5c77..957571b 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
@@ -260,9 +260,7 @@ private:
<< "'. Instruction has only "
<< format("%i", Inst.getNumOperands())
<< " operands.\nInstruction is:\n ";
- Inst.dump_pretty(ErrMsgStream,
- Checker.Disassembler->getContext().getAsmInfo(),
- Checker.InstPrinter);
+ Inst.dump_pretty(ErrMsgStream, Checker.InstPrinter);
return std::make_pair(EvalResult(ErrMsgStream.str()), "");
}
@@ -272,9 +270,7 @@ private:
raw_string_ostream ErrMsgStream(ErrMsg);
ErrMsgStream << "Operand '" << format("%i", OpIdx) << "' of instruction '"
<< Symbol << "' is not an immediate.\nInstruction is:\n ";
- Inst.dump_pretty(ErrMsgStream,
- Checker.Disassembler->getContext().getAsmInfo(),
- Checker.InstPrinter);
+ Inst.dump_pretty(ErrMsgStream, Checker.InstPrinter);
return std::make_pair(EvalResult(ErrMsgStream.str()), "");
}
@@ -314,7 +310,7 @@ private:
"");
uint64_t SymbolAddr = PCtx.IsInsideLoad
- ? Checker.getSymbolLinkerAddr(Symbol)
+ ? Checker.getSymbolLocalAddr(Symbol)
: Checker.getSymbolRemoteAddr(Symbol);
uint64_t NextPC = SymbolAddr + InstSize;
@@ -441,7 +437,7 @@ private:
// The value for the symbol depends on the context we're evaluating in:
// Inside a load this is the address in the linker's memory, outside a
// load it's the address in the target processes memory.
- uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLinkerAddr(Symbol)
+ uint64_t Value = PCtx.IsInsideLoad ? Checker.getSymbolLocalAddr(Symbol)
: Checker.getSymbolRemoteAddr(Symbol);
// Looks like a plain symbol reference.
@@ -731,18 +727,18 @@ bool RuntimeDyldCheckerImpl::checkAllRulesInBuffer(StringRef RulePrefix,
}
bool RuntimeDyldCheckerImpl::isSymbolValid(StringRef Symbol) const {
- return getRTDyld().getSymbolAddress(Symbol) != nullptr;
+ return getRTDyld().getSymbolLocalAddress(Symbol) != nullptr;
}
-uint64_t RuntimeDyldCheckerImpl::getSymbolLinkerAddr(StringRef Symbol) const {
+uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(StringRef Symbol) const {
return static_cast<uint64_t>(
- reinterpret_cast<uintptr_t>(getRTDyld().getSymbolAddress(Symbol)));
+ reinterpret_cast<uintptr_t>(getRTDyld().getSymbolLocalAddress(Symbol)));
}
uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const {
- if (uint64_t InternalSymbolAddr = getRTDyld().getSymbolLoadAddress(Symbol))
- return InternalSymbolAddr;
- return getRTDyld().MemMgr->getSymbolAddress(Symbol);
+ if (auto InternalSymbol = getRTDyld().getSymbol(Symbol))
+ return InternalSymbol.getAddress();
+ return getRTDyld().Resolver.findSymbol(Symbol).getAddress();
}
uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr,
@@ -850,14 +846,16 @@ std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubAddrFor(
StringRef
RuntimeDyldCheckerImpl::getSubsectionStartingAt(StringRef Name) const {
- RuntimeDyldImpl::SymbolTableMap::const_iterator pos =
+ RTDyldSymbolTable::const_iterator pos =
getRTDyld().GlobalSymbolTable.find(Name);
if (pos == getRTDyld().GlobalSymbolTable.end())
return StringRef();
- RuntimeDyldImpl::SymbolLoc Loc = pos->second;
- uint8_t *SectionAddr = getRTDyld().getSectionAddress(Loc.first);
- return StringRef(reinterpret_cast<const char *>(SectionAddr) + Loc.second,
- getRTDyld().Sections[Loc.first].Size - Loc.second);
+ const auto &SymInfo = pos->second;
+ uint8_t *SectionAddr = getRTDyld().getSectionAddress(SymInfo.getSectionID());
+ return StringRef(reinterpret_cast<const char *>(SectionAddr) +
+ SymInfo.getOffset(),
+ getRTDyld().Sections[SymInfo.getSectionID()].Size -
+ SymInfo.getOffset());
}
void RuntimeDyldCheckerImpl::registerSection(
@@ -887,9 +885,10 @@ void RuntimeDyldCheckerImpl::registerStubMap(
// If this is a (Section, Offset) pair, do a reverse lookup in the
// global symbol table to find the name.
for (auto &GSTEntry : getRTDyld().GlobalSymbolTable) {
- if (GSTEntry.second.first == StubMapEntry.first.SectionID &&
- GSTEntry.second.second ==
- static_cast<uint64_t>(StubMapEntry.first.Offset)) {
+ const auto &SymInfo = GSTEntry.second;
+ if (SymInfo.getSectionID() == StubMapEntry.first.SectionID &&
+ SymInfo.getOffset() ==
+ static_cast<uint64_t>(StubMapEntry.first.Offset)) {
SymbolName = GSTEntry.first();
break;
}
@@ -930,6 +929,6 @@ bool RuntimeDyldChecker::checkAllRulesInBuffer(StringRef RulePrefix,
std::pair<uint64_t, std::string>
RuntimeDyldChecker::getSectionAddr(StringRef FileName, StringRef SectionName,
- bool LinkerAddress) {
- return Impl->getSectionAddr(FileName, SectionName, LinkerAddress);
+ bool LocalAddress) {
+ return Impl->getSectionAddr(FileName, SectionName, LocalAddress);
}
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
index de20c1e..69d2a7d 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
@@ -19,6 +19,7 @@ class RuntimeDyldCheckerImpl {
friend class RuntimeDyldChecker;
friend class RuntimeDyldImpl;
friend class RuntimeDyldCheckerExprEval;
+ friend class RuntimeDyldELF;
public:
RuntimeDyldCheckerImpl(RuntimeDyld &RTDyld, MCDisassembler *Disassembler,
@@ -42,7 +43,7 @@ private:
RuntimeDyldImpl &getRTDyld() const { return *RTDyld.Dyld; }
bool isSymbolValid(StringRef Symbol) const;
- uint64_t getSymbolLinkerAddr(StringRef Symbol) const;
+ uint64_t getSymbolLocalAddr(StringRef Symbol) const;
uint64_t getSymbolRemoteAddr(StringRef Symbol) const;
uint64_t readMemoryAtAddr(uint64_t Addr, unsigned Size) const;
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index 2664a10..95421b3 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "RuntimeDyldELF.h"
+#include "RuntimeDyldCheckerImpl.h"
#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
@@ -103,11 +104,12 @@ void DyldELFObject<ELFT>::updateSymbolAddress(const SymbolRef &SymRef,
sym->st_value = static_cast<addr_type>(Addr);
}
-class LoadedELFObjectInfo : public RuntimeDyld::LoadedObjectInfo {
+class LoadedELFObjectInfo
+ : public RuntimeDyld::LoadedObjectInfoHelper<LoadedELFObjectInfo> {
public:
LoadedELFObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx,
unsigned EndIdx)
- : RuntimeDyld::LoadedObjectInfo(RTDyld, BeginIdx, EndIdx) {}
+ : LoadedObjectInfoHelper(RTDyld, BeginIdx, EndIdx) {}
OwningBinary<ObjectFile>
getObjectForDebug(const ObjectFile &Obj) const override;
@@ -183,32 +185,30 @@ LoadedELFObjectInfo::getObjectForDebug(const ObjectFile &Obj) const {
namespace llvm {
-RuntimeDyldELF::RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
+RuntimeDyldELF::RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldImpl(MemMgr, Resolver), GOTSectionID(0), CurrentGOTIndex(0) {}
RuntimeDyldELF::~RuntimeDyldELF() {}
void RuntimeDyldELF::registerEHFrames() {
- if (!MemMgr)
- return;
for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) {
SID EHFrameSID = UnregisteredEHFrameSections[i];
uint8_t *EHFrameAddr = Sections[EHFrameSID].Address;
uint64_t EHFrameLoadAddr = Sections[EHFrameSID].LoadAddress;
size_t EHFrameSize = Sections[EHFrameSID].Size;
- MemMgr->registerEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);
+ MemMgr.registerEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);
RegisteredEHFrameSections.push_back(EHFrameSID);
}
UnregisteredEHFrameSections.clear();
}
void RuntimeDyldELF::deregisterEHFrames() {
- if (!MemMgr)
- return;
for (int i = 0, e = RegisteredEHFrameSections.size(); i != e; ++i) {
SID EHFrameSID = RegisteredEHFrameSections[i];
uint8_t *EHFrameAddr = Sections[EHFrameSID].Address;
uint64_t EHFrameLoadAddr = Sections[EHFrameSID].LoadAddress;
size_t EHFrameSize = Sections[EHFrameSID].Size;
- MemMgr->deregisterEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);
+ MemMgr.deregisterEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);
}
RegisteredEHFrameSections.clear();
}
@@ -247,40 +247,18 @@ void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section,
<< format("%p\n", Section.Address + Offset));
break;
}
- case ELF::R_X86_64_GOTPCREL: {
- // findGOTEntry returns the 'G + GOT' part of the relocation calculation
- // based on the load/target address of the GOT (not the current/local addr).
- uint64_t GOTAddr = findGOTEntry(Value, SymOffset);
- uint64_t FinalAddress = Section.LoadAddress + Offset;
- // The processRelocationRef method combines the symbol offset and the addend
- // and in most cases that's what we want. For this relocation type, we need
- // the raw addend, so we subtract the symbol offset to get it.
- int64_t RealOffset = GOTAddr + Addend - SymOffset - FinalAddress;
- assert(RealOffset <= INT32_MAX && RealOffset >= INT32_MIN);
- int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
- support::ulittle32_t::ref(Section.Address + Offset) = TruncOffset;
- break;
- }
case ELF::R_X86_64_PC32: {
- // Get the placeholder value from the generated object since
- // a previous relocation attempt may have overwritten the loaded version
- support::ulittle32_t::ref Placeholder(
- (void *)(Section.ObjAddress + Offset));
uint64_t FinalAddress = Section.LoadAddress + Offset;
- int64_t RealOffset = Placeholder + Value + Addend - FinalAddress;
- assert(RealOffset <= INT32_MAX && RealOffset >= INT32_MIN);
+ int64_t RealOffset = Value + Addend - FinalAddress;
+ assert(isInt<32>(RealOffset));
int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
support::ulittle32_t::ref(Section.Address + Offset) = TruncOffset;
break;
}
case ELF::R_X86_64_PC64: {
- // Get the placeholder value from the generated object since
- // a previous relocation attempt may have overwritten the loaded version
- support::ulittle64_t::ref Placeholder(
- (void *)(Section.ObjAddress + Offset));
uint64_t FinalAddress = Section.LoadAddress + Offset;
- support::ulittle64_t::ref(Section.Address + Offset) =
- Placeholder + Value + Addend - FinalAddress;
+ int64_t RealOffset = Value + Addend - FinalAddress;
+ support::ulittle64_t::ref(Section.Address + Offset) = RealOffset;
break;
}
}
@@ -291,21 +269,12 @@ void RuntimeDyldELF::resolveX86Relocation(const SectionEntry &Section,
uint32_t Type, int32_t Addend) {
switch (Type) {
case ELF::R_386_32: {
- // Get the placeholder value from the generated object since
- // a previous relocation attempt may have overwritten the loaded version
- support::ulittle32_t::ref Placeholder(
- (void *)(Section.ObjAddress + Offset));
- support::ulittle32_t::ref(Section.Address + Offset) =
- Placeholder + Value + Addend;
+ support::ulittle32_t::ref(Section.Address + Offset) = Value + Addend;
break;
}
case ELF::R_386_PC32: {
- // Get the placeholder value from the generated object since
- // a previous relocation attempt may have overwritten the loaded version
- support::ulittle32_t::ref Placeholder(
- (void *)(Section.ObjAddress + Offset));
uint32_t FinalAddress = ((Section.LoadAddress + Offset) & 0xFFFFFFFF);
- uint32_t RealOffset = Placeholder + Value + Addend - FinalAddress;
+ uint32_t RealOffset = Value + Addend - FinalAddress;
support::ulittle32_t::ref(Section.Address + Offset) = RealOffset;
break;
}
@@ -354,8 +323,7 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section,
uint64_t BranchImm = Value + Addend - FinalAddress;
// "Check that -2^27 <= result < 2^27".
- assert(-(1LL << 27) <= static_cast<int64_t>(BranchImm) &&
- static_cast<int64_t>(BranchImm) < (1LL << 27));
+ assert(isInt<28>(BranchImm));
// AArch64 code is emitted with .rela relocations. The data already in any
// bits affected by the relocation on entry is garbage.
@@ -418,9 +386,7 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section,
((Value + Addend) & ~0xfffULL) - (FinalAddress & ~0xfffULL);
// Check that -2^32 <= X < 2^32
- assert(static_cast<int64_t>(Result) >= (-1LL << 32) &&
- static_cast<int64_t>(Result) < (1LL << 32) &&
- "overflow check failed for relocation");
+ assert(isInt<33>(Result) && "overflow check failed for relocation");
// AArch64 code is emitted with .rela relocations. The data already in any
// bits affected by the relocation on entry is garbage.
@@ -462,8 +428,6 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section,
uint64_t Offset, uint32_t Value,
uint32_t Type, int32_t Addend) {
// TODO: Add Thumb relocations.
- uint32_t *Placeholder =
- reinterpret_cast<uint32_t *>(Section.ObjAddress + Offset);
uint32_t *TargetPtr = (uint32_t *)(Section.Address + Offset);
uint32_t FinalAddress = ((Section.LoadAddress + Offset) & 0xFFFFFFFF);
Value += Addend;
@@ -480,39 +444,27 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section,
case ELF::R_ARM_NONE:
break;
- // Write a 32bit value to relocation address, taking into account the
- // implicit addend encoded in the target.
case ELF::R_ARM_PREL31:
case ELF::R_ARM_TARGET1:
case ELF::R_ARM_ABS32:
- *TargetPtr = *Placeholder + Value;
+ *TargetPtr = Value;
break;
- // Write first 16 bit of 32 bit value to the mov instruction.
- // Last 4 bit should be shifted.
+ // Write first 16 bit of 32 bit value to the mov instruction.
+ // Last 4 bit should be shifted.
case ELF::R_ARM_MOVW_ABS_NC:
- // We are not expecting any other addend in the relocation address.
- // Using 0x000F0FFF because MOVW has its 16 bit immediate split into 2
- // non-contiguous fields.
- assert((*Placeholder & 0x000F0FFF) == 0);
- Value = Value & 0xFFFF;
- *TargetPtr = *Placeholder | (Value & 0xFFF);
- *TargetPtr |= ((Value >> 12) & 0xF) << 16;
- break;
- // Write last 16 bit of 32 bit value to the mov instruction.
- // Last 4 bit should be shifted.
case ELF::R_ARM_MOVT_ABS:
- // We are not expecting any other addend in the relocation address.
- // Use 0x000F0FFF for the same reason as R_ARM_MOVW_ABS_NC.
- assert((*Placeholder & 0x000F0FFF) == 0);
-
- Value = (Value >> 16) & 0xFFFF;
- *TargetPtr = *Placeholder | (Value & 0xFFF);
+ if (Type == ELF::R_ARM_MOVW_ABS_NC)
+ Value = Value & 0xFFFF;
+ else if (Type == ELF::R_ARM_MOVT_ABS)
+ Value = (Value >> 16) & 0xFFFF;
+ *TargetPtr &= ~0x000F0FFF;
+ *TargetPtr |= Value & 0xFFF;
*TargetPtr |= ((Value >> 12) & 0xF) << 16;
break;
- // Write 24 bit relative value to the branch instruction.
+ // Write 24 bit relative value to the branch instruction.
case ELF::R_ARM_PC24: // Fall through.
case ELF::R_ARM_CALL: // Fall through.
- case ELF::R_ARM_JUMP24: {
+ case ELF::R_ARM_JUMP24:
int32_t RelValue = static_cast<int32_t>(Value - FinalAddress - 8);
RelValue = (RelValue & 0x03FFFFFC) >> 2;
assert((*TargetPtr & 0xFFFFFF) == 0xFFFFFE);
@@ -520,21 +472,11 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section,
*TargetPtr |= RelValue;
break;
}
- case ELF::R_ARM_PRIVATE_0:
- // This relocation is reserved by the ARM ELF ABI for internal use. We
- // appropriate it here to act as an R_ARM_ABS32 without any addend for use
- // in the stubs created during JIT (which can't put an addend into the
- // original object file).
- *TargetPtr = Value;
- break;
- }
}
void RuntimeDyldELF::resolveMIPSRelocation(const SectionEntry &Section,
uint64_t Offset, uint32_t Value,
uint32_t Type, int32_t Addend) {
- uint32_t *Placeholder =
- reinterpret_cast<uint32_t *>(Section.ObjAddress + Offset);
uint32_t *TargetPtr = (uint32_t *)(Section.Address + Offset);
Value += Addend;
@@ -549,30 +491,17 @@ void RuntimeDyldELF::resolveMIPSRelocation(const SectionEntry &Section,
llvm_unreachable("Not implemented relocation type!");
break;
case ELF::R_MIPS_32:
- *TargetPtr = Value + (*Placeholder);
+ *TargetPtr = Value;
break;
case ELF::R_MIPS_26:
- *TargetPtr = ((*Placeholder) & 0xfc000000) | ((Value & 0x0fffffff) >> 2);
+ *TargetPtr = ((*TargetPtr) & 0xfc000000) | ((Value & 0x0fffffff) >> 2);
break;
case ELF::R_MIPS_HI16:
// Get the higher 16-bits. Also add 1 if bit 15 is 1.
- Value += ((*Placeholder) & 0x0000ffff) << 16;
*TargetPtr =
- ((*Placeholder) & 0xffff0000) | (((Value + 0x8000) >> 16) & 0xffff);
+ ((*TargetPtr) & 0xffff0000) | (((Value + 0x8000) >> 16) & 0xffff);
break;
case ELF::R_MIPS_LO16:
- Value += ((*Placeholder) & 0x0000ffff);
- *TargetPtr = ((*Placeholder) & 0xffff0000) | (Value & 0xffff);
- break;
- case ELF::R_MIPS_UNUSED1:
- // Similar to ELF::R_ARM_PRIVATE_0, R_MIPS_UNUSED1 and R_MIPS_UNUSED2
- // are used for internal JIT purpose. These relocations are similar to
- // R_MIPS_HI16 and R_MIPS_LO16, but they do not take any addend into
- // account.
- *TargetPtr =
- ((*TargetPtr) & 0xffff0000) | (((Value + 0x8000) >> 16) & 0xffff);
- break;
- case ELF::R_MIPS_UNUSED2:
*TargetPtr = ((*TargetPtr) & 0xffff0000) | (Value & 0xffff);
break;
}
@@ -898,6 +827,18 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
}
}
+void *RuntimeDyldELF::computePlaceholderAddress(unsigned SectionID, uint64_t Offset) const {
+ return (void*)(Sections[SectionID].ObjAddress + Offset);
+}
+
+void RuntimeDyldELF::processSimpleRelocation(unsigned SectionID, uint64_t Offset, unsigned RelType, RelocationValueRef Value) {
+ RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, Value.Offset);
+ if (Value.SymbolName)
+ addRelocationForSymbol(RE, Value.SymbolName);
+ else
+ addRelocationForSection(RE, Value.SectionID);
+}
+
relocation_iterator RuntimeDyldELF::processRelocationRef(
unsigned SectionID, relocation_iterator RelI,
const ObjectFile &Obj,
@@ -920,15 +861,16 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
SymbolRef::Type SymType = SymbolRef::ST_Unknown;
// Search for the symbol in the global symbol table
- SymbolTableMap::const_iterator gsi = GlobalSymbolTable.end();
+ RTDyldSymbolTable::const_iterator gsi = GlobalSymbolTable.end();
if (Symbol != Obj.symbol_end()) {
gsi = GlobalSymbolTable.find(TargetName.data());
Symbol->getType(SymType);
}
if (gsi != GlobalSymbolTable.end()) {
- Value.SectionID = gsi->second.first;
- Value.Offset = gsi->second.second;
- Value.Addend = gsi->second.second + Addend;
+ const auto &SymInfo = gsi->second;
+ Value.SectionID = SymInfo.getSectionID();
+ Value.Offset = SymInfo.getOffset();
+ Value.Addend = SymInfo.getOffset() + Addend;
} else {
switch (SymType) {
case SymbolRef::ST_Debug: {
@@ -1014,80 +956,103 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
0);
Section.StubOffset += getMaxStubSize();
}
- } else if (Arch == Triple::arm &&
- (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.");
- SectionEntry &Section = Sections[SectionID];
+ } else if (Arch == Triple::arm) {
+ 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.");
+ SectionEntry &Section = Sections[SectionID];
- // Look for an existing stub.
- StubMap::const_iterator i = Stubs.find(Value);
- if (i != Stubs.end()) {
- resolveRelocation(Section, Offset, (uint64_t)Section.Address + i->second,
- RelType, 0);
- DEBUG(dbgs() << " Stub function found\n");
- } else {
- // Create a new stub function.
- DEBUG(dbgs() << " Create a new stub function\n");
- Stubs[Value] = Section.StubOffset;
- uint8_t *StubTargetAddr =
+ // Look for an existing stub.
+ StubMap::const_iterator i = Stubs.find(Value);
+ if (i != Stubs.end()) {
+ resolveRelocation(Section, Offset, (uint64_t)Section.Address + i->second,
+ RelType, 0);
+ DEBUG(dbgs() << " Stub function found\n");
+ } else {
+ // Create a new stub function.
+ DEBUG(dbgs() << " Create a new stub function\n");
+ Stubs[Value] = Section.StubOffset;
+ uint8_t *StubTargetAddr =
createStubFunction(Section.Address + Section.StubOffset);
- RelocationEntry RE(SectionID, StubTargetAddr - Section.Address,
- ELF::R_ARM_PRIVATE_0, Value.Addend);
- if (Value.SymbolName)
- addRelocationForSymbol(RE, Value.SymbolName);
- else
- addRelocationForSection(RE, Value.SectionID);
-
- resolveRelocation(Section, Offset,
- (uint64_t)Section.Address + Section.StubOffset, RelType,
- 0);
- Section.StubOffset += getMaxStubSize();
+ RelocationEntry RE(SectionID, StubTargetAddr - Section.Address,
+ ELF::R_ARM_ABS32, Value.Addend);
+ if (Value.SymbolName)
+ addRelocationForSymbol(RE, Value.SymbolName);
+ else
+ addRelocationForSection(RE, Value.SectionID);
+
+ resolveRelocation(Section, Offset,
+ (uint64_t)Section.Address + Section.StubOffset, RelType,
+ 0);
+ Section.StubOffset += getMaxStubSize();
+ }
+ } else {
+ uint32_t *Placeholder =
+ reinterpret_cast<uint32_t*>(computePlaceholderAddress(SectionID, Offset));
+ if (RelType == ELF::R_ARM_PREL31 || RelType == ELF::R_ARM_TARGET1 ||
+ RelType == ELF::R_ARM_ABS32) {
+ Value.Addend += *Placeholder;
+ } else if (RelType == ELF::R_ARM_MOVW_ABS_NC || RelType == ELF::R_ARM_MOVT_ABS) {
+ // See ELF for ARM documentation
+ Value.Addend += (int16_t)((*Placeholder & 0xFFF) | (((*Placeholder >> 16) & 0xF) << 12));
+ }
+ processSimpleRelocation(SectionID, Offset, RelType, Value);
}
- } else if ((Arch == Triple::mipsel || Arch == Triple::mips) &&
- RelType == ELF::R_MIPS_26) {
- // This is an Mips branch relocation, need to use a stub function.
- DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
- SectionEntry &Section = Sections[SectionID];
- uint8_t *Target = Section.Address + Offset;
- uint32_t *TargetAddress = (uint32_t *)Target;
+ } else if ((Arch == Triple::mipsel || Arch == Triple::mips)) {
+ uint32_t *Placeholder = reinterpret_cast<uint32_t*>(computePlaceholderAddress(SectionID, Offset));
+ if (RelType == ELF::R_MIPS_26) {
+ // This is an Mips branch relocation, need to use a stub function.
+ DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
+ SectionEntry &Section = Sections[SectionID];
- // Extract the addend from the instruction.
- uint32_t Addend = ((*TargetAddress) & 0x03ffffff) << 2;
+ // Extract the addend from the instruction.
+ // We shift up by two since the Value will be down shifted again
+ // when applying the relocation.
+ uint32_t Addend = ((*Placeholder) & 0x03ffffff) << 2;
- Value.Addend += Addend;
+ Value.Addend += Addend;
- // Look up for existing stub.
- StubMap::const_iterator i = Stubs.find(Value);
- if (i != Stubs.end()) {
- RelocationEntry RE(SectionID, Offset, RelType, i->second);
- addRelocationForSection(RE, SectionID);
- DEBUG(dbgs() << " Stub function found\n");
- } else {
- // Create a new stub function.
- DEBUG(dbgs() << " Create a new stub function\n");
- Stubs[Value] = Section.StubOffset;
- uint8_t *StubTargetAddr =
+ // Look up for existing stub.
+ StubMap::const_iterator i = Stubs.find(Value);
+ if (i != Stubs.end()) {
+ RelocationEntry RE(SectionID, Offset, RelType, i->second);
+ addRelocationForSection(RE, SectionID);
+ DEBUG(dbgs() << " Stub function found\n");
+ } else {
+ // Create a new stub function.
+ DEBUG(dbgs() << " Create a new stub function\n");
+ Stubs[Value] = Section.StubOffset;
+ uint8_t *StubTargetAddr =
createStubFunction(Section.Address + Section.StubOffset);
- // Creating Hi and Lo relocations for the filled stub instructions.
- RelocationEntry REHi(SectionID, StubTargetAddr - Section.Address,
- ELF::R_MIPS_UNUSED1, Value.Addend);
- RelocationEntry RELo(SectionID, StubTargetAddr - Section.Address + 4,
- ELF::R_MIPS_UNUSED2, Value.Addend);
+ // Creating Hi and Lo relocations for the filled stub instructions.
+ RelocationEntry REHi(SectionID, StubTargetAddr - Section.Address,
+ ELF::R_MIPS_HI16, Value.Addend);
+ RelocationEntry RELo(SectionID, StubTargetAddr - Section.Address + 4,
+ ELF::R_MIPS_LO16, Value.Addend);
- if (Value.SymbolName) {
- addRelocationForSymbol(REHi, Value.SymbolName);
- addRelocationForSymbol(RELo, Value.SymbolName);
- } else {
- addRelocationForSection(REHi, Value.SectionID);
- addRelocationForSection(RELo, Value.SectionID);
- }
+ if (Value.SymbolName) {
+ addRelocationForSymbol(REHi, Value.SymbolName);
+ addRelocationForSymbol(RELo, Value.SymbolName);
+ }
+ else {
+ addRelocationForSection(REHi, Value.SectionID);
+ addRelocationForSection(RELo, Value.SectionID);
+ }
- RelocationEntry RE(SectionID, Offset, RelType, Section.StubOffset);
- addRelocationForSection(RE, SectionID);
- Section.StubOffset += getMaxStubSize();
+ RelocationEntry RE(SectionID, Offset, RelType, Section.StubOffset);
+ addRelocationForSection(RE, SectionID);
+ Section.StubOffset += getMaxStubSize();
+ }
+ } else {
+ if (RelType == ELF::R_MIPS_HI16)
+ Value.Addend += ((*Placeholder) & 0x0000ffff) << 16;
+ else if (RelType == ELF::R_MIPS_LO16)
+ Value.Addend += ((*Placeholder) & 0x0000ffff);
+ else if (RelType == ELF::R_MIPS_32)
+ Value.Addend += *Placeholder;
+ processSimpleRelocation(SectionID, Offset, RelType, Value);
}
} else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) {
if (RelType == ELF::R_PPC64_REL24) {
@@ -1127,7 +1092,7 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
RangeOverflow = true;
}
}
- if (SymType == SymbolRef::ST_Unknown || RangeOverflow == true) {
+ if (SymType == SymbolRef::ST_Unknown || RangeOverflow) {
// It is an external symbol (SymbolRef::ST_Unknown) or within a range
// larger than 24-bits.
StubMap::const_iterator i = Stubs.find(Value);
@@ -1286,93 +1251,95 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
Addend);
else
resolveRelocation(Section, Offset, StubAddress, RelType, Addend);
- } else if (Arch == Triple::x86_64 && RelType == ELF::R_X86_64_PLT32) {
- // The way the PLT relocations normally work is that the linker allocates
- // the
- // PLT and this relocation makes a PC-relative call into the PLT. The PLT
- // entry will then jump to an address provided by the GOT. On first call,
- // the
- // GOT address will point back into PLT code that resolves the symbol. After
- // the first call, the GOT entry points to the actual function.
- //
- // For local functions we're ignoring all of that here and just replacing
- // the PLT32 relocation type with PC32, which will translate the relocation
- // into a PC-relative call directly to the function. For external symbols we
- // can't be sure the function will be within 2^32 bytes of the call site, so
- // we need to create a stub, which calls into the GOT. This case is
- // equivalent to the usual PLT implementation except that we use the stub
- // mechanism in RuntimeDyld (which puts stubs at the end of the section)
- // rather than allocating a PLT section.
- if (Value.SymbolName) {
- // This is a call to an external function.
- // Look for an existing stub.
- SectionEntry &Section = Sections[SectionID];
- StubMap::const_iterator i = Stubs.find(Value);
- uintptr_t StubAddress;
- if (i != Stubs.end()) {
+ } else if (Arch == Triple::x86_64) {
+ if (RelType == ELF::R_X86_64_PLT32) {
+ // The way the PLT relocations normally work is that the linker allocates
+ // the
+ // PLT and this relocation makes a PC-relative call into the PLT. The PLT
+ // entry will then jump to an address provided by the GOT. On first call,
+ // the
+ // GOT address will point back into PLT code that resolves the symbol. After
+ // the first call, the GOT entry points to the actual function.
+ //
+ // For local functions we're ignoring all of that here and just replacing
+ // the PLT32 relocation type with PC32, which will translate the relocation
+ // into a PC-relative call directly to the function. For external symbols we
+ // can't be sure the function will be within 2^32 bytes of the call site, so
+ // we need to create a stub, which calls into the GOT. This case is
+ // equivalent to the usual PLT implementation except that we use the stub
+ // mechanism in RuntimeDyld (which puts stubs at the end of the section)
+ // rather than allocating a PLT section.
+ if (Value.SymbolName) {
+ // This is a call to an external function.
+ // Look for an existing stub.
+ SectionEntry &Section = Sections[SectionID];
+ StubMap::const_iterator i = Stubs.find(Value);
+ uintptr_t StubAddress;
+ if (i != Stubs.end()) {
StubAddress = uintptr_t(Section.Address) + i->second;
DEBUG(dbgs() << " Stub function found\n");
- } else {
+ } else {
// Create a new stub function (equivalent to a PLT entry).
DEBUG(dbgs() << " Create a new stub function\n");
uintptr_t BaseAddress = uintptr_t(Section.Address);
uintptr_t StubAlignment = getStubAlignment();
StubAddress = (BaseAddress + Section.StubOffset + StubAlignment - 1) &
- -StubAlignment;
+ -StubAlignment;
unsigned StubOffset = StubAddress - BaseAddress;
Stubs[Value] = StubOffset;
createStubFunction((uint8_t *)StubAddress);
- // Create a GOT entry for the external function.
- GOTEntries.push_back(Value);
-
- // Make our stub function a relative call to the GOT entry.
- RelocationEntry RE(SectionID, StubOffset + 2, ELF::R_X86_64_GOTPCREL,
- -4);
- addRelocationForSymbol(RE, Value.SymbolName);
-
// Bump our stub offset counter
Section.StubOffset = StubOffset + getMaxStubSize();
+
+ // Allocate a GOT Entry
+ uint64_t GOTOffset = allocateGOTEntries(SectionID, 1);
+
+ // The load of the GOT address has an addend of -4
+ resolveGOTOffsetRelocation(SectionID, StubOffset + 2, GOTOffset - 4);
+
+ // Fill in the value of the symbol we're targeting into the GOT
+ addRelocationForSymbol(computeGOTOffsetRE(SectionID,GOTOffset,0,ELF::R_X86_64_64),
+ Value.SymbolName);
+ }
+
+ // Make the target call a call into the stub table.
+ resolveRelocation(Section, Offset, StubAddress, ELF::R_X86_64_PC32,
+ Addend);
+ } else {
+ RelocationEntry RE(SectionID, Offset, ELF::R_X86_64_PC32, Value.Addend,
+ Value.Offset);
+ addRelocationForSection(RE, Value.SectionID);
}
+ } else if (RelType == ELF::R_X86_64_GOTPCREL) {
+ uint64_t GOTOffset = allocateGOTEntries(SectionID, 1);
+ resolveGOTOffsetRelocation(SectionID, Offset, GOTOffset + Addend);
- // Make the target call a call into the stub table.
- resolveRelocation(Section, Offset, StubAddress, ELF::R_X86_64_PC32,
- Addend);
+ // Fill in the value of the symbol we're targeting into the GOT
+ RelocationEntry RE = computeGOTOffsetRE(SectionID, GOTOffset, Value.Offset, ELF::R_X86_64_64);
+ if (Value.SymbolName)
+ addRelocationForSymbol(RE, Value.SymbolName);
+ else
+ addRelocationForSection(RE, Value.SectionID);
+ } else if (RelType == ELF::R_X86_64_PC32) {
+ Value.Addend += support::ulittle32_t::ref(computePlaceholderAddress(SectionID, Offset));
+ processSimpleRelocation(SectionID, Offset, RelType, Value);
+ } else if (RelType == ELF::R_X86_64_PC64) {
+ Value.Addend += support::ulittle64_t::ref(computePlaceholderAddress(SectionID, Offset));
+ processSimpleRelocation(SectionID, Offset, RelType, Value);
} else {
- RelocationEntry RE(SectionID, Offset, ELF::R_X86_64_PC32, Value.Addend,
- Value.Offset);
- addRelocationForSection(RE, Value.SectionID);
+ processSimpleRelocation(SectionID, Offset, RelType, Value);
}
} else {
- if (Arch == Triple::x86_64 && RelType == ELF::R_X86_64_GOTPCREL) {
- GOTEntries.push_back(Value);
+ if (Arch == Triple::x86) {
+ Value.Addend += support::ulittle32_t::ref(computePlaceholderAddress(SectionID, Offset));
}
- RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, Value.Offset);
- if (Value.SymbolName)
- addRelocationForSymbol(RE, Value.SymbolName);
- else
- addRelocationForSection(RE, Value.SectionID);
+ processSimpleRelocation(SectionID, Offset, RelType, Value);
}
return ++RelI;
}
-void RuntimeDyldELF::updateGOTEntries(StringRef Name, uint64_t Addr) {
-
- SmallVectorImpl<std::pair<SID, GOTRelocations>>::iterator it;
- SmallVectorImpl<std::pair<SID, GOTRelocations>>::iterator end = GOTs.end();
-
- for (it = GOTs.begin(); it != end; ++it) {
- GOTRelocations &GOTEntries = it->second;
- for (int i = 0, e = GOTEntries.size(); i != e; ++i) {
- if (GOTEntries[i].SymbolName != nullptr &&
- GOTEntries[i].SymbolName == Name) {
- GOTEntries[i].Offset = Addr;
- }
- }
- }
-}
-
size_t RuntimeDyldELF::getGOTEntrySize() {
// We don't use the GOT in all of these cases, but it's essentially free
// to put them all here.
@@ -1399,83 +1366,53 @@ size_t RuntimeDyldELF::getGOTEntrySize() {
return Result;
}
-uint64_t RuntimeDyldELF::findGOTEntry(uint64_t LoadAddress, uint64_t Offset) {
-
- const size_t GOTEntrySize = getGOTEntrySize();
-
- SmallVectorImpl<std::pair<SID, GOTRelocations>>::const_iterator it;
- SmallVectorImpl<std::pair<SID, GOTRelocations>>::const_iterator end =
- GOTs.end();
-
- int GOTIndex = -1;
- for (it = GOTs.begin(); it != end; ++it) {
- SID GOTSectionID = it->first;
- const GOTRelocations &GOTEntries = it->second;
-
- // Find the matching entry in our vector.
- uint64_t SymbolOffset = 0;
- for (int i = 0, e = GOTEntries.size(); i != e; ++i) {
- if (!GOTEntries[i].SymbolName) {
- if (getSectionLoadAddress(GOTEntries[i].SectionID) == LoadAddress &&
- GOTEntries[i].Offset == Offset) {
- GOTIndex = i;
- SymbolOffset = GOTEntries[i].Offset;
- break;
- }
- } else {
- // GOT entries for external symbols use the addend as the address when
- // the external symbol has been resolved.
- if (GOTEntries[i].Offset == LoadAddress) {
- GOTIndex = i;
- // Don't use the Addend here. The relocation handler will use it.
- break;
- }
- }
- }
-
- if (GOTIndex != -1) {
- if (GOTEntrySize == sizeof(uint64_t)) {
- uint64_t *LocalGOTAddr = (uint64_t *)getSectionAddress(GOTSectionID);
- // Fill in this entry with the address of the symbol being referenced.
- LocalGOTAddr[GOTIndex] = LoadAddress + SymbolOffset;
- } else {
- uint32_t *LocalGOTAddr = (uint32_t *)getSectionAddress(GOTSectionID);
- // Fill in this entry with the address of the symbol being referenced.
- LocalGOTAddr[GOTIndex] = (uint32_t)(LoadAddress + SymbolOffset);
- }
-
- // Calculate the load address of this entry
- return getSectionLoadAddress(GOTSectionID) + (GOTIndex * GOTEntrySize);
- }
+uint64_t RuntimeDyldELF::allocateGOTEntries(unsigned SectionID, unsigned no)
+{
+ (void)SectionID; // The GOT Section is the same for all section in the object file
+ if (GOTSectionID == 0) {
+ GOTSectionID = Sections.size();
+ // Reserve a section id. We'll allocate the section later
+ // once we know the total size
+ Sections.push_back(SectionEntry(".got", 0, 0, 0));
}
+ uint64_t StartOffset = CurrentGOTIndex * getGOTEntrySize();
+ CurrentGOTIndex += no;
+ return StartOffset;
+}
+
+void RuntimeDyldELF::resolveGOTOffsetRelocation(unsigned SectionID, uint64_t Offset, uint64_t GOTOffset)
+{
+ // Fill in the relative address of the GOT Entry into the stub
+ RelocationEntry GOTRE(SectionID, Offset, ELF::R_X86_64_PC32, GOTOffset);
+ addRelocationForSection(GOTRE, GOTSectionID);
+}
- assert(GOTIndex != -1 && "Unable to find requested GOT entry.");
- return 0;
+RelocationEntry RuntimeDyldELF::computeGOTOffsetRE(unsigned SectionID, uint64_t GOTOffset, uint64_t SymbolOffset,
+ uint32_t Type)
+{
+ (void)SectionID; // The GOT Section is the same for all section in the object file
+ return RelocationEntry(GOTSectionID, GOTOffset, Type, SymbolOffset);
}
void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,
ObjSectionToIDMap &SectionMap) {
// If necessary, allocate the global offset table
- if (MemMgr) {
- // Allocate the GOT if necessary
- size_t numGOTEntries = GOTEntries.size();
- if (numGOTEntries != 0) {
- // Allocate memory for the section
- unsigned SectionID = Sections.size();
- size_t TotalSize = numGOTEntries * getGOTEntrySize();
- uint8_t *Addr = MemMgr->allocateDataSection(TotalSize, getGOTEntrySize(),
- SectionID, ".got", false);
- if (!Addr)
- report_fatal_error("Unable to allocate memory for GOT!");
-
- GOTs.push_back(std::make_pair(SectionID, GOTEntries));
- Sections.push_back(SectionEntry(".got", Addr, TotalSize, 0));
- // For now, initialize all GOT entries to zero. We'll fill them in as
- // needed when GOT-based relocations are applied.
- memset(Addr, 0, TotalSize);
- }
- } else {
- report_fatal_error("Unable to allocate memory for GOT!");
+ if (GOTSectionID != 0) {
+ // Allocate memory for the section
+ size_t TotalSize = CurrentGOTIndex * getGOTEntrySize();
+ uint8_t *Addr = MemMgr.allocateDataSection(TotalSize, getGOTEntrySize(),
+ GOTSectionID, ".got", false);
+ if (!Addr)
+ report_fatal_error("Unable to allocate memory for GOT!");
+
+ Sections[GOTSectionID] = SectionEntry(".got", Addr, TotalSize, 0);
+
+ if (Checker)
+ Checker->registerSection(Obj.getFileName(), GOTSectionID);
+
+ // For now, initialize all GOT entries to zero. We'll fill them in as
+ // needed when GOT-based relocations are applied.
+ memset(Addr, 0, TotalSize);
}
// Look for and record the EH frame section.
@@ -1489,6 +1426,9 @@ void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,
break;
}
}
+
+ GOTSectionID = 0;
+ CurrentGOTIndex = 0;
}
bool RuntimeDyldELF::isCompatibleFile(const object::ObjectFile &Obj) const {
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
index b4414b0..9a4a863 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
@@ -20,16 +20,6 @@
using namespace llvm;
namespace llvm {
-namespace {
-// Helper for extensive error checking in debug builds.
-std::error_code Check(std::error_code Err) {
- if (Err) {
- report_fatal_error(Err.message());
- }
- return Err;
-}
-
-} // end anonymous namespace
class RuntimeDyldELF : public RuntimeDyldImpl {
@@ -90,16 +80,39 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
ObjSectionToIDMap &LocalSections,
RelocationValueRef &Rel);
- uint64_t findGOTEntry(uint64_t LoadAddr, uint64_t Offset);
size_t getGOTEntrySize();
- void updateGOTEntries(StringRef Name, uint64_t Addr) override;
+ SectionEntry &getSection(unsigned SectionID) { return Sections[SectionID]; }
+
+ // Allocate no GOT entries for use in the given section.
+ uint64_t allocateGOTEntries(unsigned SectionID, unsigned no);
+
+ // Resolve the relvative address of GOTOffset in Section ID and place
+ // it at the given Offset
+ void resolveGOTOffsetRelocation(unsigned SectionID, uint64_t Offset,
+ uint64_t GOTOffset);
+
+ // For a GOT entry referenced from SectionID, compute a relocation entry
+ // that will place the final resolved value in the GOT slot
+ RelocationEntry computeGOTOffsetRE(unsigned SectionID,
+ uint64_t GOTOffset,
+ uint64_t SymbolOffset,
+ unsigned Type);
+
+ // Compute the address in memory where we can find the placeholder
+ void *computePlaceholderAddress(unsigned SectionID, uint64_t Offset) const;
+
+ // Split out common case for createing the RelocationEntry for when the relocation requires
+ // no particular advanced processing.
+ void processSimpleRelocation(unsigned SectionID, uint64_t Offset, unsigned RelType, RelocationValueRef Value);
+
+ // The tentative ID for the GOT section
+ unsigned GOTSectionID;
- // Relocation entries for symbols whose position-independent offset is
- // updated in a global offset table.
- typedef SmallVector<RelocationValueRef, 2> GOTRelocations;
- GOTRelocations GOTEntries; // List of entries requiring finalization.
- SmallVector<std::pair<SID, GOTRelocations>, 8> GOTs; // Allocated tables.
+ // Records the current number of allocated slots in the GOT
+ // (This would be equivalent to GOTEntries.size() were it not for relocations
+ // that consume more than one slot)
+ unsigned CurrentGOTIndex;
// When a module is loaded we save the SectionID of the EH frame section
// in a table until we receive a request to register all unregistered
@@ -108,8 +121,9 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
SmallVector<SID, 2> RegisteredEHFrameSections;
public:
- RuntimeDyldELF(RTDyldMemoryManager *mm);
- virtual ~RuntimeDyldELF();
+ RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver);
+ ~RuntimeDyldELF() override;
std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
loadObject(const object::ObjectFile &O) override;
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
index 2f3e3a8..90e61a5 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
#include "llvm/Object/ObjectFile.h"
@@ -36,6 +37,14 @@ 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;
/// SectionEntry - represents a section emitted into memory by the dynamic
@@ -43,7 +52,7 @@ class Twine;
class SectionEntry {
public:
/// Name - section name.
- StringRef Name;
+ std::string Name;
/// Address - address in the linker's memory where the section resides.
uint8_t *Address;
@@ -156,12 +165,34 @@ public:
}
};
+/// @brief Symbol info for RuntimeDyld.
+class SymbolTableEntry : public JITSymbolBase {
+public:
+ SymbolTableEntry()
+ : JITSymbolBase(JITSymbolFlags::None), Offset(0), SectionID(0) {}
+
+ SymbolTableEntry(unsigned SectionID, uint64_t Offset, JITSymbolFlags Flags)
+ : JITSymbolBase(Flags), Offset(Offset), SectionID(SectionID) {}
+
+ unsigned getSectionID() const { return SectionID; }
+ uint64_t getOffset() const { return Offset; }
+
+private:
+ uint64_t Offset;
+ unsigned SectionID;
+};
+
+typedef StringMap<SymbolTableEntry> RTDyldSymbolTable;
+
class RuntimeDyldImpl {
friend class RuntimeDyld::LoadedObjectInfo;
friend class RuntimeDyldCheckerImpl;
protected:
// The MemoryManager to load objects into.
- RTDyldMemoryManager *MemMgr;
+ RuntimeDyld::MemoryManager &MemMgr;
+
+ // The symbol resolver to use for external symbols.
+ RuntimeDyld::SymbolResolver &Resolver;
// Attached RuntimeDyldChecker instance. Null if no instance attached.
RuntimeDyldCheckerImpl *Checker;
@@ -172,22 +203,17 @@ protected:
SectionList Sections;
typedef unsigned SID; // Type for SectionIDs
-#define RTDYLD_INVALID_SECTION_ID ((SID)(-1))
+#define RTDYLD_INVALID_SECTION_ID ((RuntimeDyldImpl::SID)(-1))
// Keep a map of sections from object file to the SectionID which
// references it.
typedef std::map<SectionRef, unsigned> ObjSectionToIDMap;
- // A global symbol table for symbols from all loaded modules. Maps the
- // symbol name to a (SectionID, offset in section) pair.
- typedef std::pair<unsigned, uintptr_t> SymbolLoc;
- typedef StringMap<SymbolLoc> SymbolTableMap;
- SymbolTableMap GlobalSymbolTable;
+ // A global symbol table for symbols from all loaded modules.
+ RTDyldSymbolTable GlobalSymbolTable;
- // Pair representing the size and alignment requirement for a common symbol.
- typedef std::pair<unsigned, unsigned> CommonSymbolInfo;
// Keep a map of common symbols to their info pairs
- typedef std::map<SymbolRef, CommonSymbolInfo> CommonSymbolMap;
+ typedef std::vector<SymbolRef> CommonSymbolList;
// For each symbol, keep a list of relocations based on it. Anytime
// its address is reassigned (the JIT re-compiled the function, e.g.),
@@ -287,9 +313,7 @@ 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,
- const CommonSymbolMap &CommonSymbols,
- uint64_t TotalSize, SymbolTableMap &SymbolTable);
+ void 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
@@ -337,10 +361,6 @@ protected:
/// \brief Resolve relocations to external symbols.
void resolveExternalSymbols();
- /// \brief Update GOT entries for external symbols.
- // The base class does nothing. ELF overrides this.
- virtual void updateGOTEntries(StringRef Name, uint64_t Addr) {}
-
// \brief Compute an upper bound of the memory that is required to load all
// sections
void computeTotalAllocSize(const ObjectFile &Obj, uint64_t &CodeSize,
@@ -354,8 +374,10 @@ protected:
std::pair<unsigned, unsigned> loadObjectImpl(const object::ObjectFile &Obj);
public:
- RuntimeDyldImpl(RTDyldMemoryManager *mm)
- : MemMgr(mm), Checker(nullptr), ProcessAllSections(false), HasError(false) {
+ RuntimeDyldImpl(RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : MemMgr(MemMgr), Resolver(Resolver), Checker(nullptr),
+ ProcessAllSections(false), HasError(false) {
}
virtual ~RuntimeDyldImpl();
@@ -371,24 +393,26 @@ public:
virtual std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
loadObject(const object::ObjectFile &Obj) = 0;
- uint8_t* getSymbolAddress(StringRef Name) const {
+ uint8_t* getSymbolLocalAddress(StringRef Name) const {
// FIXME: Just look up as a function for now. Overly simple of course.
// Work in progress.
- SymbolTableMap::const_iterator pos = GlobalSymbolTable.find(Name);
+ RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
if (pos == GlobalSymbolTable.end())
return nullptr;
- SymbolLoc Loc = pos->second;
- return getSectionAddress(Loc.first) + Loc.second;
+ const auto &SymInfo = pos->second;
+ return getSectionAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
}
- uint64_t getSymbolLoadAddress(StringRef Name) const {
+ RuntimeDyld::SymbolInfo getSymbol(StringRef Name) const {
// FIXME: Just look up as a function for now. Overly simple of course.
// Work in progress.
- SymbolTableMap::const_iterator pos = GlobalSymbolTable.find(Name);
+ RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
if (pos == GlobalSymbolTable.end())
- return 0;
- SymbolLoc Loc = pos->second;
- return getSectionLoadAddress(Loc.first) + Loc.second;
+ return nullptr;
+ const auto &SymEntry = pos->second;
+ uint64_t TargetAddr =
+ getSectionLoadAddress(SymEntry.getSectionID()) + SymEntry.getOffset();
+ return RuntimeDyld::SymbolInfo(TargetAddr, SymEntry.getFlags());
}
void resolveRelocations();
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
index d75be28..d4a680d 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
@@ -26,11 +26,12 @@ using namespace llvm::object;
namespace {
-class LoadedMachOObjectInfo : public RuntimeDyld::LoadedObjectInfo {
+class LoadedMachOObjectInfo
+ : public RuntimeDyld::LoadedObjectInfoHelper<LoadedMachOObjectInfo> {
public:
LoadedMachOObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx,
unsigned EndIdx)
- : RuntimeDyld::LoadedObjectInfo(RTDyld, BeginIdx, EndIdx) {}
+ : LoadedObjectInfoHelper(RTDyld, BeginIdx, EndIdx) {}
OwningBinary<ObjectFile>
getObjectForDebug(const ObjectFile &Obj) const override {
@@ -64,17 +65,18 @@ RelocationValueRef RuntimeDyldMachO::getRelocationValueRef(
symbol_iterator Symbol = RI->getSymbol();
StringRef TargetName;
Symbol->getName(TargetName);
- SymbolTableMap::const_iterator SI =
+ RTDyldSymbolTable::const_iterator SI =
GlobalSymbolTable.find(TargetName.data());
if (SI != GlobalSymbolTable.end()) {
- Value.SectionID = SI->second.first;
- Value.Offset = SI->second.second + RE.Addend;
+ const auto &SymInfo = SI->second;
+ Value.SectionID = SymInfo.getSectionID();
+ Value.Offset = SymInfo.getOffset() + RE.Addend;
} else {
Value.SymbolName = TargetName.data();
Value.Offset = RE.Addend;
}
} else {
- SectionRef Sec = Obj.getRelocationSection(RelInfo);
+ SectionRef Sec = Obj.getAnyRelocationSection(RelInfo);
bool IsCode = Sec.isText();
Value.SectionID = findOrEmitSection(Obj, Sec, IsCode, ObjSectionToID);
uint64_t Addr = Sec.getAddress();
@@ -252,8 +254,6 @@ static int64_t computeDelta(SectionEntry *A, SectionEntry *B) {
template <typename Impl>
void RuntimeDyldMachOCRTPBase<Impl>::registerEHFrames() {
- if (!MemMgr)
- return;
for (int i = 0, e = UnregisteredEHFrameSections.size(); i != e; ++i) {
EHFrameRelatedSections &SectionInfo = UnregisteredEHFrameSections[i];
if (SectionInfo.EHFrameSID == RTDYLD_INVALID_SECTION_ID ||
@@ -276,22 +276,28 @@ void RuntimeDyldMachOCRTPBase<Impl>::registerEHFrames() {
P = processFDE(P, DeltaForText, DeltaForEH);
} while (P != End);
- MemMgr->registerEHFrames(EHFrame->Address, EHFrame->LoadAddress,
- EHFrame->Size);
+ MemMgr.registerEHFrames(EHFrame->Address, EHFrame->LoadAddress,
+ EHFrame->Size);
}
UnregisteredEHFrameSections.clear();
}
std::unique_ptr<RuntimeDyldMachO>
-RuntimeDyldMachO::create(Triple::ArchType Arch, RTDyldMemoryManager *MM) {
+RuntimeDyldMachO::create(Triple::ArchType Arch,
+ RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver) {
switch (Arch) {
default:
llvm_unreachable("Unsupported target for RuntimeDyldMachO.");
break;
- case Triple::arm: return make_unique<RuntimeDyldMachOARM>(MM);
- case Triple::aarch64: return make_unique<RuntimeDyldMachOAArch64>(MM);
- case Triple::x86: return make_unique<RuntimeDyldMachOI386>(MM);
- case Triple::x86_64: return make_unique<RuntimeDyldMachOX86_64>(MM);
+ case Triple::arm:
+ return make_unique<RuntimeDyldMachOARM>(MemMgr, Resolver);
+ case Triple::aarch64:
+ return make_unique<RuntimeDyldMachOAArch64>(MemMgr, Resolver);
+ case Triple::x86:
+ return make_unique<RuntimeDyldMachOI386>(MemMgr, Resolver);
+ case Triple::x86_64:
+ return make_unique<RuntimeDyldMachOX86_64>(MemMgr, Resolver);
}
}
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
index f8bfc03..45a94ba 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
@@ -49,7 +49,9 @@ protected:
// EH frame sections with the memory manager.
SmallVector<EHFrameRelatedSections, 2> UnregisteredEHFrameSections;
- RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
+ RuntimeDyldMachO(RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldImpl(MemMgr, Resolver) {}
/// This convenience method uses memcpy to extract a contiguous addend (the
/// addend size and offset are taken from the corresponding fields of the RE).
@@ -114,8 +116,10 @@ protected:
public:
/// Create a RuntimeDyldMachO instance for the given target architecture.
- static std::unique_ptr<RuntimeDyldMachO> create(Triple::ArchType Arch,
- RTDyldMemoryManager *mm);
+ static std::unique_ptr<RuntimeDyldMachO>
+ create(Triple::ArchType Arch,
+ RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver);
std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
loadObject(const object::ObjectFile &O) override;
@@ -142,7 +146,9 @@ private:
int64_t DeltaForEH);
public:
- RuntimeDyldMachOCRTPBase(RTDyldMemoryManager *mm) : RuntimeDyldMachO(mm) {}
+ RuntimeDyldMachOCRTPBase(RuntimeDyld::MemoryManager &MemMgr,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldMachO(MemMgr, Resolver) {}
void finalizeLoad(const ObjectFile &Obj,
ObjSectionToIDMap &SectionMap) override;
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h
new file mode 100644
index 0000000..478665e
--- /dev/null
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h
@@ -0,0 +1,216 @@
+//===-- RuntimeDyldCOFFX86_64.h --- COFF/X86_64 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 x86_x64 support for MC-JIT runtime dynamic linker.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFF86_64_H
+#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFF86_64_H
+
+#include "llvm/Object/COFF.h"
+#include "llvm/Support/COFF.h"
+#include "../RuntimeDyldCOFF.h"
+
+#define DEBUG_TYPE "dyld"
+
+namespace llvm {
+
+class RuntimeDyldCOFFX86_64 : public RuntimeDyldCOFF {
+
+private:
+ // When a module is loaded we save the SectionID of the unwind
+ // sections in a table until we receive a request to register all
+ // unregisteredEH frame sections with the memory manager.
+ SmallVector<SID, 2> UnregisteredEHFrameSections;
+ SmallVector<SID, 2> RegisteredEHFrameSections;
+
+public:
+ RuntimeDyldCOFFX86_64(RuntimeDyld::MemoryManager &MM,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldCOFF(MM, Resolver) {}
+
+ unsigned getMaxStubSize() override {
+ return 6; // 2-byte jmp instruction + 32-bit relative address
+ }
+
+ // The target location for the relocation is described by RE.SectionID and
+ // RE.Offset. RE.SectionID can be used to find the SectionEntry. Each
+ // SectionEntry has three members describing its location.
+ // SectionEntry::Address is the address at which the section has been loaded
+ // into memory in the current (host) process. SectionEntry::LoadAddress is
+ // the address that the section will have in the target process.
+ // SectionEntry::ObjAddress is the address of the bits for this section in the
+ // original emitted object image (also in the current address space).
+ //
+ // Relocations will be applied as if the section were loaded at
+ // SectionEntry::LoadAddress, but they will be applied at an address based
+ // on SectionEntry::Address. SectionEntry::ObjAddress will be used to refer
+ // to Target memory contents if they are required for value calculations.
+ //
+ // The Value parameter here is the load address of the symbol for the
+ // relocation to be applied. For relocations which refer to symbols in the
+ // current object Value will be the LoadAddress of the section in which
+ // the symbol resides (RE.Addend provides additional information about the
+ // symbol location). For external symbols, Value will be the address of the
+ // symbol in the target address space.
+ void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override {
+ const SectionEntry &Section = Sections[RE.SectionID];
+ uint8_t *Target = Section.Address + RE.Offset;
+
+ switch (RE.RelType) {
+
+ case COFF::IMAGE_REL_AMD64_REL32:
+ case COFF::IMAGE_REL_AMD64_REL32_1:
+ case COFF::IMAGE_REL_AMD64_REL32_2:
+ case COFF::IMAGE_REL_AMD64_REL32_3:
+ case COFF::IMAGE_REL_AMD64_REL32_4:
+ case COFF::IMAGE_REL_AMD64_REL32_5: {
+ uint32_t *TargetAddress = (uint32_t *)Target;
+ uint64_t FinalAddress = Section.LoadAddress + RE.Offset;
+ // Delta is the distance from the start of the reloc to the end of the
+ // instruction with the reloc.
+ uint64_t Delta = 4 + (RE.RelType - COFF::IMAGE_REL_AMD64_REL32);
+ Value -= FinalAddress + Delta;
+ uint64_t Result = Value + RE.Addend;
+ assert(((int64_t)Result <= INT32_MAX) && "Relocation overflow");
+ assert(((int64_t)Result >= INT32_MIN) && "Relocation underflow");
+ *TargetAddress = Result;
+ break;
+ }
+
+ case COFF::IMAGE_REL_AMD64_ADDR32NB: {
+ // Note ADDR32NB requires a well-established notion of
+ // image base. This address must be less than or equal
+ // to every section's load address, and all sections must be
+ // within a 32 bit offset from the base.
+ //
+ // For now we just set these to zero.
+ uint32_t *TargetAddress = (uint32_t *)Target;
+ *TargetAddress = 0;
+ break;
+ }
+
+ case COFF::IMAGE_REL_AMD64_ADDR64: {
+ uint64_t *TargetAddress = (uint64_t *)Target;
+ *TargetAddress = Value + RE.Addend;
+ break;
+ }
+
+ default:
+ llvm_unreachable("Relocation type not implemented yet!");
+ break;
+ }
+ }
+
+ 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(Obj.section_end());
+ Symbol->getSection(SecI);
+ // If there is no section, this must be an external reference.
+ const bool IsExtern = SecI == Obj.section_end();
+
+ // Determine the Addend used to adjust the relocation value.
+ uint64_t RelType;
+ Check(RelI->getType(RelType));
+ uint64_t Offset;
+ Check(RelI->getOffset(Offset));
+ uint64_t Addend = 0;
+ SectionEntry &Section = Sections[SectionID];
+ uintptr_t ObjTarget = Section.ObjAddress + Offset;
+
+ switch (RelType) {
+
+ case COFF::IMAGE_REL_AMD64_REL32:
+ case COFF::IMAGE_REL_AMD64_REL32_1:
+ case COFF::IMAGE_REL_AMD64_REL32_2:
+ case COFF::IMAGE_REL_AMD64_REL32_3:
+ case COFF::IMAGE_REL_AMD64_REL32_4:
+ case COFF::IMAGE_REL_AMD64_REL32_5:
+ case COFF::IMAGE_REL_AMD64_ADDR32NB: {
+ uint32_t *Displacement = (uint32_t *)ObjTarget;
+ Addend = *Displacement;
+ break;
+ }
+
+ case COFF::IMAGE_REL_AMD64_ADDR64: {
+ uint64_t *Displacement = (uint64_t *)ObjTarget;
+ Addend = *Displacement;
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ StringRef TargetName;
+ Symbol->getName(TargetName);
+
+ DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset
+ << " RelType: " << RelType << " TargetName: " << TargetName
+ << " Addend " << Addend << "\n");
+
+ if (IsExtern) {
+ RelocationEntry RE(SectionID, Offset, RelType, Addend);
+ addRelocationForSymbol(RE, TargetName);
+ } else {
+ bool IsCode = SecI->isText();
+ unsigned TargetSectionID =
+ findOrEmitSection(Obj, *SecI, IsCode, ObjSectionToID);
+ uint64_t TargetOffset = getSymbolOffset(*Symbol);
+ RelocationEntry RE(SectionID, Offset, RelType, TargetOffset + Addend);
+ addRelocationForSection(RE, TargetSectionID);
+ }
+
+ return ++RelI;
+ }
+
+ unsigned getStubAlignment() override { return 1; }
+ void registerEHFrames() override {
+ for (auto const &EHFrameSID : UnregisteredEHFrameSections) {
+ uint8_t *EHFrameAddr = Sections[EHFrameSID].Address;
+ uint64_t EHFrameLoadAddr = Sections[EHFrameSID].LoadAddress;
+ size_t EHFrameSize = Sections[EHFrameSID].Size;
+ MemMgr.registerEHFrames(EHFrameAddr, EHFrameLoadAddr, EHFrameSize);
+ RegisteredEHFrameSections.push_back(EHFrameSID);
+ }
+ UnregisteredEHFrameSections.clear();
+ }
+ void deregisterEHFrames() override {
+ // Stub
+ }
+ void 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));
+ // 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);
+ }
+ }
+ }
+};
+
+} // end namespace llvm
+
+#undef DEBUG_TYPE
+
+#endif
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
index 196fa62..99fd6e3 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
@@ -23,8 +23,9 @@ public:
typedef uint64_t TargetPtrT;
- RuntimeDyldMachOAArch64(RTDyldMemoryManager *MM)
- : RuntimeDyldMachOCRTPBase(MM) {}
+ RuntimeDyldMachOAArch64(RuntimeDyld::MemoryManager &MM,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldMachOCRTPBase(MM, Resolver) {}
unsigned getMaxStubSize() override { return 8; }
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h
index 09e430e..09e51f2 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h
@@ -25,7 +25,9 @@ public:
typedef uint32_t TargetPtrT;
- RuntimeDyldMachOARM(RTDyldMemoryManager *MM) : RuntimeDyldMachOCRTPBase(MM) {}
+ RuntimeDyldMachOARM(RuntimeDyld::MemoryManager &MM,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldMachOCRTPBase(MM, Resolver) {}
unsigned getMaxStubSize() override { return 8; }
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h
index 67d7027..053f90c 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h
@@ -22,8 +22,9 @@ public:
typedef uint32_t TargetPtrT;
- RuntimeDyldMachOI386(RTDyldMemoryManager *MM)
- : RuntimeDyldMachOCRTPBase(MM) {}
+ RuntimeDyldMachOI386(RuntimeDyld::MemoryManager &MM,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldMachOCRTPBase(MM, Resolver) {}
unsigned getMaxStubSize() override { return 0; }
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h
index 0734017..4b3b01b 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h
@@ -22,8 +22,9 @@ public:
typedef uint64_t TargetPtrT;
- RuntimeDyldMachOX86_64(RTDyldMemoryManager *MM)
- : RuntimeDyldMachOCRTPBase(MM) {}
+ RuntimeDyldMachOX86_64(RuntimeDyld::MemoryManager &MM,
+ RuntimeDyld::SymbolResolver &Resolver)
+ : RuntimeDyldMachOCRTPBase(MM, Resolver) {}
unsigned getMaxStubSize() override { return 8; }
diff --git a/contrib/llvm/lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp b/contrib/llvm/lib/ExecutionEngine/SectionMemoryManager.cpp
index 5986084..5986084 100644
--- a/contrib/llvm/lib/ExecutionEngine/MCJIT/SectionMemoryManager.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/SectionMemoryManager.cpp
diff --git a/contrib/llvm/lib/ExecutionEngine/TargetSelect.cpp b/contrib/llvm/lib/ExecutionEngine/TargetSelect.cpp
index e6679cf..57f6e08 100644
--- a/contrib/llvm/lib/ExecutionEngine/TargetSelect.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/TargetSelect.cpp
@@ -49,21 +49,19 @@ TargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple,
// Adjust the triple to match what the user requested.
const Target *TheTarget = nullptr;
if (!MArch.empty()) {
- for (TargetRegistry::iterator it = TargetRegistry::begin(),
- ie = TargetRegistry::end(); it != ie; ++it) {
- if (MArch == it->getName()) {
- TheTarget = &*it;
- break;
- }
- }
+ auto I = std::find_if(
+ TargetRegistry::targets().begin(), TargetRegistry::targets().end(),
+ [&](const Target &T) { return MArch == T.getName(); });
- if (!TheTarget) {
+ if (I == TargetRegistry::targets().end()) {
if (ErrorStr)
*ErrorStr = "No available targets are compatible with this -march, "
"see -version for the available targets.\n";
return nullptr;
}
+ TheTarget = &*I;
+
// Adjust the triple to match (if known), otherwise stick with the
// requested/host triple.
Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
OpenPOWER on IntegriCloud