Clarify getRelocationAddress x getRelocationOffset a bit.

getRelocationAddress is for dynamic libraries and executables,
getRelocationOffset for relocatable objects.

Mark the getRelocationAddress of COFF and MachO as not implemented yet. Add a
test of ELF's. llvm-readobj -r now prints the same values as readelf -r.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180259 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2013-04-25 12:28:45 +00:00
parent 02066838b5
commit 956ca7265c
11 changed files with 54 additions and 58 deletions

View File

@ -607,6 +607,8 @@ private:
mutable const char *dt_soname; mutable const char *dt_soname;
private: private:
uint64_t getROffset(DataRefImpl Rel) const;
// Records for each version index the corresponding Verdef or Vernaux entry. // Records for each version index the corresponding Verdef or Vernaux entry.
// This is filled the first time LoadVersionMap() is called. // This is filled the first time LoadVersionMap() is called.
class VersionMapEntry : public PointerIntPair<const void*, 1> { class VersionMapEntry : public PointerIntPair<const void*, 1> {
@ -1521,45 +1523,32 @@ error_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel,
template<class ELFT> template<class ELFT>
error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel, error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
uint64_t &Result) const { uint64_t &Result) const {
uint64_t offset; assert((Header->e_type == ELF::ET_EXEC || Header->e_type == ELF::ET_DYN) &&
const Elf_Shdr *sec = getSection(Rel.w.b); "Only executable and shared objects files have addresses");
switch (sec->sh_type) { Result = getROffset(Rel);
default :
report_fatal_error("Invalid section type in Rel!");
case ELF::SHT_REL : {
offset = getRel(Rel)->r_offset;
break;
}
case ELF::SHT_RELA : {
offset = getRela(Rel)->r_offset;
break;
}
}
Result = offset;
return object_error::success; return object_error::success;
} }
template<class ELFT> template<class ELFT>
error_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel, error_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel,
uint64_t &Result) const { uint64_t &Result) const {
uint64_t offset; assert(Header->e_type == ELF::ET_REL &&
"Only relocatable object files have relocation offsets");
Result = getROffset(Rel);
return object_error::success;
}
template<class ELFT>
uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const {
const Elf_Shdr *sec = getSection(Rel.w.b); const Elf_Shdr *sec = getSection(Rel.w.b);
switch (sec->sh_type) { switch (sec->sh_type) {
default : default:
report_fatal_error("Invalid section type in Rel!"); report_fatal_error("Invalid section type in Rel!");
case ELF::SHT_REL : { case ELF::SHT_REL:
offset = getRel(Rel)->r_offset; return getRel(Rel)->r_offset;
break; case ELF::SHT_RELA:
} return getRela(Rel)->r_offset;
case ELF::SHT_RELA : {
offset = getRela(Rel)->r_offset;
break;
}
} }
Result = offset - sec->sh_addr;
return object_error::success;
} }
template<class ELFT> template<class ELFT>

View File

@ -133,7 +133,7 @@ private:
int64_t Addend; int64_t Addend;
R.getAdditionalInfo(Addend); R.getAdditionalInfo(Addend);
uint64_t Address; uint64_t Address;
R.getAddress(Address); R.getOffset(Address);
return RelocToApply(Value + Addend - Address, 4); return RelocToApply(Value + Addend - Address, 4);
} }
@ -151,7 +151,7 @@ private:
int64_t Addend; int64_t Addend;
R.getAdditionalInfo(Addend); R.getAdditionalInfo(Addend);
uint64_t Address; uint64_t Address;
R.getAddress(Address); R.getOffset(Address);
return RelocToApply(Value + Addend - Address, 4); return RelocToApply(Value + Addend - Address, 4);
} }
RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) { RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) {

View File

@ -572,7 +572,7 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
reloc_e = i->end_relocations(); reloc_e = i->end_relocations();
reloc_i != reloc_e; reloc_i.increment(ec)) { reloc_i != reloc_e; reloc_i.increment(ec)) {
uint64_t Address; uint64_t Address;
reloc_i->getAddress(Address); reloc_i->getOffset(Address);
uint64_t Type; uint64_t Type;
reloc_i->getType(Type); reloc_i->getType(Type);
uint64_t SymAddr = 0; uint64_t SymAddr = 0;

View File

@ -705,8 +705,7 @@ error_code COFFObjectFile::getRelocationNext(DataRefImpl Rel,
} }
error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel, error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel,
uint64_t &Res) const { uint64_t &Res) const {
Res = toRel(Rel)->VirtualAddress; report_fatal_error("getRelocationAddress not implemented in COFFObjectFile");
return object_error::success;
} }
error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel, error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel,
uint64_t &Res) const { uint64_t &Res) const {

View File

@ -789,21 +789,7 @@ MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const {
error_code error_code
MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const { MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const {
uint64_t SectAddress; report_fatal_error("getRelocationAddress not implemented in MachOObjectFile");
DataRefImpl Sec;
Sec.d.a = Rel.d.b;
if (is64Bit()) {
macho::Section64 Sect = getSection64(Sec);
SectAddress = Sect.Address;
} else {
macho::Section Sect = getSection(Sec);
SectAddress = Sect.Address;
}
macho::RelocationEntry RE = getRelocation(Rel);
uint64_t RelAddr = getAnyRelocationAddress(RE);
Res = SectAddress + RelAddr;
return object_error::success;
} }
error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel, error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,

Binary file not shown.

View File

@ -0,0 +1,18 @@
RUN: llvm-readobj -r -expand-relocs %p/Inputs/hello-world.elf-x86-64 \
RUN: | FileCheck %s
// CHECK: Relocations [
// CHECK: Section (11) .plt {
// CHECK-NEXT: Relocation {
// CHECK-NEXT: Offset: 0x4018F8
// CHECK-NEXT: Type: R_X86_64_JUMP_SLOT (7)
// CHECK-NEXT: Symbol: __libc_start_main
// CHECK-NEXT: Info: 0x0
// CHECK-NEXT: }
// CHECK-NEXT: Relocation {
// CHECK-NEXT: Offset: 0x401900
// CHECK-NEXT: Type: R_X86_64_JUMP_SLOT (7)
// CHECK-NEXT: Symbol: puts
// CHECK-NEXT: Info: 0x0
// CHECK-NEXT: }
// CHECK-NEXT: }

View File

@ -343,7 +343,7 @@ static void DisassembleInputMachO2(StringRef Filename,
for (relocation_iterator RI = Sections[SectIdx].begin_relocations(), for (relocation_iterator RI = Sections[SectIdx].begin_relocations(),
RE = Sections[SectIdx].end_relocations(); RI != RE; RI.increment(ec)) { RE = Sections[SectIdx].end_relocations(); RI != RE; RI.increment(ec)) {
uint64_t RelocOffset, SectionAddress; uint64_t RelocOffset, SectionAddress;
RI->getAddress(RelocOffset); RI->getOffset(RelocOffset);
Sections[SectIdx].getAddress(SectionAddress); Sections[SectIdx].getAddress(SectionAddress);
RelocOffset -= SectionAddress; RelocOffset -= SectionAddress;

View File

@ -186,8 +186,8 @@ void llvm::DumpBytes(StringRef bytes) {
bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) { bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) {
uint64_t a_addr, b_addr; uint64_t a_addr, b_addr;
if (error(a.getAddress(a_addr))) return false; if (error(a.getOffset(a_addr))) return false;
if (error(b.getAddress(b_addr))) return false; if (error(b.getOffset(b_addr))) return false;
return a_addr < b_addr; return a_addr < b_addr;
} }
@ -378,7 +378,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
if (error(rel_cur->getHidden(hidden))) goto skip_print_rel; if (error(rel_cur->getHidden(hidden))) goto skip_print_rel;
if (hidden) goto skip_print_rel; if (hidden) goto skip_print_rel;
if (error(rel_cur->getAddress(addr))) goto skip_print_rel; if (error(rel_cur->getOffset(addr))) goto skip_print_rel;
// Stop when rel_cur's address is past the current instruction. // Stop when rel_cur's address is past the current instruction.
if (addr >= Index + Size) break; if (addr >= Index + Size) break;
if (error(rel_cur->getTypeName(name))) goto skip_print_rel; if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
@ -417,7 +417,7 @@ static void PrintRelocations(const ObjectFile *o) {
if (error(ri->getHidden(hidden))) continue; if (error(ri->getHidden(hidden))) continue;
if (hidden) continue; if (hidden) continue;
if (error(ri->getTypeName(relocname))) continue; if (error(ri->getTypeName(relocname))) continue;
if (error(ri->getAddress(address))) continue; if (error(ri->getOffset(address))) continue;
if (error(ri->getValueString(valuestr))) continue; if (error(ri->getValueString(valuestr))) continue;
outs() << address << " " << relocname << " " << valuestr << "\n"; outs() << address << " " << relocname << " " << valuestr << "\n";
} }

View File

@ -582,7 +582,11 @@ void ELFDumper<ELFT>::printRelocation(section_iterator Sec,
int64_t Info; int64_t Info;
StringRef SymbolName; StringRef SymbolName;
SymbolRef Symbol; SymbolRef Symbol;
if (error(RelI->getOffset(Offset))) return; if (Obj->getElfHeader()->e_type == ELF::ET_REL){
if (error(RelI->getOffset(Offset))) return;
} else {
if (error(RelI->getAddress(Offset))) return;
}
if (error(RelI->getType(RelocType))) return; if (error(RelI->getType(RelocType))) return;
if (error(RelI->getTypeName(RelocName))) return; if (error(RelI->getTypeName(RelocName))) return;
if (error(RelI->getAdditionalInfo(Info))) return; if (error(RelI->getAdditionalInfo(Info))) return;

View File

@ -143,8 +143,8 @@ bool error(error_code EC) {
bool relocAddressLess(RelocationRef a, RelocationRef b) { bool relocAddressLess(RelocationRef a, RelocationRef b) {
uint64_t a_addr, b_addr; uint64_t a_addr, b_addr;
if (error(a.getAddress(a_addr))) return false; if (error(a.getOffset(a_addr))) return false;
if (error(b.getAddress(b_addr))) return false; if (error(b.getOffset(b_addr))) return false;
return a_addr < b_addr; return a_addr < b_addr;
} }