diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2017-09-06 00:57:53 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2017-09-06 00:57:53 +0000 |
| commit | dc8b7a96bdccc73c5f4ca1baef45afba6d405908 (patch) | |
| tree | 9becdcc93b28ec5e5db6d1e31bc8abd6531eafe0 /llvm/tools | |
| parent | bad2c4a000ae189736bbdd80df71aa0776b7c66f (diff) | |
| download | bcm5719-llvm-dc8b7a96bdccc73c5f4ca1baef45afba6d405908.tar.gz bcm5719-llvm-dc8b7a96bdccc73c5f4ca1baef45afba6d405908.zip | |
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
Diffstat (limited to 'llvm/tools')
| -rw-r--r-- | llvm/tools/obj2yaml/elf2yaml.cpp | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index b603cb84aea..8997a5c4211 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -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; |

