[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 &region);
> +  template <typename RELA>
> +  static const RELA *dyn_rela_end(const DynRegionInfo &region);
> +  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