[lld] r263222 - Create a SymbolBody for locals.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 11 04:06:32 PST 2016


Author: rafael
Date: Fri Mar 11 06:06:30 2016
New Revision: 263222

URL: http://llvm.org/viewvc/llvm-project?rev=263222&view=rev
Log:
Create a SymbolBody for locals.

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

Modified:
    lld/trunk/ELF/ICF.cpp
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputFiles.h
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/MarkLive.cpp
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/Target.cpp
    lld/trunk/ELF/Target.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/ICF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ICF.cpp?rev=263222&r1=263221&r2=263222&view=diff
==============================================================================
--- lld/trunk/ELF/ICF.cpp (original)
+++ lld/trunk/ELF/ICF.cpp Fri Mar 11 06:06:30 2016
@@ -93,7 +93,7 @@ private:
   static uint64_t getHash(InputSection<ELFT> *S);
   static bool isEligible(InputSectionBase<ELFT> *Sec);
   static std::vector<InputSection<ELFT> *> getSections(SymbolTable<ELFT> *S);
-  static SymbolBody *getSymbol(const InputSection<ELFT> *Sec,
+  static SymbolBody &getSymbol(const InputSection<ELFT> *Sec,
                                const Elf_Rel *Rel);
 
   void segregate(InputSection<ELFT> **Begin, InputSection<ELFT> **End,
@@ -161,10 +161,10 @@ ICF<ELFT>::getSections(SymbolTable<ELFT>
 }
 
 template <class ELFT>
-SymbolBody *ICF<ELFT>::getSymbol(const InputSection<ELFT> *Sec,
+SymbolBody &ICF<ELFT>::getSymbol(const InputSection<ELFT> *Sec,
                                  const Elf_Rel *Rel) {
   uint32_t SymIdx = Rel->getSymbol(Config->Mips64EL);
-  return Sec->File->getSymbolBody(SymIdx);
+  return Sec->File->getSymbolBody(SymIdx).repl();
 }
 
 // All sections between Begin and End must have the same group ID before
@@ -259,26 +259,15 @@ bool ICF<ELFT>::variableEq(const InputSe
   const RelTy *EA = RelsA.end();
   const RelTy *IB = RelsB.begin();
   for (; IA != EA; ++IA, ++IB) {
-    // If both IA and IB are pointing to the same local symbol,
-    // this "if" condition must be true.
-    if (A->File == B->File &&
-        IA->getSymbol(Config->Mips64EL) == IB->getSymbol(Config->Mips64EL))
-      continue;
-
-    // Otherwise, IA and IB must be pointing to the global symbols.
-    SymbolBody *SA = getSymbol(A, (const Elf_Rel *)IA);
-    SymbolBody *SB = getSymbol(B, (const Elf_Rel *)IB);
-    if (!SA || !SB)
-      return false;
-
-    // The global symbols should be simply the same.
-    if (SA->repl() == SB->repl())
+    SymbolBody &SA = getSymbol(A, (const Elf_Rel *)IA);
+    SymbolBody &SB = getSymbol(B, (const Elf_Rel *)IB);
+    if (&SA == &SB)
       continue;
 
     // Or, the symbols should be pointing to the same section
     // in terms of the group ID.
-    auto *DA = dyn_cast<DefinedRegular<ELFT>>(SA->repl());
-    auto *DB = dyn_cast<DefinedRegular<ELFT>>(SB->repl());
+    auto *DA = dyn_cast<DefinedRegular<ELFT>>(&SA);
+    auto *DB = dyn_cast<DefinedRegular<ELFT>>(&SB);
     if (!DA || !DB)
       return false;
     if (DA->Sym.st_value != DB->Sym.st_value)

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=263222&r1=263221&r2=263222&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Fri Mar 11 06:06:30 2016
@@ -46,7 +46,7 @@ ELFKind ELFFileBase<ELFT>::getELFKind()
 
 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 @@ ELFFileBase<ELFT>::getSymbolsHelper(bool
   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> void ELFFileBase<E
 }
 
 template <class ELFT>
-typename ELFFileBase<ELFT>::Elf_Sym_Range
-ELFFileBase<ELFT>::getNonLocalSymbols() {
-  return getSymbolsHelper(false);
+elf::ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M)
+    : ELFFileBase<ELFT>(Base::ObjectKind, M) {}
+
+template <class ELFT>
+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>
-elf::ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M)
-    : ELFFileBase<ELFT>(Base::ObjectKind, M) {}
+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>
-typename elf::ObjectFile<ELFT>::Elf_Sym_Range
-elf::ObjectFile<ELFT>::getLocalSymbols() {
-  return this->getSymbolsHelper(true);
+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> uint32_t elf::Obje
 }
 
 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 @@ elf::ObjectFile<ELFT>::createInputSectio
 
 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 @@ elf::ObjectFile<ELFT>::getSection(const
 
 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 @@ SymbolBody *elf::ObjectFile<ELFT>::creat
                                      Sym->getVisibility());
   }
 
-  switch (Sym->getBinding()) {
+  switch (Binding) {
   default:
     fatal("Unexpected binding");
   case STB_GLOBAL:
@@ -399,7 +404,7 @@ template <class ELFT> void SharedFile<EL
 
 // 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) {

Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=263222&r1=263221&r2=263222&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Fri Mar 11 06:06:30 2016
@@ -84,8 +84,7 @@ protected:
   ArrayRef<Elf_Word> SymtabSHNDX;
   StringRef StringTable;
   void initStringTable();
-  Elf_Sym_Range getNonLocalSymbols();
-  Elf_Sym_Range getSymbolsHelper(bool);
+  Elf_Sym_Range getElfSymbols(bool OnlyGlobals);
 };
 
 // .o file.
@@ -110,7 +109,9 @@ public:
     return F->kind() == Base::ObjectKind;
   }
 
-  ArrayRef<SymbolBody *> getSymbols() { return SymbolBodies; }
+  ArrayRef<SymbolBody *> getSymbols();
+  ArrayRef<SymbolBody *> getLocalSymbols();
+  ArrayRef<SymbolBody *> getNonLocalSymbols();
 
   explicit ObjectFile(MemoryBufferRef M);
   void parse(llvm::DenseSet<StringRef> &ComdatGroups);
@@ -118,16 +119,10 @@ public:
   ArrayRef<InputSectionBase<ELFT> *> getSections() const { return Sections; }
   InputSectionBase<ELFT> *getSection(const Elf_Sym &Sym) const;
 
-  SymbolBody *getSymbolBody(uint32_t SymbolIndex) const {
-    uint32_t FirstNonLocal = this->Symtab->sh_info;
-    if (SymbolIndex < FirstNonLocal)
-      return nullptr;
-    return SymbolBodies[SymbolIndex - FirstNonLocal];
+  SymbolBody &getSymbolBody(uint32_t SymbolIndex) const {
+    return *SymbolBodies[SymbolIndex];
   }
 
-  Elf_Sym_Range getLocalSymbols();
-  const Elf_Sym *getLocalSymbol(uintX_t SymIndex);
-
   const Elf_Shdr *getSymbolTable() const { return this->Symtab; };
 
   // Get MIPS GP0 value defined by this file. This value represents the gp value

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=263222&r1=263221&r2=263222&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Fri Mar 11 06:06:30 2016
@@ -77,12 +77,11 @@ InputSectionBase<ELFT> *
 InputSectionBase<ELFT>::getRelocTarget(const Elf_Rel &Rel) const {
   // Global symbol
   uint32_t SymIndex = Rel.getSymbol(Config->Mips64EL);
-  if (SymbolBody *B = File->getSymbolBody(SymIndex))
-    if (auto *D = dyn_cast<DefinedRegular<ELFT>>(B->repl()))
-      return D->Section->Repl;
-  // Local symbol
-  if (const Elf_Sym *Sym = File->getLocalSymbol(SymIndex))
-    if (InputSectionBase<ELFT> *Sec = File->getSection(*Sym))
+  SymbolBody &B = File->getSymbolBody(SymIndex).repl();
+  if (auto *D = dyn_cast<DefinedRegular<ELFT>>(&B))
+    return D->Section->Repl;
+  if (auto *L = dyn_cast<LocalSymbol<ELFT>>(&B))
+    if (InputSectionBase<ELFT> *Sec = File->getSection(L->Sym))
       return Sec;
   return nullptr;
 }
@@ -122,24 +121,13 @@ void InputSection<ELFT>::copyRelocations
   for (const RelType &Rel : Rels) {
     uint32_t SymIndex = Rel.getSymbol(Config->Mips64EL);
     uint32_t Type = Rel.getType(Config->Mips64EL);
-    const Elf_Shdr *SymTab = this->File->getSymbolTable();
+    SymbolBody &Body = this->File->getSymbolBody(SymIndex).repl();
 
     RelType *P = reinterpret_cast<RelType *>(Buf);
     Buf += sizeof(RelType);
 
-    // Relocation against local symbol here means that it is probably
-    // rel[a].eh_frame section which has references to sections in r_info field.
-    if (SymIndex < SymTab->sh_info) {
-      const Elf_Sym *Sym = this->File->getLocalSymbol(SymIndex);
-      uint32_t Idx = Out<ELFT>::SymTab->Locals[Sym];
-      P->r_offset = RelocatedSection->getOffset(Rel.r_offset);
-      P->setSymbolAndType(Idx, Type, Config->Mips64EL);
-      continue;
-    }
-
-    SymbolBody *Body = this->File->getSymbolBody(SymIndex)->repl();
     P->r_offset = RelocatedSection->getOffset(Rel.r_offset);
-    P->setSymbolAndType(Body->DynsymIndex, Type, Config->Mips64EL);
+    P->setSymbolAndType(Body.DynsymIndex, Type, Config->Mips64EL);
   }
 }
 
@@ -251,19 +239,16 @@ void InputSectionBase<ELFT>::relocate(ui
       continue;
     }
 
-    const Elf_Shdr *SymTab = File->getSymbolTable();
-    SymbolBody *Body = nullptr;
-    if (SymIndex >= SymTab->sh_info)
-      Body = File->getSymbolBody(SymIndex)->repl();
+    SymbolBody &Body = File->getSymbolBody(SymIndex).repl();
 
-    if (Target->canRelaxTls(Type, Body)) {
+    if (Target->canRelaxTls(Type, &Body)) {
       uintX_t SymVA;
-      if (!Body)
+      if (Body.isLocal())
         SymVA = getLocalRelTarget(*File, RI, 0);
-      else if (Target->needsGot(Type, *Body))
-        SymVA = Body->getGotVA<ELFT>();
+      else if (Target->needsGot(Type, Body))
+        SymVA = Body.getGotVA<ELFT>();
       else
-        SymVA = Body->getVA<ELFT>();
+        SymVA = Body.getVA<ELFT>();
       // By optimizing TLS relocations, it is sometimes needed to skip
       // relocations that immediately follow TLS relocations. This function
       // knows how many slots we need to skip.
@@ -274,7 +259,7 @@ void InputSectionBase<ELFT>::relocate(ui
     // Handle relocations for local symbols -- they never get
     // resolved so we don't allocate a SymbolBody.
     uintX_t A = getAddend<ELFT>(RI);
-    if (!Body) {
+    if (Body.isLocal()) {
       uintX_t SymVA = getLocalRelTarget(*File, RI, A);
       uint8_t *PairedLoc = nullptr;
       if (Config->EMachine == EM_MIPS) {
@@ -305,26 +290,26 @@ void InputSectionBase<ELFT>::relocate(ui
     }
 
     if (Target->isTlsGlobalDynamicRel(Type) &&
-        !Target->canRelaxTls(Type, Body)) {
+        !Target->canRelaxTls(Type, &Body)) {
       Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
-                          Out<ELFT>::Got->getGlobalDynAddr(*Body) +
+                          Out<ELFT>::Got->getGlobalDynAddr(Body) +
                               getAddend<ELFT>(RI));
       continue;
     }
 
-    uintX_t SymVA = Body->getVA<ELFT>();
+    uintX_t SymVA = Body.getVA<ELFT>();
     bool CBP = canBePreempted(Body);
-    if (Target->needsPlt<ELFT>(Type, *Body)) {
-      SymVA = Body->getPltVA<ELFT>();
-    } else if (Target->needsGot(Type, *Body)) {
+    if (Target->needsPlt<ELFT>(Type, Body)) {
+      SymVA = Body.getPltVA<ELFT>();
+    } else if (Target->needsGot(Type, Body)) {
       if (Config->EMachine == EM_MIPS && !CBP)
         // Under some conditions relocations against non-local symbols require
         // entries in the local part of MIPS GOT. In that case we need an entry
         // initialized by full address of the symbol.
-        SymVA = Out<ELFT>::Got->getMipsLocalFullAddr(*Body);
+        SymVA = Out<ELFT>::Got->getMipsLocalFullAddr(Body);
       else
-        SymVA = Body->getGotVA<ELFT>();
-      if (Body->IsTls)
+        SymVA = Body.getGotVA<ELFT>();
+      if (Body.IsTls)
         Type = Target->getTlsGotRel(Type);
     } else if (Target->isSizeRel(Type) && CBP) {
       // A SIZE relocation is supposed to set a symbol size, but if a symbol
@@ -333,16 +318,16 @@ void InputSectionBase<ELFT>::relocate(ui
       // with a possibly incorrect value.
       continue;
     } else if (Config->EMachine == EM_MIPS) {
-      if (Type == R_MIPS_HI16 && Body == Config->MipsGpDisp)
+      if (Type == R_MIPS_HI16 && &Body == Config->MipsGpDisp)
         SymVA = getMipsGpAddr<ELFT>() - AddrLoc;
-      else if (Type == R_MIPS_LO16 && Body == Config->MipsGpDisp)
+      else if (Type == R_MIPS_LO16 && &Body == Config->MipsGpDisp)
         SymVA = getMipsGpAddr<ELFT>() - AddrLoc + 4;
-      else if (Body == Config->MipsLocalGp)
+      else if (&Body == Config->MipsLocalGp)
         SymVA = getMipsGpAddr<ELFT>();
-    } else if (!Target->needsCopyRel<ELFT>(Type, *Body) && CBP) {
+    } else if (!Target->needsCopyRel<ELFT>(Type, Body) && CBP) {
       continue;
     }
-    uintX_t Size = Body->getSize<ELFT>();
+    uintX_t Size = Body.getSize<ELFT>();
     Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA + A, Size + A,
                         findMipsPairedReloc(Buf, SymIndex,
                                             getMipsPairedRelocType(Type),

Modified: lld/trunk/ELF/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=263222&r1=263221&r2=263222&view=diff
==============================================================================
--- lld/trunk/ELF/MarkLive.cpp (original)
+++ lld/trunk/ELF/MarkLive.cpp Fri Mar 11 06:06:30 2016
@@ -99,7 +99,7 @@ template <class ELFT> void elf::markLive
 
   auto MarkSymbol = [&](SymbolBody *Sym) {
     if (Sym)
-      if (auto *D = dyn_cast<DefinedRegular<ELFT>>(Sym->repl()))
+      if (auto *D = dyn_cast<DefinedRegular<ELFT>>(&Sym->repl()))
         Enqueue(D->Section);
   };
 

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=263222&r1=263221&r2=263222&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Fri Mar 11 06:06:30 2016
@@ -53,9 +53,9 @@ GotPltSection<ELFT>::GotPltSection()
   this->Header.sh_addralign = sizeof(uintX_t);
 }
 
-template <class ELFT> void GotPltSection<ELFT>::addEntry(SymbolBody *Sym) {
-  Sym->GotPltIndex = Target->GotPltHeaderEntriesNum + Entries.size();
-  Entries.push_back(Sym);
+template <class ELFT> void GotPltSection<ELFT>::addEntry(SymbolBody &Sym) {
+  Sym.GotPltIndex = Target->GotPltHeaderEntriesNum + Entries.size();
+  Entries.push_back(&Sym);
 }
 
 template <class ELFT> bool GotPltSection<ELFT>::empty() const {
@@ -84,21 +84,21 @@ GotSection<ELFT>::GotSection()
   this->Header.sh_addralign = sizeof(uintX_t);
 }
 
-template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody *Sym) {
-  Sym->GotIndex = Entries.size();
-  Entries.push_back(Sym);
+template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody &Sym) {
+  Sym.GotIndex = Entries.size();
+  Entries.push_back(&Sym);
 }
 
 template <class ELFT> void GotSection<ELFT>::addMipsLocalEntry() {
   ++MipsLocalEntries;
 }
 
-template <class ELFT> bool GotSection<ELFT>::addDynTlsEntry(SymbolBody *Sym) {
-  if (Sym->hasGlobalDynIndex())
+template <class ELFT> bool GotSection<ELFT>::addDynTlsEntry(SymbolBody &Sym) {
+  if (Sym.hasGlobalDynIndex())
     return false;
-  Sym->GlobalDynIndex = Target->GotHeaderEntriesNum + Entries.size();
+  Sym.GlobalDynIndex = Target->GotHeaderEntriesNum + Entries.size();
   // Global Dynamic TLS entries take two GOT slots.
-  Entries.push_back(Sym);
+  Entries.push_back(&Sym);
   Entries.push_back(nullptr);
   return true;
 }
@@ -177,7 +177,7 @@ template <class ELFT> void GotSection<EL
     // for detailed description:
     // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
     // As the first approach, we can just store addresses for all symbols.
-    if (Config->EMachine != EM_MIPS && canBePreempted(B))
+    if (Config->EMachine != EM_MIPS && canBePreempted(*B))
       continue; // The dynamic linker will take care of it.
     uintX_t VA = B->getVA<ELFT>();
     write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(Entry, VA);
@@ -209,12 +209,12 @@ template <class ELFT> void PltSection<EL
   }
 }
 
-template <class ELFT> void PltSection<ELFT>::addEntry(SymbolBody *Sym) {
-  Sym->PltIndex = Entries.size();
+template <class ELFT> void PltSection<ELFT>::addEntry(SymbolBody &Sym) {
+  Sym.PltIndex = Entries.size();
   unsigned RelOff = Target->UseLazyBinding
                         ? Out<ELFT>::RelaPlt->getRelocOffset()
                         : Out<ELFT>::RelaDyn->getRelocOffset();
-  Entries.push_back(std::make_pair(Sym, RelOff));
+  Entries.push_back(std::make_pair(&Sym, RelOff));
 }
 
 template <class ELFT> void PltSection<ELFT>::finalize() {
@@ -891,14 +891,15 @@ template <class ELFT> void OutputSection
 
 // Returns true if a symbol can be replaced at load-time by a symbol
 // with the same name defined in other ELF executable or DSO.
-bool elf::canBePreempted(const SymbolBody *Body) {
-  if (!Body)
-    return false;  // Body is a local symbol.
-  if (Body->isShared())
+bool elf::canBePreempted(const SymbolBody &Body) {
+  if (Body.isLocal())
+    return false;
+
+  if (Body.isShared())
     return true;
 
-  if (Body->isUndefined()) {
-    if (!Body->isWeak())
+  if (Body.isUndefined()) {
+    if (!Body.isWeak())
       return true;
 
     // Ideally the static linker should see a definition for every symbol, but
@@ -912,9 +913,9 @@ bool elf::canBePreempted(const SymbolBod
   }
   if (!Config->Shared)
     return false;
-  if (Body->getVisibility() != STV_DEFAULT)
+  if (Body.getVisibility() != STV_DEFAULT)
     return false;
-  if (Config->Bsymbolic || (Config->BsymbolicFunctions && Body->IsFunc))
+  if (Config->Bsymbolic || (Config->BsymbolicFunctions && Body.IsFunc))
     return false;
   return true;
 }
@@ -1132,7 +1133,7 @@ void EHOutputSection<ELFT>::addSectionAu
       SymbolBody *Personality = nullptr;
       if (HasReloc) {
         uint32_t SymIndex = RelI->getSymbol(Config->Mips64EL);
-        Personality = S->getFile()->getSymbolBody(SymIndex)->repl();
+        Personality = &S->getFile()->getSymbolBody(SymIndex).repl();
       }
 
       std::pair<StringRef, SymbolBody *> CieInfo(Entry, Personality);
@@ -1496,9 +1497,9 @@ SymbolTableSection<ELFT>::getOutputSecti
   case SymbolBody::DefinedSyntheticKind:
     return &cast<DefinedSynthetic<ELFT>>(Sym)->Section;
   case SymbolBody::DefinedRegularKind: {
-    auto *D = cast<DefinedRegular<ELFT>>(Sym->repl());
-    if (D->Section)
-      return D->Section->OutSec;
+    auto &D = cast<DefinedRegular<ELFT>>(Sym->repl());
+    if (D.Section)
+      return D.Section->OutSec;
     break;
   }
   case SymbolBody::DefinedCommonKind:
@@ -1513,6 +1514,8 @@ SymbolTableSection<ELFT>::getOutputSecti
     break;
   case SymbolBody::DefinedBitcodeKind:
     llvm_unreachable("Should have been replaced");
+  case SymbolBody::DefinedLocalKind:
+    llvm_unreachable("Should not be used");
   }
   return nullptr;
 }

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=263222&r1=263221&r2=263222&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Fri Mar 11 06:06:30 2016
@@ -47,7 +47,7 @@ getAddend(const typename llvm::object::E
   return Rel.r_addend;
 }
 
-bool canBePreempted(const SymbolBody *Body);
+bool canBePreempted(const SymbolBody &Body);
 
 bool isValidCIdentifier(StringRef S);
 
@@ -106,9 +106,9 @@ public:
   GotSection();
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
-  void addEntry(SymbolBody *Sym);
+  void addEntry(SymbolBody &Sym);
   void addMipsLocalEntry();
-  bool addDynTlsEntry(SymbolBody *Sym);
+  bool addDynTlsEntry(SymbolBody &Sym);
   bool addTlsIndex();
   bool empty() const { return MipsLocalEntries == 0 && Entries.empty(); }
   uintX_t getMipsLocalFullAddr(const SymbolBody &B);
@@ -145,7 +145,7 @@ public:
   GotPltSection();
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
-  void addEntry(SymbolBody *Sym);
+  void addEntry(SymbolBody &Sym);
   bool empty() const;
 
 private:
@@ -160,7 +160,7 @@ public:
   PltSection();
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
-  void addEntry(SymbolBody *Sym);
+  void addEntry(SymbolBody &Sym);
   bool empty() const { return Entries.empty(); }
 
 private:
@@ -235,9 +235,6 @@ public:
   unsigned NumLocals = 0;
   StringTableSection<ELFT> &StrTabSec;
 
-  // Local symbol -> ID, filled only when producing relocatable output.
-  llvm::DenseMap<const Elf_Sym *, uint32_t> Locals;
-
 private:
   void writeLocalSymbols(uint8_t *&Buf);
   void writeGlobalSymbols(uint8_t *Buf);

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=263222&r1=263221&r2=263222&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Fri Mar 11 06:06:30 2016
@@ -92,7 +92,7 @@ void SymbolTable<ELFT>::addFile(std::uni
   auto *F = cast<ObjectFile<ELFT>>(FileP);
   ObjectFiles.emplace_back(cast<ObjectFile<ELFT>>(File.release()));
   F->parse(ComdatGroups);
-  for (SymbolBody *B : F->getSymbols())
+  for (SymbolBody *B : F->getNonLocalSymbols())
     resolve(B);
 }
 
@@ -146,7 +146,7 @@ static void addBitcodeFile(IRMover &Move
                                  /*ShouldLazyLoadMetadata*/ false));
   std::vector<GlobalValue *> Keep;
   for (SymbolBody *B : F.getSymbols()) {
-    if (B->repl() != B)
+    if (&B->repl() != B)
       continue;
     auto *DB = dyn_cast<DefinedBitcode>(B);
     if (!DB)
@@ -194,7 +194,7 @@ template <class ELFT> void SymbolTable<E
   ObjectFile<ELFT> *Obj = createCombinedLtoObject();
   llvm::DenseSet<StringRef> DummyGroups;
   Obj->parse(DummyGroups);
-  for (SymbolBody *Body : Obj->getSymbols()) {
+  for (SymbolBody *Body : Obj->getNonLocalSymbols()) {
     Symbol *Sym = insert(Body);
     if (!Sym->Body->isUndefined() && Body->isUndefined())
       continue;

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=263222&r1=263221&r2=263222&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Fri Mar 11 06:06:30 2016
@@ -68,6 +68,8 @@ typename ELFFile<ELFT>::uintX_t SymbolBo
     return 0;
   case DefinedBitcodeKind:
     llvm_unreachable("Should have been replaced");
+  case DefinedLocalKind:
+    llvm_unreachable("Should not be used");
   }
   llvm_unreachable("Invalid symbol kind");
 }

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=263222&r1=263221&r2=263222&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Fri Mar 11 06:06:30 2016
@@ -59,7 +59,8 @@ public:
     DefinedFirst,
     DefinedRegularKind = DefinedFirst,
     SharedKind,
-    DefinedElfLast = SharedKind,
+    DefinedLocalKind,
+    DefinedElfLast = DefinedLocalKind,
     DefinedCommonKind,
     DefinedBitcodeKind,
     DefinedSyntheticKind,
@@ -79,6 +80,7 @@ public:
   bool isCommon() const { return SymbolKind == DefinedCommonKind; }
   bool isLazy() const { return SymbolKind == LazyKind; }
   bool isShared() const { return SymbolKind == SharedKind; }
+  bool isLocal() const { return SymbolKind == DefinedLocalKind; }
   bool isUsedInRegularObj() const { return IsUsedInRegularObj; }
 
   // Returns the symbol name.
@@ -113,7 +115,7 @@ public:
   // has chosen the object among other objects having the same name,
   // you can access P->Backref->Body to get the resolver's result.
   void setBackref(Symbol *P) { Backref = P; }
-  SymbolBody *repl() { return Backref ? Backref->Body : this; }
+  SymbolBody &repl() { return Backref ? *Backref->Body : *this; }
   Symbol *getSymbol() { return Backref; }
 
   // Decides which symbol should "win" in the symbol table, this or
@@ -304,6 +306,18 @@ public:
   bool needsCopy() const { return this->NeedsCopyOrPltAddr && !this->IsFunc; }
 };
 
+template <class ELFT> class LocalSymbol : public DefinedElf<ELFT> {
+  typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
+
+public:
+  LocalSymbol(const Elf_Sym &Sym)
+      : DefinedElf<ELFT>(SymbolBody::DefinedLocalKind, "", Sym) {}
+
+  static bool classof(const SymbolBody *S) {
+    return S->kind() == SymbolBody::DefinedLocalKind;
+  }
+};
+
 // This class represents a symbol defined in an archive file. It is
 // created from an archive file header, and it knows how to load an
 // object file from an archive to replace itself with a defined

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=263222&r1=263221&r2=263222&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Fri Mar 11 06:06:30 2016
@@ -99,7 +99,7 @@ public:
                    uint64_t SA, uint64_t ZA = 0,
                    uint8_t *PairedLoc = nullptr) const override;
   size_t relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
-                  uint64_t SA, const SymbolBody *S) const override;
+                  uint64_t SA, const SymbolBody &S) const override;
   bool isGotRelative(uint32_t Type) const override;
   bool refersToGotEntry(uint32_t Type) const override;
 
@@ -137,7 +137,7 @@ public:
   bool isRelRelative(uint32_t Type) const override;
   bool isSizeRel(uint32_t Type) const override;
   size_t relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
-                  uint64_t SA, const SymbolBody *S) const override;
+                  uint64_t SA, const SymbolBody &S) const override;
 
 private:
   void relocateTlsLdToLe(uint8_t *Loc, uint8_t *BufEnd, uint64_t P,
@@ -191,7 +191,7 @@ public:
                    uint64_t SA, uint64_t ZA = 0,
                    uint8_t *PairedLoc = nullptr) const override;
   size_t relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
-                  uint64_t SA, const SymbolBody *S) const override;
+                  uint64_t SA, const SymbolBody &S) const override;
 
 private:
   void relocateTlsGdToLe(uint32_t Type, uint8_t *Loc, uint8_t *BufEnd,
@@ -278,7 +278,7 @@ bool TargetInfo::canRelaxTls(uint32_t Ty
   // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
   // defined.
   if (isTlsInitialExecRel(Type))
-    return !canBePreempted(S);
+    return !canBePreempted(*S);
 
   return false;
 }
@@ -317,7 +317,7 @@ TargetInfo::PltNeed TargetInfo::needsPlt
                                          const SymbolBody &S) const {
   if (isGnuIFunc<ELFT>(S))
     return Plt_Explicit;
-  if (canBePreempted(&S) && needsPltImpl(Type))
+  if (canBePreempted(S) && needsPltImpl(Type))
     return Plt_Explicit;
 
   // This handles a non PIC program call to function in a shared library.
@@ -363,7 +363,7 @@ bool TargetInfo::isTlsGlobalDynamicRel(u
 
 size_t TargetInfo::relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
                             uint64_t P, uint64_t SA,
-                            const SymbolBody *S) const {
+                            const SymbolBody &S) const {
   return 0;
 }
 
@@ -470,7 +470,7 @@ bool X86TargetInfo::needsCopyRelImpl(uin
 
 bool X86TargetInfo::needsGot(uint32_t Type, SymbolBody &S) const {
   if (S.IsTls && Type == R_386_TLS_GD)
-    return Target->canRelaxTls(Type, &S) && canBePreempted(&S);
+    return Target->canRelaxTls(Type, &S) && canBePreempted(S);
   if (Type == R_386_TLS_GOTIE || Type == R_386_TLS_IE)
     return !canRelaxTls(Type, &S);
   return Type == R_386_GOT32 || needsPlt<ELF32LE>(Type, S);
@@ -545,7 +545,7 @@ bool X86TargetInfo::needsDynRelative(uin
 
 size_t X86TargetInfo::relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
                                uint64_t P, uint64_t SA,
-                               const SymbolBody *S) const {
+                               const SymbolBody &S) const {
   switch (Type) {
   case R_386_TLS_GD:
     if (canBePreempted(S))
@@ -732,7 +732,7 @@ bool X86_64TargetInfo::refersToGotEntry(
 
 bool X86_64TargetInfo::needsGot(uint32_t Type, SymbolBody &S) const {
   if (Type == R_X86_64_TLSGD)
-    return Target->canRelaxTls(Type, &S) && canBePreempted(&S);
+    return Target->canRelaxTls(Type, &S) && canBePreempted(S);
   if (Type == R_X86_64_GOTTPOFF)
     return !canRelaxTls(Type, &S);
   return refersToGotEntry(Type) || needsPlt<ELF64LE>(Type, S);
@@ -890,7 +890,7 @@ void X86_64TargetInfo::relocateTlsIeToLe
 // This function returns a number of relocations that need to be skipped.
 size_t X86_64TargetInfo::relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
                                   uint64_t P, uint64_t SA,
-                                  const SymbolBody *S) const {
+                                  const SymbolBody &S) const {
   switch (Type) {
   case R_X86_64_DTPOFF32:
     relocateOne(Loc, BufEnd, R_X86_64_TPOFF32, P, SA);
@@ -1463,7 +1463,7 @@ void AArch64TargetInfo::relocateOne(uint
 
 size_t AArch64TargetInfo::relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
                                    uint64_t P, uint64_t SA,
-                                   const SymbolBody *S) const {
+                                   const SymbolBody &S) const {
   switch (Type) {
   case R_AARCH64_TLSDESC_ADR_PAGE21:
   case R_AARCH64_TLSDESC_LD64_LO12_NC:
@@ -1471,13 +1471,13 @@ size_t AArch64TargetInfo::relaxTls(uint8
   case R_AARCH64_TLSDESC_CALL: {
     if (canBePreempted(S))
       fatal("Unsupported TLS optimization");
-    uint64_t X = S ? S->getVA<ELF64LE>() : SA;
+    uint64_t X = S.getVA<ELF64LE>();
     relocateTlsGdToLe(Type, Loc, BufEnd, P, X);
     return 0;
   }
   case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
   case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
-    relocateTlsIeToLe(Type, Loc, BufEnd, P, S->getVA<ELF64LE>());
+    relocateTlsIeToLe(Type, Loc, BufEnd, P, S.getVA<ELF64LE>());
     return 0;
   }
   llvm_unreachable("Unknown TLS optimization");

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=263222&r1=263221&r2=263222&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Fri Mar 11 06:06:30 2016
@@ -70,7 +70,7 @@ public:
   template <class ELFT>
   bool needsCopyRel(uint32_t Type, const SymbolBody &S) const;
   virtual size_t relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type,
-                          uint64_t P, uint64_t SA, const SymbolBody *S) const;
+                          uint64_t P, uint64_t SA, const SymbolBody &S) const;
   virtual ~TargetInfo();
 
   unsigned PageSize = 4096;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=263222&r1=263221&r2=263222&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Mar 11 06:06:30 2016
@@ -256,7 +256,7 @@ template <bool Is64Bits> struct DenseMap
 }
 
 template <class ELFT, class RelT>
-static bool handleTlsRelocation(uint32_t Type, SymbolBody *Body,
+static bool handleTlsRelocation(uint32_t Type, SymbolBody &Body,
                                 InputSectionBase<ELFT> &C, RelT &RI) {
   if (Target->pointsToLocalDynamicGotEntry(Type)) {
     if (Target->canRelaxTls(Type, nullptr))
@@ -268,16 +268,17 @@ static bool handleTlsRelocation(uint32_t
     return true;
   }
 
-  if (!Body || !Body->IsTls)
+  if (!Body.IsTls)
     return false;
 
   if (Target->isTlsGlobalDynamicRel(Type)) {
-    if (!Target->canRelaxTls(Type, Body)) {
+    if (!Target->canRelaxTls(Type, &Body)) {
       if (Out<ELFT>::Got->addDynTlsEntry(Body)) {
         Out<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel,
-                                      DynamicReloc<ELFT>::Off_GTlsIndex, Body});
+                                      DynamicReloc<ELFT>::Off_GTlsIndex,
+                                      &Body});
         Out<ELFT>::RelaDyn->addReloc(
-            {Target->TlsOffsetRel, DynamicReloc<ELFT>::Off_GTlsOffset, Body});
+            {Target->TlsOffsetRel, DynamicReloc<ELFT>::Off_GTlsOffset, &Body});
       }
       return true;
     }
@@ -309,7 +310,8 @@ void Writer<ELFT>::scanRelocs(
   const ObjectFile<ELFT> &File = *C.getFile();
   for (const RelType &RI : Rels) {
     uint32_t SymIndex = RI.getSymbol(Config->Mips64EL);
-    SymbolBody *Body = File.getSymbolBody(SymIndex);
+    SymbolBody &OrigBody = File.getSymbolBody(SymIndex);
+    SymbolBody &Body = OrigBody.repl();
     uint32_t Type = RI.getType(Config->Mips64EL);
 
     // Ignore "hint" relocation because it is for optional code optimization.
@@ -320,20 +322,17 @@ void Writer<ELFT>::scanRelocs(
       HasGotOffRel = true;
 
     // Set "used" bit for --as-needed.
-    if (Body && Body->isUndefined() && !Body->isWeak())
-      if (auto *S = dyn_cast<SharedSymbol<ELFT>>(Body->repl()))
+    if (OrigBody.isUndefined() && !OrigBody.isWeak())
+      if (auto *S = dyn_cast<SharedSymbol<ELFT>>(&Body))
         S->File->IsUsed = true;
 
-    if (Body)
-      Body = Body->repl();
-
     bool CBP = canBePreempted(Body);
     if (handleTlsRelocation<ELFT>(Type, Body, C, RI))
       continue;
 
     if (Target->needsDynRelative(Type))
       Out<ELFT>::RelaDyn->addReloc({Target->RelativeRel, &C, RI.r_offset, true,
-                                    Body, getAddend<ELFT>(RI)});
+                                    &Body, getAddend<ELFT>(RI)});
 
     // MIPS has a special rule to create GOTs for local symbols.
     if (Config->EMachine == EM_MIPS && !CBP &&
@@ -345,7 +344,7 @@ void Writer<ELFT>::scanRelocs(
 
     // If a symbol in a DSO is referenced directly instead of through GOT,
     // we need to create a copy relocation for the symbol.
-    if (auto *B = dyn_cast_or_null<SharedSymbol<ELFT>>(Body)) {
+    if (auto *B = dyn_cast_or_null<SharedSymbol<ELFT>>(&Body)) {
       if (B->needsCopy())
         continue;
       if (Target->needsCopyRel<ELFT>(Type, *B)) {
@@ -359,53 +358,51 @@ void Writer<ELFT>::scanRelocs(
     // An STT_GNU_IFUNC symbol always uses a PLT entry, and all references
     // to the symbol go through the PLT. This is true even for a local
     // symbol, although local symbols normally do not require PLT entries.
-    if (Body && isGnuIFunc<ELFT>(*Body)) {
-      if (Body->isInPlt())
+    if (isGnuIFunc<ELFT>(Body)) {
+      if (Body.isInPlt())
         continue;
       Out<ELFT>::Plt->addEntry(Body);
       if (Target->UseLazyBinding) {
         Out<ELFT>::GotPlt->addEntry(Body);
         Out<ELFT>::RelaPlt->addReloc(
             {CBP ? Target->PltRel : Target->IRelativeRel,
-             DynamicReloc<ELFT>::Off_GotPlt, !CBP, Body});
+             DynamicReloc<ELFT>::Off_GotPlt, !CBP, &Body});
       } else {
         Out<ELFT>::Got->addEntry(Body);
         Out<ELFT>::RelaDyn->addReloc(
             {CBP ? Target->PltRel : Target->IRelativeRel,
-             DynamicReloc<ELFT>::Off_Got, !CBP, Body});
+             DynamicReloc<ELFT>::Off_Got, !CBP, &Body});
       }
       continue;
     }
 
     // If a relocation needs PLT, we create a PLT and a GOT slot
     // for the symbol.
-    TargetInfo::PltNeed NeedPlt = TargetInfo::Plt_No;
-    if (Body)
-      NeedPlt = Target->needsPlt<ELFT>(Type, *Body);
+    TargetInfo::PltNeed NeedPlt = Target->needsPlt<ELFT>(Type, Body);
     if (NeedPlt) {
       if (NeedPlt == TargetInfo::Plt_Implicit)
-        Body->NeedsCopyOrPltAddr = true;
-      if (Body->isInPlt())
+        Body.NeedsCopyOrPltAddr = true;
+      if (Body.isInPlt())
         continue;
       Out<ELFT>::Plt->addEntry(Body);
 
       if (Target->UseLazyBinding) {
         Out<ELFT>::GotPlt->addEntry(Body);
         Out<ELFT>::RelaPlt->addReloc(
-            {Target->PltRel, DynamicReloc<ELFT>::Off_GotPlt, Body});
+            {Target->PltRel, DynamicReloc<ELFT>::Off_GotPlt, &Body});
       } else {
-        if (Body->isInGot())
+        if (Body.isInGot())
           continue;
         Out<ELFT>::Got->addEntry(Body);
         Out<ELFT>::RelaDyn->addReloc(
-            {Target->GotRel, DynamicReloc<ELFT>::Off_Got, Body});
+            {Target->GotRel, DynamicReloc<ELFT>::Off_Got, &Body});
       }
       continue;
     }
 
     // If a relocation needs GOT, we create a GOT slot for the symbol.
-    if (Body && Target->needsGot(Type, *Body)) {
-      if (Body->isInGot())
+    if (Target->needsGot(Type, Body)) {
+      if (Body.isInGot())
         continue;
       Out<ELFT>::Got->addEntry(Body);
 
@@ -415,7 +412,7 @@ void Writer<ELFT>::scanRelocs(
         // See "Global Offset Table" in Chapter 5 in the following document
         // for detailed description:
         // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
-        Body->MustBeInDynSym = true;
+        Body.MustBeInDynSym = true;
         continue;
       }
 
@@ -424,11 +421,11 @@ void Writer<ELFT>::scanRelocs(
       if (CBP || Dynrel) {
         uint32_t DynType;
         if (CBP)
-          DynType = Body->IsTls ? Target->TlsGotRel : Target->GotRel;
+          DynType = Body.IsTls ? Target->TlsGotRel : Target->GotRel;
         else
           DynType = Target->RelativeRel;
         Out<ELFT>::RelaDyn->addReloc(
-            {DynType, DynamicReloc<ELFT>::Off_Got, !CBP, Body});
+            {DynType, DynamicReloc<ELFT>::Off_Got, !CBP, &Body});
       }
       continue;
     }
@@ -443,7 +440,7 @@ void Writer<ELFT>::scanRelocs(
         // relocation too because that case is possible for executable file
         // linking only.
         continue;
-      if (Body == Config->MipsGpDisp || Body == Config->MipsLocalGp)
+      if (&Body == Config->MipsGpDisp || &Body == Config->MipsLocalGp)
         // MIPS _gp_disp designates offset between start of function and 'gp'
         // pointer into GOT. __gnu_local_gp is equal to the current value of
         // the 'gp'. Therefore any relocations against them do not require
@@ -455,7 +452,7 @@ void Writer<ELFT>::scanRelocs(
       // We don't know anything about the finaly symbol. Just ask the dynamic
       // linker to handle the relocation for us.
       Out<ELFT>::RelaDyn->addReloc({Target->getDynRel(Type), &C, RI.r_offset,
-                                    false, Body, getAddend<ELFT>(RI)});
+                                    false, &Body, getAddend<ELFT>(RI)});
       continue;
     }
 
@@ -477,16 +474,15 @@ void Writer<ELFT>::scanRelocs(
                                     (uintX_t)getPPC64TocBase() + Addend});
       continue;
     }
-    if (Body) {
+    if (!Body.isLocal()) {
       Out<ELFT>::RelaDyn->addReloc(
-          {Target->RelativeRel, &C, RI.r_offset, true, Body, Addend});
+          {Target->RelativeRel, &C, RI.r_offset, true, &Body, Addend});
       continue;
     }
-    const Elf_Sym *Sym =
-        File.getObj().getRelocationSymbol(&RI, File.getSymbolTable());
-    InputSectionBase<ELFT> *Section = File.getSection(*Sym);
-    uintX_t Offset = Sym->st_value;
-    if (Sym->getType() == STT_SECTION) {
+    const Elf_Sym &Sym = cast<LocalSymbol<ELFT>>(Body).Sym;
+    InputSectionBase<ELFT> *Section = File.getSection(Sym);
+    uintX_t Offset = Sym.st_value;
+    if (Sym.getType() == STT_SECTION) {
       Offset += Addend;
       Addend = 0;
     }
@@ -563,7 +559,9 @@ template <class ELFT> void Writer<ELFT>:
   if (!Out<ELFT>::SymTab)
     return;
   for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab.getObjectFiles()) {
-    for (const Elf_Sym &Sym : F->getLocalSymbols()) {
+    for (SymbolBody *B : F->getLocalSymbols()) {
+      auto *L = dyn_cast<LocalSymbol<ELFT>>(B);
+      const Elf_Sym &Sym = cast<LocalSymbol<ELFT>>(B)->Sym;
       StringRef SymName = check(Sym.getName(F->getStringTable()));
       if (!shouldKeepInSymtab<ELFT>(*F, SymName, Sym))
         continue;
@@ -577,7 +575,7 @@ template <class ELFT> void Writer<ELFT>:
       }
       ++Out<ELFT>::SymTab->NumLocals;
       if (Config->Relocatable)
-        Out<ELFT>::SymTab->Locals[&Sym] = Out<ELFT>::SymTab->NumLocals;
+        L->DynsymIndex = Out<ELFT>::SymTab->NumLocals;
       F->KeptLocalSyms.push_back(std::make_pair(
           &Sym, Out<ELFT>::SymTab->StrTabSec.addString(SymName)));
     }
@@ -1428,11 +1426,8 @@ static uint32_t getELFFlags() {
 
 template <class ELFT>
 static typename ELFFile<ELFT>::uintX_t getEntryAddr() {
-  if (Config->EntrySym) {
-    if (SymbolBody *B = Config->EntrySym->repl())
-      return B->getVA<ELFT>();
-    return 0;
-  }
+  if (SymbolBody *B = Config->EntrySym)
+    return B->repl().getVA<ELFT>();
   if (Config->EntryAddr != uint64_t(-1))
     return Config->EntryAddr;
   return 0;




More information about the llvm-commits mailing list