summaryrefslogtreecommitdiffstats
path: root/llvm/tools
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2017-09-06 00:57:53 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2017-09-06 00:57:53 +0000
commitdc8b7a96bdccc73c5f4ca1baef45afba6d405908 (patch)
tree9becdcc93b28ec5e5db6d1e31bc8abd6531eafe0 /llvm/tools
parentbad2c4a000ae189736bbdd80df71aa0776b7c66f (diff)
downloadbcm5719-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.cpp25
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;
OpenPOWER on IntegriCloud