Create a SymbolBody for locals.

pr26878 shows a case where locals have to be in the got.

llvm-svn: 263222
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 7925695..6060de6 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -46,7 +46,7 @@
 
 template <class ELFT>
 typename ELFFileBase<ELFT>::Elf_Sym_Range
-ELFFileBase<ELFT>::getSymbolsHelper(bool Local) {
+ELFFileBase<ELFT>::getElfSymbols(bool OnlyGlobals) {
   if (!Symtab)
     return Elf_Sym_Range(nullptr, nullptr);
   Elf_Sym_Range Syms = ELFObj.symbols(Symtab);
@@ -54,10 +54,10 @@
   uint32_t FirstNonLocal = Symtab->sh_info;
   if (FirstNonLocal > NumSymbols)
     fatal("Invalid sh_info in symbol table");
-  if (!Local)
+
+  if (OnlyGlobals)
     return make_range(Syms.begin() + FirstNonLocal, Syms.end());
-  // +1 to skip over dummy symbol.
-  return make_range(Syms.begin() + 1, Syms.begin() + FirstNonLocal);
+  return make_range(Syms.begin(), Syms.end());
 }
 
 template <class ELFT>
@@ -77,19 +77,30 @@
 }
 
 template <class ELFT>
-typename ELFFileBase<ELFT>::Elf_Sym_Range
-ELFFileBase<ELFT>::getNonLocalSymbols() {
-  return getSymbolsHelper(false);
-}
-
-template <class ELFT>
 elf::ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M)
     : ELFFileBase<ELFT>(Base::ObjectKind, M) {}
 
 template <class ELFT>
-typename elf::ObjectFile<ELFT>::Elf_Sym_Range
-elf::ObjectFile<ELFT>::getLocalSymbols() {
-  return this->getSymbolsHelper(true);
+ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getNonLocalSymbols() {
+  if (!this->Symtab)
+    return this->SymbolBodies;
+  uint32_t FirstNonLocal = this->Symtab->sh_info;
+  return makeArrayRef(this->SymbolBodies).slice(FirstNonLocal);
+}
+
+template <class ELFT>
+ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getLocalSymbols() {
+  if (!this->Symtab)
+    return this->SymbolBodies;
+  uint32_t FirstNonLocal = this->Symtab->sh_info;
+  return makeArrayRef(this->SymbolBodies).slice(1, FirstNonLocal - 1);
+}
+
+template <class ELFT>
+ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getSymbols() {
+  if (!this->Symtab)
+    return this->SymbolBodies;
+  return makeArrayRef(this->SymbolBodies).slice(1);
 }
 
 template <class ELFT> uint32_t elf::ObjectFile<ELFT>::getMipsGp0() const {
@@ -99,16 +110,6 @@
 }
 
 template <class ELFT>
-const typename elf::ObjectFile<ELFT>::Elf_Sym *
-elf::ObjectFile<ELFT>::getLocalSymbol(uintX_t SymIndex) {
-  uint32_t FirstNonLocal = this->Symtab->sh_info;
-  if (SymIndex >= FirstNonLocal)
-    return nullptr;
-  Elf_Sym_Range Syms = this->ELFObj.symbols(this->Symtab);
-  return Syms.begin() + SymIndex;
-}
-
-template <class ELFT>
 void elf::ObjectFile<ELFT>::parse(DenseSet<StringRef> &ComdatGroups) {
   // Read section and symbol tables.
   initializeSections(ComdatGroups);
@@ -266,7 +267,7 @@
 
 template <class ELFT> void elf::ObjectFile<ELFT>::initializeSymbols() {
   this->initStringTable();
-  Elf_Sym_Range Syms = this->getNonLocalSymbols();
+  Elf_Sym_Range Syms = this->getElfSymbols(false);
   uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
   SymbolBodies.reserve(NumSymbols);
   for (const Elf_Sym &Sym : Syms)
@@ -289,6 +290,10 @@
 
 template <class ELFT>
 SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
+  unsigned char Binding = Sym->getBinding();
+  if (Binding == STB_LOCAL)
+    return new (Alloc) LocalSymbol<ELFT>(*Sym);
+
   StringRef Name = check(Sym->getName(this->StringTable));
 
   switch (Sym->st_shndx) {
@@ -300,7 +305,7 @@
                                      Sym->getVisibility());
   }
 
-  switch (Sym->getBinding()) {
+  switch (Binding) {
   default:
     fatal("Unexpected binding");
   case STB_GLOBAL:
@@ -399,7 +404,7 @@
 
 // Fully parse the shared object file. This must be called after parseSoName().
 template <class ELFT> void SharedFile<ELFT>::parseRest() {
-  Elf_Sym_Range Syms = this->getNonLocalSymbols();
+  Elf_Sym_Range Syms = this->getElfSymbols(true);
   uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());
   SymbolBodies.reserve(NumSymbols);
   for (const Elf_Sym &Sym : Syms) {