[llvm] r258001 - [llvm-readobj][ELF] Teach llvm-readobj to show dynamic relocation in REL format

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 18 06:23:07 PST 2016


s/rela/relocs/ ?

BTW LLD has Out::RelaDyn variable that in fact can represent both
".rela.dyn" and ".rel.dyn" sections.

On Mon, Jan 18, 2016 at 5:17 PM, Rafael EspĂ­ndola
<rafael.espindola at gmail.com> wrote:
> 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



-- 
Simon Atanasyan


More information about the llvm-commits mailing list