diff --git a/llvm/test/tools/llvm-readobj/ELF/dynamic-reloc.test b/llvm/test/tools/llvm-readobj/ELF/dynamic-reloc.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/ELF/dynamic-reloc.test @@ -0,0 +1,135 @@ +## Test that we are able to print dynamic relocations with --dyn-relocations. + +## Check what we print when there are no dynamic relocations in an object. +# RUN: yaml2obj --docnum=1 %s -o %t1 +# RUN: llvm-readobj --dyn-relocations %t1 2>&1 | FileCheck %s --check-prefix=LLVM-NONE +# RUN: llvm-readelf --dyn-relocations %t1 2>&1 | FileCheck %s --implicit-check-not={{.}} --allow-empty + +# LLVM-NONE: Dynamic Relocations { +# LLVM-NONE-NEXT: } +# LLVM-NONE-NOT: {{.}} + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 + +## Check that we dump all possbile dynamic relocation sections. +# RUN: yaml2obj --docnum=2 %s -o %t2.1 +# RUN: llvm-readobj --dyn-relocations %t2.1 2>&1 | \ +# RUN: FileCheck %s --implicit-check-not=warning: --check-prefix=LLVM-RELOCS +# RUN: llvm-readelf --dyn-relocations %t2.1 2>&1 | \ +# RUN: FileCheck %s --implicit-check-not=warning: --strict-whitespace \ +# RUN: --match-full-lines --check-prefixes=GNU-RELOCS,GNU-PLTREL + +## 7 == DT_RELA. +# RUN: yaml2obj --docnum=2 %s -DDTPLTREL=7 -DPLTTYPE=SHT_RELA -DPLTRELSZ=0x18 -o %t2.2 +# RUN: llvm-readobj --dyn-relocations %t2.2 2>&1 | \ +# RUN: FileCheck %s --implicit-check-not=warning: --check-prefix=LLVM-RELOCS +# RUN: llvm-readelf --dyn-relocations %t2.2 2>&1 | \ +# RUN: FileCheck %s --implicit-check-not=warning: --strict-whitespace \ +# RUN: --match-full-lines --check-prefixes=GNU-RELOCS,GNU-PLTRELA + +# LLVM-RELOCS: Dynamic Relocations { +# LLVM-RELOCS-NEXT: 0x1 R_X86_64_NONE foo 0x0 +# LLVM-RELOCS-NEXT: 0x2 R_X86_64_NONE foo 0x0 +# LLVM-RELOCS-NEXT: 0x4 R_X86_64_RELATIVE - 0x0 +# LLVM-RELOCS-NEXT: 0x8 R_X86_64_NONE foo 0x0 +# LLVM-RELOCS-NEXT: } + +# GNU-RELOCS:'RELA' relocation section at offset 0x78 contains 24 bytes: +# GNU-RELOCS-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend +# GNU-RELOCS-NEXT:0000000000000001 0000000100000000 R_X86_64_NONE 0000000000000000 foo + 0 +# GNU-RELOCS-EMPTY: +# GNU-RELOCS-NEXT:'REL' relocation section at offset 0x90 contains 16 bytes: +# GNU-RELOCS-NEXT: Offset Info Type Symbol's Value Symbol's Name +# GNU-RELOCS-NEXT:0000000000000002 0000000100000000 R_X86_64_NONE 0000000000000000 foo +# GNU-RELOCS-EMPTY: +# GNU-RELOCS-NEXT:'RELR' relocation section at offset 0xa0 contains 8 bytes: +# GNU-RELOCS-NEXT: Offset Info Type Symbol's Value Symbol's Name +# GNU-RELOCS-NEXT:0000000000000004 0000000000000008 R_X86_64_RELATIVE {{$}} +# GNU-RELOCS-EMPTY: +# GNU-PLTREL-NEXT:'PLT' relocation section at offset 0xa8 contains 16 bytes: +# GNU-PLTREL-NEXT: Offset Info Type Symbol's Value Symbol's Name +# GNU-PLTREL-NEXT:0000000000000008 0000000100000000 R_X86_64_NONE 0000000000000000 foo +# GNU-PLTRELA-NEXT:'PLT' relocation section at offset 0xa8 contains 24 bytes: +# GNU-PLTRELA-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend +# GNU-PLTRELA-NEXT:0000000000000008 0000000100000000 R_X86_64_NONE 0000000000000000 foo + 0 +# GNU-RELOCS-EMPTY: +# GNU-RELOCS-NOT:{{.}} + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .rela.dyn + Type: SHT_RELA + Relocations: + - Type: R_X86_64_NONE + Offset: 0x1 + Symbol: foo + - Name: .rel.dyn + Type: SHT_REL + Relocations: + - Type: R_X86_64_NONE + Offset: 0x2 + Symbol: foo + - Name: .relr.dyn + Type: SHT_RELR + Flags: [ SHF_ALLOC ] + Entries: [ 0x0000000000000004 ] + - Name: .plt + Type: [[PLTTYPE=SHT_REL]] + Relocations: + - Type: R_X86_64_NONE + Offset: 0x8 + Symbol: foo + - Name: .dynamic + Type: SHT_DYNAMIC + Entries: + - Tag: DT_RELA + Value: 0x0 + - Tag: DT_RELASZ + Value: 0x18 + - Tag: DT_RELAENT + Value: 0x18 +## 0x18 == offset of .rel.dyn in the segment. + - Tag: DT_REL + Value: 0x18 + - Tag: DT_RELSZ + Value: 0x10 + - Tag: DT_RELENT + Value: 0x10 +## 0x28 == offset of .relr.dyn section in the segment. + - Tag: DT_RELR + Value: 0x28 + - Tag: DT_RELRSZ + Value: 0x8 + - Tag: DT_RELRENT + Value: 0x8 +## 0x30 == offset of .plt section in the segment. + - Tag: DT_JMPREL + Value: 0x30 + - Tag: DT_PLTREL + Value: [[DTPLTREL=17]] ## 17 == DT_REL + - Tag: DT_PLTRELSZ + Value: [[PLTRELSZ=0x10]] + - Tag: DT_NULL + Value: 0x0 +Symbols: + - Name: foo +DynamicSymbols: + - Name: foo +ProgramHeaders: + - Type: PT_LOAD + Sections: + - Section: .rela.dyn + - Section: .rel.dyn + - Section: .relr.dyn + - Section: .plt + - Section: .dynamic diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -4568,19 +4568,20 @@ Obj->base(), 1) << " contains " << DynPLTRelRegion.Size << " bytes:\n"; - } - if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) { - printRelocHeader(ELF::SHT_RELA); - for (const Elf_Rela &Rela : DynPLTRelRegion.getAsArrayRef()) - printDynamicRelocation(Obj, Rela, true); - } else { - printRelocHeader(ELF::SHT_REL); - for (const Elf_Rel &Rel : DynPLTRelRegion.getAsArrayRef()) { - Elf_Rela Rela; - Rela.r_offset = Rel.r_offset; - Rela.r_info = Rel.r_info; - Rela.r_addend = 0; - printDynamicRelocation(Obj, Rela, false); + + if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) { + printRelocHeader(ELF::SHT_RELA); + for (const Elf_Rela &Rela : DynPLTRelRegion.getAsArrayRef()) + printDynamicRelocation(Obj, Rela, true); + } else { + printRelocHeader(ELF::SHT_REL); + for (const Elf_Rel &Rel : DynPLTRelRegion.getAsArrayRef()) { + Elf_Rela Rela; + Rela.r_offset = Rel.r_offset; + Rela.r_info = Rel.r_info; + Rela.r_addend = 0; + printDynamicRelocation(Obj, Rela, false); + } } } }