summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-04-25 12:28:45 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-04-25 12:28:45 +0000
commit956ca7265c697107708468b7e1b2fd21f4185bae (patch)
tree67a93afc4801ff580b60b075c6a84698fdb9b488
parent02066838b5cdf17277267e79ffbc9459a58cdd59 (diff)
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
-rw-r--r--include/llvm/Object/ELF.h49
-rw-r--r--include/llvm/Object/RelocVisitor.h4
-rw-r--r--lib/DebugInfo/DWARFContext.cpp2
-rw-r--r--lib/Object/COFFObjectFile.cpp3
-rw-r--r--lib/Object/MachOObjectFile.cpp16
-rwxr-xr-xtest/Object/Inputs/hello-world.elf-x86-64bin0 -> 4544 bytes
-rw-r--r--test/Object/relocation-executable.test18
-rw-r--r--tools/llvm-objdump/MachODump.cpp2
-rw-r--r--tools/llvm-objdump/llvm-objdump.cpp8
-rw-r--r--tools/llvm-readobj/ELFDumper.cpp6
-rw-r--r--tools/llvm-readobj/llvm-readobj.cpp4
11 files changed, 54 insertions, 58 deletions
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index 02840230f5c..4f0e5b8db8f 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -607,6 +607,8 @@ private:
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> {
@@ -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>
diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h
index 2dcbdf90532..59d810763f2 100644
--- a/include/llvm/Object/RelocVisitor.h
+++ b/include/llvm/Object/RelocVisitor.h
@@ -133,7 +133,7 @@ private:
int64_t Addend;
R.getAdditionalInfo(Addend);
uint64_t Address;
- R.getAddress(Address);
+ R.getOffset(Address);
return RelocToApply(Value + Addend - Address, 4);
}
@@ -151,7 +151,7 @@ private:
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) {
diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp
index 1e13731361a..e5daf55982f 100644
--- a/lib/DebugInfo/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARFContext.cpp
@@ -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;
diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp
index 46acd4d5370..70fec321ba3 100644
--- a/lib/Object/COFFObjectFile.cpp
+++ b/lib/Object/COFFObjectFile.cpp
@@ -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 {
diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp
index 51cd5b9a95d..14bca2bf901 100644
--- a/lib/Object/MachOObjectFile.cpp
+++ b/lib/Object/MachOObjectFile.cpp
@@ -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,
diff --git a/test/Object/Inputs/hello-world.elf-x86-64 b/test/Object/Inputs/hello-world.elf-x86-64
new file mode 100755
index 00000000000..16092b89472
--- /dev/null
+++ b/test/Object/Inputs/hello-world.elf-x86-64
Binary files differ
diff --git a/test/Object/relocation-executable.test b/test/Object/relocation-executable.test
new file mode 100644
index 00000000000..98f5b4ee2fd
--- /dev/null
+++ b/test/Object/relocation-executable.test
@@ -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: }
diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp
index d78d7f31a6c..6797e2dc5b8 100644
--- a/tools/llvm-objdump/MachODump.cpp
+++ b/tools/llvm-objdump/MachODump.cpp
@@ -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;
diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp
index 99855995651..247b90f0300 100644
--- a/tools/llvm-objdump/llvm-objdump.cpp
+++ b/tools/llvm-objdump/llvm-objdump.cpp
@@ -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;
}
@@ -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;
@@ -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";
}
diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp
index f771cbdd52b..ea1b83f32f1 100644
--- a/tools/llvm-readobj/ELFDumper.cpp
+++ b/tools/llvm-readobj/ELFDumper.cpp
@@ -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;
diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp
index 7a4b4e4431c..2e95b6b5518 100644
--- a/tools/llvm-readobj/llvm-readobj.cpp
+++ b/tools/llvm-readobj/llvm-readobj.cpp
@@ -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;
}