mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[llvm-readelf]Merge dynamic and static relocation printing to avoid code duplication
The majority of the printRelocation and printDynamicRelocation functions were identical. This patch factors this all out into a new function. There are a couple of minor differences to do with printing of symbols without names, but I think these are harmless, and in some cases a small improvement. Reviewed by: grimar, rupprecht, Higuoxing Differential Revision: https://reviews.llvm.org/D59823 llvm-svn: 357246
This commit is contained in:
parent
76661995d9
commit
12f4bad60b
95
test/tools/llvm-readobj/elf-reloc-zero-name-or-value.test
Normal file
95
test/tools/llvm-readobj/elf-reloc-zero-name-or-value.test
Normal file
@ -0,0 +1,95 @@
|
||||
# Show that the value field is omitted if a symbol has no name or value, but is
|
||||
# printed if one is present. Test for both static and dynamic relocation
|
||||
# printing.
|
||||
|
||||
# RUN: yaml2obj %s -o %t
|
||||
# RUN: llvm-readelf --relocations --dyn-relocations %t | FileCheck %s
|
||||
|
||||
# CHECK: Relocation section '.rela.text' at offset {{.*}} contains 2 entries:
|
||||
# CHECK-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
|
||||
# CHECK-NEXT: 0000000000000000 0000000000000000 R_X86_64_NONE 1
|
||||
# CHECK-NEXT: 0000000000000000 0000000100000000 R_X86_64_NONE 0000000000000000 sym + 1
|
||||
|
||||
# CHECK: Relocation section '.rela.dyn' at offset {{.*}} contains 2 entries:
|
||||
# CHECK-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
|
||||
# CHECK-NEXT: 0000000000000000 0000000000000000 R_X86_64_NONE 1
|
||||
# CHECK-NEXT: 0000000000000000 0000000100000000 R_X86_64_NONE 0000000000000000 sym + 1
|
||||
|
||||
# CHECK: 'RELA' relocation section at offset {{.*}} contains 48 bytes:
|
||||
# CHECK-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
|
||||
# CHECK-NEXT: 0000000000000000 0000000000000000 R_X86_64_NONE 1
|
||||
# CHECK-NEXT: 0000000000000000 0000000100000000 R_X86_64_NONE 0000000000000000 sym + 1
|
||||
|
||||
# TODO: Add test for symbol with no name but with a value once yaml2obj allows
|
||||
# referencing symbols with no name from relocations.
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Size: 0x10
|
||||
- Name: .rela.text
|
||||
Type: SHT_RELA
|
||||
Link: .symtab
|
||||
Info: .text
|
||||
Relocations:
|
||||
- Offset: 0
|
||||
Type: R_X86_64_NONE
|
||||
Addend: 1
|
||||
- Offset: 0
|
||||
Type: R_X86_64_NONE
|
||||
Addend: 1
|
||||
Symbol: sym
|
||||
- Name: .dynamic
|
||||
Type: SHT_DYNAMIC
|
||||
Flags: [SHF_ALLOC]
|
||||
Address: 0x1000
|
||||
AddressAlign: 0x1000
|
||||
Entries:
|
||||
- Tag: DT_RELA
|
||||
Value: 0x1100
|
||||
- Tag: DT_RELASZ
|
||||
Value: 48
|
||||
- Tag: DT_RELAENT
|
||||
Value: 24
|
||||
- Tag: DT_NULL
|
||||
Value: 0
|
||||
- Name: .rela.dyn
|
||||
Type: SHT_RELA
|
||||
Flags: [SHF_ALLOC]
|
||||
Info: .text
|
||||
Address: 0x1100
|
||||
AddressAlign: 0x100
|
||||
Relocations:
|
||||
- Offset: 0
|
||||
Type: R_X86_64_NONE
|
||||
Addend: 1
|
||||
- Offset: 0
|
||||
Type: R_X86_64_NONE
|
||||
Addend: 1
|
||||
Symbol: sym
|
||||
Symbols:
|
||||
Global:
|
||||
- Name: sym
|
||||
Value: 0
|
||||
Section: .text
|
||||
DynamicSymbols:
|
||||
Global:
|
||||
- Name: sym
|
||||
Value: 0
|
||||
Section: .text
|
||||
ProgramHeaders:
|
||||
- Type: PT_LOAD
|
||||
VAddr: 0x1000
|
||||
Sections:
|
||||
- Section: .rela.dyn
|
||||
- Section: .dynamic
|
||||
- Type: PT_DYNAMIC
|
||||
VAddr: 0x1000
|
||||
Sections:
|
||||
- Section: .dynamic
|
@ -455,6 +455,8 @@ private:
|
||||
void printRelocHeader(unsigned SType);
|
||||
void printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab,
|
||||
const Elf_Rela &R, bool IsRela);
|
||||
void printRelocation(const ELFO *Obj, const Elf_Sym *Sym,
|
||||
StringRef SymbolName, const Elf_Rela &R, bool IsRela);
|
||||
void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First,
|
||||
StringRef StrTable, bool IsDynamic) override;
|
||||
std::string getSymbolSectionNdx(const ELFO *Obj, const Elf_Sym *Symbol,
|
||||
@ -2602,12 +2604,6 @@ template <class ELFT> void GNUStyle<ELFT>::printGroupSections(const ELFO *Obj) {
|
||||
template <class ELFT>
|
||||
void GNUStyle<ELFT>::printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab,
|
||||
const Elf_Rela &R, bool IsRela) {
|
||||
// First two fields are bit width dependent. The rest of them are after are
|
||||
// fixed width.
|
||||
unsigned Bias = ELFT::Is64Bits ? 8 : 0;
|
||||
Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias};
|
||||
SmallString<32> RelocName;
|
||||
Obj->getRelocationTypeName(R.getType(Obj->isMips64EL()), RelocName);
|
||||
const Elf_Sym *Sym = unwrapOrError(Obj->getRelocationSymbol(&R, SymTab));
|
||||
std::string TargetName;
|
||||
if (Sym && Sym->getType() == ELF::STT_SECTION) {
|
||||
@ -2619,21 +2615,36 @@ void GNUStyle<ELFT>::printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab,
|
||||
TargetName = this->dumper()->getFullSymbolName(
|
||||
Sym, StrTable, SymTab->sh_type == SHT_DYNSYM /* IsDynamic */);
|
||||
}
|
||||
printRelocation(Obj, Sym, TargetName, R, IsRela);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void GNUStyle<ELFT>::printRelocation(const ELFO *Obj, const Elf_Sym *Sym,
|
||||
StringRef SymbolName, const Elf_Rela &R,
|
||||
bool IsRela) {
|
||||
// First two fields are bit width dependent. The rest of them are fixed width.
|
||||
unsigned Bias = ELFT::Is64Bits ? 8 : 0;
|
||||
Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias};
|
||||
unsigned Width = ELFT::Is64Bits ? 16 : 8;
|
||||
|
||||
Fields[0].Str = to_string(format_hex_no_prefix(R.r_offset, Width));
|
||||
Fields[1].Str = to_string(format_hex_no_prefix(R.r_info, Width));
|
||||
Fields[2].Str = RelocName.str();
|
||||
if (Sym)
|
||||
|
||||
SmallString<32> RelocName;
|
||||
Obj->getRelocationTypeName(R.getType(Obj->isMips64EL()), RelocName);
|
||||
Fields[2].Str = RelocName.c_str();
|
||||
|
||||
if (Sym && (!SymbolName.empty() || Sym->getValue() != 0))
|
||||
Fields[3].Str = to_string(format_hex_no_prefix(Sym->getValue(), Width));
|
||||
Fields[4].Str = TargetName;
|
||||
for (auto &F : Fields)
|
||||
|
||||
Fields[4].Str = SymbolName;
|
||||
for (const Field &F : Fields)
|
||||
printField(F);
|
||||
|
||||
std::string Addend;
|
||||
if (IsRela) {
|
||||
int64_t RelAddend = R.r_addend;
|
||||
if (Sym) {
|
||||
if (!SymbolName.empty()) {
|
||||
if (R.r_addend < 0) {
|
||||
Addend = " - ";
|
||||
RelAddend = std::abs(RelAddend);
|
||||
@ -3267,44 +3278,11 @@ void GNUStyle<ELFT>::printSectionMapping(const ELFO *Obj) {
|
||||
template <class ELFT>
|
||||
void GNUStyle<ELFT>::printDynamicRelocation(const ELFO *Obj, Elf_Rela R,
|
||||
bool IsRela) {
|
||||
unsigned Bias = ELFT::Is64Bits ? 8 : 0;
|
||||
// First two fields are bit width dependent. The rest of them are after are
|
||||
// fixed width.
|
||||
Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias};
|
||||
|
||||
unsigned Width = ELFT::Is64Bits ? 16 : 8;
|
||||
Fields[0].Str = to_string(format_hex_no_prefix(R.r_offset, Width));
|
||||
Fields[1].Str = to_string(format_hex_no_prefix(R.r_info, Width));
|
||||
|
||||
uint32_t SymIndex = R.getSymbol(Obj->isMips64EL());
|
||||
const Elf_Sym *Sym = this->dumper()->dynamic_symbols().begin() + SymIndex;
|
||||
SmallString<32> RelocName;
|
||||
Obj->getRelocationTypeName(R.getType(Obj->isMips64EL()), RelocName);
|
||||
Fields[2].Str = RelocName.c_str();
|
||||
|
||||
std::string SymbolName = maybeDemangle(
|
||||
unwrapOrError(Sym->getName(this->dumper()->getDynamicStringTable())));
|
||||
|
||||
if (!SymbolName.empty() || Sym->getValue() != 0)
|
||||
Fields[3].Str = to_string(format_hex_no_prefix(Sym->getValue(), Width));
|
||||
|
||||
Fields[4].Str = SymbolName;
|
||||
for (auto &Field : Fields)
|
||||
printField(Field);
|
||||
|
||||
std::string Addend;
|
||||
if (IsRela) {
|
||||
int64_t RelAddend = R.r_addend;
|
||||
if (!SymbolName.empty()) {
|
||||
if (R.r_addend < 0) {
|
||||
Addend = " - ";
|
||||
RelAddend = std::abs(RelAddend);
|
||||
} else
|
||||
Addend = " + ";
|
||||
}
|
||||
Addend += to_string(format_hex_no_prefix(RelAddend, 1));
|
||||
}
|
||||
OS << Addend << "\n";
|
||||
printRelocation(Obj, Sym, SymbolName, R, IsRela);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
|
Loading…
x
Reference in New Issue
Block a user