diff options
author | George Rimar <grimar@accesssoftek.com> | 2019-08-22 12:39:56 +0000 |
---|---|---|
committer | George Rimar <grimar@accesssoftek.com> | 2019-08-22 12:39:56 +0000 |
commit | 91208447d0a653871165c2139ac7030dc95022b3 (patch) | |
tree | 790c23065cd218da876990bf21e9edaf03ca2aca /llvm/lib/ObjectYAML/ELFEmitter.cpp | |
parent | c2ca965c8984202ef887a43c1119c7e21b559bf3 (diff) | |
download | bcm5719-llvm-91208447d0a653871165c2139ac7030dc95022b3.tar.gz bcm5719-llvm-91208447d0a653871165c2139ac7030dc95022b3.zip |
[yaml2obj] - Lookup relocation symbols in dynamic symbol when .dynsym referenced.
This fixes https://bugs.llvm.org/show_bug.cgi?id=40337.
Previously, it was always assumed that relocations referenced symbols in the static symbol table.
Now, if the Link field references a section called ".dynsym" it will look up these symbols
in the dynamic symbol table.
This patch is heavily based on D59097 by James Henderson
Differential revision: https://reviews.llvm.org/D66532
llvm-svn: 369645
Diffstat (limited to 'llvm/lib/ObjectYAML/ELFEmitter.cpp')
-rw-r--r-- | llvm/lib/ObjectYAML/ELFEmitter.cpp | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp index 5e53baf5fa4..6a2d28e16e2 100644 --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -111,10 +111,11 @@ template <class ELFT> class ELFState { NameToIdxMap SN2I; NameToIdxMap SymN2I; + NameToIdxMap DynSymN2I; ELFYAML::Object &Doc; bool buildSectionIndex(); - bool buildSymbolIndex(ArrayRef<ELFYAML::Symbol> Symbols); + bool buildSymbolIndexes(); void initELFHeader(Elf_Ehdr &Header); void initProgramHeaders(std::vector<Elf_Phdr> &PHeaders); bool initImplicitHeader(ELFState<ELFT> &State, ContiguousBlobAccumulator &CBA, @@ -717,11 +718,12 @@ bool ELFState<ELFT>::writeSectionContent( auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); + const NameToIdxMap &SymMap = Section.Link == ".dynsym" ? DynSymN2I : SymN2I; for (const auto &Rel : Section.Relocations) { unsigned SymIdx = 0; // If a relocation references a symbol, try to look one up in the symbol // table. If it is not there, treat the value as a symbol index. - if (Rel.Symbol && !SymN2I.lookup(*Rel.Symbol, SymIdx) && + if (Rel.Symbol && !SymMap.lookup(*Rel.Symbol, SymIdx) && !to_integer(*Rel.Symbol, SymIdx)) { WithColor::error() << "Unknown symbol referenced: '" << *Rel.Symbol << "' at YAML section '" << Section.Name << "'.\n"; @@ -987,11 +989,10 @@ template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() { return true; } -template <class ELFT> -bool ELFState<ELFT>::buildSymbolIndex(ArrayRef<ELFYAML::Symbol> Symbols) { +static bool buildSymbolsMap(ArrayRef<ELFYAML::Symbol> V, NameToIdxMap &Map) { bool GlobalSymbolSeen = false; std::size_t I = 0; - for (const auto &Sym : Symbols) { + for (const ELFYAML::Symbol &Sym : V) { ++I; StringRef Name = Sym.Name; @@ -1003,7 +1004,7 @@ bool ELFState<ELFT>::buildSymbolIndex(ArrayRef<ELFYAML::Symbol> Symbols) { if (Sym.Binding.value != ELF::STB_LOCAL) GlobalSymbolSeen = true; - if (!Name.empty() && !SymN2I.addName(Name, I)) { + if (!Name.empty() && !Map.addName(Name, I)) { WithColor::error() << "Repeated symbol name: '" << Name << "'.\n"; return false; } @@ -1011,6 +1012,11 @@ bool ELFState<ELFT>::buildSymbolIndex(ArrayRef<ELFYAML::Symbol> Symbols) { return true; } +template <class ELFT> bool ELFState<ELFT>::buildSymbolIndexes() { + return buildSymbolsMap(Doc.Symbols, SymN2I) && + buildSymbolsMap(Doc.DynamicSymbols, DynSymN2I); +} + template <class ELFT> void ELFState<ELFT>::finalizeStrings() { // Add the regular symbol names to .strtab section. for (const ELFYAML::Symbol &Sym : Doc.Symbols) @@ -1049,10 +1055,7 @@ int ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc) { // sections that might want to use them. State.finalizeStrings(); - if (!State.buildSectionIndex()) - return 1; - - if (!State.buildSymbolIndex(Doc.Symbols)) + if (!State.buildSectionIndex() || !State.buildSymbolIndexes()) return 1; Elf_Ehdr Header; |