From 083138333b3d99d1e9c5bc19672452ed63f29be9 Mon Sep 17 00:00:00 2001 From: James Henderson Date: Fri, 8 Mar 2019 13:22:05 +0000 Subject: [PATCH] [llvm-readelf]Don't lose negative-ness of negative addends for no symbol relocations llvm-readelf prints relocation addends as: [+-] where [+-] is determined from whether addend is less than zero or not. However, it does not print the +/- if there is no symbol, which meant that negative addends became their positive value with no indication that this had happened. This patch stops the absolute conversion when addends are negative and there is no associated symbol. Reviewed by: Higuoxing, mattd, MaskRay Differential Revision: https://reviews.llvm.org/D59095 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355696 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../elf-reloc-negative-addend-no-sym.test | 74 +++++++++++++++++++ tools/llvm-readobj/ELFDumper.cpp | 38 +++++----- 2 files changed, 95 insertions(+), 17 deletions(-) create mode 100644 test/tools/llvm-readobj/elf-reloc-negative-addend-no-sym.test diff --git a/test/tools/llvm-readobj/elf-reloc-negative-addend-no-sym.test b/test/tools/llvm-readobj/elf-reloc-negative-addend-no-sym.test new file mode 100644 index 00000000000..13e6a96cf3c --- /dev/null +++ b/test/tools/llvm-readobj/elf-reloc-negative-addend-no-sym.test @@ -0,0 +1,74 @@ +# Show that llvm-readelf properly prints the addend for relocations that do not +# have an associated symbol but have a negative addend. + +# RUN: yaml2obj %s -o %t +# RUN: llvm-readelf --relocations %t | FileCheck %s --check-prefix=REL +# RUN: llvm-readelf --dyn-relocations %t | FileCheck %s --check-prefix=DYN + +# REL: Relocation section '.rela.text' at offset {{.*}} contains 1 entries: +# REL-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend +# REL-NEXT: 0000000000000000 0000000000000000 R_X86_64_NONE ffffffffffffffff +# REL-EMPTY: +# REL-NEXT: Relocation section '.rela.dyn' at offset {{.*}} contains 1 entries: +# REL-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend +# REL-NEXT: 0000000000000008 0000000000000000 R_X86_64_NONE ffffffffffffffff + +# DYN: 'RELA' relocation section at offset {{.*}} contains 24 bytes: +# DYN-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend +# DYN-NEXT: 0000000000000008 0000000000000000 R_X86_64_NONE ffffffffffffffff + +--- !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 + - Name: .dynamic + Type: SHT_DYNAMIC + Flags: [SHF_ALLOC] + Address: 0x1000 + AddressAlign: 0x1000 + Entries: + - Tag: DT_RELA + Value: 0x1100 + - Tag: DT_RELASZ + Value: 24 + - 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: 8 + Type: R_X86_64_NONE + Addend: -1 +DynamicSymbols: + Global: + - Name: force_dynsym +ProgramHeaders: + - Type: PT_LOAD + VAddr: 0x1000 + Sections: + - Section: .rela.dyn + - Section: .dynamic + - Type: PT_DYNAMIC + VAddr: 0x1000 + Sections: + - Section: .dynamic diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index a406d366eea..793bbf06ed0 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -2730,15 +2730,18 @@ void GNUStyle::printRelocation(const ELFO *Obj, const Elf_Shdr *SymTab, printField(F); std::string Addend; - if (Sym && IsRela) { - if (R.r_addend < 0) - Addend = " - "; - else - Addend = " + "; - } + if (IsRela) { + int64_t RelAddend = R.r_addend; + if (Sym) { + if (R.r_addend < 0) { + Addend = " - "; + RelAddend = std::abs(RelAddend); + } else + Addend = " + "; + } - if (IsRela) - Addend += to_hexString(std::abs(R.r_addend), false); + Addend += to_hexString(RelAddend, false); + } OS << Addend << "\n"; } @@ -3388,17 +3391,18 @@ void GNUStyle::printDynamicRelocation(const ELFO *Obj, Elf_Rela R, for (auto &Field : Fields) printField(Field); - int64_t RelAddend = R.r_addend; std::string Addend; - if (!SymbolName.empty() && IsRela) { - if (R.r_addend < 0) - Addend = " - "; - else - 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)); } - - if (IsRela) - Addend += to_string(format_hex_no_prefix(std::abs(RelAddend), 1)); OS << Addend << "\n"; } -- 2.50.1