aboutsummaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp')
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp147
1 files changed, 107 insertions, 40 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index 53cb782c55c4..e26e6ce45db4 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -1,9 +1,8 @@
//===-- RuntimeDyld.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.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -13,7 +12,6 @@
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "RuntimeDyldCOFF.h"
-#include "RuntimeDyldCheckerImpl.h"
#include "RuntimeDyldELF.h"
#include "RuntimeDyldImpl.h"
#include "RuntimeDyldMachO.h"
@@ -376,10 +374,55 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
else
return IOrErr.takeError();
- // If there is an attached checker, notify it about the stubs for this
- // section so that they can be verified.
- if (Checker)
- Checker->registerStubMap(Obj.getFileName(), SectionID, Stubs);
+ // If there is a NotifyStubEmitted callback set, call it to register any
+ // stubs created for this section.
+ if (NotifyStubEmitted) {
+ StringRef FileName = Obj.getFileName();
+ StringRef SectionName = Sections[SectionID].getName();
+ for (auto &KV : Stubs) {
+
+ auto &VR = KV.first;
+ uint64_t StubAddr = KV.second;
+
+ // If this is a named stub, just call NotifyStubEmitted.
+ if (VR.SymbolName) {
+ NotifyStubEmitted(FileName, SectionName, VR.SymbolName, SectionID,
+ StubAddr);
+ continue;
+ }
+
+ // Otherwise we will have to try a reverse lookup on the globla symbol table.
+ for (auto &GSTMapEntry : GlobalSymbolTable) {
+ StringRef SymbolName = GSTMapEntry.first();
+ auto &GSTEntry = GSTMapEntry.second;
+ if (GSTEntry.getSectionID() == VR.SectionID &&
+ GSTEntry.getOffset() == VR.Offset) {
+ NotifyStubEmitted(FileName, SectionName, SymbolName, SectionID,
+ StubAddr);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Process remaining sections
+ if (ProcessAllSections) {
+ LLVM_DEBUG(dbgs() << "Process remaining sections:\n");
+ for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
+ SI != SE; ++SI) {
+
+ /* Ignore already loaded sections */
+ if (LocalSections.find(*SI) != LocalSections.end())
+ continue;
+
+ bool IsCode = SI->isText();
+ if (auto SectionIDOrErr =
+ findOrEmitSection(Obj, *SI, IsCode, LocalSections))
+ LLVM_DEBUG(dbgs() << "\tSectionID: " << (*SectionIDOrErr) << "\n");
+ else
+ return SectionIDOrErr.takeError();
+ }
}
// Give the subclasses a chance to tie-up any loose ends.
@@ -497,7 +540,14 @@ Error RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj,
return errorCodeToError(EC);
uint64_t StubBufSize = computeSectionStubBufSize(Obj, Section);
- uint64_t SectionSize = DataSize + StubBufSize;
+
+ uint64_t PaddingSize = 0;
+ if (Name == ".eh_frame")
+ PaddingSize += 4;
+ if (StubBufSize != 0)
+ PaddingSize += getStubAlignment() - 1;
+
+ uint64_t SectionSize = DataSize + PaddingSize + StubBufSize;
// The .eh_frame section (at least on Linux) needs an extra four bytes
// padded
@@ -703,9 +753,6 @@ Error RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
Addr += Size;
}
- if (Checker)
- Checker->registerSection(Obj.getFileName(), SectionID);
-
return Error::success();
}
@@ -725,6 +772,11 @@ RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
bool IsReadOnly = isReadOnlyData(Section);
uint64_t DataSize = Section.getSize();
+ // An alignment of 0 (at least with ELF) is identical to an alignment of 1,
+ // while being more "polite". Other formats do not support 0-aligned sections
+ // anyway, so we should guarantee that the alignment is always at least 1.
+ Alignment = std::max(1u, Alignment);
+
StringRef Name;
if (auto EC = Section.getName(Name))
return errorCodeToError(EC);
@@ -747,18 +799,19 @@ RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
if (!IsVirtual && !IsZeroInit) {
// In either case, set the location of the unrelocated section in memory,
// since we still process relocations for it even if we're not applying them.
- if (auto EC = Section.getContents(data))
- return errorCodeToError(EC);
+ if (Expected<StringRef> E = Section.getContents())
+ data = *E;
+ else
+ return E.takeError();
pData = data.data();
}
- // Code section alignment needs to be at least as high as stub alignment or
- // padding calculations may by incorrect when the section is remapped to a
- // higher alignment.
- if (IsCode) {
+ // If there are any stubs then the section alignment needs to be at least as
+ // high as stub alignment or padding calculations may by incorrect when the
+ // section is remapped.
+ if (StubBufSize != 0) {
Alignment = std::max(Alignment, getStubAlignment());
- if (StubBufSize > 0)
- PaddingSize += getStubAlignment() - 1;
+ PaddingSize += getStubAlignment() - 1;
}
// Some sections, such as debug info, don't need to be loaded for execution.
@@ -789,7 +842,7 @@ RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
// Align DataSize to stub alignment if we have any stubs (PaddingSize will
// have been increased above to account for this).
if (StubBufSize > 0)
- DataSize &= ~(getStubAlignment() - 1);
+ DataSize &= -(uint64_t)getStubAlignment();
}
LLVM_DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: "
@@ -817,9 +870,6 @@ RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
if (!IsRequired)
Sections.back().setLoadAddress(0);
- if (Checker)
- Checker->registerSection(Obj.getFileName(), SectionID);
-
return SectionID;
}
@@ -1202,42 +1252,43 @@ RuntimeDyld::RuntimeDyld(RuntimeDyld::MemoryManager &MemMgr,
// permissions are applied.
Dyld = nullptr;
ProcessAllSections = false;
- Checker = nullptr;
}
RuntimeDyld::~RuntimeDyld() {}
static std::unique_ptr<RuntimeDyldCOFF>
-createRuntimeDyldCOFF(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM,
- JITSymbolResolver &Resolver, bool ProcessAllSections,
- RuntimeDyldCheckerImpl *Checker) {
+createRuntimeDyldCOFF(
+ Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM,
+ JITSymbolResolver &Resolver, bool ProcessAllSections,
+ RuntimeDyld::NotifyStubEmittedFunction NotifyStubEmitted) {
std::unique_ptr<RuntimeDyldCOFF> Dyld =
RuntimeDyldCOFF::create(Arch, MM, Resolver);
Dyld->setProcessAllSections(ProcessAllSections);
- Dyld->setRuntimeDyldChecker(Checker);
+ Dyld->setNotifyStubEmitted(std::move(NotifyStubEmitted));
return Dyld;
}
static std::unique_ptr<RuntimeDyldELF>
createRuntimeDyldELF(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM,
JITSymbolResolver &Resolver, bool ProcessAllSections,
- RuntimeDyldCheckerImpl *Checker) {
+ RuntimeDyld::NotifyStubEmittedFunction NotifyStubEmitted) {
std::unique_ptr<RuntimeDyldELF> Dyld =
RuntimeDyldELF::create(Arch, MM, Resolver);
Dyld->setProcessAllSections(ProcessAllSections);
- Dyld->setRuntimeDyldChecker(Checker);
+ Dyld->setNotifyStubEmitted(std::move(NotifyStubEmitted));
return Dyld;
}
static std::unique_ptr<RuntimeDyldMachO>
-createRuntimeDyldMachO(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM,
- JITSymbolResolver &Resolver,
- bool ProcessAllSections,
- RuntimeDyldCheckerImpl *Checker) {
+createRuntimeDyldMachO(
+ Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM,
+ JITSymbolResolver &Resolver,
+ bool ProcessAllSections,
+ RuntimeDyld::NotifyStubEmittedFunction NotifyStubEmitted) {
std::unique_ptr<RuntimeDyldMachO> Dyld =
RuntimeDyldMachO::create(Arch, MM, Resolver);
Dyld->setProcessAllSections(ProcessAllSections);
- Dyld->setRuntimeDyldChecker(Checker);
+ Dyld->setNotifyStubEmitted(std::move(NotifyStubEmitted));
return Dyld;
}
@@ -1247,15 +1298,16 @@ RuntimeDyld::loadObject(const ObjectFile &Obj) {
if (Obj.isELF())
Dyld =
createRuntimeDyldELF(static_cast<Triple::ArchType>(Obj.getArch()),
- MemMgr, Resolver, ProcessAllSections, Checker);
+ MemMgr, Resolver, ProcessAllSections,
+ std::move(NotifyStubEmitted));
else if (Obj.isMachO())
Dyld = createRuntimeDyldMachO(
static_cast<Triple::ArchType>(Obj.getArch()), MemMgr, Resolver,
- ProcessAllSections, Checker);
+ ProcessAllSections, std::move(NotifyStubEmitted));
else if (Obj.isCOFF())
Dyld = createRuntimeDyldCOFF(
static_cast<Triple::ArchType>(Obj.getArch()), MemMgr, Resolver,
- ProcessAllSections, Checker);
+ ProcessAllSections, std::move(NotifyStubEmitted));
else
report_fatal_error("Incompatible object format!");
}
@@ -1274,6 +1326,11 @@ void *RuntimeDyld::getSymbolLocalAddress(StringRef Name) const {
return Dyld->getSymbolLocalAddress(Name);
}
+unsigned RuntimeDyld::getSymbolSectionID(StringRef Name) const {
+ assert(Dyld && "No RuntimeDyld instance attached");
+ return Dyld->getSymbolSectionID(Name);
+}
+
JITEvaluatedSymbol RuntimeDyld::getSymbol(StringRef Name) const {
if (!Dyld)
return nullptr;
@@ -1312,6 +1369,16 @@ void RuntimeDyld::finalizeWithMemoryManagerLocking() {
}
}
+StringRef RuntimeDyld::getSectionContent(unsigned SectionID) const {
+ assert(Dyld && "No Dyld instance attached");
+ return Dyld->getSectionContent(SectionID);
+}
+
+uint64_t RuntimeDyld::getSectionLoadAddress(unsigned SectionID) const {
+ assert(Dyld && "No Dyld instance attached");
+ return Dyld->getSectionLoadAddress(SectionID);
+}
+
void RuntimeDyld::registerEHFrames() {
if (Dyld)
Dyld->registerEHFrames();