mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
[RuntimeDyld] clang-format files.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204507 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4d221b3e89
commit
b0e33fdcd0
@ -35,11 +35,9 @@ void ObjectImageCommon::anchor() {}
|
||||
|
||||
namespace llvm {
|
||||
|
||||
void RuntimeDyldImpl::registerEHFrames() {
|
||||
}
|
||||
void RuntimeDyldImpl::registerEHFrames() {}
|
||||
|
||||
void RuntimeDyldImpl::deregisterEHFrames() {
|
||||
}
|
||||
void RuntimeDyldImpl::deregisterEHFrames() {}
|
||||
|
||||
// Resolve the relocations for all symbols we currently know about.
|
||||
void RuntimeDyldImpl::resolveRelocations() {
|
||||
@ -55,9 +53,8 @@ void RuntimeDyldImpl::resolveRelocations() {
|
||||
// symbol for the relocation is located. The SectionID in the relocation
|
||||
// entry provides the section to which the relocation will be applied.
|
||||
uint64_t Addr = Sections[i].LoadAddress;
|
||||
DEBUG(dbgs() << "Resolving relocations Section #" << i
|
||||
<< "\t" << format("%p", (uint8_t *)Addr)
|
||||
<< "\n");
|
||||
DEBUG(dbgs() << "Resolving relocations Section #" << i << "\t"
|
||||
<< format("%p", (uint8_t *)Addr) << "\n");
|
||||
resolveRelocationList(Relocations[i], Addr);
|
||||
Relocations.erase(i);
|
||||
}
|
||||
@ -75,7 +72,7 @@ void RuntimeDyldImpl::mapSectionAddress(const void *LocalAddress,
|
||||
llvm_unreachable("Attempting to remap address of unknown section!");
|
||||
}
|
||||
|
||||
ObjectImage* RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
|
||||
ObjectImage *RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
|
||||
MutexGuard locked(lock);
|
||||
|
||||
std::unique_ptr<ObjectImage> Obj(InputObject);
|
||||
@ -85,7 +82,7 @@ ObjectImage* RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
|
||||
// Save information about our target
|
||||
Arch = (Triple::ArchType)Obj->getArch();
|
||||
IsTargetLittleEndian = Obj->getObjectFile()->isLittleEndian();
|
||||
|
||||
|
||||
// Compute the memory size required to load all sections to be loaded
|
||||
// and pass this information to the memory manager
|
||||
if (MemMgr->needsToReserveAllocationSpace()) {
|
||||
@ -93,7 +90,7 @@ ObjectImage* RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
|
||||
computeTotalAllocSize(*Obj, CodeSize, DataSizeRO, DataSizeRW);
|
||||
MemMgr->reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW);
|
||||
}
|
||||
|
||||
|
||||
// Symbols found in this object
|
||||
StringMap<SymbolLoc> LocalSymbols;
|
||||
// Used sections from the object file
|
||||
@ -134,18 +131,19 @@ ObjectImage* RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
|
||||
section_iterator SI = Obj->end_sections();
|
||||
Check(I->getFileOffset(FileOffset));
|
||||
Check(I->getSection(SI));
|
||||
if (SI == Obj->end_sections()) continue;
|
||||
if (SI == Obj->end_sections())
|
||||
continue;
|
||||
Check(SI->getContents(SectionData));
|
||||
Check(SI->isText(IsCode));
|
||||
const uint8_t* SymPtr = (const uint8_t*)Obj->getData().data() +
|
||||
(uintptr_t)FileOffset;
|
||||
uintptr_t SectOffset = (uintptr_t)(SymPtr -
|
||||
(const uint8_t*)SectionData.begin());
|
||||
unsigned SectionID = findOrEmitSection(*Obj, *SI, IsCode, LocalSections);
|
||||
const uint8_t *SymPtr =
|
||||
(const uint8_t *)Obj->getData().data() + (uintptr_t)FileOffset;
|
||||
uintptr_t SectOffset =
|
||||
(uintptr_t)(SymPtr - (const uint8_t *)SectionData.begin());
|
||||
unsigned SectionID =
|
||||
findOrEmitSection(*Obj, *SI, IsCode, LocalSections);
|
||||
LocalSymbols[Name.data()] = SymbolLoc(SectionID, SectOffset);
|
||||
DEBUG(dbgs() << "\tFileOffset: " << format("%p", (uintptr_t)FileOffset)
|
||||
<< " flags: " << Flags
|
||||
<< " SID: " << SectionID
|
||||
<< " flags: " << Flags << " SID: " << SectionID
|
||||
<< " Offset: " << format("%p", SectOffset));
|
||||
GlobalSymbolTable[Name] = SymbolLoc(SectionID, SectOffset);
|
||||
}
|
||||
@ -171,7 +169,7 @@ ObjectImage* RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
|
||||
bool IsCode = false;
|
||||
Check(RelocatedSection->isText(IsCode));
|
||||
SectionID =
|
||||
findOrEmitSection(*Obj, *RelocatedSection, IsCode, LocalSections);
|
||||
findOrEmitSection(*Obj, *RelocatedSection, IsCode, LocalSections);
|
||||
DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
|
||||
|
||||
for (relocation_iterator I = SI->relocation_begin(),
|
||||
@ -187,37 +185,41 @@ ObjectImage* RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
|
||||
}
|
||||
|
||||
// A helper method for computeTotalAllocSize.
|
||||
// Computes the memory size required to allocate sections with the given sizes,
|
||||
// Computes the memory size required to allocate sections with the given sizes,
|
||||
// assuming that all sections are allocated with the given alignment
|
||||
static uint64_t computeAllocationSizeForSections(std::vector<uint64_t>& SectionSizes,
|
||||
uint64_t Alignment) {
|
||||
static uint64_t
|
||||
computeAllocationSizeForSections(std::vector<uint64_t> &SectionSizes,
|
||||
uint64_t Alignment) {
|
||||
uint64_t TotalSize = 0;
|
||||
for (size_t Idx = 0, Cnt = SectionSizes.size(); Idx < Cnt; Idx++) {
|
||||
uint64_t AlignedSize = (SectionSizes[Idx] + Alignment - 1) /
|
||||
Alignment * Alignment;
|
||||
uint64_t AlignedSize =
|
||||
(SectionSizes[Idx] + Alignment - 1) / Alignment * Alignment;
|
||||
TotalSize += AlignedSize;
|
||||
}
|
||||
return TotalSize;
|
||||
}
|
||||
|
||||
// Compute an upper bound of the memory size that is required to load all sections
|
||||
void RuntimeDyldImpl::computeTotalAllocSize(ObjectImage &Obj,
|
||||
uint64_t& CodeSize, uint64_t& DataSizeRO, uint64_t& DataSizeRW) {
|
||||
// Compute an upper bound of the memory size that is required to load all
|
||||
// sections
|
||||
void RuntimeDyldImpl::computeTotalAllocSize(ObjectImage &Obj,
|
||||
uint64_t &CodeSize,
|
||||
uint64_t &DataSizeRO,
|
||||
uint64_t &DataSizeRW) {
|
||||
// Compute the size of all sections required for execution
|
||||
std::vector<uint64_t> CodeSectionSizes;
|
||||
std::vector<uint64_t> ROSectionSizes;
|
||||
std::vector<uint64_t> RWSectionSizes;
|
||||
uint64_t MaxAlignment = sizeof(void*);
|
||||
uint64_t MaxAlignment = sizeof(void *);
|
||||
|
||||
// Collect sizes of all sections to be loaded;
|
||||
// Collect sizes of all sections to be loaded;
|
||||
// also determine the max alignment of all sections
|
||||
for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections();
|
||||
for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections();
|
||||
SI != SE; ++SI) {
|
||||
const SectionRef &Section = *SI;
|
||||
|
||||
bool IsRequired;
|
||||
Check(Section.isRequiredForExecution(IsRequired));
|
||||
|
||||
|
||||
// Consider only the sections that are required to be loaded for execution
|
||||
if (IsRequired) {
|
||||
uint64_t DataSize = 0;
|
||||
@ -230,17 +232,19 @@ void RuntimeDyldImpl::computeTotalAllocSize(ObjectImage &Obj,
|
||||
Check(Section.isText(IsCode));
|
||||
Check(Section.isReadOnlyData(IsReadOnly));
|
||||
Check(Section.getName(Name));
|
||||
unsigned Alignment = (unsigned) Alignment64 & 0xffffffffL;
|
||||
|
||||
unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL;
|
||||
|
||||
uint64_t StubBufSize = computeSectionStubBufSize(Obj, Section);
|
||||
uint64_t SectionSize = DataSize + StubBufSize;
|
||||
|
||||
// The .eh_frame section (at least on Linux) needs an extra four bytes padded
|
||||
|
||||
// The .eh_frame section (at least on Linux) needs an extra four bytes
|
||||
// padded
|
||||
// with zeroes added at the end. For MachO objects, this section has a
|
||||
// slightly different name, so this won't have any effect for MachO objects.
|
||||
// slightly different name, so this won't have any effect for MachO
|
||||
// objects.
|
||||
if (Name == ".eh_frame")
|
||||
SectionSize += 4;
|
||||
|
||||
|
||||
if (SectionSize > 0) {
|
||||
// save the total size of the section
|
||||
if (IsCode) {
|
||||
@ -254,14 +258,14 @@ void RuntimeDyldImpl::computeTotalAllocSize(ObjectImage &Obj,
|
||||
if (Alignment > MaxAlignment) {
|
||||
MaxAlignment = Alignment;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the size of all common symbols
|
||||
uint64_t CommonSize = 0;
|
||||
for (symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols();
|
||||
I != E; ++I) {
|
||||
for (symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); I != E;
|
||||
++I) {
|
||||
uint32_t Flags = I->getFlags();
|
||||
if (Flags & SymbolRef::SF_Common) {
|
||||
// Add the common symbols to a list. We'll allocate them all below.
|
||||
@ -274,29 +278,28 @@ void RuntimeDyldImpl::computeTotalAllocSize(ObjectImage &Obj,
|
||||
RWSectionSizes.push_back(CommonSize);
|
||||
}
|
||||
|
||||
// Compute the required allocation space for each different type of sections
|
||||
// (code, read-only data, read-write data) assuming that all sections are
|
||||
// Compute the required allocation space for each different type of sections
|
||||
// (code, read-only data, read-write data) assuming that all sections are
|
||||
// allocated with the max alignment. Note that we cannot compute with the
|
||||
// individual alignments of the sections, because then the required size
|
||||
// individual alignments of the sections, because then the required size
|
||||
// depends on the order, in which the sections are allocated.
|
||||
CodeSize = computeAllocationSizeForSections(CodeSectionSizes, MaxAlignment);
|
||||
DataSizeRO = computeAllocationSizeForSections(ROSectionSizes, MaxAlignment);
|
||||
DataSizeRW = computeAllocationSizeForSections(RWSectionSizes, MaxAlignment);
|
||||
DataSizeRW = computeAllocationSizeForSections(RWSectionSizes, MaxAlignment);
|
||||
}
|
||||
|
||||
// compute stub buffer size for the given section
|
||||
unsigned RuntimeDyldImpl::computeSectionStubBufSize(ObjectImage &Obj,
|
||||
unsigned RuntimeDyldImpl::computeSectionStubBufSize(ObjectImage &Obj,
|
||||
const SectionRef &Section) {
|
||||
unsigned StubSize = getMaxStubSize();
|
||||
if (StubSize == 0) {
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
// FIXME: this is an inefficient way to handle this. We should computed the
|
||||
// necessary section allocation size in loadObject by walking all the sections
|
||||
// once.
|
||||
unsigned StubBufSize = 0;
|
||||
for (section_iterator SI = Obj.begin_sections(),
|
||||
SE = Obj.end_sections();
|
||||
for (section_iterator SI = Obj.begin_sections(), SE = Obj.end_sections();
|
||||
SI != SE; ++SI) {
|
||||
section_iterator RelSecI = SI->getRelocatedSection();
|
||||
if (!(RelSecI == Section))
|
||||
@ -319,7 +322,7 @@ unsigned RuntimeDyldImpl::computeSectionStubBufSize(ObjectImage &Obj,
|
||||
unsigned StubAlignment = getStubAlignment();
|
||||
unsigned EndAlignment = (DataSize | Alignment) & -(DataSize | Alignment);
|
||||
if (StubAlignment > EndAlignment)
|
||||
StubBufSize += StubAlignment - EndAlignment;
|
||||
StubBufSize += StubAlignment - EndAlignment;
|
||||
return StubBufSize;
|
||||
}
|
||||
|
||||
@ -329,22 +332,20 @@ void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj,
|
||||
SymbolTableMap &SymbolTable) {
|
||||
// Allocate memory for the section
|
||||
unsigned SectionID = Sections.size();
|
||||
uint8_t *Addr = MemMgr->allocateDataSection(
|
||||
TotalSize, sizeof(void*), SectionID, StringRef(), false);
|
||||
uint8_t *Addr = MemMgr->allocateDataSection(TotalSize, sizeof(void *),
|
||||
SectionID, StringRef(), false);
|
||||
if (!Addr)
|
||||
report_fatal_error("Unable to allocate memory for common symbols!");
|
||||
uint64_t Offset = 0;
|
||||
Sections.push_back(SectionEntry(StringRef(), Addr, TotalSize, 0));
|
||||
memset(Addr, 0, TotalSize);
|
||||
|
||||
DEBUG(dbgs() << "emitCommonSection SectionID: " << SectionID
|
||||
<< " new addr: " << format("%p", Addr)
|
||||
<< " DataSize: " << TotalSize
|
||||
<< "\n");
|
||||
DEBUG(dbgs() << "emitCommonSection SectionID: " << SectionID << " new addr: "
|
||||
<< format("%p", Addr) << " DataSize: " << TotalSize << "\n");
|
||||
|
||||
// Assign the address of each symbol
|
||||
for (CommonSymbolMap::const_iterator it = CommonSymbols.begin(),
|
||||
itEnd = CommonSymbols.end(); it != itEnd; it++) {
|
||||
itEnd = CommonSymbols.end(); it != itEnd; ++it) {
|
||||
uint64_t Size = it->second.first;
|
||||
uint64_t Align = it->second.second;
|
||||
StringRef Name;
|
||||
@ -354,8 +355,8 @@ void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj,
|
||||
uint64_t AlignOffset = OffsetToAlignment((uint64_t)Addr, Align);
|
||||
Addr += AlignOffset;
|
||||
Offset += AlignOffset;
|
||||
DEBUG(dbgs() << "Allocating common symbol " << Name << " address " <<
|
||||
format("%p\n", Addr));
|
||||
DEBUG(dbgs() << "Allocating common symbol " << Name << " address "
|
||||
<< format("%p\n", Addr));
|
||||
}
|
||||
Obj.updateSymbolAddress(it->first, (uint64_t)Addr);
|
||||
SymbolTable[Name.data()] = SymbolLoc(SectionID, Offset);
|
||||
@ -365,8 +366,7 @@ void RuntimeDyldImpl::emitCommonSymbols(ObjectImage &Obj,
|
||||
}
|
||||
|
||||
unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj,
|
||||
const SectionRef &Section,
|
||||
bool IsCode) {
|
||||
const SectionRef &Section, bool IsCode) {
|
||||
|
||||
StringRef data;
|
||||
uint64_t Alignment64;
|
||||
@ -388,8 +388,8 @@ unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj,
|
||||
Check(Section.isReadOnlyData(IsReadOnly));
|
||||
Check(Section.getSize(DataSize));
|
||||
Check(Section.getName(Name));
|
||||
|
||||
StubBufSize = computeSectionStubBufSize(Obj, Section);
|
||||
|
||||
StubBufSize = computeSectionStubBufSize(Obj, Section);
|
||||
|
||||
// The .eh_frame section (at least on Linux) needs an extra four bytes padded
|
||||
// with zeroes added at the end. For MachO objects, this section has a
|
||||
@ -406,10 +406,10 @@ unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj,
|
||||
// Leave those where they are.
|
||||
if (IsRequired) {
|
||||
Allocate = DataSize + PaddingSize + StubBufSize;
|
||||
Addr = IsCode
|
||||
? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID, Name)
|
||||
: MemMgr->allocateDataSection(Allocate, Alignment, SectionID, Name,
|
||||
IsReadOnly);
|
||||
Addr = IsCode ? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID,
|
||||
Name)
|
||||
: MemMgr->allocateDataSection(Allocate, Alignment, SectionID,
|
||||
Name, IsReadOnly);
|
||||
if (!Addr)
|
||||
report_fatal_error("Unable to allocate section memory!");
|
||||
|
||||
@ -430,30 +430,22 @@ unsigned RuntimeDyldImpl::emitSection(ObjectImage &Obj,
|
||||
DataSize += PaddingSize;
|
||||
}
|
||||
|
||||
DEBUG(dbgs() << "emitSection SectionID: " << SectionID
|
||||
<< " Name: " << Name
|
||||
DEBUG(dbgs() << "emitSection SectionID: " << SectionID << " Name: " << Name
|
||||
<< " obj addr: " << format("%p", pData)
|
||||
<< " new addr: " << format("%p", Addr)
|
||||
<< " DataSize: " << DataSize
|
||||
<< " StubBufSize: " << StubBufSize
|
||||
<< " Allocate: " << Allocate
|
||||
<< "\n");
|
||||
<< " DataSize: " << DataSize << " StubBufSize: " << StubBufSize
|
||||
<< " Allocate: " << Allocate << "\n");
|
||||
Obj.updateSectionAddress(Section, (uint64_t)Addr);
|
||||
}
|
||||
else {
|
||||
} 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 = 0;
|
||||
DEBUG(dbgs() << "emitSection SectionID: " << SectionID
|
||||
<< " Name: " << Name
|
||||
<< " obj addr: " << format("%p", data.data())
|
||||
<< " new addr: 0"
|
||||
<< " DataSize: " << DataSize
|
||||
<< " StubBufSize: " << StubBufSize
|
||||
<< " Allocate: " << Allocate
|
||||
<< "\n");
|
||||
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(SectionEntry(Name, Addr, DataSize, (uintptr_t)pData));
|
||||
@ -486,8 +478,7 @@ void RuntimeDyldImpl::addRelocationForSymbol(const RelocationEntry &RE,
|
||||
// Relocation by symbol. If the symbol is found in the global symbol table,
|
||||
// create an appropriate section relocation. Otherwise, add it to
|
||||
// ExternalSymbolRelocations.
|
||||
SymbolTableMap::const_iterator Loc =
|
||||
GlobalSymbolTable.find(SymbolName);
|
||||
SymbolTableMap::const_iterator Loc = GlobalSymbolTable.find(SymbolName);
|
||||
if (Loc == GlobalSymbolTable.end()) {
|
||||
ExternalSymbolRelocations[SymbolName].push_back(RE);
|
||||
} else {
|
||||
@ -503,7 +494,7 @@ uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) {
|
||||
// This stub has to be able to access the full address space,
|
||||
// since symbol lookup won't necessarily find a handy, in-range,
|
||||
// PLT stub for functions which could be anywhere.
|
||||
uint32_t *StubAddr = (uint32_t*)Addr;
|
||||
uint32_t *StubAddr = (uint32_t *)Addr;
|
||||
|
||||
// Stub can use ip0 (== x16) to calculate address
|
||||
*StubAddr = 0xd2e00010; // movz ip0, #:abs_g3:<addr>
|
||||
@ -520,11 +511,11 @@ uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) {
|
||||
} else if (Arch == Triple::arm) {
|
||||
// TODO: There is only ARM far stub now. We should add the Thumb stub,
|
||||
// and stubs for branches Thumb - ARM and ARM - Thumb.
|
||||
uint32_t *StubAddr = (uint32_t*)Addr;
|
||||
uint32_t *StubAddr = (uint32_t *)Addr;
|
||||
*StubAddr = 0xe51ff004; // ldr pc,<label>
|
||||
return (uint8_t*)++StubAddr;
|
||||
return (uint8_t *)++StubAddr;
|
||||
} else if (Arch == Triple::mipsel || Arch == Triple::mips) {
|
||||
uint32_t *StubAddr = (uint32_t*)Addr;
|
||||
uint32_t *StubAddr = (uint32_t *)Addr;
|
||||
// 0: 3c190000 lui t9,%hi(addr).
|
||||
// 4: 27390000 addiu t9,t9,%lo(addr).
|
||||
// 8: 03200008 jr t9.
|
||||
@ -602,29 +593,30 @@ void RuntimeDyldImpl::resolveRelocationList(const RelocationList &Relocs,
|
||||
}
|
||||
|
||||
void RuntimeDyldImpl::resolveExternalSymbols() {
|
||||
while(!ExternalSymbolRelocations.empty()) {
|
||||
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");
|
||||
DEBUG(dbgs() << "Resolving absolute relocations."
|
||||
<< "\n");
|
||||
RelocationList &Relocs = i->second;
|
||||
resolveRelocationList(Relocs, 0);
|
||||
} else {
|
||||
uint64_t Addr = 0;
|
||||
SymbolTableMap::const_iterator Loc = GlobalSymbolTable.find(Name);
|
||||
if (Loc == GlobalSymbolTable.end()) {
|
||||
// This is an external symbol, try to get its address from
|
||||
// MemoryManager.
|
||||
Addr = MemMgr->getSymbolAddress(Name.data());
|
||||
// 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
|
||||
// iterator. This is also why retrieval of the relocation list
|
||||
// associated with this symbol is deferred until below this point.
|
||||
// New entries may have been added to the relocation list.
|
||||
i = ExternalSymbolRelocations.find(Name);
|
||||
// This is an external symbol, try to get its address from
|
||||
// MemoryManager.
|
||||
Addr = MemMgr->getSymbolAddress(Name.data());
|
||||
// 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
|
||||
// iterator. This is also why retrieval of the relocation list
|
||||
// associated with this symbol is deferred until below this point.
|
||||
// New entries may have been added to the relocation list.
|
||||
i = ExternalSymbolRelocations.find(Name);
|
||||
} else {
|
||||
// We found the symbol in our global table. It was probably in a
|
||||
// Module that we loaded previously.
|
||||
@ -635,12 +627,11 @@ void RuntimeDyldImpl::resolveExternalSymbols() {
|
||||
// FIXME: Implement error handling that doesn't kill the host program!
|
||||
if (!Addr)
|
||||
report_fatal_error("Program used external function '" + Name +
|
||||
"' which could not be resolved!");
|
||||
"' which could not be resolved!");
|
||||
|
||||
updateGOTEntries(Name, Addr);
|
||||
DEBUG(dbgs() << "Resolving relocations Name: " << Name
|
||||
<< "\t" << format("0x%lx", Addr)
|
||||
<< "\n");
|
||||
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;
|
||||
@ -651,7 +642,6 @@ void RuntimeDyldImpl::resolveExternalSymbols() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// RuntimeDyld class implementation
|
||||
RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
|
||||
@ -666,21 +656,17 @@ RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
|
||||
ProcessAllSections = false;
|
||||
}
|
||||
|
||||
RuntimeDyld::~RuntimeDyld() {
|
||||
delete Dyld;
|
||||
}
|
||||
RuntimeDyld::~RuntimeDyld() { delete Dyld; }
|
||||
|
||||
static std::unique_ptr<RuntimeDyldELF> createRuntimeDyldELF(
|
||||
RTDyldMemoryManager *MM,
|
||||
bool ProcessAllSections) {
|
||||
static std::unique_ptr<RuntimeDyldELF>
|
||||
createRuntimeDyldELF(RTDyldMemoryManager *MM, bool ProcessAllSections) {
|
||||
std::unique_ptr<RuntimeDyldELF> Dyld(new RuntimeDyldELF(MM));
|
||||
Dyld->setProcessAllSections(ProcessAllSections);
|
||||
return Dyld;
|
||||
}
|
||||
|
||||
static std::unique_ptr<RuntimeDyldMachO> createRuntimeDyldMachO(
|
||||
RTDyldMemoryManager *MM,
|
||||
bool ProcessAllSections) {
|
||||
static std::unique_ptr<RuntimeDyldMachO>
|
||||
createRuntimeDyldMachO(RTDyldMemoryManager *MM, bool ProcessAllSections) {
|
||||
std::unique_ptr<RuntimeDyldMachO> Dyld(new RuntimeDyldMachO(MM));
|
||||
Dyld->setProcessAllSections(ProcessAllSections);
|
||||
return Dyld;
|
||||
@ -709,8 +695,7 @@ ObjectImage *RuntimeDyld::loadObject(ObjectFile *InputObject) {
|
||||
|
||||
ObjectImage *RuntimeDyld::loadObject(ObjectBuffer *InputBuffer) {
|
||||
std::unique_ptr<ObjectImage> InputImage;
|
||||
sys::fs::file_magic Type =
|
||||
sys::fs::identify_magic(InputBuffer->getBuffer());
|
||||
sys::fs::file_magic Type = sys::fs::identify_magic(InputBuffer->getBuffer());
|
||||
|
||||
switch (Type) {
|
||||
case sys::fs::file_magic::elf_relocatable:
|
||||
@ -765,12 +750,9 @@ uint64_t RuntimeDyld::getSymbolLoadAddress(StringRef Name) {
|
||||
return Dyld->getSymbolLoadAddress(Name);
|
||||
}
|
||||
|
||||
void RuntimeDyld::resolveRelocations() {
|
||||
Dyld->resolveRelocations();
|
||||
}
|
||||
void RuntimeDyld::resolveRelocations() { Dyld->resolveRelocations(); }
|
||||
|
||||
void RuntimeDyld::reassignSectionAddress(unsigned SectionID,
|
||||
uint64_t Addr) {
|
||||
void RuntimeDyld::reassignSectionAddress(unsigned SectionID, uint64_t Addr) {
|
||||
Dyld->reassignSectionAddress(SectionID, Addr);
|
||||
}
|
||||
|
||||
@ -779,9 +761,7 @@ void RuntimeDyld::mapSectionAddress(const void *LocalAddress,
|
||||
Dyld->mapSectionAddress(LocalAddress, TargetAddress);
|
||||
}
|
||||
|
||||
StringRef RuntimeDyld::getErrorString() {
|
||||
return Dyld->getErrorString();
|
||||
}
|
||||
StringRef RuntimeDyld::getErrorString() { return Dyld->getErrorString(); }
|
||||
|
||||
void RuntimeDyld::registerEHFrames() {
|
||||
if (Dyld)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -22,65 +22,41 @@ using namespace llvm;
|
||||
namespace llvm {
|
||||
|
||||
namespace {
|
||||
// Helper for extensive error checking in debug builds.
|
||||
error_code Check(error_code Err) {
|
||||
if (Err) {
|
||||
report_fatal_error(Err.message());
|
||||
}
|
||||
return Err;
|
||||
// Helper for extensive error checking in debug builds.
|
||||
error_code Check(error_code Err) {
|
||||
if (Err) {
|
||||
report_fatal_error(Err.message());
|
||||
}
|
||||
return Err;
|
||||
}
|
||||
} // end anonymous namespace
|
||||
|
||||
class RuntimeDyldELF : public RuntimeDyldImpl {
|
||||
void resolveRelocation(const SectionEntry &Section,
|
||||
uint64_t Offset,
|
||||
uint64_t Value,
|
||||
uint32_t Type,
|
||||
int64_t Addend,
|
||||
uint64_t SymOffset=0);
|
||||
void resolveRelocation(const SectionEntry &Section, uint64_t Offset,
|
||||
uint64_t Value, uint32_t Type, int64_t Addend,
|
||||
uint64_t SymOffset = 0);
|
||||
|
||||
void resolveX86_64Relocation(const SectionEntry &Section,
|
||||
uint64_t Offset,
|
||||
uint64_t Value,
|
||||
uint32_t Type,
|
||||
int64_t Addend,
|
||||
void resolveX86_64Relocation(const SectionEntry &Section, uint64_t Offset,
|
||||
uint64_t Value, uint32_t Type, int64_t Addend,
|
||||
uint64_t SymOffset);
|
||||
|
||||
void resolveX86Relocation(const SectionEntry &Section,
|
||||
uint64_t Offset,
|
||||
uint32_t Value,
|
||||
uint32_t Type,
|
||||
int32_t Addend);
|
||||
void resolveX86Relocation(const SectionEntry &Section, uint64_t Offset,
|
||||
uint32_t Value, uint32_t Type, int32_t Addend);
|
||||
|
||||
void resolveAArch64Relocation(const SectionEntry &Section,
|
||||
uint64_t Offset,
|
||||
uint64_t Value,
|
||||
uint32_t Type,
|
||||
int64_t Addend);
|
||||
void resolveAArch64Relocation(const SectionEntry &Section, uint64_t Offset,
|
||||
uint64_t Value, uint32_t Type, int64_t Addend);
|
||||
|
||||
void resolveARMRelocation(const SectionEntry &Section,
|
||||
uint64_t Offset,
|
||||
uint32_t Value,
|
||||
uint32_t Type,
|
||||
int32_t Addend);
|
||||
void resolveARMRelocation(const SectionEntry &Section, uint64_t Offset,
|
||||
uint32_t Value, uint32_t Type, int32_t Addend);
|
||||
|
||||
void resolveMIPSRelocation(const SectionEntry &Section,
|
||||
uint64_t Offset,
|
||||
uint32_t Value,
|
||||
uint32_t Type,
|
||||
int32_t Addend);
|
||||
void resolveMIPSRelocation(const SectionEntry &Section, uint64_t Offset,
|
||||
uint32_t Value, uint32_t Type, int32_t Addend);
|
||||
|
||||
void resolvePPC64Relocation(const SectionEntry &Section,
|
||||
uint64_t Offset,
|
||||
uint64_t Value,
|
||||
uint32_t Type,
|
||||
int64_t Addend);
|
||||
void resolvePPC64Relocation(const SectionEntry &Section, uint64_t Offset,
|
||||
uint64_t Value, uint32_t Type, int64_t Addend);
|
||||
|
||||
void resolveSystemZRelocation(const SectionEntry &Section,
|
||||
uint64_t Offset,
|
||||
uint64_t Value,
|
||||
uint32_t Type,
|
||||
int64_t Addend);
|
||||
void resolveSystemZRelocation(const SectionEntry &Section, uint64_t Offset,
|
||||
uint64_t Value, uint32_t Type, int64_t Addend);
|
||||
|
||||
unsigned getMaxStubSize() override {
|
||||
if (Arch == Triple::aarch64)
|
||||
@ -107,8 +83,7 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
|
||||
}
|
||||
|
||||
uint64_t findPPC64TOC() const;
|
||||
void findOPDEntrySection(ObjectImage &Obj,
|
||||
ObjSectionToIDMap &LocalSections,
|
||||
void findOPDEntrySection(ObjectImage &Obj, ObjSectionToIDMap &LocalSections,
|
||||
RelocationValueRef &Rel);
|
||||
|
||||
uint64_t findGOTEntry(uint64_t LoadAddr, uint64_t Offset);
|
||||
@ -129,8 +104,7 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
|
||||
SmallVector<SID, 2> RegisteredEHFrameSections;
|
||||
|
||||
public:
|
||||
RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm)
|
||||
{}
|
||||
RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
|
||||
|
||||
void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override;
|
||||
relocation_iterator
|
||||
|
@ -39,7 +39,6 @@ namespace llvm {
|
||||
class ObjectBuffer;
|
||||
class Twine;
|
||||
|
||||
|
||||
/// SectionEntry - represents a section emitted into memory by the dynamic
|
||||
/// linker.
|
||||
class SectionEntry {
|
||||
@ -69,8 +68,9 @@ public:
|
||||
|
||||
SectionEntry(StringRef name, uint8_t *address, size_t size,
|
||||
uintptr_t objAddress)
|
||||
: Name(name), Address(address), Size(size), LoadAddress((uintptr_t)address),
|
||||
StubOffset(size), ObjAddress(objAddress) {}
|
||||
: Name(name), Address(address), Size(size),
|
||||
LoadAddress((uintptr_t)address), StubOffset(size),
|
||||
ObjAddress(objAddress) {}
|
||||
};
|
||||
|
||||
/// RelocationEntry - used to represent relocations internally in the dynamic
|
||||
@ -101,33 +101,33 @@ public:
|
||||
unsigned Size;
|
||||
|
||||
RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend)
|
||||
: SectionID(id), Offset(offset), RelType(type), Addend(addend),
|
||||
SymOffset(0), IsPCRel(false), Size(0) {}
|
||||
: SectionID(id), Offset(offset), RelType(type), Addend(addend),
|
||||
SymOffset(0), IsPCRel(false), Size(0) {}
|
||||
|
||||
RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend,
|
||||
uint64_t symoffset)
|
||||
: SectionID(id), Offset(offset), RelType(type), Addend(addend),
|
||||
SymOffset(symoffset), IsPCRel(false), Size(0) {}
|
||||
: SectionID(id), Offset(offset), RelType(type), Addend(addend),
|
||||
SymOffset(symoffset), IsPCRel(false), Size(0) {}
|
||||
|
||||
RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend,
|
||||
bool IsPCRel, unsigned Size)
|
||||
: SectionID(id), Offset(offset), RelType(type), Addend(addend),
|
||||
SymOffset(0), IsPCRel(IsPCRel), Size(Size) {}
|
||||
: SectionID(id), Offset(offset), RelType(type), Addend(addend),
|
||||
SymOffset(0), IsPCRel(IsPCRel), Size(Size) {}
|
||||
};
|
||||
|
||||
class RelocationValueRef {
|
||||
public:
|
||||
unsigned SectionID;
|
||||
uint64_t Offset;
|
||||
int64_t Addend;
|
||||
unsigned SectionID;
|
||||
uint64_t Offset;
|
||||
int64_t Addend;
|
||||
const char *SymbolName;
|
||||
RelocationValueRef(): SectionID(0), Offset(0), Addend(0), SymbolName(0) {}
|
||||
RelocationValueRef() : SectionID(0), Offset(0), Addend(0), SymbolName(0) {}
|
||||
|
||||
inline bool operator==(const RelocationValueRef &Other) const {
|
||||
return SectionID == Other.SectionID && Offset == Other.Offset &&
|
||||
Addend == Other.Addend && SymbolName == Other.SymbolName;
|
||||
}
|
||||
inline bool operator <(const RelocationValueRef &Other) const {
|
||||
inline bool operator<(const RelocationValueRef &Other) const {
|
||||
if (SectionID != Other.SectionID)
|
||||
return SectionID < Other.SectionID;
|
||||
if (Offset != Other.Offset)
|
||||
@ -149,7 +149,7 @@ protected:
|
||||
SectionList Sections;
|
||||
|
||||
typedef unsigned SID; // Type for SectionIDs
|
||||
#define RTDYLD_INVALID_SECTION_ID ((SID)(-1))
|
||||
#define RTDYLD_INVALID_SECTION_ID ((SID)(-1))
|
||||
|
||||
// Keep a map of sections from object file to the SectionID which
|
||||
// references it.
|
||||
@ -221,52 +221,49 @@ protected:
|
||||
}
|
||||
|
||||
uint8_t *getSectionAddress(unsigned SectionID) {
|
||||
return (uint8_t*)Sections[SectionID].Address;
|
||||
return (uint8_t *)Sections[SectionID].Address;
|
||||
}
|
||||
|
||||
void writeInt16BE(uint8_t *Addr, uint16_t Value) {
|
||||
if (IsTargetLittleEndian)
|
||||
Value = sys::SwapByteOrder(Value);
|
||||
*Addr = (Value >> 8) & 0xFF;
|
||||
*(Addr+1) = Value & 0xFF;
|
||||
*Addr = (Value >> 8) & 0xFF;
|
||||
*(Addr + 1) = Value & 0xFF;
|
||||
}
|
||||
|
||||
void writeInt32BE(uint8_t *Addr, uint32_t Value) {
|
||||
if (IsTargetLittleEndian)
|
||||
Value = sys::SwapByteOrder(Value);
|
||||
*Addr = (Value >> 24) & 0xFF;
|
||||
*(Addr+1) = (Value >> 16) & 0xFF;
|
||||
*(Addr+2) = (Value >> 8) & 0xFF;
|
||||
*(Addr+3) = Value & 0xFF;
|
||||
*Addr = (Value >> 24) & 0xFF;
|
||||
*(Addr + 1) = (Value >> 16) & 0xFF;
|
||||
*(Addr + 2) = (Value >> 8) & 0xFF;
|
||||
*(Addr + 3) = Value & 0xFF;
|
||||
}
|
||||
|
||||
void writeInt64BE(uint8_t *Addr, uint64_t Value) {
|
||||
if (IsTargetLittleEndian)
|
||||
Value = sys::SwapByteOrder(Value);
|
||||
*Addr = (Value >> 56) & 0xFF;
|
||||
*(Addr+1) = (Value >> 48) & 0xFF;
|
||||
*(Addr+2) = (Value >> 40) & 0xFF;
|
||||
*(Addr+3) = (Value >> 32) & 0xFF;
|
||||
*(Addr+4) = (Value >> 24) & 0xFF;
|
||||
*(Addr+5) = (Value >> 16) & 0xFF;
|
||||
*(Addr+6) = (Value >> 8) & 0xFF;
|
||||
*(Addr+7) = Value & 0xFF;
|
||||
*Addr = (Value >> 56) & 0xFF;
|
||||
*(Addr + 1) = (Value >> 48) & 0xFF;
|
||||
*(Addr + 2) = (Value >> 40) & 0xFF;
|
||||
*(Addr + 3) = (Value >> 32) & 0xFF;
|
||||
*(Addr + 4) = (Value >> 24) & 0xFF;
|
||||
*(Addr + 5) = (Value >> 16) & 0xFF;
|
||||
*(Addr + 6) = (Value >> 8) & 0xFF;
|
||||
*(Addr + 7) = Value & 0xFF;
|
||||
}
|
||||
|
||||
/// \brief Given the common symbols discovered in the object file, emit a
|
||||
/// new section for them and update the symbol mappings in the object and
|
||||
/// symbol table.
|
||||
void emitCommonSymbols(ObjectImage &Obj,
|
||||
const CommonSymbolMap &CommonSymbols,
|
||||
uint64_t TotalSize,
|
||||
SymbolTableMap &SymbolTable);
|
||||
void emitCommonSymbols(ObjectImage &Obj, const CommonSymbolMap &CommonSymbols,
|
||||
uint64_t TotalSize, SymbolTableMap &SymbolTable);
|
||||
|
||||
/// \brief 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.
|
||||
unsigned emitSection(ObjectImage &Obj,
|
||||
const SectionRef &Section,
|
||||
unsigned emitSection(ObjectImage &Obj, const SectionRef &Section,
|
||||
bool IsCode);
|
||||
|
||||
/// \brief Find Section in LocalSections. If the secton is not found - emit
|
||||
@ -274,10 +271,8 @@ protected:
|
||||
/// \param IsCode if it's true then allocateCodeSection() will be
|
||||
/// used for emmits, else allocateDataSection() will be used.
|
||||
/// \return SectionID.
|
||||
unsigned findOrEmitSection(ObjectImage &Obj,
|
||||
const SectionRef &Section,
|
||||
bool IsCode,
|
||||
ObjSectionToIDMap &LocalSections);
|
||||
unsigned findOrEmitSection(ObjectImage &Obj, const SectionRef &Section,
|
||||
bool IsCode, ObjSectionToIDMap &LocalSections);
|
||||
|
||||
// \brief Add a relocation entry that uses the given section.
|
||||
void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID);
|
||||
@ -288,7 +283,7 @@ protected:
|
||||
|
||||
/// \brief Emits long jump instruction to Addr.
|
||||
/// \return Pointer to the memory area for emitting target address.
|
||||
uint8_t* createStubFunction(uint8_t *Addr);
|
||||
uint8_t *createStubFunction(uint8_t *Addr);
|
||||
|
||||
/// \brief Resolves relocations from Relocs list with address from Value.
|
||||
void resolveRelocationList(const RelocationList &Relocs, uint64_t Value);
|
||||
@ -312,19 +307,18 @@ protected:
|
||||
// The base class does nothing. ELF overrides this.
|
||||
virtual void updateGOTEntries(StringRef Name, uint64_t Addr) {}
|
||||
|
||||
// \brief Compute an upper bound of the memory that is required to load all sections
|
||||
void computeTotalAllocSize(ObjectImage &Obj,
|
||||
uint64_t& CodeSize,
|
||||
uint64_t& DataSizeRO,
|
||||
uint64_t& DataSizeRW);
|
||||
|
||||
// \brief Compute an upper bound of the memory that is required to load all
|
||||
// sections
|
||||
void computeTotalAllocSize(ObjectImage &Obj, uint64_t &CodeSize,
|
||||
uint64_t &DataSizeRO, uint64_t &DataSizeRW);
|
||||
|
||||
// \brief Compute the stub buffer size required for a section
|
||||
unsigned computeSectionStubBufSize(ObjectImage &Obj,
|
||||
const SectionRef &Section);
|
||||
|
||||
public:
|
||||
RuntimeDyldImpl(RTDyldMemoryManager *mm)
|
||||
: MemMgr(mm), ProcessAllSections(false), HasError(false) {}
|
||||
: MemMgr(mm), ProcessAllSections(false), HasError(false) {}
|
||||
|
||||
virtual ~RuntimeDyldImpl();
|
||||
|
||||
@ -332,7 +326,7 @@ public:
|
||||
this->ProcessAllSections = ProcessAllSections;
|
||||
}
|
||||
|
||||
ObjectImage* loadObject(ObjectImage* InputObject);
|
||||
ObjectImage *loadObject(ObjectImage *InputObject);
|
||||
|
||||
void *getSymbolAddress(StringRef Name) {
|
||||
// FIXME: Just look up as a function for now. Overly simple of course.
|
||||
|
@ -20,18 +20,19 @@ using namespace llvm::object;
|
||||
|
||||
namespace llvm {
|
||||
|
||||
static unsigned char *processFDE(unsigned char *P, intptr_t DeltaForText, intptr_t DeltaForEH) {
|
||||
uint32_t Length = *((uint32_t*)P);
|
||||
static unsigned char *processFDE(unsigned char *P, intptr_t DeltaForText,
|
||||
intptr_t DeltaForEH) {
|
||||
uint32_t Length = *((uint32_t *)P);
|
||||
P += 4;
|
||||
unsigned char *Ret = P + Length;
|
||||
uint32_t Offset = *((uint32_t*)P);
|
||||
uint32_t Offset = *((uint32_t *)P);
|
||||
if (Offset == 0) // is a CIE
|
||||
return Ret;
|
||||
|
||||
P += 4;
|
||||
intptr_t FDELocation = *((intptr_t*)P);
|
||||
intptr_t FDELocation = *((intptr_t *)P);
|
||||
intptr_t NewLocation = FDELocation - DeltaForText;
|
||||
*((intptr_t*)P) = NewLocation;
|
||||
*((intptr_t *)P) = NewLocation;
|
||||
P += sizeof(intptr_t);
|
||||
|
||||
// Skip the FDE address range
|
||||
@ -40,16 +41,16 @@ static unsigned char *processFDE(unsigned char *P, intptr_t DeltaForText, intptr
|
||||
uint8_t Augmentationsize = *P;
|
||||
P += 1;
|
||||
if (Augmentationsize != 0) {
|
||||
intptr_t LSDA = *((intptr_t*)P);
|
||||
intptr_t LSDA = *((intptr_t *)P);
|
||||
intptr_t NewLSDA = LSDA - DeltaForEH;
|
||||
*((intptr_t*)P) = NewLSDA;
|
||||
*((intptr_t *)P) = NewLSDA;
|
||||
}
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
static intptr_t computeDelta(SectionEntry *A, SectionEntry *B) {
|
||||
intptr_t ObjDistance = A->ObjAddress - B->ObjAddress;
|
||||
intptr_t ObjDistance = A->ObjAddress - B->ObjAddress;
|
||||
intptr_t MemDistance = A->LoadAddress - B->LoadAddress;
|
||||
return ObjDistance - MemDistance;
|
||||
}
|
||||
@ -76,12 +77,11 @@ void RuntimeDyldMachO::registerEHFrames() {
|
||||
|
||||
unsigned char *P = EHFrame->Address;
|
||||
unsigned char *End = P + EHFrame->Size;
|
||||
do {
|
||||
do {
|
||||
P = processFDE(P, DeltaForText, DeltaForEH);
|
||||
} while(P != End);
|
||||
} while (P != End);
|
||||
|
||||
MemMgr->registerEHFrames(EHFrame->Address,
|
||||
EHFrame->LoadAddress,
|
||||
MemMgr->registerEHFrames(EHFrame->Address, EHFrame->LoadAddress,
|
||||
EHFrame->Size);
|
||||
}
|
||||
UnregisteredEHFrameSections.clear();
|
||||
@ -103,9 +103,8 @@ void RuntimeDyldMachO::finalizeLoad(ObjSectionToIDMap &SectionMap) {
|
||||
else if (Name == "__gcc_except_tab")
|
||||
ExceptTabSID = i->second;
|
||||
}
|
||||
UnregisteredEHFrameSections.push_back(EHFrameRelatedSections(EHFrameSID,
|
||||
TextSID,
|
||||
ExceptTabSID));
|
||||
UnregisteredEHFrameSections.push_back(
|
||||
EHFrameRelatedSections(EHFrameSID, TextSID, ExceptTabSID));
|
||||
}
|
||||
|
||||
// The target location for the relocation is described by RE.SectionID and
|
||||
@ -136,67 +135,45 @@ void RuntimeDyldMachO::resolveRelocation(const RelocationEntry &RE,
|
||||
}
|
||||
|
||||
void RuntimeDyldMachO::resolveRelocation(const SectionEntry &Section,
|
||||
uint64_t Offset,
|
||||
uint64_t Value,
|
||||
uint32_t Type,
|
||||
int64_t Addend,
|
||||
bool isPCRel,
|
||||
unsigned LogSize) {
|
||||
uint64_t Offset, uint64_t Value,
|
||||
uint32_t Type, int64_t Addend,
|
||||
bool isPCRel, unsigned LogSize) {
|
||||
uint8_t *LocalAddress = Section.Address + Offset;
|
||||
uint64_t FinalAddress = Section.LoadAddress + Offset;
|
||||
unsigned MachoType = Type;
|
||||
unsigned Size = 1 << LogSize;
|
||||
|
||||
DEBUG(dbgs() << "resolveRelocation LocalAddress: "
|
||||
<< format("%p", LocalAddress)
|
||||
<< " FinalAddress: " << format("%p", FinalAddress)
|
||||
<< " Value: " << format("%p", Value)
|
||||
<< " Addend: " << Addend
|
||||
<< " isPCRel: " << isPCRel
|
||||
<< " MachoType: " << MachoType
|
||||
<< " Size: " << Size
|
||||
<< "\n");
|
||||
<< format("%p", LocalAddress)
|
||||
<< " FinalAddress: " << format("%p", FinalAddress)
|
||||
<< " Value: " << format("%p", Value) << " Addend: " << Addend
|
||||
<< " isPCRel: " << isPCRel << " MachoType: " << MachoType
|
||||
<< " Size: " << Size << "\n");
|
||||
|
||||
// This just dispatches to the proper target specific routine.
|
||||
switch (Arch) {
|
||||
default: llvm_unreachable("Unsupported CPU type!");
|
||||
default:
|
||||
llvm_unreachable("Unsupported CPU type!");
|
||||
case Triple::x86_64:
|
||||
resolveX86_64Relocation(LocalAddress,
|
||||
FinalAddress,
|
||||
(uintptr_t)Value,
|
||||
isPCRel,
|
||||
MachoType,
|
||||
Size,
|
||||
Addend);
|
||||
resolveX86_64Relocation(LocalAddress, FinalAddress, (uintptr_t)Value,
|
||||
isPCRel, MachoType, Size, Addend);
|
||||
break;
|
||||
case Triple::x86:
|
||||
resolveI386Relocation(LocalAddress,
|
||||
FinalAddress,
|
||||
(uintptr_t)Value,
|
||||
isPCRel,
|
||||
MachoType,
|
||||
Size,
|
||||
Addend);
|
||||
resolveI386Relocation(LocalAddress, FinalAddress, (uintptr_t)Value, isPCRel,
|
||||
MachoType, Size, Addend);
|
||||
break;
|
||||
case Triple::arm: // Fall through.
|
||||
case Triple::arm: // Fall through.
|
||||
case Triple::thumb:
|
||||
resolveARMRelocation(LocalAddress,
|
||||
FinalAddress,
|
||||
(uintptr_t)Value,
|
||||
isPCRel,
|
||||
MachoType,
|
||||
Size,
|
||||
Addend);
|
||||
resolveARMRelocation(LocalAddress, FinalAddress, (uintptr_t)Value, isPCRel,
|
||||
MachoType, Size, Addend);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool RuntimeDyldMachO::resolveI386Relocation(uint8_t *LocalAddress,
|
||||
uint64_t FinalAddress,
|
||||
uint64_t Value,
|
||||
bool isPCRel,
|
||||
unsigned Type,
|
||||
unsigned Size,
|
||||
uint64_t Value, bool isPCRel,
|
||||
unsigned Type, unsigned Size,
|
||||
int64_t Addend) {
|
||||
if (isPCRel)
|
||||
Value -= FinalAddress + 4; // see resolveX86_64Relocation
|
||||
@ -222,10 +199,8 @@ bool RuntimeDyldMachO::resolveI386Relocation(uint8_t *LocalAddress,
|
||||
|
||||
bool RuntimeDyldMachO::resolveX86_64Relocation(uint8_t *LocalAddress,
|
||||
uint64_t FinalAddress,
|
||||
uint64_t Value,
|
||||
bool isPCRel,
|
||||
unsigned Type,
|
||||
unsigned Size,
|
||||
uint64_t Value, bool isPCRel,
|
||||
unsigned Type, unsigned Size,
|
||||
int64_t Addend) {
|
||||
// If the relocation is PC-relative, the value to be encoded is the
|
||||
// pointer difference.
|
||||
@ -234,7 +209,7 @@ bool RuntimeDyldMachO::resolveX86_64Relocation(uint8_t *LocalAddress,
|
||||
// address. Is that expected? Only for branches, perhaps?
|
||||
Value -= FinalAddress + 4;
|
||||
|
||||
switch(Type) {
|
||||
switch (Type) {
|
||||
default:
|
||||
llvm_unreachable("Invalid relocation type!");
|
||||
case MachO::X86_64_RELOC_SIGNED_1:
|
||||
@ -246,7 +221,7 @@ bool RuntimeDyldMachO::resolveX86_64Relocation(uint8_t *LocalAddress,
|
||||
Value += Addend;
|
||||
// Mask in the target value a byte at a time (we don't have an alignment
|
||||
// guarantee for the target address, so this is safest).
|
||||
uint8_t *p = (uint8_t*)LocalAddress;
|
||||
uint8_t *p = (uint8_t *)LocalAddress;
|
||||
for (unsigned i = 0; i < Size; ++i) {
|
||||
*p++ = (uint8_t)Value;
|
||||
Value >>= 8;
|
||||
@ -263,10 +238,8 @@ bool RuntimeDyldMachO::resolveX86_64Relocation(uint8_t *LocalAddress,
|
||||
|
||||
bool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress,
|
||||
uint64_t FinalAddress,
|
||||
uint64_t Value,
|
||||
bool isPCRel,
|
||||
unsigned Type,
|
||||
unsigned Size,
|
||||
uint64_t Value, bool isPCRel,
|
||||
unsigned Type, unsigned Size,
|
||||
int64_t Addend) {
|
||||
// If the relocation is PC-relative, the value to be encoded is the
|
||||
// pointer difference.
|
||||
@ -278,13 +251,13 @@ bool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress,
|
||||
Value -= 8;
|
||||
}
|
||||
|
||||
switch(Type) {
|
||||
switch (Type) {
|
||||
default:
|
||||
llvm_unreachable("Invalid relocation type!");
|
||||
case MachO::ARM_RELOC_VANILLA: {
|
||||
// Mask in the target value a byte at a time (we don't have an alignment
|
||||
// guarantee for the target address, so this is safest).
|
||||
uint8_t *p = (uint8_t*)LocalAddress;
|
||||
uint8_t *p = (uint8_t *)LocalAddress;
|
||||
for (unsigned i = 0; i < Size; ++i) {
|
||||
*p++ = (uint8_t)Value;
|
||||
Value >>= 8;
|
||||
@ -294,7 +267,7 @@ bool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress,
|
||||
case MachO::ARM_RELOC_BR24: {
|
||||
// Mask the value into the target address. We know instructions are
|
||||
// 32-bit aligned, so we can do it all at once.
|
||||
uint32_t *p = (uint32_t*)LocalAddress;
|
||||
uint32_t *p = (uint32_t *)LocalAddress;
|
||||
// The low two bits of the value are not encoded.
|
||||
Value >>= 2;
|
||||
// Mask the value to 24 bits.
|
||||
@ -320,17 +293,14 @@ bool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress,
|
||||
return false;
|
||||
}
|
||||
|
||||
relocation_iterator
|
||||
RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
|
||||
relocation_iterator RelI,
|
||||
ObjectImage &Obj,
|
||||
ObjSectionToIDMap &ObjSectionToID,
|
||||
const SymbolTableMap &Symbols,
|
||||
StubMap &Stubs) {
|
||||
relocation_iterator RuntimeDyldMachO::processRelocationRef(
|
||||
unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj,
|
||||
ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols,
|
||||
StubMap &Stubs) {
|
||||
const ObjectFile *OF = Obj.getObjectFile();
|
||||
const MachOObjectFile *MachO = static_cast<const MachOObjectFile*>(OF);
|
||||
const MachOObjectFile *MachO = static_cast<const MachOObjectFile *>(OF);
|
||||
MachO::any_relocation_info RE =
|
||||
MachO->getRelocation(RelI->getRawDataRefImpl());
|
||||
MachO->getRelocation(RelI->getRawDataRefImpl());
|
||||
|
||||
uint32_t RelType = MachO->getAnyRelocationType(RE);
|
||||
|
||||
@ -368,7 +338,8 @@ RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
|
||||
Value.Addend = lsi->second.second + Addend;
|
||||
} else {
|
||||
// Search for the symbol in the global symbol table
|
||||
SymbolTableMap::const_iterator gsi = GlobalSymbolTable.find(TargetName.data());
|
||||
SymbolTableMap::const_iterator gsi =
|
||||
GlobalSymbolTable.find(TargetName.data());
|
||||
if (gsi != GlobalSymbolTable.end()) {
|
||||
Value.SectionID = gsi->second.first;
|
||||
Value.Addend = gsi->second.second + Addend;
|
||||
@ -411,21 +382,19 @@ RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
|
||||
}
|
||||
resolveRelocation(Section, Offset, (uint64_t)Addr,
|
||||
MachO::X86_64_RELOC_UNSIGNED, Value.Addend, true, 2);
|
||||
} else if (Arch == Triple::arm &&
|
||||
(RelType & 0xf) == MachO::ARM_RELOC_BR24) {
|
||||
} else if (Arch == Triple::arm && (RelType & 0xf) == MachO::ARM_RELOC_BR24) {
|
||||
// This is an ARM branch relocation, need to use a stub function.
|
||||
|
||||
// Look up for existing stub.
|
||||
StubMap::const_iterator i = Stubs.find(Value);
|
||||
if (i != Stubs.end())
|
||||
resolveRelocation(Section, Offset,
|
||||
(uint64_t)Section.Address + i->second,
|
||||
resolveRelocation(Section, Offset, (uint64_t)Section.Address + i->second,
|
||||
RelType, 0, IsPCRel, Size);
|
||||
else {
|
||||
// Create a new stub function.
|
||||
Stubs[Value] = Section.StubOffset;
|
||||
uint8_t *StubTargetAddr = createStubFunction(Section.Address +
|
||||
Section.StubOffset);
|
||||
uint8_t *StubTargetAddr =
|
||||
createStubFunction(Section.Address + Section.StubOffset);
|
||||
RelocationEntry RE(SectionID, StubTargetAddr - Section.Address,
|
||||
MachO::GENERIC_RELOC_VANILLA, Value.Addend);
|
||||
if (Value.SymbolName)
|
||||
@ -433,13 +402,12 @@ RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
|
||||
else
|
||||
addRelocationForSection(RE, Value.SectionID);
|
||||
resolveRelocation(Section, Offset,
|
||||
(uint64_t)Section.Address + Section.StubOffset,
|
||||
RelType, 0, IsPCRel, Size);
|
||||
(uint64_t)Section.Address + Section.StubOffset, RelType,
|
||||
0, IsPCRel, Size);
|
||||
Section.StubOffset += getMaxStubSize();
|
||||
}
|
||||
} else {
|
||||
RelocationEntry RE(SectionID, Offset, RelType, Value.Addend,
|
||||
IsPCRel, Size);
|
||||
RelocationEntry RE(SectionID, Offset, RelType, Value.Addend, IsPCRel, Size);
|
||||
if (Value.SymbolName)
|
||||
addRelocationForSymbol(RE, Value.SymbolName);
|
||||
else
|
||||
@ -448,21 +416,23 @@ RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
|
||||
return ++RelI;
|
||||
}
|
||||
|
||||
|
||||
bool RuntimeDyldMachO::isCompatibleFormat(
|
||||
const ObjectBuffer *InputBuffer) const {
|
||||
bool
|
||||
RuntimeDyldMachO::isCompatibleFormat(const ObjectBuffer *InputBuffer) const {
|
||||
if (InputBuffer->getBufferSize() < 4)
|
||||
return false;
|
||||
StringRef Magic(InputBuffer->getBufferStart(), 4);
|
||||
if (Magic == "\xFE\xED\xFA\xCE") return true;
|
||||
if (Magic == "\xCE\xFA\xED\xFE") return true;
|
||||
if (Magic == "\xFE\xED\xFA\xCF") return true;
|
||||
if (Magic == "\xCF\xFA\xED\xFE") return true;
|
||||
if (Magic == "\xFE\xED\xFA\xCE")
|
||||
return true;
|
||||
if (Magic == "\xCE\xFA\xED\xFE")
|
||||
return true;
|
||||
if (Magic == "\xFE\xED\xFA\xCF")
|
||||
return true;
|
||||
if (Magic == "\xCF\xFA\xED\xFE")
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RuntimeDyldMachO::isCompatibleFile(
|
||||
const object::ObjectFile *Obj) const {
|
||||
bool RuntimeDyldMachO::isCompatibleFile(const object::ObjectFile *Obj) const {
|
||||
return Obj->isMachO();
|
||||
}
|
||||
|
||||
|
@ -23,38 +23,21 @@
|
||||
using namespace llvm;
|
||||
using namespace llvm::object;
|
||||
|
||||
|
||||
namespace llvm {
|
||||
class RuntimeDyldMachO : public RuntimeDyldImpl {
|
||||
bool resolveI386Relocation(uint8_t *LocalAddress,
|
||||
uint64_t FinalAddress,
|
||||
uint64_t Value,
|
||||
bool isPCRel,
|
||||
unsigned Type,
|
||||
unsigned Size,
|
||||
int64_t Addend);
|
||||
bool resolveX86_64Relocation(uint8_t *LocalAddress,
|
||||
uint64_t FinalAddress,
|
||||
uint64_t Value,
|
||||
bool isPCRel,
|
||||
unsigned Type,
|
||||
unsigned Size,
|
||||
int64_t Addend);
|
||||
bool resolveARMRelocation(uint8_t *LocalAddress,
|
||||
uint64_t FinalAddress,
|
||||
uint64_t Value,
|
||||
bool isPCRel,
|
||||
unsigned Type,
|
||||
unsigned Size,
|
||||
int64_t Addend);
|
||||
bool resolveI386Relocation(uint8_t *LocalAddress, uint64_t FinalAddress,
|
||||
uint64_t Value, bool isPCRel, unsigned Type,
|
||||
unsigned Size, int64_t Addend);
|
||||
bool resolveX86_64Relocation(uint8_t *LocalAddress, uint64_t FinalAddress,
|
||||
uint64_t Value, bool isPCRel, unsigned Type,
|
||||
unsigned Size, int64_t Addend);
|
||||
bool resolveARMRelocation(uint8_t *LocalAddress, uint64_t FinalAddress,
|
||||
uint64_t Value, bool isPCRel, unsigned Type,
|
||||
unsigned Size, int64_t Addend);
|
||||
|
||||
void resolveRelocation(const SectionEntry &Section,
|
||||
uint64_t Offset,
|
||||
uint64_t Value,
|
||||
uint32_t Type,
|
||||
int64_t Addend,
|
||||
bool isPCRel,
|
||||
unsigned Size);
|
||||
void resolveRelocation(const SectionEntry &Section, uint64_t Offset,
|
||||
uint64_t Value, uint32_t Type, int64_t Addend,
|
||||
bool isPCRel, unsigned Size);
|
||||
|
||||
unsigned getMaxStubSize() override {
|
||||
if (Arch == Triple::arm || Arch == Triple::thumb)
|
||||
@ -65,16 +48,15 @@ class RuntimeDyldMachO : public RuntimeDyldImpl {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned getStubAlignment() override {
|
||||
return 1;
|
||||
}
|
||||
unsigned getStubAlignment() override { return 1; }
|
||||
|
||||
struct EHFrameRelatedSections {
|
||||
EHFrameRelatedSections() : EHFrameSID(RTDYLD_INVALID_SECTION_ID),
|
||||
TextSID(RTDYLD_INVALID_SECTION_ID),
|
||||
ExceptTabSID(RTDYLD_INVALID_SECTION_ID) {}
|
||||
EHFrameRelatedSections()
|
||||
: EHFrameSID(RTDYLD_INVALID_SECTION_ID),
|
||||
TextSID(RTDYLD_INVALID_SECTION_ID),
|
||||
ExceptTabSID(RTDYLD_INVALID_SECTION_ID) {}
|
||||
EHFrameRelatedSections(SID EH, SID T, SID Ex)
|
||||
: EHFrameSID(EH), TextSID(T), ExceptTabSID(Ex) {}
|
||||
: EHFrameSID(EH), TextSID(T), ExceptTabSID(Ex) {}
|
||||
SID EHFrameSID;
|
||||
SID TextSID;
|
||||
SID ExceptTabSID;
|
||||
@ -84,6 +66,7 @@ class RuntimeDyldMachO : public RuntimeDyldImpl {
|
||||
// in a table until we receive a request to register all unregistered
|
||||
// EH frame sections with the memory manager.
|
||||
SmallVector<EHFrameRelatedSections, 2> UnregisteredEHFrameSections;
|
||||
|
||||
public:
|
||||
RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
|
||||
|
||||
@ -97,12 +80,12 @@ public:
|
||||
void registerEHFrames() override;
|
||||
void finalizeLoad(ObjSectionToIDMap &SectionMap) override;
|
||||
|
||||
|
||||
static ObjectImage *createObjectImage(ObjectBuffer *InputBuffer) {
|
||||
return new ObjectImageCommon(InputBuffer);
|
||||
}
|
||||
|
||||
static ObjectImage *createObjectImageFromFile(object::ObjectFile *InputObject) {
|
||||
static ObjectImage *
|
||||
createObjectImageFromFile(object::ObjectFile *InputObject) {
|
||||
return new ObjectImageCommon(InputObject);
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user