aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ExecutionEngine
diff options
context:
space:
mode:
authorPirama Arumuga Nainar <pirama@google.com>2015-04-08 08:55:49 -0700
committerPirama Arumuga Nainar <pirama@google.com>2015-04-09 15:04:38 -0700
commit4c5e43da7792f75567b693105cc53e3f1992ad98 (patch)
tree1b2c9792582e12f5af0b1512e3094425f0dc0df9 /lib/ExecutionEngine
parentc75239e6119d0f9a74c57099d91cbc9bde56bf33 (diff)
downloadexternal_llvm-4c5e43da7792f75567b693105cc53e3f1992ad98.zip
external_llvm-4c5e43da7792f75567b693105cc53e3f1992ad98.tar.gz
external_llvm-4c5e43da7792f75567b693105cc53e3f1992ad98.tar.bz2
Update aosp/master llvm for rebase to r233350
Change-Id: I07d935f8793ee8ec6b7da003f6483046594bca49
Diffstat (limited to 'lib/ExecutionEngine')
-rw-r--r--lib/ExecutionEngine/ExecutionEngine.cpp38
-rw-r--r--lib/ExecutionEngine/Interpreter/CMakeLists.txt2
-rw-r--r--lib/ExecutionEngine/Interpreter/Execution.cpp17
-rw-r--r--lib/ExecutionEngine/MCJIT/MCJIT.cpp7
-rw-r--r--lib/ExecutionEngine/Orc/IndirectionUtils.cpp1
-rw-r--r--lib/ExecutionEngine/Orc/OrcMCJITReplacement.h4
-rw-r--r--lib/ExecutionEngine/Orc/OrcTargetSupport.cpp6
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/Android.mk1
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt1
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp81
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp85
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h46
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp18
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h2
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp2
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h10
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h49
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h214
18 files changed, 475 insertions, 109 deletions
diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp
index 12e0e6a..c586ba7 100644
--- a/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#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"
@@ -399,33 +400,12 @@ int ExecutionEngine::runFunctionAsMain(Function *Fn,
return runFunction(Fn, GVArgs).IntVal.getZExtValue();
}
-EngineBuilder::EngineBuilder() {
- InitEngine();
-}
+EngineBuilder::EngineBuilder() : EngineBuilder(nullptr) {}
EngineBuilder::EngineBuilder(std::unique_ptr<Module> M)
- : M(std::move(M)), MCJMM(nullptr) {
- InitEngine();
-}
-
-EngineBuilder::~EngineBuilder() {}
-
-EngineBuilder &EngineBuilder::setMCJITMemoryManager(
- std::unique_ptr<RTDyldMemoryManager> mcjmm) {
- MCJMM = std::move(mcjmm);
- return *this;
-}
-
-void EngineBuilder::InitEngine() {
- WhichEngine = EngineKind::Either;
- ErrorStr = nullptr;
- OptLevel = CodeGenOpt::Default;
- MCJMM = nullptr;
- Options = TargetOptions();
- RelocModel = Reloc::Default;
- CMModel = CodeModel::JITDefault;
- UseOrcMCJITReplacement = false;
-
+ : M(std::move(M)), WhichEngine(EngineKind::Either), ErrorStr(nullptr),
+ OptLevel(CodeGenOpt::Default), MCJMM(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
@@ -435,6 +415,14 @@ void EngineBuilder::InitEngine() {
#endif
}
+EngineBuilder::~EngineBuilder() = default;
+
+EngineBuilder &EngineBuilder::setMCJITMemoryManager(
+ std::unique_ptr<RTDyldMemoryManager> mcjmm) {
+ MCJMM = std::move(mcjmm);
+ return *this;
+}
+
ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
std::unique_ptr<TargetMachine> TheTM(TM); // Take ownership.
diff --git a/lib/ExecutionEngine/Interpreter/CMakeLists.txt b/lib/ExecutionEngine/Interpreter/CMakeLists.txt
index 1aac3ac..4dbc2df 100644
--- a/lib/ExecutionEngine/Interpreter/CMakeLists.txt
+++ b/lib/ExecutionEngine/Interpreter/CMakeLists.txt
@@ -13,7 +13,7 @@ add_llvm_library(LLVMInterpreter
)
if( LLVM_ENABLE_FFI )
- target_link_libraries( LLVMInterpreter ${cmake_2_8_12_PRIVATE} ${FFI_LIBRARY_PATH} )
+ target_link_libraries( LLVMInterpreter PRIVATE ${FFI_LIBRARY_PATH} )
endif()
add_dependencies(LLVMInterpreter intrinsics_gen)
diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp
index 93bb2d1..2e8eb16 100644
--- a/lib/ExecutionEngine/Interpreter/Execution.cpp
+++ b/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;
@@ -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,
diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp
index e500d3d..20b8553 100644
--- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp
+++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp
@@ -137,8 +137,7 @@ std::unique_ptr<MemoryBuffer> MCJIT::emitObject(Module *M) {
legacy::PassManager PM;
- M->setDataLayout(TM->getDataLayout());
- PM.add(new DataLayoutPass());
+ M->setDataLayout(*TM->getDataLayout());
// The RuntimeDyld will take ownership of this shortly
SmallVector<char, 4096> ObjBufferSV;
@@ -258,7 +257,7 @@ uint64_t MCJIT::getExistingSymbolAddress(const std::string &Name) {
Mangler Mang(TM->getDataLayout());
SmallString<128> FullName;
Mang.getNameWithPrefix(FullName, Name);
- return Dyld.getSymbolLoadAddress(FullName);
+ return Dyld.getSymbol(FullName).getAddress();
}
Module *MCJIT::findModuleForSymbol(const std::string &Name,
@@ -384,7 +383,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(
diff --git a/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
index 61c947f..8cf490f 100644
--- a/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
+++ b/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ExecutionEngine/Orc/CloneSubModule.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
diff --git a/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h b/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
index 1b7b161..00e39bb 100644
--- a/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
+++ b/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h
@@ -133,8 +133,8 @@ public:
// If this module doesn't have a DataLayout attached then attach the
// default.
- if (!M->getDataLayout())
- M->setDataLayout(getDataLayout());
+ if (M->getDataLayout().isDefault())
+ M->setDataLayout(*getDataLayout());
Modules.push_back(std::move(M));
std::vector<Module *> Ms;
diff --git a/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp b/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp
index b5dda8e..6fe5301 100644
--- a/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp
+++ b/lib/ExecutionEngine/Orc/OrcTargetSupport.cpp
@@ -39,7 +39,7 @@ template <typename OStream> void restoreX86Regs(OStream &OS) {
}
template <typename TargetT>
-uint64_t executeCompileCallback(JITCompileCallbackManagerBase<TargetT> *JCBM,
+uint64_t executeCompileCallback(JITCompileCallbackManagerBase *JCBM,
TargetAddress CallbackID) {
return JCBM->executeCompileCallback(CallbackID);
}
@@ -52,7 +52,8 @@ namespace orc {
const char* OrcX86_64::ResolverBlockName = "orc_resolver_block";
void OrcX86_64::insertResolverBlock(
- Module &M, JITCompileCallbackManagerBase<OrcX86_64> &JCBM) {
+ Module &M, JITCompileCallbackManagerBase &JCBM) {
+ const unsigned X86_64_TrampolineLength = 6;
auto CallbackPtr = executeCompileCallback<OrcX86_64>;
uint64_t CallbackAddr =
static_cast<uint64_t>(reinterpret_cast<uintptr_t>(CallbackPtr));
@@ -77,6 +78,7 @@ void OrcX86_64::insertResolverBlock(
AsmStream << " leaq jit_callback_manager_addr(%rip), %rdi\n"
<< " movq (%rdi), %rdi\n"
<< " movq " << ReturnAddrOffset << "(%rsp), %rsi\n"
+ << " subq $" << X86_64_TrampolineLength << ", %rsi\n"
<< " movabsq $" << CallbackAddr << ", %rax\n"
<< " callq *%rax\n"
<< " movq %rax, " << ReturnAddrOffset << "(%rsp)\n";
diff --git a/lib/ExecutionEngine/RuntimeDyld/Android.mk b/lib/ExecutionEngine/RuntimeDyld/Android.mk
index 76aae67..40fdd7c 100644
--- a/lib/ExecutionEngine/RuntimeDyld/Android.mk
+++ b/lib/ExecutionEngine/RuntimeDyld/Android.mk
@@ -8,6 +8,7 @@ LOCAL_SRC_FILES := \
RTDyldMemoryManager.cpp \
RuntimeDyldChecker.cpp \
RuntimeDyld.cpp \
+ RuntimeDyldCOFF.cpp \
RuntimeDyldELF.cpp \
RuntimeDyldMachO.cpp
diff --git a/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt b/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt
index 12bbcc6..e78408a 100644
--- a/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt
+++ b/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt
@@ -2,6 +2,7 @@ add_llvm_library(LLVMRuntimeDyld
RTDyldMemoryManager.cpp
RuntimeDyld.cpp
RuntimeDyldChecker.cpp
+ RuntimeDyldCOFF.cpp
RuntimeDyldELF.cpp
RuntimeDyldMachO.cpp
)
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index 54f1a1c..a0ed7cf 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/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"
@@ -195,10 +197,13 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
<< " SID: " << SectionID << " Offset: "
<< format("%p", (uintptr_t)SectOffset)
<< " flags: " << Flags << "\n");
- SymbolInfo::Visibility Vis =
- (Flags & SymbolRef::SF_Exported) ?
- SymbolInfo::Default : SymbolInfo::Hidden;
- GlobalSymbolTable[Name] = SymbolInfo(SectionID, SectOffset, Vis);
+ 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);
}
}
}
@@ -264,6 +269,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;
}
@@ -273,6 +292,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;
}
@@ -281,6 +309,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);
@@ -497,12 +528,15 @@ void RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
Offset += AlignOffset;
}
uint32_t Flags = Sym.getFlags();
- SymbolInfo::Visibility Vis =
- (Flags & SymbolRef::SF_Exported) ?
- SymbolInfo::Default : SymbolInfo::Hidden;
+ 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] = SymbolInfo(SectionID, Offset, Vis);
+ GlobalSymbolTable[Name] =
+ SymbolTableEntry(SectionID, Offset, RTDyldSymFlags);
Offset += Size;
Addr += Size;
}
@@ -512,7 +546,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;
@@ -542,6 +575,7 @@ unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
// Some sections, such as debug info, don't need to be loaded for execution.
// Leave those where they are.
if (IsRequired) {
+ Check(Section.getContents(data));
Allocate = DataSize + PaddingSize + StubBufSize;
Addr = IsCode ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID,
Name)
@@ -816,6 +850,15 @@ RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
RuntimeDyld::~RuntimeDyld() {}
+static std::unique_ptr<RuntimeDyldCOFF>
+createRuntimeDyldCOFF(Triple::ArchType Arch, RTDyldMemoryManager *MM,
+ bool ProcessAllSections, RuntimeDyldCheckerImpl *Checker) {
+ std::unique_ptr<RuntimeDyldCOFF> Dyld(RuntimeDyldCOFF::create(Arch, MM));
+ Dyld->setProcessAllSections(ProcessAllSections);
+ Dyld->setRuntimeDyldChecker(Checker);
+ return Dyld;
+}
+
static std::unique_ptr<RuntimeDyldELF>
createRuntimeDyldELF(RTDyldMemoryManager *MM, bool ProcessAllSections,
RuntimeDyldCheckerImpl *Checker) {
@@ -843,6 +886,10 @@ RuntimeDyld::loadObject(const ObjectFile &Obj) {
Dyld = createRuntimeDyldMachO(
static_cast<Triple::ArchType>(Obj.getArch()), MM,
ProcessAllSections, Checker);
+ else if (Obj.isCOFF())
+ Dyld = createRuntimeDyldCOFF(
+ static_cast<Triple::ArchType>(Obj.getArch()), MM,
+ ProcessAllSections, Checker);
else
report_fatal_error("Incompatible object format!");
}
@@ -853,22 +900,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);
-}
-
-uint64_t RuntimeDyld::getExportedSymbolLoadAddress(StringRef Name) const {
- if (!Dyld)
- return 0;
- return Dyld->getExportedSymbolLoadAddress(Name);
+ return nullptr;
+ return Dyld->getSymbol(Name);
}
void RuntimeDyld::resolveRelocations() { Dyld->resolveRelocations(); }
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp
new file mode 100644
index 0000000..56bcb8e
--- /dev/null
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.cpp
@@ -0,0 +1,85 @@
+//===-- 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::LoadedObjectInfo {
+public:
+ LoadedCOFFObjectInfo(RuntimeDyldImpl &RTDyld, unsigned BeginIdx,
+ unsigned EndIdx)
+ : RuntimeDyld::LoadedObjectInfo(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, RTDyldMemoryManager *MM) {
+ switch (Arch) {
+ default:
+ llvm_unreachable("Unsupported target for RuntimeDyldCOFF.");
+ break;
+ case Triple::x86_64:
+ return make_unique<RuntimeDyldCOFFX86_64>(MM);
+ }
+}
+
+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/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h
new file mode 100644
index 0000000..681a3e5
--- /dev/null
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCOFF.h
@@ -0,0 +1,46 @@
+//===-- 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,
+ RTDyldMemoryManager *MM);
+
+protected:
+ RuntimeDyldCOFF(RTDyldMemoryManager *MM) : RuntimeDyldImpl(MM) {}
+ uint64_t getSymbolOffset(const SymbolRef &Sym);
+};
+
+} // end namespace llvm
+
+#undef DEBUG_TYPE
+
+#endif
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
index 976a434..c991408 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
@@ -310,7 +310,7 @@ private:
"");
uint64_t SymbolAddr = PCtx.IsInsideLoad
- ? Checker.getSymbolLinkerAddr(Symbol)
+ ? Checker.getSymbolLocalAddr(Symbol)
: Checker.getSymbolRemoteAddr(Symbol);
uint64_t NextPC = SymbolAddr + InstSize;
@@ -437,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.
@@ -727,17 +727,17 @@ 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;
+ if (auto InternalSymbol = getRTDyld().getSymbol(Symbol))
+ return InternalSymbol.getAddress();
return getRTDyld().MemMgr->getSymbolAddress(Symbol);
}
@@ -929,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/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
index de20c1e..e8d299a 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
@@ -42,7 +42,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/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index 0f3ca0f..6278170 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -1128,7 +1128,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);
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
index b4414b0..71260d0 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
+++ b/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 {
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
index f37a9a7..05060dd 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
@@ -36,6 +36,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
@@ -156,27 +164,24 @@ public:
}
};
-/// @brief Symbol info for RuntimeDyld.
-class SymbolInfo {
+/// @brief Symbol info for RuntimeDyld.
+class SymbolTableEntry : public JITSymbolBase {
public:
- typedef enum { Hidden = 0, Default = 1 } Visibility;
-
- SymbolInfo() : Offset(0), SectionID(0), Vis(Hidden) {}
+ SymbolTableEntry()
+ : JITSymbolBase(JITSymbolFlags::None), Offset(0), SectionID(0) {}
- SymbolInfo(unsigned SectionID, uint64_t Offset, Visibility Vis)
- : Offset(Offset), SectionID(SectionID), Vis(Vis) {}
+ 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; }
- Visibility getVisibility() const { return Vis; }
private:
uint64_t Offset;
- unsigned SectionID : 31;
- Visibility Vis : 1;
+ unsigned SectionID;
};
-typedef StringMap<SymbolInfo> RTDyldSymbolTable;
+typedef StringMap<SymbolTableEntry> RTDyldSymbolTable;
class RuntimeDyldImpl {
friend class RuntimeDyld::LoadedObjectInfo;
@@ -386,7 +391,7 @@ 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.
RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
@@ -396,24 +401,16 @@ public:
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.
RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
if (pos == GlobalSymbolTable.end())
- return 0;
- const auto &SymInfo = pos->second;
- return getSectionLoadAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
- }
-
- uint64_t getExportedSymbolLoadAddress(StringRef Name) const {
- RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
- if (pos == GlobalSymbolTable.end())
- return 0;
- const auto &SymInfo = pos->second;
- if (SymInfo.getVisibility() == SymbolInfo::Hidden)
- return 0;
- return getSectionLoadAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
+ 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/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h
new file mode 100644
index 0000000..ce2f4a2
--- /dev/null
+++ b/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h
@@ -0,0 +1,214 @@
+//===-- 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(RTDyldMemoryManager *MM) : RuntimeDyldCOFF(MM) {}
+
+ 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 {
+ // Find the symbol referred to in the relocation, and
+ // get its section and offset.
+ //
+ // Insist for now that all symbols be resolvable within
+ // the scope of this object file.
+ symbol_iterator Symbol = RelI->getSymbol();
+ if (Symbol == Obj.symbol_end())
+ report_fatal_error("Unknown symbol in relocation");
+ unsigned TargetSectionID = 0;
+ uint64_t TargetOffset = UnknownAddressOrSize;
+ section_iterator SecI(Obj.section_end());
+ Symbol->getSection(SecI);
+ if (SecI == Obj.section_end())
+ report_fatal_error("Unknown section in relocation");
+ bool IsCode = SecI->isText();
+ TargetSectionID = findOrEmitSection(Obj, *SecI, IsCode, ObjSectionToID);
+ TargetOffset = getSymbolOffset(*Symbol);
+
+ // 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");
+
+ RelocationEntry RE(SectionID, Offset, RelType, TargetOffset + Addend);
+ addRelocationForSection(RE, TargetSectionID);
+
+ return ++RelI;
+ }
+
+ unsigned getStubAlignment() override { return 1; }
+ void registerEHFrames() override {
+ if (!MemMgr)
+ return;
+ 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