template <class ELFT>
section_iterator
ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
- if (EF.getHeader()->e_type != ELF::ET_REL)
- return section_end();
-
const Elf_Shdr *EShdr = getSection(Sec);
uintX_t Type = EShdr->sh_type;
if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
}
template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
- assert(EF.getHeader()->e_type == ELF::ET_REL &&
- "Only relocatable object files have relocation offsets");
- const Elf_Shdr *sec = getRelSection(Rel);
- if (sec->sh_type == ELF::SHT_REL)
- return getRel(Rel)->r_offset;
-
- return getRela(Rel)->r_offset;
+uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {\r
+ const Elf_Shdr *sec = getRelSection(Rel);\r
+ uint64_t Offset = sec->sh_type == ELF::SHT_REL ?\r
+ getRel(Rel)->r_offset :\r
+ getRela(Rel)->r_offset;\r
+ if (EF.getHeader()->e_type == ELF::ET_EXEC ||\r
+ EF.getHeader()->e_type == ELF::ET_DYN) {\r
+ // For an executable file or a shared object, the value is the virtual\r
+ // address of the storage unit affected by the relocation.\r
+ auto SectionIter = getRelocatedSection(toDRI(sec));\r
+ if (SectionIter != section_end())\r
+ Offset -= SectionIter->getAddress();\r
+ }\r
+ return Offset;
}
template <class ELFT>
--- /dev/null
+// This test checks that relocation in nonrelocatable files are printed\r
+// RUN: llvm-objdump -r %p/Inputs/relocations-in-nonrelocatable.elf-x86_64 | FileCheck %s\r
+\r
+// (main.c)\r
+// void g(void){}\r
+// int main(void) { g(); };\r
+// gcc main.c -o main -Wl,--emit-relocs\r
+\r
+CHECK: 00000000000000f8 R_X86_64_PC32 g-4-P
\ No newline at end of file
void llvm::PrintRelocations(const ObjectFile *Obj) {
StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 :
"%08" PRIx64;
- // Regular objdump doesn't print relocations in non-relocatable object
- // files.
- if (!Obj->isRelocatableObject())
- return;
for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
if (Section.relocation_begin() == Section.relocation_end())