[llvm] r258001 - [llvm-readobj][ELF] Teach llvm-readobj to show dynamic relocation in REL format
Rafael EspĂndola via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 18 06:17:53 PST 2016
dyn_rela_end is a funny name for something that can return a rel or a rela.
On 16 January 2016 at 17:40, Simon Atanasyan via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: atanasyan
> Date: Sat Jan 16 16:40:09 2016
> New Revision: 258001
>
> URL: http://llvm.org/viewvc/llvm-project?rev=258001&view=rev
> Log:
> [llvm-readobj][ELF] Teach llvm-readobj to show dynamic relocation in REL format
>
> MIPS 32-bit ABI uses REL relocation record format to save dynamic
> relocations. The patch teaches llvm-readobj to show dynamic relocations
> in this format.
>
> Differential Revision: http://reviews.llvm.org/D16114
>
> Added:
> llvm/trunk/test/Object/Inputs/dyn-rel.so.elf-mips (with props)
> llvm/trunk/test/Object/dyn-rel-relocation.test
> Modified:
> llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
>
> Added: llvm/trunk/test/Object/Inputs/dyn-rel.so.elf-mips
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/Inputs/dyn-rel.so.elf-mips?rev=258001&view=auto
> ==============================================================================
> Binary files llvm/trunk/test/Object/Inputs/dyn-rel.so.elf-mips (added) and llvm/trunk/test/Object/Inputs/dyn-rel.so.elf-mips Sat Jan 16 16:40:09 2016 differ
>
> Propchange: llvm/trunk/test/Object/Inputs/dyn-rel.so.elf-mips
> ------------------------------------------------------------------------------
> svn:executable = *
>
> Added: llvm/trunk/test/Object/dyn-rel-relocation.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/dyn-rel-relocation.test?rev=258001&view=auto
> ==============================================================================
> --- llvm/trunk/test/Object/dyn-rel-relocation.test (added)
> +++ llvm/trunk/test/Object/dyn-rel-relocation.test Sat Jan 16 16:40:09 2016
> @@ -0,0 +1,71 @@
> +// Check that 'llvm-readobj -dyn-relocations' shows dynamic relocations
> +// if they have REL record format.
> +
> +// dyn-rel.so.elf-mips
> +// % cat test.s
> +// .globl __start
> +// __start:
> +// nop
> +//
> +// .data
> +// .type v1, at object
> +// .size v1,4
> +// v1:
> +// .word 0
> +//
> +// .globl v2
> +// .type v2, at object
> +// .size v2,8
> +// v2:
> +// .word v2+4 # R_MIPS_32 target v2 addend 4
> +// .word v1 # R_MIPS_32 target v1 addend 0
> +//
> +// % llvm-mc -filetype=obj -triple=mips-unknown-linux -o test.o test.s
> +// % ld -m elf32btsmip -shared -o dyn-rel.so.elf-mips test.o
> +
> +RUN: llvm-readobj -relocations -dyn-relocations -expand-relocs \
> +RUN: %p/Inputs/dyn-rel.so.elf-mips | FileCheck %s
> +
> +// CHECK: Relocations [
> +// CHECK-NEXT: Section (6) .rel.dyn {
> +// CHECK-NEXT: Relocation {
> +// CHECK-NEXT: Offset: 0x0
> +// CHECK-NEXT: Type: R_MIPS_NONE (0)
> +// CHECK-NEXT: Symbol: - (0)
> +// CHECK-NEXT: Addend: 0x0
> +// CHECK-NEXT: }
> +// CHECK-NEXT: Relocation {
> +// CHECK-NEXT: Offset: 0x102F8
> +// CHECK-NEXT: Type: R_MIPS_REL32 (3)
> +// CHECK-NEXT: Symbol: - (0)
> +// CHECK-NEXT: Addend: 0x0
> +// CHECK-NEXT: }
> +// CHECK-NEXT: Relocation {
> +// CHECK-NEXT: Offset: 0x102F4
> +// CHECK-NEXT: Type: R_MIPS_REL32 (3)
> +// CHECK-NEXT: Symbol: v2 (9)
> +// CHECK-NEXT: Addend: 0x0
> +// CHECK-NEXT: }
> +// CHECK-NEXT: }
> +// CHECK-NEXT: ]
> +
> +// CHECK: Dynamic Relocations {
> +// CHECK-NEXT: Relocation {
> +// CHECK-NEXT: Offset: 0x0
> +// CHECK-NEXT: Type: R_MIPS_NONE (0)
> +// CHECK-NEXT: Symbol: -
> +// CHECK-NEXT: Addend: 0x0
> +// CHECK-NEXT: }
> +// CHECK-NEXT: Relocation {
> +// CHECK-NEXT: Offset: 0x102F8
> +// CHECK-NEXT: Type: R_MIPS_REL32 (3)
> +// CHECK-NEXT: Symbol: -
> +// CHECK-NEXT: Addend: 0x0
> +// CHECK-NEXT: }
> +// CHECK-NEXT: Relocation {
> +// CHECK-NEXT: Offset: 0x102F4
> +// CHECK-NEXT: Type: R_MIPS_REL32 (3)
> +// CHECK-NEXT: Symbol: v2
> +// CHECK-NEXT: Addend: 0x0
> +// CHECK-NEXT: }
> +// CHECK-NEXT: }
>
> Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=258001&r1=258000&r2=258001&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
> +++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Sat Jan 16 16:40:09 2016
> @@ -75,6 +75,7 @@ private:
> typedef typename ELFO::Elf_Dyn_Range Elf_Dyn_Range;
> typedef typename ELFO::Elf_Rel Elf_Rel;
> typedef typename ELFO::Elf_Rela Elf_Rela;
> + typedef typename ELFO::Elf_Rel_Range Elf_Rel_Range;
> typedef typename ELFO::Elf_Rela_Range Elf_Rela_Range;
> typedef typename ELFO::Elf_Phdr Elf_Phdr;
> typedef typename ELFO::Elf_Half Elf_Half;
> @@ -104,12 +105,16 @@ private:
> void printSymbol(const Elf_Sym *Symbol, const Elf_Shdr *SymTab,
> StringRef StrTable, bool IsDynamic);
>
> + void printDynamicRelocation(Elf_Rela Rel);
> void printRelocations(const Elf_Shdr *Sec);
> void printRelocation(Elf_Rela Rel, const Elf_Shdr *SymTab);
> void printValue(uint64_t Type, uint64_t Value);
>
> - const Elf_Rela *dyn_rela_begin() const;
> - const Elf_Rela *dyn_rela_end() const;
> + template <typename RELA>
> + static const RELA *dyn_rela_begin(const DynRegionInfo ®ion);
> + template <typename RELA>
> + static const RELA *dyn_rela_end(const DynRegionInfo ®ion);
> + Elf_Rel_Range dyn_rels() const;
> Elf_Rela_Range dyn_relas() const;
> StringRef getDynamicString(uint64_t Offset) const;
> const Elf_Dyn *dynamic_table_begin() const {
> @@ -129,6 +134,7 @@ private:
> void LoadVersionDefs(const Elf_Shdr *sec) const;
>
> const ELFO *Obj;
> + DynRegionInfo DynRelRegion;
> DynRegionInfo DynRelaRegion;
> const Elf_Phdr *DynamicProgHeader = nullptr;
> StringRef DynamicStringTable;
> @@ -944,6 +950,15 @@ ELFDumper<ELFT>::ELFDumper(const ELFFile
> GnuHashTable =
> reinterpret_cast<const Elf_GnuHash *>(toMappedAddr(Dyn.getPtr()));
> break;
> + case ELF::DT_REL:
> + DynRelRegion.Addr = toMappedAddr(Dyn.getPtr());
> + break;
> + case ELF::DT_RELSZ:
> + DynRelRegion.Size = Dyn.getVal();
> + break;
> + case ELF::DT_RELENT:
> + DynRelRegion.EntSize = Dyn.getVal();
> + break;
> case ELF::DT_RELA:
> DynRelaRegion.Addr = toMappedAddr(Dyn.getPtr());
> break;
> @@ -1011,25 +1026,32 @@ ELFDumper<ELFT>::ELFDumper(const ELFFile
> }
>
> template <typename ELFT>
> -const typename ELFDumper<ELFT>::Elf_Rela *
> -ELFDumper<ELFT>::dyn_rela_begin() const {
> - if (DynRelaRegion.Size && DynRelaRegion.EntSize != sizeof(Elf_Rela))
> +template <typename RELA>
> +const RELA *ELFDumper<ELFT>::dyn_rela_begin(const DynRegionInfo &Region) {
> + if (Region.Size && Region.EntSize != sizeof(RELA))
> report_fatal_error("Invalid relocation entry size");
> - return reinterpret_cast<const Elf_Rela *>(DynRelaRegion.Addr);
> + return reinterpret_cast<const RELA *>(Region.Addr);
> }
>
> template <typename ELFT>
> -const typename ELFDumper<ELFT>::Elf_Rela *
> -ELFDumper<ELFT>::dyn_rela_end() const {
> - uint64_t Size = DynRelaRegion.Size;
> - if (Size % sizeof(Elf_Rela))
> +template <typename RELA>
> +const RELA *ELFDumper<ELFT>::dyn_rela_end(const DynRegionInfo &Region) {
> + uint64_t Size = Region.Size;
> + if (Size % sizeof(RELA))
> report_fatal_error("Invalid relocation table size");
> - return dyn_rela_begin() + Size / sizeof(Elf_Rela);
> + return dyn_rela_begin<RELA>(Region) + Size / sizeof(RELA);
> +}
> +
> +template <typename ELFT>
> +typename ELFDumper<ELFT>::Elf_Rel_Range ELFDumper<ELFT>::dyn_rels() const {
> + return make_range(dyn_rela_begin<Elf_Rel>(DynRelRegion),
> + dyn_rela_end<Elf_Rel>(DynRelRegion));
> }
>
> template <typename ELFT>
> typename ELFDumper<ELFT>::Elf_Rela_Range ELFDumper<ELFT>::dyn_relas() const {
> - return make_range(dyn_rela_begin(), dyn_rela_end());
> + return make_range(dyn_rela_begin<Elf_Rela>(DynRelaRegion),
> + dyn_rela_end<Elf_Rela>(DynRelaRegion));
> }
>
> template<class ELFT>
> @@ -1158,31 +1180,22 @@ void ELFDumper<ELFT>::printRelocations()
> }
> }
>
> -template<class ELFT>
> -void ELFDumper<ELFT>::printDynamicRelocations() {
> +template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocations() {
> + if (DynRelRegion.Size && DynRelaRegion.Size)
> + report_fatal_error("There are both REL and RELA dynamic relocations");
> W.startLine() << "Dynamic Relocations {\n";
> W.indent();
> - for (const Elf_Rela &Rel : dyn_relas()) {
> - SmallString<32> RelocName;
> - Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
> - StringRef SymbolName;
> - uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL());
> - const Elf_Sym *Sym = DynSymStart + SymIndex;
> - SymbolName = errorOrDefault(Sym->getName(DynamicStringTable));
> - if (opts::ExpandRelocs) {
> - DictScope Group(W, "Relocation");
> - W.printHex("Offset", Rel.r_offset);
> - W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
> - W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
> - W.printHex("Addend", Rel.r_addend);
> - }
> - else {
> - raw_ostream& OS = W.startLine();
> - OS << W.hex(Rel.r_offset) << " " << RelocName << " "
> - << (SymbolName.size() > 0 ? SymbolName : "-") << " "
> - << W.hex(Rel.r_addend) << "\n";
> + if (DynRelaRegion.Size > 0)
> + for (const Elf_Rela &Rela : dyn_relas())
> + printDynamicRelocation(Rela);
> + else
> + for (const Elf_Rel &Rel : dyn_rels()) {
> + 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";
> }
> @@ -1242,6 +1255,28 @@ void ELFDumper<ELFT>::printRelocation(El
> << W.hex(Rel.r_addend) << "\n";
> }
> }
> +
> +template <class ELFT>
> +void ELFDumper<ELFT>::printDynamicRelocation(Elf_Rela Rel) {
> + SmallString<32> RelocName;
> + Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName);
> + StringRef SymbolName;
> + uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL());
> + const Elf_Sym *Sym = DynSymStart + SymIndex;
> + SymbolName = errorOrDefault(Sym->getName(DynamicStringTable));
> + if (opts::ExpandRelocs) {
> + DictScope Group(W, "Relocation");
> + W.printHex("Offset", Rel.r_offset);
> + W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL()));
> + W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
> + W.printHex("Addend", Rel.r_addend);
> + } else {
> + raw_ostream &OS = W.startLine();
> + OS << W.hex(Rel.r_offset) << " " << RelocName << " "
> + << (SymbolName.size() > 0 ? SymbolName : "-") << " "
> + << W.hex(Rel.r_addend) << "\n";
> + }
> +}
>
> template<class ELFT>
> void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic) {
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list