Use the section name if a STT_SECTION symbol has empty name.

Without this we would have multiple relocations pointing to symbols
with the same name: the empty string. There was no way for yaml2obj to
be able to handle that.

A more general solution would be to unique symbol names in a similar
way to how we unique section names.  In practice I think this covers
all common cases and is a bit more user friendly than using names like
sym1, sym2, sym3, etc.

llvm-svn: 312603
This commit is contained in:
Rafael Espindola 2017-09-06 00:57:53 +00:00
parent 97cfe8f552
commit a4c851ec3c
3 changed files with 66 additions and 21 deletions

View File

@ -0,0 +1,9 @@
# RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
# RUN: obj2yaml %t.o | FileCheck %s
# CHECK: Relocations:
# CHECK: Symbol: .text
# CHECK: Symbols:
# CHECK: - Name: .text
.quad .text

View File

@ -268,19 +268,26 @@ ELF-MIPSEL-NEXT: - Name: '$.str'
ELF-MIPSEL-NEXT: Type: STT_OBJECT
ELF-MIPSEL-NEXT: Section: .rodata.str1.1
ELF-MIPSEL-NEXT: Size: 0x000000000000000D
ELF-MIPSEL-NEXT: - Type: STT_SECTION
ELF-MIPSEL-NEXT: - Name: .text
ELF-MIPSEL-NEXT: Type: STT_SECTION
ELF-MIPSEL-NEXT: Section: .text
ELF-MIPSEL-NEXT: - Type: STT_SECTION
ELF-MIPSEL-NEXT: - Name: .data
ELF-MIPSEL-NEXT: Type: STT_SECTION
ELF-MIPSEL-NEXT: Section: .data
ELF-MIPSEL-NEXT: - Type: STT_SECTION
ELF-MIPSEL-NEXT: - Name: .bss
ELF-MIPSEL-NEXT: Type: STT_SECTION
ELF-MIPSEL-NEXT: Section: .bss
ELF-MIPSEL-NEXT: - Type: STT_SECTION
ELF-MIPSEL-NEXT: - Name: .mdebug.abi32
ELF-MIPSEL-NEXT: Type: STT_SECTION
ELF-MIPSEL-NEXT: Section: .mdebug.abi32
ELF-MIPSEL-NEXT: - Type: STT_SECTION
ELF-MIPSEL-NEXT: - Name: .rodata.str1.1
ELF-MIPSEL-NEXT: Type: STT_SECTION
ELF-MIPSEL-NEXT: Section: .rodata.str1.1
ELF-MIPSEL-NEXT: - Type: STT_SECTION
ELF-MIPSEL-NEXT: - Name: .reginfo
ELF-MIPSEL-NEXT: Type: STT_SECTION
ELF-MIPSEL-NEXT: Section: .reginfo
ELF-MIPSEL-NEXT: - Type: STT_SECTION
ELF-MIPSEL-NEXT: - Name: .MIPS.abiflags
ELF-MIPSEL-NEXT: Type: STT_SECTION
ELF-MIPSEL-NEXT: Section: .MIPS.abiflags
ELF-MIPSEL-NEXT: Global:
ELF-MIPSEL-NEXT: - Name: main
@ -336,17 +343,22 @@ ELF-MIPS64EL-NEXT: AddressAlign: 0x0000000000000004
ELF-MIPS64EL-NEXT: Content: ''
ELF-MIPS64EL-NEXT: Symbols:
ELF-MIPS64EL-NEXT: Local:
ELF-MIPS64EL-NEXT: - Type: STT_SECTION
ELF-MIPS64EL-NEXT: - Name: .text
ELF-MIPS64EL-NEXT: Type: STT_SECTION
ELF-MIPS64EL-NEXT: Section: .text
ELF-MIPS64EL-NEXT: - Type: STT_SECTION
ELF-MIPS64EL-NEXT: - Name: .data
ELF-MIPS64EL-NEXT: Type: STT_SECTION
ELF-MIPS64EL-NEXT: Section: .data
ELF-MIPS64EL-NEXT: - Type: STT_SECTION
ELF-MIPS64EL-NEXT: - Name: .bss
ELF-MIPS64EL-NEXT: Type: STT_SECTION
ELF-MIPS64EL-NEXT: Section: .bss
ELF-MIPS64EL-NEXT: - Name: bar
ELF-MIPS64EL-NEXT: Section: .data
ELF-MIPS64EL-NEXT: - Type: STT_SECTION
ELF-MIPS64EL-NEXT: - Name: .MIPS.options
ELF-MIPS64EL-NEXT: Type: STT_SECTION
ELF-MIPS64EL-NEXT: Section: .MIPS.options
ELF-MIPS64EL-NEXT: - Type: STT_SECTION
ELF-MIPS64EL-NEXT: - Name: .pdr
ELF-MIPS64EL-NEXT: Type: STT_SECTION
ELF-MIPS64EL-NEXT: Section: .pdr
ELF-MIPS64EL-NEXT: Global:
ELF-MIPS64EL-NEXT: - Name: zed
@ -382,7 +394,7 @@ ELF-X86-64-NEXT: AddressAlign: 0x0000000000000008
ELF-X86-64-NEXT: Info: .text
ELF-X86-64-NEXT: Relocations:
ELF-X86-64-NEXT: - Offset: 0x000000000000000D
ELF-X86-64-NEXT: Symbol: ''
ELF-X86-64-NEXT: Symbol: .rodata.str1.1
ELF-X86-64-NEXT: Type: R_X86_64_32S
ELF-X86-64-NEXT: - Offset: 0x0000000000000012
ELF-X86-64-NEXT: Symbol: puts
@ -396,11 +408,14 @@ ELF-X86-64-NEXT: Symbols:
ELF-X86-64-NEXT: Local:
ELF-X86-64-NEXT: - Name: trivial-object-test.s
ELF-X86-64-NEXT: Type: STT_FILE
ELF-X86-64-NEXT: - Type: STT_SECTION
ELF-X86-64-NEXT: - Name: .text
ELF-X86-64-NEXT: Type: STT_SECTION
ELF-X86-64-NEXT: Section: .text
ELF-X86-64-NEXT: - Type: STT_SECTION
ELF-X86-64-NEXT: - Name: .rodata.str1.1
ELF-X86-64-NEXT: Type: STT_SECTION
ELF-X86-64-NEXT: Section: .rodata.str1.1
ELF-X86-64-NEXT: - Type: STT_SECTION
ELF-X86-64-NEXT: - Name: .note.GNU-stack
ELF-X86-64-NEXT: Type: STT_SECTION
ELF-X86-64-NEXT: Section: .note.GNU-stack
ELF-X86-64-NEXT: Global:
ELF-X86-64-NEXT: - Name: main
@ -431,9 +446,11 @@ ELF-AVR-NEXT: AddressAlign: 0x0000000000000001
ELF-AVR-NEXT: Content: ''
ELF-AVR-NEXT: Symbols:
ELF-AVR-NEXT: Local:
ELF-AVR-NEXT: - Type: STT_SECTION
ELF-AVR-NEXT: - Name: .text
ELF-AVR-NEXT: Type: STT_SECTION
ELF-AVR-NEXT: Section: .text
ELF-AVR-NEXT: - Type: STT_SECTION
ELF-AVR-NEXT: - Name: .data
ELF-AVR-NEXT: Type: STT_SECTION
ELF-AVR-NEXT: Section: .data
ELF-AVR-NEXT: Value: 0x0000000000800060
ELF-AVR-NEXT: - Name: a.o

View File

@ -36,6 +36,8 @@ class ELFDumper {
DenseSet<StringRef> UsedSectionNames;
std::vector<std::string> SectionNames;
Expected<StringRef> getUniquedSectionName(const Elf_Shdr *Sec);
Expected<StringRef> getSymbolName(const Elf_Sym *Sym, StringRef StrTable,
const Elf_Shdr *SymTab);
const object::ELFFile<ELFT> &Obj;
ArrayRef<Elf_Word> ShndxTable;
@ -87,6 +89,23 @@ ELFDumper<ELFT>::getUniquedSectionName(const Elf_Shdr *Sec) {
return Ret;
}
template <class ELFT>
Expected<StringRef> ELFDumper<ELFT>::getSymbolName(const Elf_Sym *Sym,
StringRef StrTable,
const Elf_Shdr *SymTab) {
Expected<StringRef> SymbolNameOrErr = Sym->getName(StrTable);
if (!SymbolNameOrErr)
return SymbolNameOrErr;
StringRef Name = *SymbolNameOrErr;
if (Name.empty() && Sym->getType() == ELF::STT_SECTION) {
auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
if (!ShdrOrErr)
return ShdrOrErr.takeError();
return getUniquedSectionName(*ShdrOrErr);
}
return Name;
}
template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
auto Y = make_unique<ELFYAML::Object>();
@ -217,7 +236,7 @@ ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
S.Size = Sym->st_size;
S.Other = Sym->st_other;
Expected<StringRef> SymbolNameOrErr = Sym->getName(StrTable);
Expected<StringRef> SymbolNameOrErr = getSymbolName(Sym, StrTable, SymTab);
if (!SymbolNameOrErr)
return errorToErrorCode(SymbolNameOrErr.takeError());
S.Name = SymbolNameOrErr.get();
@ -259,7 +278,7 @@ std::error_code ELFDumper<ELFT>::dumpRelocation(const RelT *Rel,
StringRef StrTab = *StrTabOrErr;
if (Sym) {
Expected<StringRef> NameOrErr = Sym->getName(StrTab);
Expected<StringRef> NameOrErr = getSymbolName(Sym, StrTab, SymTab);
if (!NameOrErr)
return errorToErrorCode(NameOrErr.takeError());
R.Symbol = NameOrErr.get();
@ -425,7 +444,7 @@ ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) {
auto sectionContents = Obj.getSectionContents(Shdr);
if (!sectionContents)
return errorToErrorCode(sectionContents.takeError());
Expected<StringRef> symbolName = symbol->getName(StrTab);
Expected<StringRef> symbolName = getSymbolName(symbol, StrTab, Symtab);
if (!symbolName)
return errorToErrorCode(symbolName.takeError());
S->Info = *symbolName;