mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-27 06:35:30 +00:00
[RuntimeDyld] Allow processRelocationRef to process more than one relocation entry at a time.
Some targets require more than one relocation entry to perform a relocation. This change allows processRelocationRef to process more than one relocation entry at a time by passing the relocation iterator itself instead of just the relocation entry. Related to <rdar://problem/16199095> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204439 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fc029f2983
commit
4923eea4f6
@ -390,6 +390,7 @@ protected:
|
||||
bool &Result) const override;
|
||||
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
|
||||
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
|
||||
bool section_rel_empty(DataRefImpl Sec) const override;
|
||||
|
||||
void moveRelocationNext(DataRefImpl &Rel) const override;
|
||||
error_code getRelocationAddress(DataRefImpl Rel,
|
||||
|
@ -91,6 +91,7 @@ protected:
|
||||
bool &Result) const override;
|
||||
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
|
||||
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
|
||||
bool section_rel_empty(DataRefImpl Sec) const override;
|
||||
section_iterator getRelocatedSection(DataRefImpl Sec) const override;
|
||||
|
||||
void moveRelocationNext(DataRefImpl &Rel) const override;
|
||||
@ -557,6 +558,12 @@ ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
|
||||
return relocation_iterator(RelocationRef(RelData, this));
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
bool ELFObjectFile<ELFT>::section_rel_empty(DataRefImpl Sec) const {
|
||||
const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p);
|
||||
return S->sh_size == 0;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
section_iterator
|
||||
ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
|
||||
|
@ -91,6 +91,7 @@ public:
|
||||
bool &Result) const override;
|
||||
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
|
||||
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
|
||||
bool section_rel_empty(DataRefImpl Sec) const override;
|
||||
|
||||
void moveRelocationNext(DataRefImpl &Rel) const override;
|
||||
error_code getRelocationAddress(DataRefImpl Rel,
|
||||
|
@ -87,6 +87,7 @@ public:
|
||||
SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
|
||||
|
||||
bool operator==(const SectionRef &Other) const;
|
||||
bool operator!=(const SectionRef &Other) const;
|
||||
bool operator<(const SectionRef &Other) const;
|
||||
|
||||
void moveNext();
|
||||
@ -116,6 +117,7 @@ public:
|
||||
relocation_iterator_range relocations() const {
|
||||
return relocation_iterator_range(relocation_begin(), relocation_end());
|
||||
}
|
||||
bool relocation_empty() const;
|
||||
section_iterator getRelocatedSection() const;
|
||||
|
||||
DataRefImpl getRawDataRefImpl() const;
|
||||
@ -259,6 +261,7 @@ protected:
|
||||
bool &Result) const = 0;
|
||||
virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
|
||||
virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
|
||||
virtual bool section_rel_empty(DataRefImpl Sec) const = 0;
|
||||
virtual section_iterator getRelocatedSection(DataRefImpl Sec) const;
|
||||
|
||||
// Same as above for RelocationRef.
|
||||
@ -392,6 +395,10 @@ inline bool SectionRef::operator==(const SectionRef &Other) const {
|
||||
return SectionPimpl == Other.SectionPimpl;
|
||||
}
|
||||
|
||||
inline bool SectionRef::operator!=(const SectionRef &Other) const {
|
||||
return SectionPimpl != Other.SectionPimpl;
|
||||
}
|
||||
|
||||
inline bool SectionRef::operator<(const SectionRef &Other) const {
|
||||
return SectionPimpl < Other.SectionPimpl;
|
||||
}
|
||||
@ -461,6 +468,10 @@ inline relocation_iterator SectionRef::relocation_end() const {
|
||||
return OwningObject->section_rel_end(SectionPimpl);
|
||||
}
|
||||
|
||||
inline bool SectionRef::relocation_empty() const {
|
||||
return OwningObject->section_rel_empty(SectionPimpl);
|
||||
}
|
||||
|
||||
inline section_iterator SectionRef::getRelocatedSection() const {
|
||||
return OwningObject->getRelocatedSection(SectionPimpl);
|
||||
}
|
||||
|
@ -35,6 +35,10 @@ inline bool operator==(const DataRefImpl &a, const DataRefImpl &b) {
|
||||
return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
|
||||
}
|
||||
|
||||
inline bool operator!=(const DataRefImpl &a, const DataRefImpl &b) {
|
||||
return !operator==(a, b);
|
||||
}
|
||||
|
||||
inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
|
||||
// Check bitwise identical. This is the only legal way to compare a union w/o
|
||||
// knowing which member is in use.
|
||||
|
@ -165,18 +165,19 @@ ObjectImage* RuntimeDyldImpl::loadObject(ObjectImage *InputObject) {
|
||||
StubMap Stubs;
|
||||
section_iterator RelocatedSection = SI->getRelocatedSection();
|
||||
|
||||
if ((SI->relocation_begin() != SI->relocation_end()) ||
|
||||
ProcessAllSections) {
|
||||
bool IsCode = false;
|
||||
Check(RelocatedSection->isText(IsCode));
|
||||
SectionID =
|
||||
findOrEmitSection(*Obj, *RelocatedSection, IsCode, LocalSections);
|
||||
DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
|
||||
}
|
||||
if (SI->relocation_empty() && !ProcessAllSections)
|
||||
continue;
|
||||
|
||||
for (const RelocationRef &Reloc : SI->relocations())
|
||||
processRelocationRef(SectionID, Reloc, *Obj, LocalSections, LocalSymbols,
|
||||
Stubs);
|
||||
bool IsCode = false;
|
||||
Check(RelocatedSection->isText(IsCode));
|
||||
SectionID =
|
||||
findOrEmitSection(*Obj, *RelocatedSection, IsCode, LocalSections);
|
||||
DEBUG(dbgs() << "\tSectionID: " << SectionID << "\n");
|
||||
|
||||
for (relocation_iterator I = SI->relocation_begin(),
|
||||
E = SI->relocation_end(); I != E;)
|
||||
I = processRelocationRef(SectionID, I, *Obj, LocalSections, LocalSymbols,
|
||||
Stubs);
|
||||
}
|
||||
|
||||
// Give the subclasses a chance to tie-up any loose ends.
|
||||
|
@ -919,17 +919,18 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
|
||||
}
|
||||
}
|
||||
|
||||
void RuntimeDyldELF::processRelocationRef(unsigned SectionID,
|
||||
RelocationRef RelI,
|
||||
ObjectImage &Obj,
|
||||
ObjSectionToIDMap &ObjSectionToID,
|
||||
const SymbolTableMap &Symbols,
|
||||
StubMap &Stubs) {
|
||||
relocation_iterator
|
||||
RuntimeDyldELF::processRelocationRef(unsigned SectionID,
|
||||
relocation_iterator RelI,
|
||||
ObjectImage &Obj,
|
||||
ObjSectionToIDMap &ObjSectionToID,
|
||||
const SymbolTableMap &Symbols,
|
||||
StubMap &Stubs) {
|
||||
uint64_t RelType;
|
||||
Check(RelI.getType(RelType));
|
||||
Check(RelI->getType(RelType));
|
||||
int64_t Addend;
|
||||
Check(getELFRelocationAddend(RelI, Addend));
|
||||
symbol_iterator Symbol = RelI.getSymbol();
|
||||
Check(getELFRelocationAddend(*RelI, Addend));
|
||||
symbol_iterator Symbol = RelI->getSymbol();
|
||||
|
||||
// Obtain the symbol name which is referenced in the relocation
|
||||
StringRef TargetName;
|
||||
@ -1001,7 +1002,7 @@ void RuntimeDyldELF::processRelocationRef(unsigned SectionID,
|
||||
}
|
||||
}
|
||||
uint64_t Offset;
|
||||
Check(RelI.getOffset(Offset));
|
||||
Check(RelI->getOffset(Offset));
|
||||
|
||||
DEBUG(dbgs() << "\t\tSectionID: " << SectionID
|
||||
<< " Offset: " << Offset
|
||||
@ -1337,6 +1338,7 @@ void RuntimeDyldELF::processRelocationRef(unsigned SectionID,
|
||||
else
|
||||
addRelocationForSection(RE, Value.SectionID);
|
||||
}
|
||||
return ++RelI;
|
||||
}
|
||||
|
||||
void RuntimeDyldELF::updateGOTEntries(StringRef Name, uint64_t Addr) {
|
||||
|
@ -133,10 +133,10 @@ public:
|
||||
{}
|
||||
|
||||
void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override;
|
||||
void processRelocationRef(unsigned SectionID, RelocationRef RelI,
|
||||
ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID,
|
||||
const SymbolTableMap &Symbols,
|
||||
StubMap &Stubs) override;
|
||||
relocation_iterator
|
||||
processRelocationRef(unsigned SectionID, relocation_iterator RelI,
|
||||
ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID,
|
||||
const SymbolTableMap &Symbols, StubMap &Stubs) override;
|
||||
bool isCompatibleFormat(const ObjectBuffer *Buffer) const override;
|
||||
bool isCompatibleFile(const object::ObjectFile *Buffer) const override;
|
||||
void registerEHFrames() override;
|
||||
|
@ -300,12 +300,10 @@ protected:
|
||||
|
||||
/// \brief Parses the object file relocation and stores it to Relocations
|
||||
/// or SymbolRelocations (this depends on the object file type).
|
||||
virtual void processRelocationRef(unsigned SectionID,
|
||||
RelocationRef RelI,
|
||||
ObjectImage &Obj,
|
||||
ObjSectionToIDMap &ObjSectionToID,
|
||||
const SymbolTableMap &Symbols,
|
||||
StubMap &Stubs) = 0;
|
||||
virtual relocation_iterator
|
||||
processRelocationRef(unsigned SectionID, relocation_iterator RelI,
|
||||
ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID,
|
||||
const SymbolTableMap &Symbols, StubMap &Stubs) = 0;
|
||||
|
||||
/// \brief Resolve relocations to external symbols.
|
||||
void resolveExternalSymbols();
|
||||
@ -321,7 +319,8 @@ protected:
|
||||
uint64_t& DataSizeRW);
|
||||
|
||||
// \brief Compute the stub buffer size required for a section
|
||||
unsigned computeSectionStubBufSize(ObjectImage &Obj, const SectionRef &Section);
|
||||
unsigned computeSectionStubBufSize(ObjectImage &Obj,
|
||||
const SectionRef &Section);
|
||||
|
||||
public:
|
||||
RuntimeDyldImpl(RTDyldMemoryManager *mm)
|
||||
|
@ -320,15 +320,17 @@ bool RuntimeDyldMachO::resolveARMRelocation(uint8_t *LocalAddress,
|
||||
return false;
|
||||
}
|
||||
|
||||
void RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
|
||||
RelocationRef 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);
|
||||
MachO::any_relocation_info RE= MachO->getRelocation(RelI.getRawDataRefImpl());
|
||||
MachO::any_relocation_info RE =
|
||||
MachO->getRelocation(RelI->getRawDataRefImpl());
|
||||
|
||||
uint32_t RelType = MachO->getAnyRelocationType(RE);
|
||||
|
||||
@ -339,7 +341,7 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
|
||||
// Note: This will fail horribly where the relocations *do* need to be
|
||||
// applied, but that was already the case.
|
||||
if (MachO->isRelocationScattered(RE))
|
||||
return;
|
||||
return ++RelI;
|
||||
|
||||
RelocationValueRef Value;
|
||||
SectionEntry &Section = Sections[SectionID];
|
||||
@ -348,7 +350,7 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
|
||||
bool IsPCRel = MachO->getAnyRelocationPCRel(RE);
|
||||
unsigned Size = MachO->getAnyRelocationLength(RE);
|
||||
uint64_t Offset;
|
||||
RelI.getOffset(Offset);
|
||||
RelI->getOffset(Offset);
|
||||
uint8_t *LocalAddress = Section.Address + Offset;
|
||||
unsigned NumBytes = 1 << Size;
|
||||
uint64_t Addend = 0;
|
||||
@ -356,7 +358,7 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
|
||||
|
||||
if (isExtern) {
|
||||
// Obtain the symbol name which is referenced in the relocation
|
||||
symbol_iterator Symbol = RelI.getSymbol();
|
||||
symbol_iterator Symbol = RelI->getSymbol();
|
||||
StringRef TargetName;
|
||||
Symbol->getName(TargetName);
|
||||
// First search for the symbol in the local symbol table
|
||||
@ -443,6 +445,7 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
|
||||
else
|
||||
addRelocationForSection(RE, Value.SectionID);
|
||||
}
|
||||
return ++RelI;
|
||||
}
|
||||
|
||||
|
||||
|
@ -88,10 +88,10 @@ public:
|
||||
RuntimeDyldMachO(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
|
||||
|
||||
void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override;
|
||||
void processRelocationRef(unsigned SectionID, RelocationRef RelI,
|
||||
ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID,
|
||||
const SymbolTableMap &Symbols,
|
||||
StubMap &Stubs) override;
|
||||
relocation_iterator
|
||||
processRelocationRef(unsigned SectionID, relocation_iterator RelI,
|
||||
ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID,
|
||||
const SymbolTableMap &Symbols, StubMap &Stubs) override;
|
||||
bool isCompatibleFormat(const ObjectBuffer *Buffer) const override;
|
||||
bool isCompatibleFile(const object::ObjectFile *Obj) const override;
|
||||
void registerEHFrames() override;
|
||||
|
@ -410,6 +410,11 @@ relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const {
|
||||
return relocation_iterator(RelocationRef(Ret, this));
|
||||
}
|
||||
|
||||
bool COFFObjectFile::section_rel_empty(DataRefImpl Ref) const {
|
||||
const coff_section *Sec = toSec(Ref);
|
||||
return Sec->NumberOfRelocations == 0;
|
||||
}
|
||||
|
||||
// Initialize the pointer to the symbol table.
|
||||
error_code COFFObjectFile::initSymbolTablePtr() {
|
||||
if (error_code EC = getObject(
|
||||
|
@ -818,6 +818,16 @@ MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
|
||||
return relocation_iterator(RelocationRef(Ret, this));
|
||||
}
|
||||
|
||||
bool MachOObjectFile::section_rel_empty(DataRefImpl Sec) const {
|
||||
if (is64Bit()) {
|
||||
MachO::section_64 Sect = getSection64(Sec);
|
||||
return Sect.nreloc == 0;
|
||||
} else {
|
||||
MachO::section Sect = getSection(Sec);
|
||||
return Sect.nreloc == 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
|
||||
const MachO::any_relocation_info *P =
|
||||
reinterpret_cast<const MachO::any_relocation_info *>(Rel.p);
|
||||
|
Loading…
Reference in New Issue
Block a user