From: George Rimar Date: Tue, 7 May 2019 13:14:18 +0000 (+0000) Subject: [llvm-objdump] - Print relocation record in a GNU format. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f4cd658f2db0cb055e89e5d1ff320969f19d0452;p=llvm [llvm-objdump] - Print relocation record in a GNU format. This fixes the https://bugs.llvm.org/show_bug.cgi?id=41355. Previously with -r we printed relocation section name instead of the target section name. It was like this: "RELOCATION RECORDS FOR [.rel.text]" Now it is: "RELOCATION RECORDS FOR [.text]" Also when relocation target section has more than one relocation section, we did not combine the output. Now we do. Differential revision: https://reviews.llvm.org/D61312 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360143 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index de4867c2cd5..3d293c6969e 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -13,6 +13,7 @@ #ifndef LLVM_OBJECT_OBJECTFILE_H #define LLVM_OBJECT_OBJECTFILE_H +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/iterator_range.h" @@ -421,14 +422,16 @@ inline SectionRef::SectionRef(DataRefImpl SectionP, , OwningObject(Owner) {} inline bool SectionRef::operator==(const SectionRef &Other) const { - return SectionPimpl == Other.SectionPimpl; + return OwningObject == Other.OwningObject && + SectionPimpl == Other.SectionPimpl; } inline bool SectionRef::operator!=(const SectionRef &Other) const { - return SectionPimpl != Other.SectionPimpl; + return !(*this == Other); } inline bool SectionRef::operator<(const SectionRef &Other) const { + assert(OwningObject == Other.OwningObject); return SectionPimpl < Other.SectionPimpl; } @@ -560,6 +563,25 @@ inline const ObjectFile *RelocationRef::getObject() const { } // end namespace object +template <> struct DenseMapInfo { + static bool isEqual(const object::SectionRef &A, + const object::SectionRef &B) { + return A == B; + } + static object::SectionRef getEmptyKey() { + return object::SectionRef({}, nullptr); + } + static object::SectionRef getTombstoneKey() { + object::DataRefImpl TS; + TS.p = (uintptr_t)-1; + return object::SectionRef(TS, nullptr); + } + static unsigned getHashValue(const object::SectionRef &Sec) { + object::DataRefImpl Raw = Sec.getRawDataRefImpl(); + return hash_combine(Raw.p, Raw.d.a, Raw.d.b); + } +}; + } // end namespace llvm #endif // LLVM_OBJECT_OBJECTFILE_H diff --git a/test/CodeGen/BPF/reloc-btf.ll b/test/CodeGen/BPF/reloc-btf.ll index b2011ef30f1..8dbd2eff76c 100644 --- a/test/CodeGen/BPF/reloc-btf.ll +++ b/test/CodeGen/BPF/reloc-btf.ll @@ -7,10 +7,10 @@ entry: } ; CHECK-RELOC: file format ELF64-BPF -; CHECK-RELOC: RELOCATION RECORDS FOR [.rel.debug_info]: +; CHECK-RELOC: RELOCATION RECORDS FOR [.debug_info]: ; CHECK-RELOC: R_BPF_64_32 .debug_abbrev ; CHECK-RELOC: R_BPF_64_64 .text -; CHECK-RELOC: RELOCATION RECORDS FOR [.rel.BTF.ext]: +; CHECK-RELOC: RELOCATION RECORDS FOR [.BTF.ext]: ; CHECK-RELOC: R_BPF_NONE .text attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } diff --git a/test/CodeGen/BPF/reloc.ll b/test/CodeGen/BPF/reloc.ll index 53a7a1f4eab..d39131ad56a 100644 --- a/test/CodeGen/BPF/reloc.ll +++ b/test/CodeGen/BPF/reloc.ll @@ -33,7 +33,7 @@ define i32 @bpf_prog1(%struct.bpf_context* nocapture %ctx) #0 section "events/ne ret i32 0 ; CHECK-RELOC: file format ELF64-BPF -; CHECK-RELOC: RELOCATION RECORDS FOR [.rel.eh_frame]: +; CHECK-RELOC: RELOCATION RECORDS FOR [.eh_frame]: ; CHECK-RELOC: R_BPF_64_64 events/net/netif_receive_skb } diff --git a/test/DebugInfo/X86/DW_AT_location-reference.ll b/test/DebugInfo/X86/DW_AT_location-reference.ll index 7c12e1223c5..3ea6aea002b 100644 --- a/test/DebugInfo/X86/DW_AT_location-reference.ll +++ b/test/DebugInfo/X86/DW_AT_location-reference.ll @@ -47,7 +47,7 @@ ; DARWIN-NOT: X86_64_RELOC{{.*}} __debug_loc ; Check we have a relocation for the debug_loc entry in Linux output. -; LINUX: RELOCATION RECORDS FOR [.rela.debug_info] +; LINUX: RELOCATION RECORDS FOR [.debug_info] ; LINUX-NOT: RELOCATION RECORDS ; LINUX: R_X86_64{{.*}} .debug_loc diff --git a/test/DebugInfo/X86/split-dwarf-cross-unit-reference.ll b/test/DebugInfo/X86/split-dwarf-cross-unit-reference.ll index 759a4d7ca36..7b73abacdf5 100644 --- a/test/DebugInfo/X86/split-dwarf-cross-unit-reference.ll +++ b/test/DebugInfo/X86/split-dwarf-cross-unit-reference.ll @@ -44,7 +44,7 @@ ; DWO: .debug_info.dwo contents: ; CHECK-NOT: .rel{{a?}}.debug_info.dwo -; CHECK: RELOCATION RECORDS FOR [.rel{{a?}}.debug_info]: +; CHECK: RELOCATION RECORDS FOR [.debug_info]: ; CHECK-NOT: RELOCATION RECORDS ; Expect one relocation in debug_info, from the inlined f1 in foo to its ; abstract origin in bar diff --git a/test/MC/AArch64/basic-pic.s b/test/MC/AArch64/basic-pic.s index 79e03c2e299..ccfd983e052 100644 --- a/test/MC/AArch64/basic-pic.s +++ b/test/MC/AArch64/basic-pic.s @@ -1,6 +1,6 @@ // RUN: llvm-mc -triple=aarch64-none-linux-gnu -filetype=obj %s -o -| llvm-objdump -r - | FileCheck %s -// CHECK: RELOCATION RECORDS FOR [.rela.text] +// CHECK: RELOCATION RECORDS FOR [.text] .file "/home/espindola/llvm/llvm/test/CodeGen/AArch64/basic-pic.ll" .text diff --git a/test/MC/ARM/dwarf-asm-multiple-sections-dwarf-2.s b/test/MC/ARM/dwarf-asm-multiple-sections-dwarf-2.s index 5891a317007..fbb1d689273 100644 --- a/test/MC/ARM/dwarf-asm-multiple-sections-dwarf-2.s +++ b/test/MC/ARM/dwarf-asm-multiple-sections-dwarf-2.s @@ -49,7 +49,7 @@ b: // DWARF-NOT: .debug_pubnames contents: -// RELOC: RELOCATION RECORDS FOR [.rel.debug_info]: +// RELOC: RELOCATION RECORDS FOR [.debug_info]: // RELOC-NEXT: 00000006 R_ARM_ABS32 .debug_abbrev // RELOC-NEXT: 0000000c R_ARM_ABS32 .debug_line // RELOC-NEXT: R_ARM_ABS32 .text @@ -57,9 +57,9 @@ b: // RELOC-NEXT: R_ARM_ABS32 .text // RELOC-NEXT: R_ARM_ABS32 foo -// RELOC-NOT: RELOCATION RECORDS FOR [.rel.debug_ranges]: +// RELOC-NOT: RELOCATION RECORDS FOR [.debug_ranges]: -// RELOC: RELOCATION RECORDS FOR [.rel.debug_aranges]: +// RELOC: RELOCATION RECORDS FOR [.debug_aranges]: // RELOC-NEXT: 00000006 R_ARM_ABS32 .debug_info // RELOC-NEXT: 00000010 R_ARM_ABS32 .text // RELOC-NEXT: 00000018 R_ARM_ABS32 foo diff --git a/test/MC/ARM/dwarf-asm-multiple-sections.s b/test/MC/ARM/dwarf-asm-multiple-sections.s index f995958d9f8..906cd0b607d 100644 --- a/test/MC/ARM/dwarf-asm-multiple-sections.s +++ b/test/MC/ARM/dwarf-asm-multiple-sections.s @@ -77,7 +77,7 @@ b: // Offsets are different in DWARF v5 due to different header layout. -// RELOC: RELOCATION RECORDS FOR [.rel.debug_info]: +// RELOC: RELOCATION RECORDS FOR [.debug_info]: // RELOC4-NEXT: 00000006 R_ARM_ABS32 .debug_abbrev // RELOC4-NEXT: 0000000c R_ARM_ABS32 .debug_line // RELOC4-NEXT: 00000010 R_ARM_ABS32 .debug_ranges @@ -87,11 +87,11 @@ b: // RELOC-NEXT: R_ARM_ABS32 .text // RELOC-NEXT: R_ARM_ABS32 foo -// RELOC: RELOCATION RECORDS FOR [.rel.debug_ranges]: +// RELOC: RELOCATION RECORDS FOR [.debug_ranges]: // RELOC-NEXT: 00000004 R_ARM_ABS32 .text // RELOC-NEXT: 00000014 R_ARM_ABS32 foo -// RELOC: RELOCATION RECORDS FOR [.rel.debug_aranges]: +// RELOC: RELOCATION RECORDS FOR [.debug_aranges]: // RELOC-NEXT: 00000006 R_ARM_ABS32 .debug_info // RELOC-NEXT: 00000010 R_ARM_ABS32 .text // RELOC-NEXT: 00000018 R_ARM_ABS32 foo diff --git a/test/MC/ARM/dwarf-asm-nonstandard-section.s b/test/MC/ARM/dwarf-asm-nonstandard-section.s index 0bc9f1df70f..38e46b9d1f0 100644 --- a/test/MC/ARM/dwarf-asm-nonstandard-section.s +++ b/test/MC/ARM/dwarf-asm-nonstandard-section.s @@ -42,15 +42,15 @@ b: -// RELOC: RELOCATION RECORDS FOR [.rel.debug_info]: +// RELOC: RELOCATION RECORDS FOR [.debug_info]: // RELOC-NEXT: 00000006 R_ARM_ABS32 .debug_abbrev // RELOC-NEXT: 0000000c R_ARM_ABS32 .debug_line // RELOC-NEXT: R_ARM_ABS32 foo // RELOC-NEXT: R_ARM_ABS32 foo // RELOC-NEXT: R_ARM_ABS32 foo -// RELOC-NOT: RELOCATION RECORDS FOR [.rel.debug_ranges]: +// RELOC-NOT: RELOCATION RECORDS FOR [.debug_ranges]: -// RELOC: RELOCATION RECORDS FOR [.rel.debug_aranges]: +// RELOC: RELOCATION RECORDS FOR [.debug_aranges]: // RELOC-NEXT: 00000006 R_ARM_ABS32 .debug_info // RELOC-NEXT: 00000010 R_ARM_ABS32 foo diff --git a/test/MC/ARM/dwarf-asm-single-section.s b/test/MC/ARM/dwarf-asm-single-section.s index 1e0880d91c9..709818d477e 100644 --- a/test/MC/ARM/dwarf-asm-single-section.s +++ b/test/MC/ARM/dwarf-asm-single-section.s @@ -41,15 +41,15 @@ a: // DWARF-NOT: .debug_pubnames contents: -// RELOC: RELOCATION RECORDS FOR [.rel.debug_info]: +// RELOC: RELOCATION RECORDS FOR [.debug_info]: // RELOC-NEXT: 00000006 R_ARM_ABS32 .debug_abbrev // RELOC-NEXT: 0000000c R_ARM_ABS32 .debug_line // RELOC-NEXT: R_ARM_ABS32 .text // RELOC-NEXT: R_ARM_ABS32 .text // RELOC-NEXT: R_ARM_ABS32 .text -// RELOC-NOT: RELOCATION RECORDS FOR [.rel.debug_ranges]: +// RELOC-NOT: RELOCATION RECORDS FOR [.debug_ranges]: -// RELOC: RELOCATION RECORDS FOR [.rel.debug_aranges]: +// RELOC: RELOCATION RECORDS FOR [.debug_aranges]: // RELOC-NEXT: 00000006 R_ARM_ABS32 .debug_info // RELOC-NEXT: 00000010 R_ARM_ABS32 .text diff --git a/test/MC/ARM/symbol-variants.s b/test/MC/ARM/symbol-variants.s index 96fa18055f0..96fc4bda037 100644 --- a/test/MC/ARM/symbol-variants.s +++ b/test/MC/ARM/symbol-variants.s @@ -1,7 +1,7 @@ @ RUN: llvm-mc < %s -triple armv7-none-linux-gnueabi -filetype=obj | llvm-objdump -triple armv7-none-linux-gnueabi -r - | FileCheck %s --check-prefix=CHECK --check-prefix=ARM @ RUN: llvm-mc < %s -triple thumbv7-none-linux-gnueabi -filetype=obj | llvm-objdump -triple thumbv7-none-linux-gnueabi -r - | FileCheck %s --check-prefix=CHECK --check-prefix=THUMB -@ CHECK-LABEL: RELOCATION RECORDS FOR [.rel.text] +@ CHECK-LABEL: RELOCATION RECORDS FOR [.text] .Lsym: @ empty diff --git a/test/MC/Hexagon/extended_relocations.ll b/test/MC/Hexagon/extended_relocations.ll index a16185c3994..dde50bf8dac 100644 --- a/test/MC/Hexagon/extended_relocations.ll +++ b/test/MC/Hexagon/extended_relocations.ll @@ -1,6 +1,6 @@ ; RUN: llc -filetype=obj -march=hexagon %s -o - | llvm-objdump -r - | FileCheck %s -; CHECK: RELOCATION RECORDS FOR [.rela.text]: +; CHECK: RELOCATION RECORDS FOR [.text]: ; CHECK: 00000000 R_HEX_B22_PCREL printf ; CHECK: 00000004 R_HEX_32_6_X .rodata.str1.1 ; CHECK: 00000008 R_HEX_6_X .rodata.str1.1 diff --git a/test/Object/objdump-relocations.test b/test/Object/objdump-relocations.test index 73e9a4866c6..22d2baa4310 100644 --- a/test/Object/objdump-relocations.test +++ b/test/Object/objdump-relocations.test @@ -51,7 +51,7 @@ ELF-hexagon: R_HEX_B22_PCREL puts ELF-MIPS64EL: .data ELF-MIPS64EL: R_MIPS_64/R_MIPS_NONE/R_MIPS_NONE zed -ELF-MIPSEL: .rel.text +ELF-MIPSEL: .text ELF-MIPSEL: R_MIPS_HI16 _gp_disp ELF-MIPSEL: R_MIPS_LO16 _gp_disp ELF-MIPSEL: R_MIPS_GOT16 $.str diff --git a/test/Object/objdump-shndx.test b/test/Object/objdump-shndx.test index 41b61632750..f3691db9d60 100644 --- a/test/Object/objdump-shndx.test +++ b/test/Object/objdump-shndx.test @@ -4,5 +4,5 @@ Test that llvm-objdump can handle shndx. The relocation points to a section symbol that has st_shndx == SHN_XINDEX. To print the section name llvm-objdump has to use the shndx section. -CHECK: RELOCATION RECORDS FOR [.rela.text]: +CHECK: RELOCATION RECORDS FOR [.text]: CHECK-NEXT: 0000000000000000 R_X86_64_32 bar diff --git a/test/tools/llvm-objdump/relocations-elf.test b/test/tools/llvm-objdump/relocations-elf.test index 019dcc20208..87fe55c0411 100644 --- a/test/tools/llvm-objdump/relocations-elf.test +++ b/test/tools/llvm-objdump/relocations-elf.test @@ -1,20 +1,18 @@ -# RUN: yaml2obj %s > %t +# RUN: yaml2obj --docnum=1 %s > %t # RUN: llvm-objdump --reloc %t > %t1 # RUN: llvm-objdump -r %t > %t2 # RUN: cmp %t1 %t2 # RUN: FileCheck %s --input-file=%t1 -# CHECK: RELOCATION RECORDS FOR [.rel.text]: -# CHECK: 0000000000000001 R_X86_64_32 glob1 -# CHECK: 0000000000000001 R_X86_64_32S glob2 -# CHECK: 0000000000000002 R_X86_64_64 loc1 +# CHECK: RELOCATION RECORDS FOR [.text]: +# CHECK-NEXT: 0000000000000001 R_X86_64_32 glob1 +# CHECK-NEXT: 0000000000000001 R_X86_64_32S glob2 +# CHECK-NEXT: 0000000000000002 R_X86_64_64 loc1 +# CHECK-NEXT: 0000000000000001 R_X86_64_32 glob1+1 +# CHECK-NEXT: 0000000000000001 R_X86_64_32S glob2+2 +# CHECK-NEXT: 0000000000000002 R_X86_64_64 loc1+3 -# CHECK: RELOCATION RECORDS FOR [.rela.text]: -# CHECK: 0000000000000001 R_X86_64_32 glob1+1 -# CHECK: 0000000000000001 R_X86_64_32S glob2+2 -# CHECK: 0000000000000002 R_X86_64_64 loc1+3 - -!ELF +--- !ELF FileHeader: !FileHeader Class: ELFCLASS64 Data: ELFDATA2LSB @@ -72,3 +70,24 @@ Symbols: Binding: STB_GLOBAL - Name: glob2 Binding: STB_GLOBAL + +## Check we report an error if the relocated section identified by the +## sh_info field of a relocation section is invalid. +# RUN: yaml2obj --docnum=2 %s > %t2 +# RUN: not llvm-objdump --reloc %t2 2>&1 | FileCheck %s --check-prefix=ERR +# ERR: LLVM ERROR: Invalid data was encountered while parsing the file + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: +- Name: .rela.foo + Type: SHT_RELA + Link: .symtab + Info: 0x255 + Relocations: + - Offset: 0x1 + Type: R_X86_64_NONE diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 77307bf6fbb..ea3922bbbb1 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -1447,22 +1447,34 @@ void printRelocations(const ObjectFile *Obj) { if (!Obj->isRelocatableObject()) return; + // Build a mapping from relocation target to a vector of relocation + // sections. Usually, there is an only one relocation section for + // each relocated section. + MapVector> SecToRelSec; for (const SectionRef &Section : ToolSectionFilter(*Obj)) { if (Section.relocation_begin() == Section.relocation_end()) continue; + const SectionRef TargetSec = *Section.getRelocatedSection(); + SecToRelSec[TargetSec].push_back(Section); + } + + for (std::pair> &P : SecToRelSec) { StringRef SecName; - error(Section.getName(SecName)); + error(P.first.getName(SecName)); outs() << "RELOCATION RECORDS FOR [" << SecName << "]:\n"; - for (const RelocationRef &Reloc : Section.relocations()) { - uint64_t Address = Reloc.getOffset(); - SmallString<32> RelocName; - SmallString<32> ValueStr; - if (Address < StartAddress || Address > StopAddress || getHidden(Reloc)) - continue; - Reloc.getTypeName(RelocName); - error(getRelocationValueString(Reloc, ValueStr)); - outs() << format(Fmt.data(), Address) << " " << RelocName << " " - << ValueStr << "\n"; + + for (SectionRef Section : P.second) { + for (const RelocationRef &Reloc : Section.relocations()) { + uint64_t Address = Reloc.getOffset(); + SmallString<32> RelocName; + SmallString<32> ValueStr; + if (Address < StartAddress || Address > StopAddress || getHidden(Reloc)) + continue; + Reloc.getTypeName(RelocName); + error(getRelocationValueString(Reloc, ValueStr)); + outs() << format(Fmt.data(), Address) << " " << RelocName << " " + << ValueStr << "\n"; + } } outs() << "\n"; }