forked from OSchip/llvm-project
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:
parent
e6c0144208
commit
806f006490
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
@ -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: ]
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue