Handle relocations that don't point to symbols.

In ELF (as in MachO), not all relocations point to symbols. Represent this
properly by using a symbol_iterator instead of a SymbolRef. Update llvm-readobj
ELF's dumper to handle relocatios without symbols.

llvm-svn: 183284
This commit is contained in:
Rafael Espindola 2013-06-05 01:33:53 +00:00
parent e6c0144208
commit 806f006490
19 changed files with 62 additions and 73 deletions

View File

@ -243,8 +243,7 @@ protected:
uint64_t &Res) const;
virtual error_code getRelocationOffset(DataRefImpl Rel,
uint64_t &Res) const;
virtual error_code getRelocationSymbol(DataRefImpl Rel,
SymbolRef &Res) const;
virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const;
virtual error_code getRelocationType(DataRefImpl Rel,
uint64_t &Res) const;
virtual error_code getRelocationTypeName(DataRefImpl Rel,

View File

@ -716,8 +716,7 @@ protected:
uint64_t &Res) const;
virtual error_code getRelocationOffset(DataRefImpl Rel,
uint64_t &Res) const;
virtual error_code getRelocationSymbol(DataRefImpl Rel,
SymbolRef &Res) const;
virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const;
virtual error_code getRelocationType(DataRefImpl Rel,
uint64_t &Res) const;
virtual error_code getRelocationTypeName(DataRefImpl Rel,
@ -1503,9 +1502,9 @@ error_code ELFObjectFile<ELFT>::getRelocationNext(DataRefImpl Rel,
return object_error::success;
}
template<class ELFT>
error_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel,
SymbolRef &Result) const {
template <class ELFT>
symbol_iterator
ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
uint32_t symbolIdx;
const Elf_Shdr *sec = getRelSection(Rel);
switch (sec->sh_type) {
@ -1520,6 +1519,9 @@ error_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel,
break;
}
}
if (!symbolIdx)
return end_symbols();
DataRefImpl SymbolData;
IndexMap_t::const_iterator it =
SymbolTableSectionsIndexMap.find(sec->sh_link);
@ -1527,8 +1529,7 @@ error_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel,
report_fatal_error("Relocation symbol table not found!");
SymbolData.d.a = symbolIdx;
SymbolData.d.b = it->second;
Result = SymbolRef(SymbolData, this);
return object_error::success;
return symbol_iterator(SymbolRef(SymbolData, this));
}
template<class ELFT>

View File

@ -72,7 +72,7 @@ public:
RelocationRef &Res) const;
virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const;
virtual error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const;
virtual error_code getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const;
virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const;
virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const;
virtual error_code getRelocationTypeName(DataRefImpl Rel,
SmallVectorImpl<char> &Result) const;

View File

@ -85,6 +85,7 @@ inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
}
class SymbolRef;
typedef content_iterator<SymbolRef> symbol_iterator;
/// RelocationRef - This is a value type class that represents a single
/// relocation in the list of relocations in the object file.
@ -103,7 +104,7 @@ public:
error_code getAddress(uint64_t &Result) const;
error_code getOffset(uint64_t &Result) const;
error_code getSymbol(SymbolRef &Result) const;
symbol_iterator getSymbol() const;
error_code getType(uint64_t &Result) const;
/// @brief Indicates whether this relocation should hidden when listing
@ -236,7 +237,6 @@ public:
DataRefImpl getRawDataRefImpl() const;
};
typedef content_iterator<SymbolRef> symbol_iterator;
/// LibraryRef - This is a value type class that represents a single library in
/// the list of libraries needed by a shared or dynamic object.
@ -334,8 +334,7 @@ protected:
uint64_t &Res) const =0;
virtual error_code getRelocationOffset(DataRefImpl Rel,
uint64_t &Res) const =0;
virtual error_code getRelocationSymbol(DataRefImpl Rel,
SymbolRef &Res) const = 0;
virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const = 0;
virtual error_code getRelocationType(DataRefImpl Rel,
uint64_t &Res) const = 0;
virtual error_code getRelocationTypeName(DataRefImpl Rel,
@ -566,8 +565,8 @@ inline error_code RelocationRef::getOffset(uint64_t &Result) const {
return OwningObject->getRelocationOffset(RelocationPimpl, Result);
}
inline error_code RelocationRef::getSymbol(SymbolRef &Result) const {
return OwningObject->getRelocationSymbol(RelocationPimpl, Result);
inline symbol_iterator RelocationRef::getSymbol() const {
return OwningObject->getRelocationSymbol(RelocationPimpl);
}
inline error_code RelocationRef::getType(uint64_t &Result) const {

View File

@ -595,9 +595,8 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
uint64_t SymAddr = 0;
// ELF relocations may need the symbol address
if (Obj->isELF()) {
object::SymbolRef Sym;
reloc_i->getSymbol(Sym);
Sym.getAddress(SymAddr);
object::symbol_iterator Sym = reloc_i->getSymbol();
Sym->getAddress(SymAddr);
}
object::RelocVisitor V(Obj->getFileFormatName());

View File

@ -551,9 +551,8 @@ void RuntimeDyldELF::findOPDEntrySection(ObjectImage &Obj,
continue;
}
SymbolRef TargetSymbol;
uint64_t TargetSymbolOffset;
check(i->getSymbol(TargetSymbol));
symbol_iterator TargetSymbol = i->getSymbol();
check(i->getOffset(TargetSymbolOffset));
int64_t Addend;
check(getELFRelocationAddend(*i, Addend));
@ -576,7 +575,7 @@ void RuntimeDyldELF::findOPDEntrySection(ObjectImage &Obj,
continue;
section_iterator tsi(Obj.end_sections());
check(TargetSymbol.getSection(tsi));
check(TargetSymbol->getSection(tsi));
Rel.SectionID = findOrEmitSection(Obj, (*tsi), true, LocalSections);
Rel.Addend = (intptr_t)Addend;
return;
@ -777,12 +776,11 @@ void RuntimeDyldELF::processRelocationRef(unsigned SectionID,
Check(RelI.getType(RelType));
int64_t Addend;
Check(getELFRelocationAddend(RelI, Addend));
SymbolRef Symbol;
Check(RelI.getSymbol(Symbol));
symbol_iterator Symbol = RelI.getSymbol();
// Obtain the symbol name which is referenced in the relocation
StringRef TargetName;
Symbol.getName(TargetName);
Symbol->getName(TargetName);
DEBUG(dbgs() << "\t\tRelType: " << RelType
<< " Addend: " << Addend
<< " TargetName: " << TargetName
@ -791,7 +789,7 @@ void RuntimeDyldELF::processRelocationRef(unsigned SectionID,
// First search for the symbol in the local symbol table
SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data());
SymbolRef::Type SymType;
Symbol.getType(SymType);
Symbol->getType(SymType);
if (lsi != Symbols.end()) {
Value.SectionID = lsi->second.first;
Value.Addend = lsi->second.second + Addend;
@ -809,7 +807,7 @@ void RuntimeDyldELF::processRelocationRef(unsigned SectionID,
// and can be changed by another developers. Maybe best way is add
// a new symbol type ST_Section to SymbolRef and use it.
section_iterator si(Obj.end_sections());
Symbol.getSection(si);
Symbol->getSection(si);
if (si == Obj.end_sections())
llvm_unreachable("Symbol section not found, bad object file format!");
DEBUG(dbgs() << "\t\tThis is section symbol\n");

View File

@ -302,10 +302,9 @@ void RuntimeDyldMachO::processRelocationRef(unsigned SectionID,
if (isExtern) {
// Obtain the symbol name which is referenced in the relocation
SymbolRef Symbol;
RelI.getSymbol(Symbol);
symbol_iterator Symbol = RelI.getSymbol();
StringRef TargetName;
Symbol.getName(TargetName);
Symbol->getName(TargetName);
// First search for the symbol in the local symbol table
SymbolTableMap::const_iterator lsi = Symbols.find(TargetName.data());
if (lsi != Symbols.end()) {

View File

@ -712,13 +712,11 @@ error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel,
Res = toRel(Rel)->VirtualAddress;
return object_error::success;
}
error_code COFFObjectFile::getRelocationSymbol(DataRefImpl Rel,
SymbolRef &Res) const {
symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
const coff_relocation* R = toRel(Rel);
DataRefImpl Symb;
Symb.p = reinterpret_cast<uintptr_t>(SymbolTable + R->SymbolTableIndex);
Res = SymbolRef(Symb, this);
return object_error::success;
return symbol_iterator(SymbolRef(Symb, this));
}
error_code COFFObjectFile::getRelocationType(DataRefImpl Rel,
uint64_t &Res) const {

View File

@ -869,15 +869,13 @@ error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
return object_error::success;
}
error_code
MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const {
symbol_iterator
MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
macho::RelocationEntry RE = getRelocation(Rel);
uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
bool isExtern = getPlainRelocationExternal(RE);
if (!isExtern) {
Res = *end_symbols();
return object_error::success;
}
if (!isExtern)
return end_symbols();
macho::SymtabLoadCommand S = getSymtabLoadCommand();
unsigned SymbolTableEntrySize = is64Bit() ?
@ -886,8 +884,7 @@ MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const {
uint64_t Offset = S.SymbolTableOffset + SymbolIdx * SymbolTableEntrySize;
DataRefImpl Sym;
Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
Res = SymbolRef(Sym, this);
return object_error::success;
return symbol_iterator(SymbolRef(Sym, this));
}
error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,

View File

@ -219,10 +219,7 @@ uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) {
}
LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) {
SymbolRef ret;
if (error_code ec = (*unwrap(RI))->getSymbol(ret))
report_fatal_error(ec.message());
symbol_iterator ret = (*unwrap(RI))->getSymbol();
return wrap(new symbol_iterator(ret));
}

View File

@ -27,11 +27,11 @@ public:
const MCExpr *createExprForRelocation(RelocationRef Rel) {
uint64_t RelType; Rel.getType(RelType);
SymbolRef SymRef; Rel.getSymbol(SymRef);
symbol_iterator SymI = Rel.getSymbol();
StringRef SymName; SymRef.getName(SymName);
uint64_t SymAddr; SymRef.getAddress(SymAddr);
uint64_t SymSize; SymRef.getSize(SymSize);
StringRef SymName; SymI->getName(SymName);
uint64_t SymAddr; SymI->getAddress(SymAddr);
uint64_t SymSize; SymI->getSize(SymSize);
int64_t Addend; getELFRelocationAddend(Rel, Addend);
MCSymbol *Sym = Ctx.GetOrCreateSymbol(SymName);

View File

@ -28,10 +28,10 @@ public:
const MachOObjectFile *Obj = cast<MachOObjectFile>(Rel.getObjectFile());
uint64_t RelType; Rel.getType(RelType);
SymbolRef SymRef; Rel.getSymbol(SymRef);
symbol_iterator SymI = Rel.getSymbol();
StringRef SymName; SymRef.getName(SymName);
uint64_t SymAddr; SymRef.getAddress(SymAddr);
StringRef SymName; SymI->getName(SymName);
uint64_t SymAddr; SymI->getAddress(SymAddr);
RelocationEntry RE = Obj->getRelocation(Rel.getRawDataRefImpl());
bool isPCRel = Obj->getAnyRelocationPCRel(RE);
@ -86,12 +86,11 @@ public:
const MCExpr *LHS = MCSymbolRefExpr::Create(Sym, Ctx);
SymbolRef RSymRef;
RelNext.getSymbol(RSymRef);
symbol_iterator RSymI = RelNext.getSymbol();
uint64_t RSymAddr;
RSymRef.getAddress(RSymAddr);
RSymI->getAddress(RSymAddr);
StringRef RSymName;
RSymRef.getName(RSymName);
RSymI->getName(RSymName);
MCSymbol *RSym = Ctx.GetOrCreateSymbol(RSymName);
if (RSym->isVariable() == false)

Binary file not shown.

View File

@ -0,0 +1,7 @@
RUN: llvm-readobj -r %p/Inputs/elf-reloc-no-sym.x86_64 | FileCheck %s
CHECK: Relocations [
CHECK-NEXT: Section (1) .rela.plt {
CHECK-NEXT: 0x4011D8 R_X86_64_IRELATIVE - 0x400120
CHECK-NEXT: }
CHECK-NEXT: ]

View File

@ -178,7 +178,7 @@ static error_code resolveSymbol(const std::vector<RelocationRef> &Rels,
uint64_t Ofs;
if (error_code ec = I->getOffset(Ofs)) return ec;
if (Ofs == Offset) {
if (error_code ec = I->getSymbol(Sym)) return ec;
Sym = *I->getSymbol();
break;
}
}

View File

@ -250,10 +250,9 @@ static void DisassembleInputMachO2(StringRef Filename,
Sections[SectIdx].getAddress(SectionAddress);
RelocOffset -= SectionAddress;
SymbolRef RelocSym;
RI->getSymbol(RelocSym);
symbol_iterator RelocSym = RI->getSymbol();
Relocs.push_back(std::make_pair(RelocOffset, RelocSym));
Relocs.push_back(std::make_pair(RelocOffset, *RelocSym));
}
array_pod_sort(Relocs.begin(), Relocs.end());

View File

@ -201,8 +201,7 @@ static error_code resolveSymbol(const std::vector<RelocationRef> &Rels,
return EC;
if (Ofs == Offset) {
if (error_code EC = RelI->getSymbol(Sym))
return EC;
Sym = *RelI->getSymbol();
return readobj_error::success;
}
}
@ -670,14 +669,13 @@ void COFFDumper::printRelocation(section_iterator SecI,
uint64_t Offset;
uint64_t RelocType;
SmallString<32> RelocName;
SymbolRef Symbol;
StringRef SymbolName;
StringRef Contents;
if (error(RelI->getOffset(Offset))) return;
if (error(RelI->getType(RelocType))) return;
if (error(RelI->getTypeName(RelocName))) return;
if (error(RelI->getSymbol(Symbol))) return;
if (error(Symbol.getName(SymbolName))) return;
symbol_iterator Symbol = RelI->getSymbol();
if (error(Symbol->getName(SymbolName))) return;
if (error(SecI->getContents(Contents))) return;
if (opts::ExpandRelocs) {

View File

@ -571,7 +571,6 @@ void ELFDumper<ELFT>::printRelocation(section_iterator Sec,
SmallString<32> RelocName;
int64_t Addend;
StringRef SymbolName;
SymbolRef Symbol;
if (Obj->getElfHeader()->e_type == ELF::ET_REL){
if (error(RelI->getOffset(Offset))) return;
} else {
@ -580,8 +579,9 @@ void ELFDumper<ELFT>::printRelocation(section_iterator Sec,
if (error(RelI->getType(RelocType))) return;
if (error(RelI->getTypeName(RelocName))) return;
if (error(getELFRelocationAddend(*RelI, Addend))) return;
if (error(RelI->getSymbol(Symbol))) return;
if (error(Symbol.getName(SymbolName))) return;
symbol_iterator Symbol = RelI->getSymbol();
if (Symbol != Obj->end_symbols() && error(Symbol->getName(SymbolName)))
return;
if (opts::ExpandRelocs) {
DictScope Group(W, "Relocation");

View File

@ -341,12 +341,11 @@ void MachODumper::printRelocation(const MachOObjectFile *Obj,
uint64_t Offset;
SmallString<32> RelocName;
StringRef SymbolName;
SymbolRef Symbol;
if (error(RelI->getOffset(Offset))) return;
if (error(RelI->getTypeName(RelocName))) return;
if (error(RelI->getSymbol(Symbol))) return;
if (symbol_iterator(Symbol) != Obj->end_symbols() &&
error(Symbol.getName(SymbolName)))
symbol_iterator Symbol = RelI->getSymbol();
if (Symbol != Obj->end_symbols() &&
error(Symbol->getName(SymbolName)))
return;
DataRefImpl DR = RelI->getRawDataRefImpl();