[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 ®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
--
Simon Atanasyan
More information about the llvm-commits
mailing list