Index: llvm/trunk/test/tools/llvm-readobj/elf-reloc-zero-name-or-value.test =================================================================== --- llvm/trunk/test/tools/llvm-readobj/elf-reloc-zero-name-or-value.test +++ llvm/trunk/test/tools/llvm-readobj/elf-reloc-zero-name-or-value.test @@ -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 Index: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp +++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp @@ -455,6 +455,8 @@ 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 void GNUStyle::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 @@ TargetName = this->dumper()->getFullSymbolName( Sym, StrTable, SymTab->sh_type == SHT_DYNSYM /* IsDynamic */); } + printRelocation(Obj, Sym, TargetName, R, IsRela); +} +template +void GNUStyle::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 @@ template void GNUStyle::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