mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-25 00:24:26 +00:00
[RuntimeDyld] Add support for MachO __jump_table and __pointers sections, and
SECTDIFF relocations on 32-bit x86. This fixes several of the MCJIT regression test failures that show up on 32-bit builds. <rdar://problem/16886294> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208635 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -111,6 +111,9 @@ public:
|
|||||||
basic_symbol_iterator symbol_begin_impl() const override;
|
basic_symbol_iterator symbol_begin_impl() const override;
|
||||||
basic_symbol_iterator symbol_end_impl() const override;
|
basic_symbol_iterator symbol_end_impl() const override;
|
||||||
|
|
||||||
|
// MachO specific.
|
||||||
|
basic_symbol_iterator getSymbolByIndex(unsigned Index) const;
|
||||||
|
|
||||||
section_iterator section_begin() const override;
|
section_iterator section_begin() const override;
|
||||||
section_iterator section_end() const override;
|
section_iterator section_end() const override;
|
||||||
|
|
||||||
|
@ -144,12 +144,14 @@ ObjectImage *RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
|
|||||||
bool IsCommon = Flags & SymbolRef::SF_Common;
|
bool IsCommon = Flags & SymbolRef::SF_Common;
|
||||||
if (IsCommon) {
|
if (IsCommon) {
|
||||||
// Add the common symbols to a list. We'll allocate them all below.
|
// Add the common symbols to a list. We'll allocate them all below.
|
||||||
uint32_t Align;
|
if (!GlobalSymbolTable.count(Name)) {
|
||||||
Check(I->getAlignment(Align));
|
uint32_t Align;
|
||||||
uint64_t Size = 0;
|
Check(I->getAlignment(Align));
|
||||||
Check(I->getSize(Size));
|
uint64_t Size = 0;
|
||||||
CommonSize += Size + Align;
|
Check(I->getSize(Size));
|
||||||
CommonSymbols[*I] = CommonSymbolInfo(Size, Align);
|
CommonSize += Size + Align;
|
||||||
|
CommonSymbols[*I] = CommonSymbolInfo(Size, Align);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (SymType == object::SymbolRef::ST_Function ||
|
if (SymType == object::SymbolRef::ST_Function ||
|
||||||
SymType == object::SymbolRef::ST_Data ||
|
SymType == object::SymbolRef::ST_Data ||
|
||||||
@ -177,7 +179,7 @@ ObjectImage *RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
|
|||||||
|
|
||||||
// Allocate common symbols
|
// Allocate common symbols
|
||||||
if (CommonSize != 0)
|
if (CommonSize != 0)
|
||||||
emitCommonSymbols(*Obj, CommonSymbols, CommonSize, LocalSymbols);
|
emitCommonSymbols(*Obj, CommonSymbols, CommonSize, GlobalSymbolTable);
|
||||||
|
|
||||||
// Parse and process relocations
|
// Parse and process relocations
|
||||||
DEBUG(dbgs() << "Parse relocations:\n");
|
DEBUG(dbgs() << "Parse relocations:\n");
|
||||||
@ -205,7 +207,7 @@ ObjectImage *RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Give the subclasses a chance to tie-up any loose ends.
|
// Give the subclasses a chance to tie-up any loose ends.
|
||||||
finalizeLoad(LocalSections);
|
finalizeLoad(*Obj, LocalSections);
|
||||||
|
|
||||||
return Obj.release();
|
return Obj.release();
|
||||||
}
|
}
|
||||||
@ -587,6 +589,8 @@ uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr) {
|
|||||||
*Addr = 0xFF; // jmp
|
*Addr = 0xFF; // jmp
|
||||||
*(Addr+1) = 0x25; // rip
|
*(Addr+1) = 0x25; // rip
|
||||||
// 32-bit PC-relative address of the GOT entry will be stored at Addr+2
|
// 32-bit PC-relative address of the GOT entry will be stored at Addr+2
|
||||||
|
} else if (Arch == Triple::x86) {
|
||||||
|
*Addr = 0xE9; // 32-bit pc-relative jump.
|
||||||
}
|
}
|
||||||
return Addr;
|
return Addr;
|
||||||
}
|
}
|
||||||
|
@ -1397,7 +1397,8 @@ uint64_t RuntimeDyldELF::findGOTEntry(uint64_t LoadAddress, uint64_t Offset) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RuntimeDyldELF::finalizeLoad(ObjSectionToIDMap &SectionMap) {
|
void RuntimeDyldELF::finalizeLoad(ObjectImage &ObjImg,
|
||||||
|
ObjSectionToIDMap &SectionMap) {
|
||||||
// If necessary, allocate the global offset table
|
// If necessary, allocate the global offset table
|
||||||
if (MemMgr) {
|
if (MemMgr) {
|
||||||
// Allocate the GOT if necessary
|
// Allocate the GOT if necessary
|
||||||
|
@ -116,7 +116,8 @@ public:
|
|||||||
bool isCompatibleFile(const object::ObjectFile *Buffer) const override;
|
bool isCompatibleFile(const object::ObjectFile *Buffer) const override;
|
||||||
void registerEHFrames() override;
|
void registerEHFrames() override;
|
||||||
void deregisterEHFrames() override;
|
void deregisterEHFrames() override;
|
||||||
void finalizeLoad(ObjSectionToIDMap &SectionMap) override;
|
void finalizeLoad(ObjectImage &ObjImg,
|
||||||
|
ObjSectionToIDMap &SectionMap) override;
|
||||||
virtual ~RuntimeDyldELF();
|
virtual ~RuntimeDyldELF();
|
||||||
|
|
||||||
static ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);
|
static ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);
|
||||||
|
@ -90,9 +90,17 @@ public:
|
|||||||
/// used to make a relocation section relative instead of symbol relative.
|
/// used to make a relocation section relative instead of symbol relative.
|
||||||
int64_t Addend;
|
int64_t Addend;
|
||||||
|
|
||||||
|
struct SectionPair {
|
||||||
|
uint32_t SectionA;
|
||||||
|
uint32_t SectionB;
|
||||||
|
};
|
||||||
|
|
||||||
/// SymOffset - Section offset of the relocation entry's symbol (used for GOT
|
/// SymOffset - Section offset of the relocation entry's symbol (used for GOT
|
||||||
/// lookup).
|
/// lookup).
|
||||||
uint64_t SymOffset;
|
union {
|
||||||
|
uint64_t SymOffset;
|
||||||
|
SectionPair Sections;
|
||||||
|
};
|
||||||
|
|
||||||
/// True if this is a PCRel relocation (MachO specific).
|
/// True if this is a PCRel relocation (MachO specific).
|
||||||
bool IsPCRel;
|
bool IsPCRel;
|
||||||
@ -113,6 +121,16 @@ public:
|
|||||||
bool IsPCRel, unsigned Size)
|
bool IsPCRel, unsigned Size)
|
||||||
: SectionID(id), Offset(offset), RelType(type), Addend(addend),
|
: SectionID(id), Offset(offset), RelType(type), Addend(addend),
|
||||||
SymOffset(0), IsPCRel(IsPCRel), Size(Size) {}
|
SymOffset(0), IsPCRel(IsPCRel), Size(Size) {}
|
||||||
|
|
||||||
|
RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend,
|
||||||
|
unsigned SectionA, uint64_t SectionAOffset, unsigned SectionB,
|
||||||
|
uint64_t SectionBOffset, bool IsPCRel, unsigned Size)
|
||||||
|
: SectionID(id), Offset(offset), RelType(type),
|
||||||
|
Addend(SectionAOffset - SectionBOffset + addend), IsPCRel(IsPCRel),
|
||||||
|
Size(Size) {
|
||||||
|
Sections.SectionA = SectionA;
|
||||||
|
Sections.SectionB = SectionB;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class RelocationValueRef {
|
class RelocationValueRef {
|
||||||
@ -373,7 +391,7 @@ public:
|
|||||||
|
|
||||||
virtual void deregisterEHFrames();
|
virtual void deregisterEHFrames();
|
||||||
|
|
||||||
virtual void finalizeLoad(ObjSectionToIDMap &SectionMap) {}
|
virtual void finalizeLoad(ObjectImage &ObjImg, ObjSectionToIDMap &SectionMap) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
@ -23,6 +23,8 @@ namespace llvm {
|
|||||||
|
|
||||||
static unsigned char *processFDE(unsigned char *P, intptr_t DeltaForText,
|
static unsigned char *processFDE(unsigned char *P, intptr_t DeltaForText,
|
||||||
intptr_t DeltaForEH) {
|
intptr_t DeltaForEH) {
|
||||||
|
DEBUG(dbgs() << "Processing FDE: Delta for text: " << DeltaForText
|
||||||
|
<< ", Delta for EH: " << DeltaForEH << "\n");
|
||||||
uint32_t Length = *((uint32_t *)P);
|
uint32_t Length = *((uint32_t *)P);
|
||||||
P += 4;
|
P += 4;
|
||||||
unsigned char *Ret = P + Length;
|
unsigned char *Ret = P + Length;
|
||||||
@ -88,7 +90,8 @@ void RuntimeDyldMachO::registerEHFrames() {
|
|||||||
UnregisteredEHFrameSections.clear();
|
UnregisteredEHFrameSections.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RuntimeDyldMachO::finalizeLoad(ObjSectionToIDMap &SectionMap) {
|
void RuntimeDyldMachO::finalizeLoad(ObjectImage &ObjImg,
|
||||||
|
ObjSectionToIDMap &SectionMap) {
|
||||||
unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID;
|
unsigned EHFrameSID = RTDYLD_INVALID_SECTION_ID;
|
||||||
unsigned TextSID = RTDYLD_INVALID_SECTION_ID;
|
unsigned TextSID = RTDYLD_INVALID_SECTION_ID;
|
||||||
unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID;
|
unsigned ExceptTabSID = RTDYLD_INVALID_SECTION_ID;
|
||||||
@ -103,6 +106,12 @@ void RuntimeDyldMachO::finalizeLoad(ObjSectionToIDMap &SectionMap) {
|
|||||||
TextSID = i->second;
|
TextSID = i->second;
|
||||||
else if (Name == "__gcc_except_tab")
|
else if (Name == "__gcc_except_tab")
|
||||||
ExceptTabSID = i->second;
|
ExceptTabSID = i->second;
|
||||||
|
else if (Name == "__jump_table")
|
||||||
|
populateJumpTable(cast<MachOObjectFile>(*ObjImg.getObjectFile()),
|
||||||
|
Section, i->second);
|
||||||
|
else if (Name == "__pointers")
|
||||||
|
populatePointersSection(cast<MachOObjectFile>(*ObjImg.getObjectFile()),
|
||||||
|
Section, i->second);
|
||||||
}
|
}
|
||||||
UnregisteredEHFrameSections.push_back(
|
UnregisteredEHFrameSections.push_back(
|
||||||
EHFrameRelatedSections(EHFrameSID, TextSID, ExceptTabSID));
|
EHFrameRelatedSections(EHFrameSID, TextSID, ExceptTabSID));
|
||||||
@ -182,7 +191,14 @@ bool RuntimeDyldMachO::resolveI386Relocation(const RelocationEntry &RE,
|
|||||||
return applyRelocationValue(LocalAddress, Value + RE.Addend,
|
return applyRelocationValue(LocalAddress, Value + RE.Addend,
|
||||||
1 << RE.Size);
|
1 << RE.Size);
|
||||||
case MachO::GENERIC_RELOC_SECTDIFF:
|
case MachO::GENERIC_RELOC_SECTDIFF:
|
||||||
case MachO::GENERIC_RELOC_LOCAL_SECTDIFF:
|
case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
|
||||||
|
uint64_t SectionABase = Sections[RE.Sections.SectionA].LoadAddress;
|
||||||
|
uint64_t SectionBBase = Sections[RE.Sections.SectionB].LoadAddress;
|
||||||
|
assert((Value == SectionABase || Value == SectionBBase) &&
|
||||||
|
"Unexpected SECTDIFF relocation value.");
|
||||||
|
Value = SectionABase - SectionBBase + RE.Addend;
|
||||||
|
return applyRelocationValue(LocalAddress, Value, 1 << RE.Size);
|
||||||
|
}
|
||||||
case MachO::GENERIC_RELOC_PB_LA_PTR:
|
case MachO::GENERIC_RELOC_PB_LA_PTR:
|
||||||
return Error("Relocation type not implemented yet!");
|
return Error("Relocation type not implemented yet!");
|
||||||
}
|
}
|
||||||
@ -319,6 +335,157 @@ bool RuntimeDyldMachO::resolveARM64Relocation(const RelocationEntry &RE,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RuntimeDyldMachO::populateJumpTable(MachOObjectFile &Obj,
|
||||||
|
const SectionRef &JTSection,
|
||||||
|
unsigned JTSectionID) {
|
||||||
|
assert(!Obj.is64Bit() &&
|
||||||
|
"__jump_table section not supported in 64-bit MachO.");
|
||||||
|
|
||||||
|
MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand();
|
||||||
|
MachO::section Sec32 = Obj.getSection(JTSection.getRawDataRefImpl());
|
||||||
|
uint32_t JTSectionSize = Sec32.size;
|
||||||
|
unsigned FirstIndirectSymbol = Sec32.reserved1;
|
||||||
|
unsigned JTEntrySize = Sec32.reserved2;
|
||||||
|
unsigned NumJTEntries = JTSectionSize / JTEntrySize;
|
||||||
|
uint8_t* JTSectionAddr = getSectionAddress(JTSectionID);
|
||||||
|
unsigned JTEntryOffset = 0;
|
||||||
|
|
||||||
|
assert((JTSectionSize % JTEntrySize) == 0 &&
|
||||||
|
"Jump-table section does not contain a whole number of stubs?");
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < NumJTEntries; ++i) {
|
||||||
|
unsigned SymbolIndex =
|
||||||
|
Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i);
|
||||||
|
symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex);
|
||||||
|
StringRef IndirectSymbolName;
|
||||||
|
SI->getName(IndirectSymbolName);
|
||||||
|
uint8_t* JTEntryAddr = JTSectionAddr + JTEntryOffset;
|
||||||
|
createStubFunction(JTEntryAddr);
|
||||||
|
RelocationEntry RE(JTSectionID, JTEntryOffset + 1,
|
||||||
|
MachO::GENERIC_RELOC_VANILLA, 0, true, 2);
|
||||||
|
addRelocationForSymbol(RE, IndirectSymbolName);
|
||||||
|
JTEntryOffset += JTEntrySize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RuntimeDyldMachO::populatePointersSection(MachOObjectFile &Obj,
|
||||||
|
const SectionRef &PTSection,
|
||||||
|
unsigned PTSectionID) {
|
||||||
|
assert(!Obj.is64Bit() &&
|
||||||
|
"__pointers section not supported in 64-bit MachO.");
|
||||||
|
|
||||||
|
MachO::dysymtab_command DySymTabCmd = Obj.getDysymtabLoadCommand();
|
||||||
|
MachO::section Sec32 = Obj.getSection(PTSection.getRawDataRefImpl());
|
||||||
|
uint32_t PTSectionSize = Sec32.size;
|
||||||
|
unsigned FirstIndirectSymbol = Sec32.reserved1;
|
||||||
|
const unsigned PTEntrySize = 4;
|
||||||
|
unsigned NumPTEntries = PTSectionSize / PTEntrySize;
|
||||||
|
unsigned PTEntryOffset = 0;
|
||||||
|
|
||||||
|
assert((PTSectionSize % PTEntrySize) == 0 &&
|
||||||
|
"Pointers section does not contain a whole number of stubs?");
|
||||||
|
|
||||||
|
DEBUG(dbgs() << "Populating __pointers, Section ID " << PTSectionID
|
||||||
|
<< ", " << NumPTEntries << " entries, "
|
||||||
|
<< PTEntrySize << " bytes each:\n");
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < NumPTEntries; ++i) {
|
||||||
|
unsigned SymbolIndex =
|
||||||
|
Obj.getIndirectSymbolTableEntry(DySymTabCmd, FirstIndirectSymbol + i);
|
||||||
|
symbol_iterator SI = Obj.getSymbolByIndex(SymbolIndex);
|
||||||
|
StringRef IndirectSymbolName;
|
||||||
|
SI->getName(IndirectSymbolName);
|
||||||
|
DEBUG(dbgs() << " " << IndirectSymbolName << ": index " << SymbolIndex
|
||||||
|
<< ", PT offset: " << PTEntryOffset << "\n");
|
||||||
|
RelocationEntry RE(PTSectionID, PTEntryOffset,
|
||||||
|
MachO::GENERIC_RELOC_VANILLA, 0, false, 2);
|
||||||
|
addRelocationForSymbol(RE, IndirectSymbolName);
|
||||||
|
PTEntryOffset += PTEntrySize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
section_iterator getSectionByAddress(const MachOObjectFile &Obj,
|
||||||
|
uint64_t Addr) {
|
||||||
|
section_iterator SI = Obj.section_begin();
|
||||||
|
section_iterator SE = Obj.section_end();
|
||||||
|
|
||||||
|
for (; SI != SE; ++SI) {
|
||||||
|
uint64_t SAddr, SSize;
|
||||||
|
SI->getAddress(SAddr);
|
||||||
|
SI->getSize(SSize);
|
||||||
|
if ((Addr >= SAddr) && (Addr < SAddr + SSize))
|
||||||
|
return SI;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SE;
|
||||||
|
}
|
||||||
|
|
||||||
|
relocation_iterator RuntimeDyldMachO::processSECTDIFFRelocation(
|
||||||
|
unsigned SectionID,
|
||||||
|
relocation_iterator RelI,
|
||||||
|
ObjectImage &Obj,
|
||||||
|
ObjSectionToIDMap &ObjSectionToID) {
|
||||||
|
const MachOObjectFile *MachO =
|
||||||
|
static_cast<const MachOObjectFile*>(Obj.getObjectFile());
|
||||||
|
MachO::any_relocation_info RE =
|
||||||
|
MachO->getRelocation(RelI->getRawDataRefImpl());
|
||||||
|
|
||||||
|
SectionEntry &Section = Sections[SectionID];
|
||||||
|
uint32_t RelocType = MachO->getAnyRelocationType(RE);
|
||||||
|
bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
|
||||||
|
unsigned Size = MachO->getAnyRelocationLength(RE);
|
||||||
|
uint64_t Offset;
|
||||||
|
RelI->getOffset(Offset);
|
||||||
|
uint8_t *LocalAddress = Section.Address + Offset;
|
||||||
|
unsigned NumBytes = 1 << Size;
|
||||||
|
int64_t Addend = 0;
|
||||||
|
memcpy(&Addend, LocalAddress, NumBytes);
|
||||||
|
|
||||||
|
++RelI;
|
||||||
|
MachO::any_relocation_info RE2 =
|
||||||
|
MachO->getRelocation(RelI->getRawDataRefImpl());
|
||||||
|
|
||||||
|
uint32_t AddrA = MachO->getScatteredRelocationValue(RE);
|
||||||
|
section_iterator SAI = getSectionByAddress(*MachO, AddrA);
|
||||||
|
assert(SAI != MachO->section_end() && "Can't find section for address A");
|
||||||
|
uint64_t SectionABase;
|
||||||
|
SAI->getAddress(SectionABase);
|
||||||
|
uint64_t SectionAOffset = AddrA - SectionABase;
|
||||||
|
SectionRef SectionA = *SAI;
|
||||||
|
bool IsCode;
|
||||||
|
SectionA.isText(IsCode);
|
||||||
|
uint32_t SectionAID = findOrEmitSection(Obj, SectionA, IsCode,
|
||||||
|
ObjSectionToID);
|
||||||
|
|
||||||
|
uint32_t AddrB = MachO->getScatteredRelocationValue(RE2);
|
||||||
|
section_iterator SBI = getSectionByAddress(*MachO, AddrB);
|
||||||
|
assert(SBI != MachO->section_end() && "Can't find seciton for address B");
|
||||||
|
uint64_t SectionBBase;
|
||||||
|
SBI->getAddress(SectionBBase);
|
||||||
|
uint64_t SectionBOffset = AddrB - SectionBBase;
|
||||||
|
SectionRef SectionB = *SBI;
|
||||||
|
uint32_t SectionBID = findOrEmitSection(Obj, SectionB, IsCode,
|
||||||
|
ObjSectionToID);
|
||||||
|
|
||||||
|
if (Addend != AddrA - AddrB)
|
||||||
|
Error("Unexpected SECTDIFF relocation addend.");
|
||||||
|
|
||||||
|
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, 0,
|
||||||
|
SectionAID, SectionAOffset, SectionBID, SectionBOffset,
|
||||||
|
IsPCRel, Size);
|
||||||
|
|
||||||
|
addRelocationForSection(R, SectionAID);
|
||||||
|
addRelocationForSection(R, SectionBID);
|
||||||
|
|
||||||
|
return RelI;
|
||||||
|
}
|
||||||
|
|
||||||
relocation_iterator RuntimeDyldMachO::processRelocationRef(
|
relocation_iterator RuntimeDyldMachO::processRelocationRef(
|
||||||
unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj,
|
unsigned SectionID, relocation_iterator RelI, ObjectImage &Obj,
|
||||||
ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols,
|
ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols,
|
||||||
@ -336,8 +503,13 @@ relocation_iterator RuntimeDyldMachO::processRelocationRef(
|
|||||||
// only needs to be reapplied if symbols move relative to one another.
|
// only needs to be reapplied if symbols move relative to one another.
|
||||||
// Note: This will fail horribly where the relocations *do* need to be
|
// Note: This will fail horribly where the relocations *do* need to be
|
||||||
// applied, but that was already the case.
|
// applied, but that was already the case.
|
||||||
if (MachO->isRelocationScattered(RE))
|
if (MachO->isRelocationScattered(RE)) {
|
||||||
|
if (RelType == MachO::GENERIC_RELOC_SECTDIFF ||
|
||||||
|
RelType == MachO::GENERIC_RELOC_LOCAL_SECTDIFF)
|
||||||
|
return processSECTDIFFRelocation(SectionID, RelI, Obj, ObjSectionToID);
|
||||||
|
|
||||||
return ++RelI;
|
return ++RelI;
|
||||||
|
}
|
||||||
|
|
||||||
RelocationValueRef Value;
|
RelocationValueRef Value;
|
||||||
SectionEntry &Section = Sections[SectionID];
|
SectionEntry &Section = Sections[SectionID];
|
||||||
|
@ -46,6 +46,14 @@ private:
|
|||||||
bool resolveARMRelocation(const RelocationEntry &RE, uint64_t Value);
|
bool resolveARMRelocation(const RelocationEntry &RE, uint64_t Value);
|
||||||
bool resolveARM64Relocation(const RelocationEntry &RE, uint64_t Value);
|
bool resolveARM64Relocation(const RelocationEntry &RE, uint64_t Value);
|
||||||
|
|
||||||
|
// Populate stubs in __jump_table section.
|
||||||
|
void populateJumpTable(MachOObjectFile &Obj, const SectionRef &JTSection,
|
||||||
|
unsigned JTSectionID);
|
||||||
|
|
||||||
|
// Populate __pointers section.
|
||||||
|
void populatePointersSection(MachOObjectFile &Obj, const SectionRef &PTSection,
|
||||||
|
unsigned PTSectionID);
|
||||||
|
|
||||||
unsigned getMaxStubSize() override {
|
unsigned getMaxStubSize() override {
|
||||||
if (Arch == Triple::arm || Arch == Triple::thumb)
|
if (Arch == Triple::arm || Arch == Triple::thumb)
|
||||||
return 8; // 32-bit instruction and 32-bit address
|
return 8; // 32-bit instruction and 32-bit address
|
||||||
@ -57,6 +65,12 @@ private:
|
|||||||
|
|
||||||
unsigned getStubAlignment() override { return 1; }
|
unsigned getStubAlignment() override { return 1; }
|
||||||
|
|
||||||
|
relocation_iterator processSECTDIFFRelocation(
|
||||||
|
unsigned SectionID,
|
||||||
|
relocation_iterator RelI,
|
||||||
|
ObjectImage &ObjImg,
|
||||||
|
ObjSectionToIDMap &ObjSectionToID);
|
||||||
|
|
||||||
struct EHFrameRelatedSections {
|
struct EHFrameRelatedSections {
|
||||||
EHFrameRelatedSections()
|
EHFrameRelatedSections()
|
||||||
: EHFrameSID(RTDYLD_INVALID_SECTION_ID),
|
: EHFrameSID(RTDYLD_INVALID_SECTION_ID),
|
||||||
@ -85,7 +99,8 @@ public:
|
|||||||
bool isCompatibleFormat(const ObjectBuffer *Buffer) const override;
|
bool isCompatibleFormat(const ObjectBuffer *Buffer) const override;
|
||||||
bool isCompatibleFile(const object::ObjectFile *Obj) const override;
|
bool isCompatibleFile(const object::ObjectFile *Obj) const override;
|
||||||
void registerEHFrames() override;
|
void registerEHFrames() override;
|
||||||
void finalizeLoad(ObjSectionToIDMap &SectionMap) override;
|
void finalizeLoad(ObjectImage &ObjImg,
|
||||||
|
ObjSectionToIDMap &SectionMap) override;
|
||||||
|
|
||||||
static ObjectImage *createObjectImage(ObjectBuffer *InputBuffer) {
|
static ObjectImage *createObjectImage(ObjectBuffer *InputBuffer) {
|
||||||
return new ObjectImageCommon(InputBuffer);
|
return new ObjectImageCommon(InputBuffer);
|
||||||
|
@ -1158,13 +1158,7 @@ error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
|
|||||||
}
|
}
|
||||||
|
|
||||||
basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
|
basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
|
||||||
DataRefImpl DRI;
|
return getSymbolByIndex(0);
|
||||||
if (!SymtabLoadCmd)
|
|
||||||
return basic_symbol_iterator(SymbolRef(DRI, this));
|
|
||||||
|
|
||||||
MachO::symtab_command Symtab = getSymtabLoadCommand();
|
|
||||||
DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
|
|
||||||
return basic_symbol_iterator(SymbolRef(DRI, this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
|
basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
|
||||||
@ -1182,6 +1176,20 @@ basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
|
|||||||
return basic_symbol_iterator(SymbolRef(DRI, this));
|
return basic_symbol_iterator(SymbolRef(DRI, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
|
||||||
|
DataRefImpl DRI;
|
||||||
|
if (!SymtabLoadCmd)
|
||||||
|
return basic_symbol_iterator(SymbolRef(DRI, this));
|
||||||
|
|
||||||
|
MachO::symtab_command Symtab = getSymtabLoadCommand();
|
||||||
|
assert(Index < Symtab.nsyms && "Requested symbol index is out of range.");
|
||||||
|
unsigned SymbolTableEntrySize =
|
||||||
|
is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
|
||||||
|
DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
|
||||||
|
DRI.p += Index * SymbolTableEntrySize;
|
||||||
|
return basic_symbol_iterator(SymbolRef(DRI, this));
|
||||||
|
}
|
||||||
|
|
||||||
section_iterator MachOObjectFile::section_begin() const {
|
section_iterator MachOObjectFile::section_begin() const {
|
||||||
DataRefImpl DRI;
|
DataRefImpl DRI;
|
||||||
return section_iterator(SectionRef(DRI, this));
|
return section_iterator(SectionRef(DRI, this));
|
||||||
|
Reference in New Issue
Block a user