forked from OSchip/llvm-project
[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 llvm-svn: 360143
This commit is contained in:
parent
7399ad3193
commit
5c922f6988
|
@ -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<object::SectionRef> {
|
||||
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
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<SectionRef, std::vector<SectionRef>> 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<SectionRef, std::vector<SectionRef>> &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";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue