[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>

llvm-svn: 204439
This commit is contained in:
Juergen Ributzka 2014-03-21 07:26:41 +00:00
parent 997a923eeb
commit 046709f06b
13 changed files with 90 additions and 46 deletions

View File

@ -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,

View File

@ -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 {

View File

@ -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,

View File

@ -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);
}

View File

@ -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.

View File

@ -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.

View File

@ -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) {

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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;

View File

@ -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(

View File

@ -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);