1
0
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:
James Henderson 2019-03-29 11:47:19 +00:00
parent 76661995d9
commit 12f4bad60b
2 changed files with 118 additions and 45 deletions

View 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

View File

@ -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>