summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp')
-rw-r--r--llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp40
1 files changed, 31 insertions, 9 deletions
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index 8198836f7a0..4d1d74cf34a 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -233,7 +233,7 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
return NameOrErr.takeError();
// Compute JIT symbol flags.
- JITSymbolFlags JITSymFlags = JITSymbolFlags::fromObjectSymbol(*I);
+ JITSymbolFlags JITSymFlags = getJITSymbolFlags(*I);
// If this is a weak definition, check to see if there's a strong one.
// If there is, skip this symbol (we won't be providing it: the strong
@@ -616,6 +616,10 @@ void RuntimeDyldImpl::writeBytesUnaligned(uint64_t Value, uint8_t *Dst,
}
}
+JITSymbolFlags RuntimeDyldImpl::getJITSymbolFlags(const BasicSymbolRef &SR) {
+ return JITSymbolFlags::fromObjectSymbol(SR);
+}
+
Error RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
CommonSymbolList &CommonSymbols) {
if (CommonSymbols.empty())
@@ -685,7 +689,7 @@ Error RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
Addr += AlignOffset;
Offset += AlignOffset;
}
- JITSymbolFlags JITSymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
+ JITSymbolFlags JITSymFlags = getJITSymbolFlags(Sym);
DEBUG(dbgs() << "Allocating common symbol " << Name << " address "
<< format("%p", Addr) << "\n");
GlobalSymbolTable[Name] =
@@ -746,8 +750,11 @@ RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
// 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 (IsCode) {
Alignment = std::max(Alignment, getStubAlignment());
+ if (StubBufSize > 0)
+ PaddingSize += getStubAlignment() - 1;
+ }
// Some sections, such as debug info, don't need to be loaded for execution.
// Process those only if explicitly requested.
@@ -771,8 +778,13 @@ RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
// Fill in any extra bytes we allocated for padding
if (PaddingSize != 0) {
memset(Addr + DataSize, 0, PaddingSize);
- // Update the DataSize variable so that the stub offset is set correctly.
+ // Update the DataSize variable to include padding.
DataSize += PaddingSize;
+
+ // 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);
}
DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name
@@ -864,7 +876,7 @@ uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr,
} else if (Arch == Triple::arm || Arch == Triple::armeb) {
// TODO: There is only ARM far stub now. We should add the Thumb stub,
// and stubs for branches Thumb - ARM and ARM - Thumb.
- writeBytesUnaligned(0xe51ff004, Addr, 4); // ldr pc,<label>
+ writeBytesUnaligned(0xe51ff004, Addr, 4); // ldr pc, [pc, #-4]
return Addr + 4;
} else if (IsMipsO32ABI) {
// 0: 3c190000 lui t9,%hi(addr).
@@ -971,15 +983,17 @@ Error RuntimeDyldImpl::resolveExternalSymbols() {
resolveRelocationList(Relocs, 0);
} else {
uint64_t Addr = 0;
+ JITSymbolFlags Flags;
RTDyldSymbolTable::const_iterator Loc = GlobalSymbolTable.find(Name);
if (Loc == GlobalSymbolTable.end()) {
// This is an external symbol, try to get its address from the symbol
// resolver.
// First search for the symbol in this logical dylib.
if (auto Sym = Resolver.findSymbolInLogicalDylib(Name.data())) {
- if (auto AddrOrErr = Sym.getAddress())
+ if (auto AddrOrErr = Sym.getAddress()) {
Addr = *AddrOrErr;
- else
+ Flags = Sym.getFlags();
+ } else
return AddrOrErr.takeError();
} else if (auto Err = Sym.takeError())
return Err;
@@ -987,9 +1001,10 @@ Error RuntimeDyldImpl::resolveExternalSymbols() {
// If that fails, try searching for an external symbol.
if (!Addr) {
if (auto Sym = Resolver.findSymbol(Name.data())) {
- if (auto AddrOrErr = Sym.getAddress())
+ if (auto AddrOrErr = Sym.getAddress()) {
Addr = *AddrOrErr;
- else
+ Flags = Sym.getFlags();
+ } else
return AddrOrErr.takeError();
} else if (auto Err = Sym.takeError())
return Err;
@@ -1007,6 +1022,7 @@ Error RuntimeDyldImpl::resolveExternalSymbols() {
const auto &SymInfo = Loc->second;
Addr = getSectionLoadAddress(SymInfo.getSectionID()) +
SymInfo.getOffset();
+ Flags = SymInfo.getFlags();
}
// FIXME: Implement error handling that doesn't kill the host program!
@@ -1017,6 +1033,12 @@ Error RuntimeDyldImpl::resolveExternalSymbols() {
// If Resolver returned UINT64_MAX, the client wants to handle this symbol
// manually and we shouldn't resolve its relocations.
if (Addr != UINT64_MAX) {
+
+ // Tweak the address based on the symbol flags if necessary.
+ // For example, this is used by RuntimeDyldMachOARM to toggle the low bit
+ // if the target symbol is Thumb.
+ Addr = modifyAddressBasedOnFlags(Addr, Flags);
+
DEBUG(dbgs() << "Resolving relocations Name: " << Name << "\t"
<< format("0x%lx", Addr) << "\n");
// This list may have been updated when we called getSymbolAddress, so
OpenPOWER on IntegriCloud