aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/ExecutionEngine/RuntimeDyld
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/ExecutionEngine/RuntimeDyld')
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/JITSymbol.cpp50
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp2
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp380
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp27
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp164
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h58
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp16
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h45
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h63
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h122
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp44
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.h4
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h103
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h32
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h12
-rw-r--r--contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h2
16 files changed, 725 insertions, 399 deletions
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/JITSymbol.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/JITSymbol.cpp
index 87059ef2b88f..18eb0e461921 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/JITSymbol.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/JITSymbol.cpp
@@ -47,3 +47,53 @@ ARMJITSymbolFlags llvm::ARMJITSymbolFlags::fromObjectSymbol(
Flags |= ARMJITSymbolFlags::Thumb;
return Flags;
}
+
+/// Performs lookup by, for each symbol, first calling
+/// findSymbolInLogicalDylib and if that fails calling
+/// findSymbol.
+Expected<JITSymbolResolver::LookupResult>
+LegacyJITSymbolResolver::lookup(const LookupSet &Symbols) {
+ JITSymbolResolver::LookupResult Result;
+ for (auto &Symbol : Symbols) {
+ std::string SymName = Symbol.str();
+ if (auto Sym = findSymbolInLogicalDylib(SymName)) {
+ if (auto AddrOrErr = Sym.getAddress())
+ Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
+ else
+ return AddrOrErr.takeError();
+ } else if (auto Err = Sym.takeError())
+ return std::move(Err);
+ else {
+ // findSymbolInLogicalDylib failed. Lets try findSymbol.
+ if (auto Sym = findSymbol(SymName)) {
+ if (auto AddrOrErr = Sym.getAddress())
+ Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
+ else
+ return AddrOrErr.takeError();
+ } else if (auto Err = Sym.takeError())
+ return std::move(Err);
+ else
+ return make_error<StringError>("Symbol not found: " + Symbol,
+ inconvertibleErrorCode());
+ }
+ }
+
+ return std::move(Result);
+}
+
+/// Performs flags lookup by calling findSymbolInLogicalDylib and
+/// returning the flags value for that symbol.
+Expected<JITSymbolResolver::LookupFlagsResult>
+LegacyJITSymbolResolver::lookupFlags(const LookupSet &Symbols) {
+ JITSymbolResolver::LookupFlagsResult Result;
+
+ for (auto &Symbol : Symbols) {
+ std::string SymName = Symbol.str();
+ if (auto Sym = findSymbolInLogicalDylib(SymName))
+ Result[Symbol] = Sym.getFlags();
+ else if (auto Err = Sym.takeError())
+ return std::move(Err);
+ }
+
+ return std::move(Result);
+}
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
index 99e84b7496d4..e774af05ebdd 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RTDyldMemoryManager.cpp
@@ -298,4 +298,6 @@ void *RTDyldMemoryManager::getPointerToNamedFunction(const std::string &Name,
return (void*)Addr;
}
+void RTDyldMemoryManager::anchor() {}
+void MCJITMemoryManager::anchor() {}
} // namespace llvm
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
index c5e4dfa1e536..1189be599edd 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
@@ -122,10 +122,8 @@ void RuntimeDyldImpl::resolveRelocations() {
MutexGuard locked(lock);
// Print out the sections prior to relocation.
- DEBUG(
- for (int i = 0, e = Sections.size(); i != e; ++i)
- dumpSectionMemory(Sections[i], "before relocations");
- );
+ LLVM_DEBUG(for (int i = 0, e = Sections.size(); i != e; ++i)
+ dumpSectionMemory(Sections[i], "before relocations"););
// First, resolve relocations associated with external symbols.
if (auto Err = resolveExternalSymbols()) {
@@ -140,18 +138,15 @@ void RuntimeDyldImpl::resolveRelocations() {
// entry provides the section to which the relocation will be applied.
int Idx = it->first;
uint64_t Addr = Sections[Idx].getLoadAddress();
- DEBUG(dbgs() << "Resolving relocations Section #" << Idx << "\t"
- << format("%p", (uintptr_t)Addr) << "\n");
+ LLVM_DEBUG(dbgs() << "Resolving relocations Section #" << Idx << "\t"
+ << format("%p", (uintptr_t)Addr) << "\n");
resolveRelocationList(it->second, Addr);
}
Relocations.clear();
// Print out sections after relocation.
- DEBUG(
- for (int i = 0, e = Sections.size(); i != e; ++i)
- dumpSectionMemory(Sections[i], "after relocations");
- );
-
+ LLVM_DEBUG(for (int i = 0, e = Sections.size(); i != e; ++i)
+ dumpSectionMemory(Sections[i], "after relocations"););
}
void RuntimeDyldImpl::mapSectionAddress(const void *LocalAddress,
@@ -202,10 +197,35 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
ObjSectionToIDMap LocalSections;
// Common symbols requiring allocation, with their sizes and alignments
- CommonSymbolList CommonSymbols;
+ CommonSymbolList CommonSymbolsToAllocate;
+
+ uint64_t CommonSize = 0;
+ uint32_t CommonAlign = 0;
+
+ // First, collect all weak and common symbols. We need to know if stronger
+ // definitions occur elsewhere.
+ JITSymbolResolver::LookupFlagsResult SymbolFlags;
+ {
+ JITSymbolResolver::LookupSet Symbols;
+ for (auto &Sym : Obj.symbols()) {
+ uint32_t Flags = Sym.getFlags();
+ if ((Flags & SymbolRef::SF_Common) || (Flags & SymbolRef::SF_Weak)) {
+ // Get symbol name.
+ if (auto NameOrErr = Sym.getName())
+ Symbols.insert(*NameOrErr);
+ else
+ return NameOrErr.takeError();
+ }
+ }
+
+ if (auto FlagsResultOrErr = Resolver.lookupFlags(Symbols))
+ SymbolFlags = std::move(*FlagsResultOrErr);
+ else
+ return FlagsResultOrErr.takeError();
+ }
// Parse symbols
- DEBUG(dbgs() << "Parse symbols:\n");
+ LLVM_DEBUG(dbgs() << "Parse symbols:\n");
for (symbol_iterator I = Obj.symbol_begin(), E = Obj.symbol_end(); I != E;
++I) {
uint32_t Flags = I->getFlags();
@@ -214,106 +234,112 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
if (Flags & SymbolRef::SF_Undefined)
continue;
- if (Flags & SymbolRef::SF_Common)
- CommonSymbols.push_back(*I);
- else {
+ // Get the symbol type.
+ object::SymbolRef::Type SymType;
+ if (auto SymTypeOrErr = I->getType())
+ SymType = *SymTypeOrErr;
+ else
+ return SymTypeOrErr.takeError();
- // Get the symbol type.
- object::SymbolRef::Type SymType;
- if (auto SymTypeOrErr = I->getType())
- SymType = *SymTypeOrErr;
- else
- return SymTypeOrErr.takeError();
+ // Get symbol name.
+ StringRef Name;
+ if (auto NameOrErr = I->getName())
+ Name = *NameOrErr;
+ else
+ return NameOrErr.takeError();
- // Get symbol name.
- StringRef Name;
- if (auto NameOrErr = I->getName())
- Name = *NameOrErr;
- else
- return NameOrErr.takeError();
-
- // Compute JIT symbol flags.
- 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
- // definition will). If there's no strong definition, make this definition
- // strong.
- if (JITSymFlags.isWeak()) {
- // First check whether there's already a definition in this instance.
- // FIXME: Override existing weak definitions with strong ones.
- if (GlobalSymbolTable.count(Name))
- continue;
- // Then check the symbol resolver to see if there's a definition
- // elsewhere in this logical dylib.
- if (auto Sym = Resolver.findSymbolInLogicalDylib(Name)) {
- if (Sym.getFlags().isStrongDefinition())
- continue;
- } else if (auto Err = Sym.takeError())
- return std::move(Err);
- // else
- JITSymFlags &= ~JITSymbolFlags::Weak;
- }
+ // Compute JIT symbol flags.
+ 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
+ // definition will). If there's no strong definition, make this definition
+ // strong.
+ if (JITSymFlags.isWeak() || JITSymFlags.isCommon()) {
+ // First check whether there's already a definition in this instance.
+ // FIXME: Override existing weak definitions with strong ones.
+ if (GlobalSymbolTable.count(Name))
+ continue;
- if (Flags & SymbolRef::SF_Absolute &&
- SymType != object::SymbolRef::ST_File) {
- uint64_t Addr = 0;
- if (auto AddrOrErr = I->getAddress())
- Addr = *AddrOrErr;
- else
- return AddrOrErr.takeError();
-
- unsigned SectionID = AbsoluteSymbolSection;
-
- DEBUG(dbgs() << "\tType: " << SymType << " (absolute) Name: " << Name
- << " SID: " << SectionID << " Offset: "
- << format("%p", (uintptr_t)Addr)
- << " flags: " << Flags << "\n");
- GlobalSymbolTable[Name] =
- SymbolTableEntry(SectionID, Addr, JITSymFlags);
- } else if (SymType == object::SymbolRef::ST_Function ||
- SymType == object::SymbolRef::ST_Data ||
- SymType == object::SymbolRef::ST_Unknown ||
- SymType == object::SymbolRef::ST_Other) {
-
- section_iterator SI = Obj.section_end();
- if (auto SIOrErr = I->getSection())
- SI = *SIOrErr;
- else
- return SIOrErr.takeError();
+ // Then check whether we found flags for an existing symbol during the
+ // flags lookup earlier.
+ auto FlagsI = SymbolFlags.find(Name);
+ if (FlagsI == SymbolFlags.end() ||
+ (JITSymFlags.isWeak() && !FlagsI->second.isStrong()) ||
+ (JITSymFlags.isCommon() && FlagsI->second.isCommon())) {
+ if (JITSymFlags.isWeak())
+ JITSymFlags &= ~JITSymbolFlags::Weak;
+ if (JITSymFlags.isCommon()) {
+ JITSymFlags &= ~JITSymbolFlags::Common;
+ uint32_t Align = I->getAlignment();
+ uint64_t Size = I->getCommonSize();
+ if (!CommonAlign)
+ CommonAlign = Align;
+ CommonSize += alignTo(CommonSize, Align) + Size;
+ CommonSymbolsToAllocate.push_back(*I);
+ }
+ } else
+ continue;
+ }
- if (SI == Obj.section_end())
- continue;
+ if (Flags & SymbolRef::SF_Absolute &&
+ SymType != object::SymbolRef::ST_File) {
+ uint64_t Addr = 0;
+ if (auto AddrOrErr = I->getAddress())
+ Addr = *AddrOrErr;
+ else
+ return AddrOrErr.takeError();
+
+ unsigned SectionID = AbsoluteSymbolSection;
+
+ LLVM_DEBUG(dbgs() << "\tType: " << SymType << " (absolute) Name: " << Name
+ << " SID: " << SectionID
+ << " Offset: " << format("%p", (uintptr_t)Addr)
+ << " flags: " << Flags << "\n");
+ GlobalSymbolTable[Name] = SymbolTableEntry(SectionID, Addr, JITSymFlags);
+ } else if (SymType == object::SymbolRef::ST_Function ||
+ SymType == object::SymbolRef::ST_Data ||
+ SymType == object::SymbolRef::ST_Unknown ||
+ SymType == object::SymbolRef::ST_Other) {
+
+ section_iterator SI = Obj.section_end();
+ if (auto SIOrErr = I->getSection())
+ SI = *SIOrErr;
+ else
+ return SIOrErr.takeError();
- // Get symbol offset.
- uint64_t SectOffset;
- if (auto Err = getOffset(*I, *SI, SectOffset))
- return std::move(Err);
+ if (SI == Obj.section_end())
+ continue;
- bool IsCode = SI->isText();
- unsigned SectionID;
- if (auto SectionIDOrErr = findOrEmitSection(Obj, *SI, IsCode,
- LocalSections))
- SectionID = *SectionIDOrErr;
- else
- return SectionIDOrErr.takeError();
+ // Get symbol offset.
+ uint64_t SectOffset;
+ if (auto Err = getOffset(*I, *SI, SectOffset))
+ return std::move(Err);
+
+ bool IsCode = SI->isText();
+ unsigned SectionID;
+ if (auto SectionIDOrErr =
+ findOrEmitSection(Obj, *SI, IsCode, LocalSections))
+ SectionID = *SectionIDOrErr;
+ else
+ return SectionIDOrErr.takeError();
- DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name
- << " SID: " << SectionID << " Offset: "
- << format("%p", (uintptr_t)SectOffset)
- << " flags: " << Flags << "\n");
- GlobalSymbolTable[Name] =
+ LLVM_DEBUG(dbgs() << "\tType: " << SymType << " Name: " << Name
+ << " SID: " << SectionID
+ << " Offset: " << format("%p", (uintptr_t)SectOffset)
+ << " flags: " << Flags << "\n");
+ GlobalSymbolTable[Name] =
SymbolTableEntry(SectionID, SectOffset, JITSymFlags);
- }
}
}
// Allocate common symbols
- if (auto Err = emitCommonSymbols(Obj, CommonSymbols))
+ if (auto Err = emitCommonSymbols(Obj, CommonSymbolsToAllocate, CommonSize,
+ CommonAlign))
return std::move(Err);
// Parse and process relocations
- DEBUG(dbgs() << "Parse relocations:\n");
+ LLVM_DEBUG(dbgs() << "Parse relocations:\n");
for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
SI != SE; ++SI) {
StubMap Stubs;
@@ -336,7 +362,7 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
else
return SectionIDOrErr.takeError();
- DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
+ LLVM_DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
for (; I != E;)
if (auto IOrErr = processRelocationRef(SectionID, I, Obj, LocalSections, Stubs))
@@ -621,45 +647,12 @@ JITSymbolFlags RuntimeDyldImpl::getJITSymbolFlags(const BasicSymbolRef &SR) {
}
Error RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
- CommonSymbolList &CommonSymbols) {
- if (CommonSymbols.empty())
+ CommonSymbolList &SymbolsToAllocate,
+ uint64_t CommonSize,
+ uint32_t CommonAlign) {
+ if (SymbolsToAllocate.empty())
return Error::success();
- uint64_t CommonSize = 0;
- uint32_t CommonAlign = CommonSymbols.begin()->getAlignment();
- CommonSymbolList SymbolsToAllocate;
-
- DEBUG(dbgs() << "Processing common symbols...\n");
-
- for (const auto &Sym : CommonSymbols) {
- StringRef Name;
- if (auto NameOrErr = Sym.getName())
- Name = *NameOrErr;
- else
- return NameOrErr.takeError();
-
- // Skip common symbols already elsewhere.
- if (GlobalSymbolTable.count(Name)) {
- DEBUG(dbgs() << "\tSkipping already emitted common symbol '" << Name
- << "'\n");
- continue;
- }
-
- if (auto Sym = Resolver.findSymbolInLogicalDylib(Name)) {
- if (!Sym.getFlags().isCommon()) {
- DEBUG(dbgs() << "\tSkipping common symbol '" << Name
- << "' in favor of stronger definition.\n");
- continue;
- }
- }
- uint32_t Align = Sym.getAlignment();
- uint64_t Size = Sym.getCommonSize();
-
- CommonSize = alignTo(CommonSize, Align) + Size;
-
- SymbolsToAllocate.push_back(Sym);
- }
-
// Allocate memory for the section
unsigned SectionID = Sections.size();
uint8_t *Addr = MemMgr.allocateDataSection(CommonSize, CommonAlign, SectionID,
@@ -671,8 +664,9 @@ Error RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
SectionEntry("<common symbols>", Addr, CommonSize, CommonSize, 0));
memset(Addr, 0, CommonSize);
- DEBUG(dbgs() << "emitCommonSection SectionID: " << SectionID << " new addr: "
- << format("%p", Addr) << " DataSize: " << CommonSize << "\n");
+ LLVM_DEBUG(dbgs() << "emitCommonSection SectionID: " << SectionID
+ << " new addr: " << format("%p", Addr)
+ << " DataSize: " << CommonSize << "\n");
// Assign the address of each symbol
for (auto &Sym : SymbolsToAllocate) {
@@ -690,8 +684,8 @@ Error RuntimeDyldImpl::emitCommonSymbols(const ObjectFile &Obj,
Offset += AlignOffset;
}
JITSymbolFlags JITSymFlags = getJITSymbolFlags(Sym);
- DEBUG(dbgs() << "Allocating common symbol " << Name << " address "
- << format("%p", Addr) << "\n");
+ LLVM_DEBUG(dbgs() << "Allocating common symbol " << Name << " address "
+ << format("%p", Addr) << "\n");
GlobalSymbolTable[Name] =
SymbolTableEntry(SectionID, Offset, JITSymFlags);
Offset += Size;
@@ -787,21 +781,22 @@ RuntimeDyldImpl::emitSection(const ObjectFile &Obj,
DataSize &= ~(getStubAlignment() - 1);
}
- DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name
- << " obj addr: " << format("%p", pData)
- << " new addr: " << format("%p", Addr)
- << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize
- << " Allocate: " << Allocate << "\n");
+ LLVM_DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: "
+ << Name << " obj addr: " << format("%p", pData)
+ << " new addr: " << format("%p", Addr) << " DataSize: "
+ << DataSize << " StubBufSize: " << StubBufSize
+ << " Allocate: " << Allocate << "\n");
} else {
// Even if we didn't load the section, we need to record an entry for it
// to handle later processing (and by 'handle' I mean don't do anything
// with these sections).
Allocate = 0;
Addr = nullptr;
- DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name
- << " obj addr: " << format("%p", data.data()) << " new addr: 0"
- << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize
- << " Allocate: " << Allocate << "\n");
+ LLVM_DEBUG(
+ dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name
+ << " obj addr: " << format("%p", data.data()) << " new addr: 0"
+ << " DataSize: " << DataSize << " StubBufSize: " << StubBufSize
+ << " Allocate: " << Allocate << "\n");
}
Sections.push_back(
@@ -978,10 +973,11 @@ void RuntimeDyldImpl::reassignSectionAddress(unsigned SectionID,
// Addr is a uint64_t because we can't assume the pointer width
// of the target is the same as that of the host. Just use a generic
// "big enough" type.
- DEBUG(dbgs() << "Reassigning address for section " << SectionID << " ("
- << Sections[SectionID].getName() << "): "
- << format("0x%016" PRIx64, Sections[SectionID].getLoadAddress())
- << " -> " << format("0x%016" PRIx64, Addr) << "\n");
+ LLVM_DEBUG(
+ dbgs() << "Reassigning address for section " << SectionID << " ("
+ << Sections[SectionID].getName() << "): "
+ << format("0x%016" PRIx64, Sections[SectionID].getLoadAddress())
+ << " -> " << format("0x%016" PRIx64, Addr) << "\n");
Sections[SectionID].setLoadAddress(Addr);
}
@@ -997,14 +993,50 @@ void RuntimeDyldImpl::resolveRelocationList(const RelocationList &Relocs,
}
Error RuntimeDyldImpl::resolveExternalSymbols() {
+ StringMap<JITEvaluatedSymbol> ExternalSymbolMap;
+
+ // Resolution can trigger emission of more symbols, so iterate until
+ // we've resolved *everything*.
+ {
+ JITSymbolResolver::LookupSet ResolvedSymbols;
+
+ while (true) {
+ JITSymbolResolver::LookupSet NewSymbols;
+
+ for (auto &RelocKV : ExternalSymbolRelocations) {
+ StringRef Name = RelocKV.first();
+ if (!Name.empty() && !GlobalSymbolTable.count(Name) &&
+ !ResolvedSymbols.count(Name))
+ NewSymbols.insert(Name);
+ }
+
+ if (NewSymbols.empty())
+ break;
+
+ auto NewResolverResults = Resolver.lookup(NewSymbols);
+ if (!NewResolverResults)
+ return NewResolverResults.takeError();
+
+ assert(NewResolverResults->size() == NewSymbols.size() &&
+ "Should have errored on unresolved symbols");
+
+ for (auto &RRKV : *NewResolverResults) {
+ assert(!ResolvedSymbols.count(RRKV.first) && "Redundant resolution?");
+ ExternalSymbolMap.insert(RRKV);
+ ResolvedSymbols.insert(RRKV.first);
+ }
+ }
+ }
+
while (!ExternalSymbolRelocations.empty()) {
+
StringMap<RelocationList>::iterator i = ExternalSymbolRelocations.begin();
StringRef Name = i->first();
if (Name.size() == 0) {
// This is an absolute symbol, use an address of zero.
- DEBUG(dbgs() << "Resolving absolute relocations."
- << "\n");
+ LLVM_DEBUG(dbgs() << "Resolving absolute relocations."
+ << "\n");
RelocationList &Relocs = i->second;
resolveRelocationList(Relocs, 0);
} else {
@@ -1012,29 +1044,10 @@ Error RuntimeDyldImpl::resolveExternalSymbols() {
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()) {
- Addr = *AddrOrErr;
- Flags = Sym.getFlags();
- } else
- return AddrOrErr.takeError();
- } else if (auto Err = Sym.takeError())
- return Err;
-
- // If that fails, try searching for an external symbol.
- if (!Addr) {
- if (auto Sym = Resolver.findSymbol(Name.data())) {
- if (auto AddrOrErr = Sym.getAddress()) {
- Addr = *AddrOrErr;
- Flags = Sym.getFlags();
- } else
- return AddrOrErr.takeError();
- } else if (auto Err = Sym.takeError())
- return Err;
- }
+ auto RRI = ExternalSymbolMap.find(Name);
+ assert(RRI != ExternalSymbolMap.end() && "No result for symbol");
+ Addr = RRI->second.getAddress();
+ Flags = RRI->second.getFlags();
// 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
@@ -1065,8 +1078,8 @@ Error RuntimeDyldImpl::resolveExternalSymbols() {
// if the target symbol is Thumb.
Addr = modifyAddressBasedOnFlags(Addr, Flags);
- DEBUG(dbgs() << "Resolving relocations Name: " << Name << "\t"
- << format("0x%lx", Addr) << "\n");
+ LLVM_DEBUG(dbgs() << "Resolving relocations Name: " << Name << "\t"
+ << format("0x%lx", Addr) << "\n");
// This list may have been updated when we called getSymbolAddress, so
// don't change this code to get the list earlier.
RelocationList &Relocs = i->second;
@@ -1095,6 +1108,7 @@ uint64_t RuntimeDyld::LoadedObjectInfo::getSectionLoadAddress(
void RuntimeDyld::MemoryManager::anchor() {}
void JITSymbolResolver::anchor() {}
+void LegacyJITSymbolResolver::anchor() {}
RuntimeDyld::RuntimeDyld(RuntimeDyld::MemoryManager &MemMgr,
JITSymbolResolver &Resolver)
@@ -1185,6 +1199,12 @@ JITEvaluatedSymbol RuntimeDyld::getSymbol(StringRef Name) const {
return Dyld->getSymbol(Name);
}
+std::map<StringRef, JITEvaluatedSymbol> RuntimeDyld::getSymbolTable() const {
+ if (!Dyld)
+ return std::map<StringRef, JITEvaluatedSymbol>();
+ return Dyld->getSymbolTable();
+}
+
void RuntimeDyld::resolveRelocations() { Dyld->resolveRelocations(); }
void RuntimeDyld::reassignSectionAddress(unsigned SectionID, uint64_t Addr) {
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
index 5bc7434e703f..fa8906869b3a 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
@@ -688,12 +688,13 @@ RuntimeDyldCheckerImpl::RuntimeDyldCheckerImpl(RuntimeDyld &RTDyld,
bool RuntimeDyldCheckerImpl::check(StringRef CheckExpr) const {
CheckExpr = CheckExpr.trim();
- DEBUG(dbgs() << "RuntimeDyldChecker: Checking '" << CheckExpr << "'...\n");
+ LLVM_DEBUG(dbgs() << "RuntimeDyldChecker: Checking '" << CheckExpr
+ << "'...\n");
RuntimeDyldCheckerExprEval P(*this, ErrStream);
bool Result = P.evaluate(CheckExpr);
(void)Result;
- DEBUG(dbgs() << "RuntimeDyldChecker: '" << CheckExpr << "' "
- << (Result ? "passed" : "FAILED") << ".\n");
+ LLVM_DEBUG(dbgs() << "RuntimeDyldChecker: '" << CheckExpr << "' "
+ << (Result ? "passed" : "FAILED") << ".\n");
return Result;
}
@@ -731,7 +732,14 @@ bool RuntimeDyldCheckerImpl::checkAllRulesInBuffer(StringRef RulePrefix,
bool RuntimeDyldCheckerImpl::isSymbolValid(StringRef Symbol) const {
if (getRTDyld().getSymbol(Symbol))
return true;
- return !!getRTDyld().Resolver.findSymbol(Symbol);
+ JITSymbolResolver::LookupSet Symbols({Symbol});
+ auto Result = getRTDyld().Resolver.lookup(Symbols);
+ if (!Result) {
+ logAllUnhandledErrors(Result.takeError(), errs(), "RTDyldChecker: ");
+ return false;
+ }
+ assert(Result->count(Symbol) && "Missing symbol result");
+ return true;
}
uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(StringRef Symbol) const {
@@ -742,7 +750,16 @@ uint64_t RuntimeDyldCheckerImpl::getSymbolLocalAddr(StringRef Symbol) const {
uint64_t RuntimeDyldCheckerImpl::getSymbolRemoteAddr(StringRef Symbol) const {
if (auto InternalSymbol = getRTDyld().getSymbol(Symbol))
return InternalSymbol.getAddress();
- return cantFail(getRTDyld().Resolver.findSymbol(Symbol).getAddress());
+
+ JITSymbolResolver::LookupSet Symbols({Symbol});
+ auto Result = getRTDyld().Resolver.lookup(Symbols);
+ if (!Result) {
+ logAllUnhandledErrors(Result.takeError(), errs(), "RTDyldChecker: ");
+ return 0;
+ }
+ auto I = Result->find(Symbol);
+ assert(I != Result->end() && "Missing symbol result");
+ return I->second.getAddress();
}
uint64_t RuntimeDyldCheckerImpl::readMemoryAtAddr(uint64_t SrcAddr,
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index 2c57eee191db..cc6729d21320 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -65,7 +65,7 @@ template <class ELFT> class DyldELFObject : public ELFObjectFile<ELFT> {
typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr;
- typedef typename ELFDataTypeTypedefHelper<ELFT>::value_type addr_type;
+ typedef typename ELFT::uint addr_type;
DyldELFObject(ELFObjectFile<ELFT> &&Obj);
@@ -148,8 +148,8 @@ template <typename ELFT>
static Expected<std::unique_ptr<DyldELFObject<ELFT>>>
createRTDyldELFObject(MemoryBufferRef Buffer, const ObjectFile &SourceObject,
const LoadedELFObjectInfo &L) {
- typedef typename ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
- typedef typename ELFDataTypeTypedefHelper<ELFT>::value_type addr_type;
+ typedef typename ELFT::Shdr Elf_Shdr;
+ typedef typename ELFT::uint addr_type;
Expected<std::unique_ptr<DyldELFObject<ELFT>>> ObjOrErr =
DyldELFObject<ELFT>::create(Buffer);
@@ -273,8 +273,8 @@ void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section,
case ELF::R_X86_64_64: {
support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) =
Value + Addend;
- DEBUG(dbgs() << "Writing " << format("%p", (Value + Addend)) << " at "
- << format("%p\n", Section.getAddressWithOffset(Offset)));
+ LLVM_DEBUG(dbgs() << "Writing " << format("%p", (Value + Addend)) << " at "
+ << format("%p\n", Section.getAddressWithOffset(Offset)));
break;
}
case ELF::R_X86_64_32:
@@ -286,8 +286,8 @@ void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section,
uint32_t TruncatedAddr = (Value & 0xFFFFFFFF);
support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
TruncatedAddr;
- DEBUG(dbgs() << "Writing " << format("%p", TruncatedAddr) << " at "
- << format("%p\n", Section.getAddressWithOffset(Offset)));
+ LLVM_DEBUG(dbgs() << "Writing " << format("%p", TruncatedAddr) << " at "
+ << format("%p\n", Section.getAddressWithOffset(Offset)));
break;
}
case ELF::R_X86_64_PC8: {
@@ -312,6 +312,22 @@ void RuntimeDyldELF::resolveX86_64Relocation(const SectionEntry &Section,
int64_t RealOffset = Value + Addend - FinalAddress;
support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) =
RealOffset;
+ LLVM_DEBUG(dbgs() << "Writing " << format("%p", RealOffset) << " at "
+ << format("%p\n", FinalAddress));
+ break;
+ }
+ case ELF::R_X86_64_GOTOFF64: {
+ // Compute Value - GOTBase.
+ uint64_t GOTBase = 0;
+ for (const auto &Section : Sections) {
+ if (Section.getName() == ".got") {
+ GOTBase = Section.getLoadAddressWithOffset(0);
+ break;
+ }
+ }
+ assert(GOTBase != 0 && "missing GOT");
+ int64_t GOTOffset = Value - GOTBase + Addend;
+ support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) = GOTOffset;
break;
}
}
@@ -326,6 +342,9 @@ void RuntimeDyldELF::resolveX86Relocation(const SectionEntry &Section,
Value + Addend;
break;
}
+ // Handle R_386_PLT32 like R_386_PC32 since it should be able to
+ // reach any 32 bit address.
+ case ELF::R_386_PLT32:
case ELF::R_386_PC32: {
uint32_t FinalAddress =
Section.getLoadAddressWithOffset(Offset) & 0xFFFFFFFF;
@@ -351,12 +370,12 @@ void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section,
// Data should use target endian. Code should always use little endian.
bool isBE = Arch == Triple::aarch64_be;
- DEBUG(dbgs() << "resolveAArch64Relocation, LocalAddress: 0x"
- << format("%llx", Section.getAddressWithOffset(Offset))
- << " FinalAddress: 0x" << format("%llx", FinalAddress)
- << " Value: 0x" << format("%llx", Value) << " Type: 0x"
- << format("%x", Type) << " Addend: 0x" << format("%llx", Addend)
- << "\n");
+ LLVM_DEBUG(dbgs() << "resolveAArch64Relocation, LocalAddress: 0x"
+ << format("%llx", Section.getAddressWithOffset(Offset))
+ << " FinalAddress: 0x" << format("%llx", FinalAddress)
+ << " Value: 0x" << format("%llx", Value) << " Type: 0x"
+ << format("%x", Type) << " Addend: 0x"
+ << format("%llx", Addend) << "\n");
switch (Type) {
default:
@@ -471,11 +490,12 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section,
uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset) & 0xFFFFFFFF;
Value += Addend;
- DEBUG(dbgs() << "resolveARMRelocation, LocalAddress: "
- << Section.getAddressWithOffset(Offset)
- << " FinalAddress: " << format("%p", FinalAddress) << " Value: "
- << format("%x", Value) << " Type: " << format("%x", Type)
- << " Addend: " << format("%x", Addend) << "\n");
+ LLVM_DEBUG(dbgs() << "resolveARMRelocation, LocalAddress: "
+ << Section.getAddressWithOffset(Offset)
+ << " FinalAddress: " << format("%p", FinalAddress)
+ << " Value: " << format("%x", Value)
+ << " Type: " << format("%x", Type)
+ << " Addend: " << format("%x", Addend) << "\n");
switch (Type) {
default:
@@ -526,10 +546,11 @@ void RuntimeDyldELF::setMipsABI(const ObjectFile &Obj) {
IsMipsN64ABI = false;
return;
}
- unsigned AbiVariant;
- Obj.getPlatformFlags(AbiVariant);
- IsMipsO32ABI = AbiVariant & ELF::EF_MIPS_ABI_O32;
- IsMipsN32ABI = AbiVariant & ELF::EF_MIPS_ABI2;
+ if (auto *E = dyn_cast<ELFObjectFileBase>(&Obj)) {
+ unsigned AbiVariant = E->getPlatformFlags();
+ IsMipsO32ABI = AbiVariant & ELF::EF_MIPS_ABI_O32;
+ IsMipsN32ABI = AbiVariant & ELF::EF_MIPS_ABI2;
+ }
IsMipsN64ABI = Obj.getFileFormatName().equals("ELF64-mips");
}
@@ -718,9 +739,11 @@ void RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section,
writeInt16BE(LocalAddress, applyPPClo(Value + Addend) & ~3);
break;
case ELF::R_PPC64_ADDR16_HI:
+ case ELF::R_PPC64_ADDR16_HIGH:
writeInt16BE(LocalAddress, applyPPChi(Value + Addend));
break;
case ELF::R_PPC64_ADDR16_HA:
+ case ELF::R_PPC64_ADDR16_HIGHA:
writeInt16BE(LocalAddress, applyPPCha(Value + Addend));
break;
case ELF::R_PPC64_ADDR16_HIGHER:
@@ -767,8 +790,9 @@ void RuntimeDyldELF::resolvePPC64Relocation(const SectionEntry &Section,
int64_t delta = static_cast<int64_t>(Value - FinalAddress + Addend);
if (SignExtend64<26>(delta) != delta)
llvm_unreachable("Relocation R_PPC64_REL24 overflow");
- // Generates a 'bl <address>' instruction
- writeInt32BE(LocalAddress, 0x48000001 | (delta & 0x03FFFFFC));
+ // We preserve bits other than LI field, i.e. PO and AA/LK fields.
+ uint32_t Inst = readBytesUnaligned(LocalAddress, 4);
+ writeInt32BE(LocalAddress, (Inst & 0xFC000003) | (delta & 0x03FFFFFC));
} break;
case ELF::R_PPC64_REL32: {
uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
@@ -855,16 +879,16 @@ void RuntimeDyldELF::resolveBPFRelocation(const SectionEntry &Section,
break;
case ELF::R_BPF_64_64: {
write(isBE, Section.getAddressWithOffset(Offset), Value + Addend);
- DEBUG(dbgs() << "Writing " << format("%p", (Value + Addend)) << " at "
- << format("%p\n", Section.getAddressWithOffset(Offset)));
+ LLVM_DEBUG(dbgs() << "Writing " << format("%p", (Value + Addend)) << " at "
+ << format("%p\n", Section.getAddressWithOffset(Offset)));
break;
}
case ELF::R_BPF_64_32: {
Value += Addend;
assert(Value <= UINT32_MAX);
write(isBE, Section.getAddressWithOffset(Offset), static_cast<uint32_t>(Value));
- DEBUG(dbgs() << "Writing " << format("%p", Value) << " at "
- << format("%p\n", Section.getAddressWithOffset(Offset)));
+ LLVM_DEBUG(dbgs() << "Writing " << format("%p", Value) << " at "
+ << format("%p\n", Section.getAddressWithOffset(Offset)));
break;
}
}
@@ -1021,7 +1045,7 @@ void RuntimeDyldELF::resolveAArch64Branch(unsigned SectionID,
relocation_iterator RelI,
StubMap &Stubs) {
- DEBUG(dbgs() << "\t\tThis is an AArch64 branch relocation.");
+ LLVM_DEBUG(dbgs() << "\t\tThis is an AArch64 branch relocation.");
SectionEntry &Section = Sections[SectionID];
uint64_t Offset = RelI->getOffset();
@@ -1032,10 +1056,10 @@ void RuntimeDyldELF::resolveAArch64Branch(unsigned SectionID,
resolveRelocation(Section, Offset,
(uint64_t)Section.getAddressWithOffset(i->second),
RelType, 0);
- DEBUG(dbgs() << " Stub function found\n");
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
} else if (!resolveAArch64ShortBranch(SectionID, RelI, Value)) {
// Create a new stub function.
- DEBUG(dbgs() << " Create a new stub function\n");
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
Stubs[Value] = Section.getStubOffset();
uint8_t *StubTargetAddr = createStubFunction(
Section.getAddressWithOffset(Section.getStubOffset()));
@@ -1092,8 +1116,8 @@ RuntimeDyldELF::processRelocationRef(
else
return TargetNameOrErr.takeError();
}
- DEBUG(dbgs() << "\t\tRelType: " << RelType << " Addend: " << Addend
- << " TargetName: " << TargetName << "\n");
+ LLVM_DEBUG(dbgs() << "\t\tRelType: " << RelType << " Addend: " << Addend
+ << " TargetName: " << TargetName << "\n");
RelocationValueRef Value;
// First search for the symbol in the local symbol table
SymbolRef::Type SymType = SymbolRef::ST_Unknown;
@@ -1134,7 +1158,7 @@ RuntimeDyldELF::processRelocationRef(
section_iterator si = *SectionOrErr;
if (si == Obj.section_end())
llvm_unreachable("Symbol section not found, bad object file format!");
- DEBUG(dbgs() << "\t\tThis is section symbol\n");
+ LLVM_DEBUG(dbgs() << "\t\tThis is section symbol\n");
bool isCode = si->isText();
if (auto SectionIDOrErr = findOrEmitSection(Obj, (*si), isCode,
ObjSectionToID))
@@ -1166,8 +1190,8 @@ RuntimeDyldELF::processRelocationRef(
uint64_t Offset = RelI->getOffset();
- DEBUG(dbgs() << "\t\tSectionID: " << SectionID << " Offset: " << Offset
- << "\n");
+ LLVM_DEBUG(dbgs() << "\t\tSectionID: " << SectionID << " Offset: " << Offset
+ << "\n");
if ((Arch == Triple::aarch64 || Arch == Triple::aarch64_be)) {
if (RelType == ELF::R_AARCH64_CALL26 || RelType == ELF::R_AARCH64_JUMP26) {
resolveAArch64Branch(SectionID, Value, RelI, Stubs);
@@ -1189,7 +1213,7 @@ RuntimeDyldELF::processRelocationRef(
if (RelType == ELF::R_ARM_PC24 || RelType == ELF::R_ARM_CALL ||
RelType == ELF::R_ARM_JUMP24) {
// This is an ARM branch relocation, need to use a stub function.
- DEBUG(dbgs() << "\t\tThis is an ARM branch relocation.\n");
+ LLVM_DEBUG(dbgs() << "\t\tThis is an ARM branch relocation.\n");
SectionEntry &Section = Sections[SectionID];
// Look for an existing stub.
@@ -1199,10 +1223,10 @@ RuntimeDyldELF::processRelocationRef(
Section, Offset,
reinterpret_cast<uint64_t>(Section.getAddressWithOffset(i->second)),
RelType, 0);
- DEBUG(dbgs() << " Stub function found\n");
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
} else {
// Create a new stub function.
- DEBUG(dbgs() << " Create a new stub function\n");
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
Stubs[Value] = Section.getStubOffset();
uint8_t *StubTargetAddr = createStubFunction(
Section.getAddressWithOffset(Section.getStubOffset()));
@@ -1237,7 +1261,7 @@ RuntimeDyldELF::processRelocationRef(
uint32_t Opcode = readBytesUnaligned(Placeholder, 4);
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.");
+ LLVM_DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
SectionEntry &Section = Sections[SectionID];
// Extract the addend from the instruction.
@@ -1252,14 +1276,13 @@ RuntimeDyldELF::processRelocationRef(
if (i != Stubs.end()) {
RelocationEntry RE(SectionID, Offset, RelType, i->second);
addRelocationForSection(RE, SectionID);
- DEBUG(dbgs() << " Stub function found\n");
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
} else {
// Create a new stub function.
- DEBUG(dbgs() << " Create a new stub function\n");
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
Stubs[Value] = Section.getStubOffset();
- unsigned AbiVariant;
- O.getPlatformFlags(AbiVariant);
+ unsigned AbiVariant = Obj.getPlatformFlags();
uint8_t *StubTargetAddr = createStubFunction(
Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);
@@ -1340,7 +1363,7 @@ RuntimeDyldELF::processRelocationRef(
addRelocationForSection(RE, Value.SectionID);
} else 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.");
+ LLVM_DEBUG(dbgs() << "\t\tThis is a Mips branch relocation.");
SectionEntry &Section = Sections[SectionID];
// Look up for existing stub.
@@ -1348,14 +1371,13 @@ RuntimeDyldELF::processRelocationRef(
if (i != Stubs.end()) {
RelocationEntry RE(SectionID, Offset, RelType, i->second);
addRelocationForSection(RE, SectionID);
- DEBUG(dbgs() << " Stub function found\n");
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
} else {
// Create a new stub function.
- DEBUG(dbgs() << " Create a new stub function\n");
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
Stubs[Value] = Section.getStubOffset();
- unsigned AbiVariant;
- O.getPlatformFlags(AbiVariant);
+ unsigned AbiVariant = Obj.getPlatformFlags();
uint8_t *StubTargetAddr = createStubFunction(
Section.getAddressWithOffset(Section.getStubOffset()), AbiVariant);
@@ -1412,8 +1434,7 @@ RuntimeDyldELF::processRelocationRef(
} else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) {
if (RelType == ELF::R_PPC64_REL24) {
// Determine ABI variant in use for this object.
- unsigned AbiVariant;
- Obj.getPlatformFlags(AbiVariant);
+ unsigned AbiVariant = Obj.getPlatformFlags();
AbiVariant &= ELF::EF_PPC64_ABI;
// A PPC branch relocation will need a stub function if the target is
// an external symbol (either Value.SymbolName is set, or SymType is
@@ -1461,10 +1482,10 @@ RuntimeDyldELF::processRelocationRef(
reinterpret_cast<uint64_t>(
Section.getAddressWithOffset(i->second)),
RelType, 0);
- DEBUG(dbgs() << " Stub function found\n");
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
} else {
// Create a new stub function.
- DEBUG(dbgs() << " Create a new stub function\n");
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
Stubs[Value] = Section.getStubOffset();
uint8_t *StubTargetAddr = createStubFunction(
Section.getAddressWithOffset(Section.getStubOffset()),
@@ -1581,7 +1602,7 @@ RuntimeDyldELF::processRelocationRef(
// parts of the stub separately. However, as things stand, we allocate
// a stub for every relocation, so using a GOT in JIT code should be
// no less space efficient than using an explicit constant pool.
- DEBUG(dbgs() << "\t\tThis is a SystemZ indirect relocation.");
+ LLVM_DEBUG(dbgs() << "\t\tThis is a SystemZ indirect relocation.");
SectionEntry &Section = Sections[SectionID];
// Look for an existing stub.
@@ -1589,10 +1610,10 @@ RuntimeDyldELF::processRelocationRef(
uintptr_t StubAddress;
if (i != Stubs.end()) {
StubAddress = uintptr_t(Section.getAddressWithOffset(i->second));
- DEBUG(dbgs() << " Stub function found\n");
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
} else {
// Create a new stub function.
- DEBUG(dbgs() << " Create a new stub function\n");
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
uintptr_t BaseAddress = uintptr_t(Section.getAddress());
uintptr_t StubAlignment = getStubAlignment();
@@ -1643,10 +1664,10 @@ RuntimeDyldELF::processRelocationRef(
uintptr_t StubAddress;
if (i != Stubs.end()) {
StubAddress = uintptr_t(Section.getAddress()) + i->second;
- DEBUG(dbgs() << " Stub function found\n");
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
} else {
// Create a new stub function (equivalent to a PLT entry).
- DEBUG(dbgs() << " Create a new stub function\n");
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
uintptr_t BaseAddress = uintptr_t(Section.getAddress());
uintptr_t StubAlignment = getStubAlignment();
@@ -1695,6 +1716,29 @@ RuntimeDyldELF::processRelocationRef(
addRelocationForSymbol(RE, Value.SymbolName);
else
addRelocationForSection(RE, Value.SectionID);
+ } else if (RelType == ELF::R_X86_64_GOT64) {
+ // Fill in a 64-bit GOT offset.
+ uint64_t GOTOffset = allocateGOTEntries(1);
+ resolveRelocation(Sections[SectionID], Offset, GOTOffset,
+ ELF::R_X86_64_64, 0);
+
+ // Fill in the value of the symbol we're targeting into the GOT
+ RelocationEntry RE =
+ computeGOTOffsetRE(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_GOTPC64) {
+ // Materialize the address of the base of the GOT relative to the PC.
+ // This doesn't create a GOT entry, but it does mean we need a GOT
+ // section.
+ (void)allocateGOTEntries(0);
+ resolveGOTOffsetRelocation(SectionID, Offset, Addend, ELF::R_X86_64_PC64);
+ } else if (RelType == ELF::R_X86_64_GOTOFF64) {
+ // GOTOFF relocations ultimately require a section difference relocation.
+ (void)allocateGOTEntries(0);
+ processSimpleRelocation(SectionID, Offset, RelType, Value);
} else if (RelType == ELF::R_X86_64_PC32) {
Value.Addend += support::ulittle32_t::ref(computePlaceholderAddress(SectionID, Offset));
processSimpleRelocation(SectionID, Offset, RelType, Value);
@@ -1866,6 +1910,7 @@ bool RuntimeDyldELF::relocationNeedsGot(const RelocationRef &R) const {
if (Arch == Triple::x86_64)
return RelTy == ELF::R_X86_64_GOTPCREL ||
RelTy == ELF::R_X86_64_GOTPCRELX ||
+ RelTy == ELF::R_X86_64_GOT64 ||
RelTy == ELF::R_X86_64_REX_GOTPCRELX;
return false;
}
@@ -1882,6 +1927,9 @@ bool RuntimeDyldELF::relocationNeedsStub(const RelocationRef &R) const {
case ELF::R_X86_64_GOTPCREL:
case ELF::R_X86_64_GOTPCRELX:
case ELF::R_X86_64_REX_GOTPCRELX:
+ case ELF::R_X86_64_GOTPC64:
+ case ELF::R_X86_64_GOT64:
+ case ELF::R_X86_64_GOTOFF64:
case ELF::R_X86_64_PC32:
case ELF::R_X86_64_PC64:
case ELF::R_X86_64_64:
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
index e046a8504e9f..4d7cc36d0666 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
@@ -87,7 +87,7 @@ public:
uint8_t *getAddress() const { return Address; }
- /// \brief Return the address of this section with an offset.
+ /// Return the address of this section with an offset.
uint8_t *getAddressWithOffset(unsigned OffsetBytes) const {
assert(OffsetBytes <= AllocationSize && "Offset out of bounds!");
return Address + OffsetBytes;
@@ -98,7 +98,7 @@ public:
uint64_t getLoadAddress() const { return LoadAddress; }
void setLoadAddress(uint64_t LA) { LoadAddress = LA; }
- /// \brief Return the load address of this section with an offset.
+ /// Return the load address of this section with an offset.
uint64_t getLoadAddressWithOffset(unsigned OffsetBytes) const {
assert(OffsetBytes <= AllocationSize && "Offset out of bounds!");
return LoadAddress + OffsetBytes;
@@ -217,7 +217,7 @@ public:
}
};
-/// @brief Symbol info for RuntimeDyld.
+/// Symbol info for RuntimeDyld.
class SymbolTableEntry {
public:
SymbolTableEntry() = default;
@@ -381,13 +381,14 @@ protected:
return Addr;
}
- /// \brief Given the common symbols discovered in the object file, emit a
+ /// 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.
Error emitCommonSymbols(const ObjectFile &Obj,
- CommonSymbolList &CommonSymbols);
+ CommonSymbolList &CommonSymbols, uint64_t CommonSize,
+ uint32_t CommonAlign);
- /// \brief Emits section data from the object file to the MemoryManager.
+ /// Emits section data from the object file to the MemoryManager.
/// \param IsCode if it's true then allocateCodeSection() will be
/// used for emits, else allocateDataSection() will be used.
/// \return SectionID.
@@ -395,7 +396,7 @@ protected:
const SectionRef &Section,
bool IsCode);
- /// \brief Find Section in LocalSections. If the secton is not found - emit
+ /// Find Section in LocalSections. If the secton is not found - emit
/// it and store in LocalSections.
/// \param IsCode if it's true then allocateCodeSection() will be
/// used for emmits, else allocateDataSection() will be used.
@@ -404,26 +405,26 @@ protected:
const SectionRef &Section, bool IsCode,
ObjSectionToIDMap &LocalSections);
- // \brief Add a relocation entry that uses the given section.
+ // Add a relocation entry that uses the given section.
void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID);
- // \brief Add a relocation entry that uses the given symbol. This symbol may
+ // Add a relocation entry that uses the given symbol. This symbol may
// be found in the global symbol table, or it may be external.
void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName);
- /// \brief Emits long jump instruction to Addr.
+ /// Emits long jump instruction to Addr.
/// \return Pointer to the memory area for emitting target address.
uint8_t *createStubFunction(uint8_t *Addr, unsigned AbiVariant = 0);
- /// \brief Resolves relocations from Relocs list with address from Value.
+ /// Resolves relocations from Relocs list with address from Value.
void resolveRelocationList(const RelocationList &Relocs, uint64_t Value);
- /// \brief A object file specific relocation resolver
+ /// A object file specific relocation resolver
/// \param RE The relocation to be resolved
/// \param Value Target symbol address to apply the relocation action
virtual void resolveRelocation(const RelocationEntry &RE, uint64_t Value) = 0;
- /// \brief Parses one or more object file relocations (some object files use
+ /// Parses one or more object file relocations (some object files use
/// relocation pairs) and stores it to Relocations or SymbolRelocations
/// (this depends on the object file type).
/// \return Iterator to the next relocation that needs to be parsed.
@@ -432,35 +433,35 @@ protected:
const ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID,
StubMap &Stubs) = 0;
- /// \brief Resolve relocations to external symbols.
+ /// Resolve relocations to external symbols.
Error resolveExternalSymbols();
- // \brief Compute an upper bound of the memory that is required to load all
+ // Compute an upper bound of the memory that is required to load all
// sections
Error computeTotalAllocSize(const ObjectFile &Obj,
uint64_t &CodeSize, uint32_t &CodeAlign,
uint64_t &RODataSize, uint32_t &RODataAlign,
uint64_t &RWDataSize, uint32_t &RWDataAlign);
- // \brief Compute GOT size
+ // Compute GOT size
unsigned computeGOTSize(const ObjectFile &Obj);
- // \brief Compute the stub buffer size required for a section
+ // Compute the stub buffer size required for a section
unsigned computeSectionStubBufSize(const ObjectFile &Obj,
const SectionRef &Section);
- // \brief Implementation of the generic part of the loadObject algorithm.
+ // Implementation of the generic part of the loadObject algorithm.
Expected<ObjSectionToIDMap> loadObjectImpl(const object::ObjectFile &Obj);
- // \brief Return size of Global Offset Table (GOT) entry
+ // Return size of Global Offset Table (GOT) entry
virtual size_t getGOTEntrySize() { return 0; }
- // \brief Return true if the relocation R may require allocating a GOT entry.
+ // Return true if the relocation R may require allocating a GOT entry.
virtual bool relocationNeedsGot(const RelocationRef &R) const {
return false;
}
- // \brief Return true if the relocation R may require allocating a stub.
+ // Return true if the relocation R may require allocating a stub.
virtual bool relocationNeedsStub(const RelocationRef &R) const {
return true; // Conservative answer
}
@@ -518,6 +519,21 @@ public:
return JITEvaluatedSymbol(TargetAddr, SymEntry.getFlags());
}
+ std::map<StringRef, JITEvaluatedSymbol> getSymbolTable() const {
+ std::map<StringRef, JITEvaluatedSymbol> Result;
+
+ for (auto &KV : GlobalSymbolTable) {
+ auto SectionID = KV.second.getSectionID();
+ uint64_t SectionAddr = 0;
+ if (SectionID != AbsoluteSymbolSection)
+ SectionAddr = getSectionLoadAddress(SectionID);
+ Result[KV.first()] =
+ JITEvaluatedSymbol(SectionAddr + KV.second.getOffset(), KV.second.getFlags());
+ }
+
+ return Result;
+ }
+
void resolveRelocations();
void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
index b0561f68edb3..c5a215c83331 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp
@@ -196,10 +196,10 @@ Error RuntimeDyldMachO::populateIndirectSymbolPointersSection(
assert((PTSectionSize % PTEntrySize) == 0 &&
"Pointers section does not contain a whole number of stubs?");
- DEBUG(dbgs() << "Populating pointer table section "
- << Sections[PTSectionID].getName() << ", Section ID "
- << PTSectionID << ", " << NumPTEntries << " entries, "
- << PTEntrySize << " bytes each:\n");
+ LLVM_DEBUG(dbgs() << "Populating pointer table section "
+ << Sections[PTSectionID].getName() << ", Section ID "
+ << PTSectionID << ", " << NumPTEntries << " entries, "
+ << PTEntrySize << " bytes each:\n");
for (unsigned i = 0; i < NumPTEntries; ++i) {
unsigned SymbolIndex =
@@ -210,8 +210,8 @@ Error RuntimeDyldMachO::populateIndirectSymbolPointersSection(
IndirectSymbolName = *IndirectSymbolNameOrErr;
else
return IndirectSymbolNameOrErr.takeError();
- DEBUG(dbgs() << " " << IndirectSymbolName << ": index " << SymbolIndex
- << ", PT offset: " << PTEntryOffset << "\n");
+ LLVM_DEBUG(dbgs() << " " << IndirectSymbolName << ": index " << SymbolIndex
+ << ", PT offset: " << PTEntryOffset << "\n");
RelocationEntry RE(PTSectionID, PTEntryOffset,
MachO::GENERIC_RELOC_VANILLA, 0, false, 2);
addRelocationForSymbol(RE, IndirectSymbolName);
@@ -275,8 +275,8 @@ unsigned char *RuntimeDyldMachOCRTPBase<Impl>::processFDE(uint8_t *P,
int64_t DeltaForEH) {
typedef typename Impl::TargetPtrT TargetPtrT;
- DEBUG(dbgs() << "Processing FDE: Delta for text: " << DeltaForText
- << ", Delta for EH: " << DeltaForEH << "\n");
+ LLVM_DEBUG(dbgs() << "Processing FDE: Delta for text: " << DeltaForText
+ << ", Delta for EH: " << DeltaForEH << "\n");
uint32_t Length = readBytesUnaligned(P, 4);
P += 4;
uint8_t *Ret = P + Length;
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h
index 04678f224466..dd65051edad7 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFI386.h
@@ -80,9 +80,9 @@ public:
SmallString<32> RelTypeName;
RelI->getTypeName(RelTypeName);
#endif
- DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset
- << " RelType: " << RelTypeName << " TargetName: " << TargetName
- << " Addend " << Addend << "\n");
+ LLVM_DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset
+ << " RelType: " << RelTypeName << " TargetName: "
+ << TargetName << " Addend " << Addend << "\n");
unsigned TargetSectionID = -1;
if (Section == Obj.section_end()) {
@@ -145,10 +145,11 @@ public:
: Sections[RE.Sections.SectionA].getLoadAddressWithOffset(
RE.Addend);
assert(Result <= UINT32_MAX && "relocation overflow");
- DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
- << " RelType: IMAGE_REL_I386_DIR32"
- << " TargetSection: " << RE.Sections.SectionA
- << " Value: " << format("0x%08" PRIx32, Result) << '\n');
+ LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
+ << " RelType: IMAGE_REL_I386_DIR32"
+ << " TargetSection: " << RE.Sections.SectionA
+ << " Value: " << format("0x%08" PRIx32, Result)
+ << '\n');
writeBytesUnaligned(Result, Target, 4);
break;
}
@@ -159,10 +160,11 @@ public:
Sections[RE.Sections.SectionA].getLoadAddressWithOffset(RE.Addend) -
Sections[0].getLoadAddress();
assert(Result <= UINT32_MAX && "relocation overflow");
- DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
- << " RelType: IMAGE_REL_I386_DIR32NB"
- << " TargetSection: " << RE.Sections.SectionA
- << " Value: " << format("0x%08" PRIx32, Result) << '\n');
+ LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
+ << " RelType: IMAGE_REL_I386_DIR32NB"
+ << " TargetSection: " << RE.Sections.SectionA
+ << " Value: " << format("0x%08" PRIx32, Result)
+ << '\n');
writeBytesUnaligned(Result, Target, 4);
break;
}
@@ -176,10 +178,11 @@ public:
"relocation overflow");
assert(static_cast<int64_t>(Result) >= INT32_MIN &&
"relocation underflow");
- DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
- << " RelType: IMAGE_REL_I386_REL32"
- << " TargetSection: " << RE.Sections.SectionA
- << " Value: " << format("0x%08" PRIx32, Result) << '\n');
+ LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
+ << " RelType: IMAGE_REL_I386_REL32"
+ << " TargetSection: " << RE.Sections.SectionA
+ << " Value: " << format("0x%08" PRIx32, Result)
+ << '\n');
writeBytesUnaligned(Result, Target, 4);
break;
}
@@ -187,18 +190,18 @@ public:
// 16-bit section index of the section that contains the target.
assert(static_cast<uint32_t>(RE.SectionID) <= UINT16_MAX &&
"relocation overflow");
- DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
- << " RelType: IMAGE_REL_I386_SECTION Value: " << RE.SectionID
- << '\n');
+ LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
+ << " RelType: IMAGE_REL_I386_SECTION Value: "
+ << RE.SectionID << '\n');
writeBytesUnaligned(RE.SectionID, Target, 2);
break;
case COFF::IMAGE_REL_I386_SECREL:
// 32-bit offset of the target from the beginning of its section.
assert(static_cast<uint64_t>(RE.Addend) <= UINT32_MAX &&
"relocation overflow");
- DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
- << " RelType: IMAGE_REL_I386_SECREL Value: " << RE.Addend
- << '\n');
+ LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
+ << " RelType: IMAGE_REL_I386_SECREL Value: "
+ << RE.Addend << '\n');
writeBytesUnaligned(RE.Addend, Target, 4);
break;
default:
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h
index 9000435764df..729ea1ec48a4 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFThumb.h
@@ -97,9 +97,9 @@ public:
SmallString<32> RelTypeName;
RelI->getTypeName(RelTypeName);
#endif
- DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset
- << " RelType: " << RelTypeName << " TargetName: " << TargetName
- << " Addend " << Addend << "\n");
+ LLVM_DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset
+ << " RelType: " << RelTypeName << " TargetName: "
+ << TargetName << " Addend " << Addend << "\n");
unsigned TargetSectionID = -1;
if (Section == Obj.section_end()) {
@@ -187,10 +187,11 @@ public:
: Sections[RE.Sections.SectionA].getLoadAddressWithOffset(RE.Addend);
Result |= ISASelectionBit;
assert(Result <= UINT32_MAX && "relocation overflow");
- DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
- << " RelType: IMAGE_REL_ARM_ADDR32"
- << " TargetSection: " << RE.Sections.SectionA
- << " Value: " << format("0x%08" PRIx32, Result) << '\n');
+ LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
+ << " RelType: IMAGE_REL_ARM_ADDR32"
+ << " TargetSection: " << RE.Sections.SectionA
+ << " Value: " << format("0x%08" PRIx32, Result)
+ << '\n');
writeBytesUnaligned(Result, Target, 4);
break;
}
@@ -200,10 +201,11 @@ public:
uint64_t Result = Sections[RE.Sections.SectionA].getLoadAddress() -
Sections[0].getLoadAddress() + RE.Addend;
assert(Result <= UINT32_MAX && "relocation overflow");
- DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
- << " RelType: IMAGE_REL_ARM_ADDR32NB"
- << " TargetSection: " << RE.Sections.SectionA
- << " Value: " << format("0x%08" PRIx32, Result) << '\n');
+ LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
+ << " RelType: IMAGE_REL_ARM_ADDR32NB"
+ << " TargetSection: " << RE.Sections.SectionA
+ << " Value: " << format("0x%08" PRIx32, Result)
+ << '\n');
Result |= ISASelectionBit;
writeBytesUnaligned(Result, Target, 4);
break;
@@ -212,18 +214,18 @@ public:
// 16-bit section index of the section that contains the target.
assert(static_cast<uint32_t>(RE.SectionID) <= UINT16_MAX &&
"relocation overflow");
- DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
- << " RelType: IMAGE_REL_ARM_SECTION Value: " << RE.SectionID
- << '\n');
+ LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
+ << " RelType: IMAGE_REL_ARM_SECTION Value: "
+ << RE.SectionID << '\n');
writeBytesUnaligned(RE.SectionID, Target, 2);
break;
case COFF::IMAGE_REL_ARM_SECREL:
// 32-bit offset of the target from the beginning of its section.
assert(static_cast<uint64_t>(RE.Addend) <= UINT32_MAX &&
"relocation overflow");
- DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
- << " RelType: IMAGE_REL_ARM_SECREL Value: " << RE.Addend
- << '\n');
+ LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
+ << " RelType: IMAGE_REL_ARM_SECREL Value: " << RE.Addend
+ << '\n');
writeBytesUnaligned(RE.Addend, Target, 2);
break;
case COFF::IMAGE_REL_ARM_MOV32T: {
@@ -231,10 +233,11 @@ public:
uint64_t Result =
Sections[RE.Sections.SectionA].getLoadAddressWithOffset(RE.Addend);
assert(Result <= UINT32_MAX && "relocation overflow");
- DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
- << " RelType: IMAGE_REL_ARM_MOV32T"
- << " TargetSection: " << RE.Sections.SectionA
- << " Value: " << format("0x%08" PRIx32, Result) << '\n');
+ LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
+ << " RelType: IMAGE_REL_ARM_MOV32T"
+ << " TargetSection: " << RE.Sections.SectionA
+ << " Value: " << format("0x%08" PRIx32, Result)
+ << '\n');
// MOVW(T3): |11110|i|10|0|1|0|0|imm4|0|imm3|Rd|imm8|
// imm32 = zext imm4:i:imm3:imm8
@@ -262,9 +265,9 @@ public:
"relocation overflow");
assert(static_cast<int64_t>(RE.Addend) >= INT32_MIN &&
"relocation underflow");
- DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
- << " RelType: IMAGE_REL_ARM_BRANCH20T"
- << " Value: " << static_cast<int32_t>(Value) << '\n');
+ LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
+ << " RelType: IMAGE_REL_ARM_BRANCH20T"
+ << " Value: " << static_cast<int32_t>(Value) << '\n');
static_cast<void>(Value);
llvm_unreachable("unimplemented relocation");
break;
@@ -277,9 +280,9 @@ public:
"relocation overflow");
assert(static_cast<int64_t>(RE.Addend) >= INT32_MIN &&
"relocation underflow");
- DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
- << " RelType: IMAGE_REL_ARM_BRANCH24T"
- << " Value: " << static_cast<int32_t>(Value) << '\n');
+ LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
+ << " RelType: IMAGE_REL_ARM_BRANCH24T"
+ << " Value: " << static_cast<int32_t>(Value) << '\n');
static_cast<void>(Value);
llvm_unreachable("unimplemented relocation");
break;
@@ -292,9 +295,9 @@ public:
"relocation overflow");
assert(static_cast<int64_t>(RE.Addend) >= INT32_MIN &&
"relocation underflow");
- DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
- << " RelType: IMAGE_REL_ARM_BLX23T"
- << " Value: " << static_cast<int32_t>(Value) << '\n');
+ LLVM_DEBUG(dbgs() << "\t\tOffset: " << RE.Offset
+ << " RelType: IMAGE_REL_ARM_BLX23T"
+ << " Value: " << static_cast<int32_t>(Value) << '\n');
static_cast<void>(Value);
llvm_unreachable("unimplemented relocation");
break;
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h
index 7cbb43854151..2d6e5c4aea67 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldCOFFX86_64.h
@@ -30,15 +30,33 @@ private:
// unregisteredEH frame sections with the memory manager.
SmallVector<SID, 2> UnregisteredEHFrameSections;
SmallVector<SID, 2> RegisteredEHFrameSections;
+ uint64_t ImageBase;
+
+ // Fake an __ImageBase pointer by returning the section with the lowest adress
+ uint64_t getImageBase() {
+ if (!ImageBase) {
+ ImageBase = std::numeric_limits<uint64_t>::max();
+ for (const SectionEntry &Section : Sections)
+ ImageBase = std::min(ImageBase, Section.getLoadAddress());
+ }
+ return ImageBase;
+ }
+
+ void write32BitOffset(uint8_t *Target, int64_t Addend, uint64_t Delta) {
+ uint64_t Result = Addend + Delta;
+ assert(Result <= UINT32_MAX && "Relocation overflow");
+ writeBytesUnaligned(Result, Target, 4);
+ }
public:
RuntimeDyldCOFFX86_64(RuntimeDyld::MemoryManager &MM,
JITSymbolResolver &Resolver)
- : RuntimeDyldCOFF(MM, Resolver) {}
+ : RuntimeDyldCOFF(MM, Resolver), ImageBase(0) {}
- unsigned getMaxStubSize() override {
- return 6; // 2-byte jmp instruction + 32-bit relative address
- }
+ unsigned getStubAlignment() override { return 1; }
+
+ // 2-byte jmp instruction + 32-bit relative address + 64-bit absolute jump
+ unsigned getMaxStubSize() override { return 14; }
// The target location for the relocation is described by RE.SectionID and
// RE.Offset. RE.SectionID can be used to find the SectionEntry. Each
@@ -85,13 +103,17 @@ public:
}
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.
- writeBytesUnaligned(0, Target, 4);
+ // ADDR32NB requires an offset less than 2GB from 'ImageBase'.
+ // The MemoryManager can make sure this is always true by forcing the
+ // memory layout to be: CodeSection < ReadOnlySection < ReadWriteSection.
+ const uint64_t ImageBase = getImageBase();
+ if (Value < ImageBase || ((Value - ImageBase) > UINT32_MAX)) {
+ llvm::errs() << "IMAGE_REL_AMD64_ADDR32NB relocation requires an"
+ << "ordered section layout.\n";
+ write32BitOffset(Target, 0, 0);
+ } else {
+ write32BitOffset(Target, RE.Addend, Value - ImageBase);
+ }
break;
}
@@ -106,6 +128,52 @@ public:
}
}
+ std::tuple<uint64_t, uint64_t, uint64_t>
+ generateRelocationStub(unsigned SectionID, StringRef TargetName,
+ uint64_t Offset, uint64_t RelType, uint64_t Addend,
+ StubMap &Stubs) {
+ uintptr_t StubOffset;
+ SectionEntry &Section = Sections[SectionID];
+
+ RelocationValueRef OriginalRelValueRef;
+ OriginalRelValueRef.SectionID = SectionID;
+ OriginalRelValueRef.Offset = Offset;
+ OriginalRelValueRef.Addend = Addend;
+ OriginalRelValueRef.SymbolName = TargetName.data();
+
+ auto Stub = Stubs.find(OriginalRelValueRef);
+ if (Stub == Stubs.end()) {
+ LLVM_DEBUG(dbgs() << " Create a new stub function for "
+ << TargetName.data() << "\n");
+
+ StubOffset = Section.getStubOffset();
+ Stubs[OriginalRelValueRef] = StubOffset;
+ createStubFunction(Section.getAddressWithOffset(StubOffset));
+ Section.advanceStubOffset(getMaxStubSize());
+ } else {
+ LLVM_DEBUG(dbgs() << " Stub function found for " << TargetName.data()
+ << "\n");
+ StubOffset = Stub->second;
+ }
+
+ // FIXME: If RelType == COFF::IMAGE_REL_AMD64_ADDR32NB we should be able
+ // to ignore the __ImageBase requirement and just forward to the stub
+ // directly as an offset of this section:
+ // write32BitOffset(Section.getAddressWithOffset(Offset), 0, StubOffset);
+ // .xdata exception handler's aren't having this though.
+
+ // Resolve original relocation to stub function.
+ const RelocationEntry RE(SectionID, Offset, RelType, Addend);
+ resolveRelocation(RE, Section.getLoadAddressWithOffset(StubOffset));
+
+ // adjust relocation info so resolution writes to the stub function
+ Addend = 0;
+ Offset = StubOffset + 6;
+ RelType = COFF::IMAGE_REL_AMD64_ADDR64;
+
+ return std::make_tuple(Offset, RelType, Addend);
+ }
+
Expected<relocation_iterator>
processRelocationRef(unsigned SectionID,
relocation_iterator RelI,
@@ -131,6 +199,11 @@ public:
SectionEntry &Section = Sections[SectionID];
uintptr_t ObjTarget = Section.getObjAddress() + Offset;
+ Expected<StringRef> TargetNameOrErr = Symbol->getName();
+ if (!TargetNameOrErr)
+ return TargetNameOrErr.takeError();
+ StringRef TargetName = *TargetNameOrErr;
+
switch (RelType) {
case COFF::IMAGE_REL_AMD64_REL32:
@@ -142,6 +215,11 @@ public:
case COFF::IMAGE_REL_AMD64_ADDR32NB: {
uint8_t *Displacement = (uint8_t *)ObjTarget;
Addend = readBytesUnaligned(Displacement, 4);
+
+ if (IsExtern)
+ std::tie(Offset, RelType, Addend) = generateRelocationStub(
+ SectionID, TargetName, Offset, RelType, Addend, Stubs);
+
break;
}
@@ -155,14 +233,9 @@ public:
break;
}
- Expected<StringRef> TargetNameOrErr = Symbol->getName();
- if (!TargetNameOrErr)
- return TargetNameOrErr.takeError();
- StringRef TargetName = *TargetNameOrErr;
-
- DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset
- << " RelType: " << RelType << " TargetName: " << TargetName
- << " Addend " << Addend << "\n");
+ LLVM_DEBUG(dbgs() << "\t\tIn Section " << SectionID << " Offset " << Offset
+ << " RelType: " << RelType << " TargetName: "
+ << TargetName << " Addend " << Addend << "\n");
if (IsExtern) {
RelocationEntry RE(SectionID, Offset, RelType, Addend);
@@ -183,7 +256,6 @@ public:
return ++RelI;
}
- unsigned getStubAlignment() override { return 1; }
void registerEHFrames() override {
for (auto const &EHFrameSID : UnregisteredEHFrameSections) {
uint8_t *EHFrameAddr = Sections[EHFrameSID].getAddress();
@@ -194,6 +266,7 @@ public:
}
UnregisteredEHFrameSections.clear();
}
+
Error finalizeLoad(const ObjectFile &Obj,
ObjSectionToIDMap &SectionMap) override {
// Look for and record the EH frame section IDs.
@@ -202,11 +275,12 @@ public:
StringRef Name;
if (auto EC = Section.getName(Name))
return errorCodeToError(EC);
- // Note unwind info is split across .pdata and .xdata, so this
- // may not be sufficiently general for all users.
- if (Name == ".xdata") {
+
+ // Note unwind info is stored in .pdata but often points to .xdata
+ // with an IMAGE_REL_AMD64_ADDR32NB relocation. Using a memory manager
+ // that keeps sections ordered in relation to __ImageBase is necessary.
+ if (Name == ".pdata")
UnregisteredEHFrameSections.push_back(SectionPair.second);
- }
}
return Error::success();
}
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp
index fe0f48e66a81..3a166b40af2d 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp
@@ -55,12 +55,12 @@ RuntimeDyldELFMips::evaluateMIPS32Relocation(const SectionEntry &Section,
uint64_t Offset, uint64_t Value,
uint32_t Type) {
- DEBUG(dbgs() << "evaluateMIPS32Relocation, LocalAddress: 0x"
- << format("%llx", Section.getAddressWithOffset(Offset))
- << " FinalAddress: 0x"
- << format("%llx", Section.getLoadAddressWithOffset(Offset))
- << " Value: 0x" << format("%llx", Value) << " Type: 0x"
- << format("%x", Type) << "\n");
+ LLVM_DEBUG(dbgs() << "evaluateMIPS32Relocation, LocalAddress: 0x"
+ << format("%llx", Section.getAddressWithOffset(Offset))
+ << " FinalAddress: 0x"
+ << format("%llx", Section.getLoadAddressWithOffset(Offset))
+ << " Value: 0x" << format("%llx", Value) << " Type: 0x"
+ << format("%x", Type) << "\n");
switch (Type) {
default:
@@ -110,15 +110,16 @@ int64_t RuntimeDyldELFMips::evaluateMIPS64Relocation(
const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type,
int64_t Addend, uint64_t SymOffset, SID SectionID) {
- DEBUG(dbgs() << "evaluateMIPS64Relocation, LocalAddress: 0x"
- << format("%llx", Section.getAddressWithOffset(Offset))
- << " FinalAddress: 0x"
- << format("%llx", Section.getLoadAddressWithOffset(Offset))
- << " Value: 0x" << format("%llx", Value) << " Type: 0x"
- << format("%x", Type) << " Addend: 0x" << format("%llx", Addend)
- << " Offset: " << format("%llx" PRIx64, Offset)
- << " SID: " << format("%d", SectionID)
- << " SymOffset: " << format("%x", SymOffset) << "\n");
+ LLVM_DEBUG(dbgs() << "evaluateMIPS64Relocation, LocalAddress: 0x"
+ << format("%llx", Section.getAddressWithOffset(Offset))
+ << " FinalAddress: 0x"
+ << format("%llx", Section.getLoadAddressWithOffset(Offset))
+ << " Value: 0x" << format("%llx", Value) << " Type: 0x"
+ << format("%x", Type) << " Addend: 0x"
+ << format("%llx", Addend)
+ << " Offset: " << format("%llx" PRIx64, Offset)
+ << " SID: " << format("%d", SectionID)
+ << " SymOffset: " << format("%x", SymOffset) << "\n");
switch (Type) {
default:
@@ -307,13 +308,12 @@ void RuntimeDyldELFMips::resolveMIPSO32Relocation(const SectionEntry &Section,
uint8_t *TargetPtr = Section.getAddressWithOffset(Offset);
Value += Addend;
- DEBUG(dbgs() << "resolveMIPSO32Relocation, LocalAddress: "
- << Section.getAddressWithOffset(Offset) << " FinalAddress: "
- << format("%p", Section.getLoadAddressWithOffset(Offset))
- << " Value: " << format("%x", Value)
- << " Type: " << format("%x", Type)
- << " Addend: " << format("%x", Addend)
- << " SymOffset: " << format("%x", Offset) << "\n");
+ LLVM_DEBUG(dbgs() << "resolveMIPSO32Relocation, LocalAddress: "
+ << Section.getAddressWithOffset(Offset) << " FinalAddress: "
+ << format("%p", Section.getLoadAddressWithOffset(Offset))
+ << " Value: " << format("%x", Value) << " Type: "
+ << format("%x", Type) << " Addend: " << format("%x", Addend)
+ << " SymOffset: " << format("%x", Offset) << "\n");
Value = evaluateMIPS32Relocation(Section, Offset, Value, Type);
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.h
index ce54a2717673..f53b9e6bd75a 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.h
@@ -39,13 +39,13 @@ protected:
uint64_t SymOffset, SID SectionID);
private:
- /// \brief A object file specific relocation resolver
+ /// A object file specific relocation resolver
/// \param RE The relocation to be resolved
/// \param Value Target symbol address to apply the relocation action
uint64_t evaluateRelocation(const RelocationEntry &RE, uint64_t Value,
uint64_t Addend);
- /// \brief A object file specific relocation resolver
+ /// A object file specific relocation resolver
/// \param RE The relocation to be resolved
/// \param Value Target symbol address to apply the relocation action
void applyRelocation(const RelocationEntry &RE, uint64_t Value);
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
index 97cbc153b227..2a619c549cfa 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOAArch64.h
@@ -32,18 +32,37 @@ public:
unsigned getStubAlignment() override { return 8; }
/// Extract the addend encoded in the instruction / memory location.
- int64_t decodeAddend(const RelocationEntry &RE) const {
+ Expected<int64_t> decodeAddend(const RelocationEntry &RE) const {
const SectionEntry &Section = Sections[RE.SectionID];
uint8_t *LocalAddress = Section.getAddressWithOffset(RE.Offset);
unsigned NumBytes = 1 << RE.Size;
int64_t Addend = 0;
// Verify that the relocation has the correct size and alignment.
switch (RE.RelType) {
- default:
- llvm_unreachable("Unsupported relocation type!");
- case MachO::ARM64_RELOC_UNSIGNED:
- assert((NumBytes == 4 || NumBytes == 8) && "Invalid relocation size.");
+ default: {
+ std::string ErrMsg;
+ {
+ raw_string_ostream ErrStream(ErrMsg);
+ ErrStream << "Unsupported relocation type: "
+ << getRelocName(RE.RelType);
+ }
+ return make_error<StringError>(std::move(ErrMsg),
+ inconvertibleErrorCode());
+ }
+ case MachO::ARM64_RELOC_POINTER_TO_GOT:
+ case MachO::ARM64_RELOC_UNSIGNED: {
+ if (NumBytes != 4 && NumBytes != 8) {
+ std::string ErrMsg;
+ {
+ raw_string_ostream ErrStream(ErrMsg);
+ ErrStream << "Invalid relocation size for relocation "
+ << getRelocName(RE.RelType);
+ }
+ return make_error<StringError>(std::move(ErrMsg),
+ inconvertibleErrorCode());
+ }
break;
+ }
case MachO::ARM64_RELOC_BRANCH26:
case MachO::ARM64_RELOC_PAGE21:
case MachO::ARM64_RELOC_PAGEOFF12:
@@ -58,6 +77,7 @@ public:
switch (RE.RelType) {
default:
llvm_unreachable("Unsupported relocation type!");
+ case MachO::ARM64_RELOC_POINTER_TO_GOT:
case MachO::ARM64_RELOC_UNSIGNED:
// This could be an unaligned memory location.
if (NumBytes == 4)
@@ -66,9 +86,11 @@ public:
Addend = *reinterpret_cast<support::ulittle64_t *>(LocalAddress);
break;
case MachO::ARM64_RELOC_BRANCH26: {
- // Verify that the relocation points to the expected branch instruction.
+ // Verify that the relocation points to a B/BL instruction.
auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
- assert((*p & 0xFC000000) == 0x14000000 && "Expected branch instruction.");
+ assert(((*p & 0xFC000000) == 0x14000000 ||
+ (*p & 0xFC000000) == 0x94000000) &&
+ "Expected branch instruction.");
// Get the 26 bit addend encoded in the branch instruction and sign-extend
// to 64 bit. The lower 2 bits are always zeros and are therefore implicit
@@ -137,6 +159,7 @@ public:
switch (RelType) {
default:
llvm_unreachable("Unsupported relocation type!");
+ case MachO::ARM64_RELOC_POINTER_TO_GOT:
case MachO::ARM64_RELOC_UNSIGNED:
assert((NumBytes == 4 || NumBytes == 8) && "Invalid relocation size.");
break;
@@ -154,6 +177,7 @@ public:
switch (RelType) {
default:
llvm_unreachable("Unsupported relocation type!");
+ case MachO::ARM64_RELOC_POINTER_TO_GOT:
case MachO::ARM64_RELOC_UNSIGNED:
// This could be an unaligned memory location.
if (NumBytes == 4)
@@ -164,7 +188,9 @@ public:
case MachO::ARM64_RELOC_BRANCH26: {
auto *p = reinterpret_cast<support::aligned_ulittle32_t *>(LocalAddress);
// Verify that the relocation points to the expected branch instruction.
- assert((*p & 0xFC000000) == 0x14000000 && "Expected branch instruction.");
+ assert(((*p & 0xFC000000) == 0x14000000 ||
+ (*p & 0xFC000000) == 0x94000000) &&
+ "Expected branch instruction.");
// Verify addend value.
assert((Addend & 0x3) == 0 && "Branch target is not aligned");
@@ -278,7 +304,20 @@ public:
return processSubtractRelocation(SectionID, RelI, Obj, ObjSectionToID);
RelocationEntry RE(getRelocationEntry(SectionID, Obj, RelI));
- RE.Addend = decodeAddend(RE);
+
+ if (RE.RelType == MachO::ARM64_RELOC_POINTER_TO_GOT) {
+ bool Valid =
+ (RE.Size == 2 && RE.IsPCRel) || (RE.Size == 3 && !RE.IsPCRel);
+ if (!Valid)
+ return make_error<StringError>("ARM64_RELOC_POINTER_TO_GOT supports "
+ "32-bit pc-rel or 64-bit absolute only",
+ inconvertibleErrorCode());
+ }
+
+ if (auto Addend = decodeAddend(RE))
+ RE.Addend = *Addend;
+ else
+ return Addend.takeError();
assert((ExplicitAddend == 0 || RE.Addend == 0) && "Relocation has "\
"ARM64_RELOC_ADDEND and embedded addend in the instruction.");
@@ -292,13 +331,17 @@ public:
return ValueOrErr.takeError();
bool IsExtern = Obj.getPlainRelocationExternal(RelInfo);
- if (!IsExtern && RE.IsPCRel)
+ if (RE.RelType == MachO::ARM64_RELOC_POINTER_TO_GOT) {
+ // We'll take care of the offset in processGOTRelocation.
+ Value.Offset = 0;
+ } else if (!IsExtern && RE.IsPCRel)
makeValueAddendPCRel(Value, RelI, 1 << RE.Size);
RE.Addend = Value.Offset;
if (RE.RelType == MachO::ARM64_RELOC_GOT_LOAD_PAGE21 ||
- RE.RelType == MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12)
+ RE.RelType == MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12 ||
+ RE.RelType == MachO::ARM64_RELOC_POINTER_TO_GOT)
processGOTRelocation(RE, Value, Stubs);
else {
if (Value.SymbolName)
@@ -311,7 +354,7 @@ public:
}
void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override {
- DEBUG(dumpRelocationToResolve(RE, Value));
+ LLVM_DEBUG(dumpRelocationToResolve(RE, Value));
const SectionEntry &Section = Sections[RE.SectionID];
uint8_t *LocalAddress = Section.getAddressWithOffset(RE.Offset);
@@ -331,6 +374,19 @@ public:
encodeAddend(LocalAddress, 1 << RE.Size, RelType, Value + RE.Addend);
break;
}
+
+ case MachO::ARM64_RELOC_POINTER_TO_GOT: {
+ assert(((RE.Size == 2 && RE.IsPCRel) || (RE.Size == 3 && !RE.IsPCRel)) &&
+ "ARM64_RELOC_POINTER_TO_GOT only supports 32-bit pc-rel or 64-bit "
+ "absolute");
+ // Addend is the GOT entry address and RE.Offset the target of the
+ // relocation.
+ uint64_t Result =
+ RE.IsPCRel ? (RE.Addend - RE.Offset) : (Value + RE.Addend);
+ encodeAddend(LocalAddress, 1 << RE.Size, RelType, Result);
+ break;
+ }
+
case MachO::ARM64_RELOC_BRANCH26: {
assert(RE.IsPCRel && "not PCRel and ARM64_RELOC_BRANCH26 not supported");
// Check if branch is in range.
@@ -368,7 +424,7 @@ public:
writeBytesUnaligned(Value, LocalAddress, 1 << RE.Size);
break;
}
- case MachO::ARM64_RELOC_POINTER_TO_GOT:
+
case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21:
case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12:
llvm_unreachable("Relocation type not yet implemented!");
@@ -386,7 +442,9 @@ public:
private:
void processGOTRelocation(const RelocationEntry &RE,
RelocationValueRef &Value, StubMap &Stubs) {
- assert(RE.Size == 2);
+ assert((RE.RelType == MachO::ARM64_RELOC_POINTER_TO_GOT &&
+ (RE.Size == 2 || RE.Size == 3)) ||
+ RE.Size == 2);
SectionEntry &Section = Sections[RE.SectionID];
StubMap::const_iterator i = Stubs.find(Value);
int64_t Offset;
@@ -459,6 +517,23 @@ private:
return ++RelI;
}
+ static const char *getRelocName(uint32_t RelocType) {
+ switch (RelocType) {
+ case MachO::ARM64_RELOC_UNSIGNED: return "ARM64_RELOC_UNSIGNED";
+ case MachO::ARM64_RELOC_SUBTRACTOR: return "ARM64_RELOC_SUBTRACTOR";
+ case MachO::ARM64_RELOC_BRANCH26: return "ARM64_RELOC_BRANCH26";
+ case MachO::ARM64_RELOC_PAGE21: return "ARM64_RELOC_PAGE21";
+ case MachO::ARM64_RELOC_PAGEOFF12: return "ARM64_RELOC_PAGEOFF12";
+ case MachO::ARM64_RELOC_GOT_LOAD_PAGE21: return "ARM64_RELOC_GOT_LOAD_PAGE21";
+ case MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12: return "ARM64_RELOC_GOT_LOAD_PAGEOFF12";
+ case MachO::ARM64_RELOC_POINTER_TO_GOT: return "ARM64_RELOC_POINTER_TO_GOT";
+ case MachO::ARM64_RELOC_TLVP_LOAD_PAGE21: return "ARM64_RELOC_TLVP_LOAD_PAGE21";
+ case MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12: return "ARM64_RELOC_TLVP_LOAD_PAGEOFF12";
+ case MachO::ARM64_RELOC_ADDEND: return "ARM64_RELOC_ADDEND";
+ }
+ return "Unrecognized arm64 addend";
+ }
+
};
}
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h
index 990629de2f1d..64a6b2901819 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h
@@ -47,6 +47,18 @@ public:
return Addr;
}
+ bool isAddrTargetThumb(unsigned SectionID, uint64_t Offset) {
+ auto TargetObjAddr = Sections[SectionID].getObjAddress() + Offset;
+ for (auto &KV : GlobalSymbolTable) {
+ auto &Entry = KV.second;
+ auto SymbolObjAddr =
+ Sections[Entry.getSectionID()].getObjAddress() + Entry.getOffset();
+ if (TargetObjAddr == SymbolObjAddr)
+ return (Entry.getFlags().getTargetFlags() & ARMJITSymbolFlags::Thumb);
+ }
+ return false;
+ }
+
Expected<int64_t> decodeAddend(const RelocationEntry &RE) const {
const SectionEntry &Section = Sections[RE.SectionID];
uint8_t *LocalAddress = Section.getAddressWithOffset(RE.Offset);
@@ -161,12 +173,18 @@ public:
// the value as being a thumb stub: we don't want to mix it up with an ARM
// stub targeting the same function.
if (RE.RelType == MachO::ARM_THUMB_RELOC_BR22)
- Value.IsStubThumb = TargetIsLocalThumbFunc;
+ Value.IsStubThumb = true;
if (RE.IsPCRel)
makeValueAddendPCRel(Value, RelI,
(RE.RelType == MachO::ARM_THUMB_RELOC_BR22) ? 4 : 8);
+ // If this is a non-external branch target check whether Value points to a
+ // thumb func.
+ if (!Value.SymbolName && (RelType == MachO::ARM_RELOC_BR24 ||
+ RelType == MachO::ARM_THUMB_RELOC_BR22))
+ RE.IsTargetThumbFunc = isAddrTargetThumb(Value.SectionID, Value.Offset);
+
if (RE.RelType == MachO::ARM_RELOC_BR24 ||
RE.RelType == MachO::ARM_THUMB_RELOC_BR22)
processBranchRelocation(RE, Value, Stubs);
@@ -182,7 +200,7 @@ public:
}
void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override {
- DEBUG(dumpRelocationToResolve(RE, Value));
+ LLVM_DEBUG(dumpRelocationToResolve(RE, Value));
const SectionEntry &Section = Sections[RE.SectionID];
uint8_t *LocalAddress = Section.getAddressWithOffset(RE.Offset);
@@ -388,11 +406,11 @@ private:
// addend = Encoded - Expected
// = Encoded - (AddrA - AddrB)
- DEBUG(dbgs() << "Found SECTDIFF: AddrA: " << AddrA << ", AddrB: " << AddrB
- << ", Addend: " << Addend << ", SectionA ID: " << SectionAID
- << ", SectionAOffset: " << SectionAOffset
- << ", SectionB ID: " << SectionBID
- << ", SectionBOffset: " << SectionBOffset << "\n");
+ LLVM_DEBUG(dbgs() << "Found SECTDIFF: AddrA: " << AddrA
+ << ", AddrB: " << AddrB << ", Addend: " << Addend
+ << ", SectionA ID: " << SectionAID << ", SectionAOffset: "
+ << SectionAOffset << ", SectionB ID: " << SectionBID
+ << ", SectionBOffset: " << SectionBOffset << "\n");
RelocationEntry R(SectionID, Offset, RelocType, Addend, SectionAID,
SectionAOffset, SectionBID, SectionBOffset, IsPCRel,
HalfDiffKindBits);
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h
index c42f1751a181..d384d70b8b0f 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOI386.h
@@ -97,7 +97,7 @@ public:
}
void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override {
- DEBUG(dumpRelocationToResolve(RE, Value));
+ LLVM_DEBUG(dumpRelocationToResolve(RE, Value));
const SectionEntry &Section = Sections[RE.SectionID];
uint8_t *LocalAddress = Section.getAddressWithOffset(RE.Offset);
@@ -192,11 +192,11 @@ private:
// Compute the addend 'C' from the original expression 'A - B + C'.
Addend -= AddrA - AddrB;
- DEBUG(dbgs() << "Found SECTDIFF: AddrA: " << AddrA << ", AddrB: " << AddrB
- << ", Addend: " << Addend << ", SectionA ID: " << SectionAID
- << ", SectionAOffset: " << SectionAOffset
- << ", SectionB ID: " << SectionBID
- << ", SectionBOffset: " << SectionBOffset << "\n");
+ LLVM_DEBUG(dbgs() << "Found SECTDIFF: AddrA: " << AddrA
+ << ", AddrB: " << AddrB << ", Addend: " << Addend
+ << ", SectionA ID: " << SectionAID << ", SectionAOffset: "
+ << SectionAOffset << ", SectionB ID: " << SectionBID
+ << ", SectionBOffset: " << SectionBOffset << "\n");
RelocationEntry R(SectionID, Offset, RelocType, Addend, SectionAID,
SectionAOffset, SectionBID, SectionBOffset,
IsPCRel, Size);
diff --git a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h
index 32fd3efddd0d..9732ea6a0cd2 100644
--- a/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h
+++ b/contrib/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOX86_64.h
@@ -85,7 +85,7 @@ public:
}
void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override {
- DEBUG(dumpRelocationToResolve(RE, Value));
+ LLVM_DEBUG(dumpRelocationToResolve(RE, Value));
const SectionEntry &Section = Sections[RE.SectionID];
uint8_t *LocalAddress = Section.getAddressWithOffset(RE.Offset);