Skip to content

Commit

Permalink
Clarify getRelocationAddress x getRelocationOffset a bit.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
espindola committed Apr 25, 2013
1 parent 0206683 commit 956ca72
Show file tree
Hide file tree
Showing 11 changed files with 54 additions and 58 deletions.
49 changes: 19 additions & 30 deletions include/llvm/Object/ELF.h
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,8 @@ class ELFObjectFile : public ObjectFile {
mutable const char *dt_soname;

private:
uint64_t getROffset(DataRefImpl Rel) const;

// Records for each version index the corresponding Verdef or Vernaux entry.
// This is filled the first time LoadVersionMap() is called.
class VersionMapEntry : public PointerIntPair<const void*, 1> {
Expand Down Expand Up @@ -1521,45 +1523,32 @@ error_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel,
template<class ELFT>
error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
uint64_t &Result) const {
uint64_t offset;
const Elf_Shdr *sec = getSection(Rel.w.b);
switch (sec->sh_type) {
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;
assert((Header->e_type == ELF::ET_EXEC || Header->e_type == ELF::ET_DYN) &&
"Only executable and shared objects files have addresses");
Result = getROffset(Rel);
return object_error::success;
}

template<class ELFT>
error_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel,
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);
switch (sec->sh_type) {
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;
}
default:
report_fatal_error("Invalid section type in Rel!");
case ELF::SHT_REL:
return getRel(Rel)->r_offset;
case ELF::SHT_RELA:
return getRela(Rel)->r_offset;
}

Result = offset - sec->sh_addr;
return object_error::success;
}

template<class ELFT>
Expand Down
4 changes: 2 additions & 2 deletions include/llvm/Object/RelocVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class RelocVisitor {
int64_t Addend;
R.getAdditionalInfo(Addend);
uint64_t Address;
R.getAddress(Address);
R.getOffset(Address);
return RelocToApply(Value + Addend - Address, 4);
}

Expand All @@ -151,7 +151,7 @@ class RelocVisitor {
int64_t Addend;
R.getAdditionalInfo(Addend);
uint64_t Address;
R.getAddress(Address);
R.getOffset(Address);
return RelocToApply(Value + Addend - Address, 4);
}
RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) {
Expand Down
2 changes: 1 addition & 1 deletion lib/DebugInfo/DWARFContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
reloc_e = i->end_relocations();
reloc_i != reloc_e; reloc_i.increment(ec)) {
uint64_t Address;
reloc_i->getAddress(Address);
reloc_i->getOffset(Address);
uint64_t Type;
reloc_i->getType(Type);
uint64_t SymAddr = 0;
Expand Down
3 changes: 1 addition & 2 deletions lib/Object/COFFObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -705,8 +705,7 @@ error_code COFFObjectFile::getRelocationNext(DataRefImpl Rel,
}
error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel,
uint64_t &Res) const {
Res = toRel(Rel)->VirtualAddress;
return object_error::success;
report_fatal_error("getRelocationAddress not implemented in COFFObjectFile");
}
error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel,
uint64_t &Res) const {
Expand Down
16 changes: 1 addition & 15 deletions lib/Object/MachOObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -789,21 +789,7 @@ MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const {

error_code
MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const {
uint64_t SectAddress;
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;
report_fatal_error("getRelocationAddress not implemented in MachOObjectFile");
}

error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
Expand Down
Binary file added test/Object/Inputs/hello-world.elf-x86-64
Binary file not shown.
18 changes: 18 additions & 0 deletions test/Object/relocation-executable.test
Original file line number Diff line number Diff line change
@@ -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: }
2 changes: 1 addition & 1 deletion tools/llvm-objdump/MachODump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ static void DisassembleInputMachO2(StringRef Filename,
for (relocation_iterator RI = Sections[SectIdx].begin_relocations(),
RE = Sections[SectIdx].end_relocations(); RI != RE; RI.increment(ec)) {
uint64_t RelocOffset, SectionAddress;
RI->getAddress(RelocOffset);
RI->getOffset(RelocOffset);
Sections[SectIdx].getAddress(SectionAddress);
RelocOffset -= SectionAddress;

Expand Down
8 changes: 4 additions & 4 deletions tools/llvm-objdump/llvm-objdump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ void llvm::DumpBytes(StringRef bytes) {

bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) {
uint64_t a_addr, b_addr;
if (error(a.getAddress(a_addr))) return false;
if (error(b.getAddress(b_addr))) return false;
if (error(a.getOffset(a_addr))) return false;
if (error(b.getOffset(b_addr))) return false;
return a_addr < b_addr;
}

Expand Down Expand Up @@ -378,7 +378,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
if (error(rel_cur->getHidden(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.
if (addr >= Index + Size) break;
if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
Expand Down Expand Up @@ -417,7 +417,7 @@ static void PrintRelocations(const ObjectFile *o) {
if (error(ri->getHidden(hidden))) continue;
if (hidden) 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;
outs() << address << " " << relocname << " " << valuestr << "\n";
}
Expand Down
6 changes: 5 additions & 1 deletion tools/llvm-readobj/ELFDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,11 @@ void ELFDumper<ELFT>::printRelocation(section_iterator Sec,
int64_t Info;
StringRef SymbolName;
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->getTypeName(RelocName))) return;
if (error(RelI->getAdditionalInfo(Info))) return;
Expand Down
4 changes: 2 additions & 2 deletions tools/llvm-readobj/llvm-readobj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ bool error(error_code EC) {

bool relocAddressLess(RelocationRef a, RelocationRef b) {
uint64_t a_addr, b_addr;
if (error(a.getAddress(a_addr))) return false;
if (error(b.getAddress(b_addr))) return false;
if (error(a.getOffset(a_addr))) return false;
if (error(b.getOffset(b_addr))) return false;
return a_addr < b_addr;
}

Expand Down

0 comments on commit 956ca72

Please sign in to comment.