diff --git a/test/Object/relocation-executable.test b/test/Object/relocation-executable.test index 93d4dee3089..bb0bb157b6a 100644 --- a/test/Object/relocation-executable.test +++ b/test/Object/relocation-executable.test @@ -34,6 +34,18 @@ RUN: %p/Inputs/hello-world.elf-x86-64 | FileCheck %s --check-prefix=DYN // DYN-NEXT: Symbol: __gmon_start__ // DYN-NEXT: Addend: 0x0 // DYN-NEXT: } +// DYN-NEXT: Relocation { +// DYN-NEXT: Offset: 0x4018F8 +// DYN-NEXT: Type: R_X86_64_JUMP_SLOT (7) +// DYN-NEXT: Symbol: __libc_start_main +// DYN-NEXT: Addend: 0x0 +// DYN-NEXT: } +// DYN-NEXT: Relocation { +// DYN-NEXT: Offset: 0x401900 +// DYN-NEXT: Type: R_X86_64_JUMP_SLOT (7) +// DYN-NEXT: Symbol: puts +// DYN-NEXT: Addend: 0x0 +// DYN-NEXT: } // DYN-NEXT: } RUN: llvm-readobj -dyn-relocations -expand-relocs \ diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index b8c815e4b35..f305d6d0d6c 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -60,6 +60,8 @@ struct DynRegionInfo { template iterator_range getAsRange() const { const Type *Start = reinterpret_cast(Addr); + if (!Start) + return {Start, Start}; if (EntSize != sizeof(Type) || Size % EntSize) reportError("Invalid entity size"); return {Start, Start + (Size / EntSize)}; @@ -152,6 +154,7 @@ private: const ELFO *Obj; DynRegionInfo DynRelRegion; DynRegionInfo DynRelaRegion; + DynRegionInfo DynPLTRelRegion; const Elf_Phdr *DynamicProgHeader = nullptr; StringRef DynamicStringTable; const Elf_Sym *DynSymStart = nullptr; @@ -1105,6 +1108,21 @@ void ELFDumper::parseDynamicTable( case ELF::DT_RELENT: DynRelRegion.EntSize = Dyn.getVal(); break; + case ELF::DT_PLTREL: + if (Dyn.getVal() == DT_REL) + DynPLTRelRegion.EntSize = sizeof(Elf_Rel); + else if (Dyn.getVal() == DT_RELA) + DynPLTRelRegion.EntSize = sizeof(Elf_Rela); + else + reportError(Twine("unknown DT_PLTREL value of ") + + Twine((uint64_t)Dyn.getVal())); + break; + case ELF::DT_JMPREL: + DynPLTRelRegion.Addr = toMappedAddr(Dyn.getPtr()); + break; + case ELF::DT_PLTRELSZ: + DynPLTRelRegion.Size = Dyn.getVal(); + break; } } if (StringTableBegin) @@ -1246,6 +1264,17 @@ template void ELFDumper::printDynamicRelocations() { Rela.r_addend = 0; printDynamicRelocation(Rela); } + if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) + for (const Elf_Rela &Rela : DynPLTRelRegion.getAsRange()) + printDynamicRelocation(Rela); + else + for (const Elf_Rel &Rel : DynPLTRelRegion.getAsRange()) { + Elf_Rela Rela; + Rela.r_offset = Rel.r_offset; + Rela.r_info = Rel.r_info; + Rela.r_addend = 0; + printDynamicRelocation(Rela); + } W.unindent(); W.startLine() << "}\n"; }