[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
diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index 5e53baf..6a2d28e 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -111,10 +111,11 @@
 
   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 @@
 
   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 @@
   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 @@
     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 @@
   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 @@
   // 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;