[lld] r316841 - Pass symbol attributes instead of ElfSym to Shared symbol ctor.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 28 13:15:56 PDT 2017


Author: ruiu
Date: Sat Oct 28 13:15:56 2017
New Revision: 316841

URL: http://llvm.org/viewvc/llvm-project?rev=316841&view=rev
Log:
Pass symbol attributes instead of ElfSym to Shared symbol ctor.

This change allows us to use less templates for Shared symbol and
the functions that deals with shared symbols.

Modified:
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputFiles.h
    lld/trunk/ELF/MapFile.cpp
    lld/trunk/ELF/MapFile.h
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/SymbolTable.h
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=316841&r1=316840&r2=316841&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Sat Oct 28 13:15:56 2017
@@ -514,11 +514,9 @@ template <class ELFT> void ObjFile<ELFT>
 }
 
 template <class ELFT>
-InputSectionBase *ObjFile<ELFT>::getSection(const Elf_Sym &Sym) const {
-  uint32_t Index = this->getSectionIndex(Sym);
+InputSectionBase *ObjFile<ELFT>::getSection(uint32_t Index) const {
   if (Index == 0)
     return nullptr;
-
   if (Index >= this->Sections.size())
     fatal(toString(this) + ": invalid section index: " + Twine(Index));
 
@@ -533,7 +531,7 @@ InputSectionBase *ObjFile<ELFT>::getSect
 template <class ELFT>
 SymbolBody *ObjFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
   int Binding = Sym->getBinding();
-  InputSectionBase *Sec = getSection(*Sym);
+  InputSectionBase *Sec = getSection(this->getSectionIndex(*Sym));
 
   uint8_t StOther = Sym->st_other;
   uint8_t Type = Sym->getType();
@@ -629,14 +627,6 @@ SharedFile<ELFT>::SharedFile(MemoryBuffe
     : ELFFileBase<ELFT>(Base::SharedKind, M), SoName(DefaultSoName),
       AsNeeded(Config->AsNeeded) {}
 
-template <class ELFT>
-const typename ELFT::Shdr *
-SharedFile<ELFT>::getSection(const Elf_Sym &Sym) const {
-  return check(
-      this->getObj().getSection(&Sym, this->ELFSyms, this->SymtabSHNDX),
-      toString(this));
-}
-
 // Partially parse the shared object file so that we can call
 // getSoName on this object.
 template <class ELFT> void SharedFile<ELFT>::parseSoName() {
@@ -735,6 +725,10 @@ template <class ELFT> void SharedFile<EL
   const Elf_Versym *Versym = nullptr;
   std::vector<const Elf_Verdef *> Verdefs = parseVerdefs(Versym);
 
+  ArrayRef<Elf_Shdr> Sections =
+      check(this->getObj().sections(), toString(this));
+
+  // Add symbols to the symbol table.
   Elf_Sym_Range Syms = this->getGlobalELFSyms();
   for (const Elf_Sym &Sym : Syms) {
     unsigned VersymIndex = 0;
@@ -765,15 +759,25 @@ template <class ELFT> void SharedFile<EL
       V = Verdefs[VersymIndex];
     }
 
+    // We do not usually care about alignments of data in shared object
+    // files because the loader takes care of it. However, if we promote a
+    // DSO symbol to point to .bss due to copy relocation, we need to keep
+    // the original alignment requirements. We infer it here.
+    uint32_t Alignment = 1 << countTrailingZeros((uint64_t)Sym.st_value);
+    if (0 < Sym.st_shndx && Sym.st_shndx < Sections.size()) {
+      uint32_t SecAlign = Sections[Sym.st_shndx].sh_addralign;
+      Alignment = std::min(Alignment, SecAlign);
+    }
+
     if (!Hidden)
-      Symtab->addShared(Name, this, Sym, V);
+      Symtab->addShared(Name, this, Sym, Alignment, V);
 
     // Also add the symbol with the versioned name to handle undefined symbols
     // with explicit versions.
     if (V) {
       StringRef VerName = this->StringTable.data() + V->getAux()->vda_name;
       Name = Saver.save(Name + "@" + VerName);
-      Symtab->addShared(Name, this, Sym, V);
+      Symtab->addShared(Name, this, Sym, Alignment, V);
     }
   }
 }

Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=316841&r1=316840&r2=316841&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Sat Oct 28 13:15:56 2017
@@ -167,7 +167,7 @@ public:
   ObjFile(MemoryBufferRef M, StringRef ArchiveName);
   void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
 
-  InputSectionBase *getSection(const Elf_Sym &Sym) const;
+  InputSectionBase *getSection(uint32_t Index) const;
 
   SymbolBody &getSymbolBody(uint32_t SymbolIndex) const {
     if (SymbolIndex >= this->Symbols.size())
@@ -294,7 +294,6 @@ template <class ELFT> class SharedFile :
 public:
   std::string SoName;
 
-  const Elf_Shdr *getSection(const Elf_Sym &Sym) const;
   llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; }
 
   static bool classof(const InputFile *F) {

Modified: lld/trunk/ELF/MapFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MapFile.cpp?rev=316841&r1=316840&r2=316841&view=diff
==============================================================================
--- lld/trunk/ELF/MapFile.cpp (original)
+++ lld/trunk/ELF/MapFile.cpp Sat Oct 28 13:15:56 2017
@@ -49,7 +49,7 @@ static void writeHeader(raw_ostream &OS,
 static std::string indent(int Depth) { return std::string(Depth * 8, ' '); }
 
 // Returns a list of all symbols that we want to print out.
-template <class ELFT> static std::vector<Defined *> getSymbols() {
+static std::vector<Defined *> getSymbols() {
   std::vector<Defined *> V;
   for (InputFile *File : ObjectFiles) {
     for (SymbolBody *B : File->getSymbols()) {
@@ -90,13 +90,12 @@ static SymbolMapTy getSectionSyms(ArrayR
 // Construct a map from symbols to their stringified representations.
 // Demangling symbols (which is what toString() does) is slow, so
 // we do that in batch using parallel-for.
-template <class ELFT>
 static DenseMap<Defined *, std::string>
 getSymbolStrings(ArrayRef<Defined *> Syms) {
   std::vector<std::string> Str(Syms.size());
   parallelForEachN(0, Syms.size(), [&](size_t I) {
     raw_string_ostream OS(Str[I]);
-    writeHeader(OS, Syms[I]->getVA(), Syms[I]->template getSize<ELFT>(), 0);
+    writeHeader(OS, Syms[I]->getVA(), Syms[I]->getSize(), 0);
     OS << indent(2) << toString(*Syms[I]);
   });
 
@@ -106,7 +105,7 @@ getSymbolStrings(ArrayRef<Defined *> Sym
   return Ret;
 }
 
-template <class ELFT> void elf::writeMapFile() {
+void elf::writeMapFile() {
   if (Config->MapFile.empty())
     return;
 
@@ -119,12 +118,12 @@ template <class ELFT> void elf::writeMap
   }
 
   // Collect symbol info that we want to print out.
-  std::vector<Defined *> Syms = getSymbols<ELFT>();
+  std::vector<Defined *> Syms = getSymbols();
   SymbolMapTy SectionSyms = getSectionSyms(Syms);
-  DenseMap<Defined *, std::string> SymStr = getSymbolStrings<ELFT>(Syms);
+  DenseMap<Defined *, std::string> SymStr = getSymbolStrings(Syms);
 
   // Print out the header line.
-  int W = ELFT::Is64Bits ? 16 : 8;
+  int W = Config->Is64 ? 16 : 8;
   OS << left_justify("Address", W) << ' ' << left_justify("Size", W)
      << " Align Out     In      Symbol\n";
 
@@ -148,8 +147,3 @@ template <class ELFT> void elf::writeMap
     }
   }
 }
-
-template void elf::writeMapFile<ELF32LE>();
-template void elf::writeMapFile<ELF32BE>();
-template void elf::writeMapFile<ELF64LE>();
-template void elf::writeMapFile<ELF64BE>();

Modified: lld/trunk/ELF/MapFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MapFile.h?rev=316841&r1=316840&r2=316841&view=diff
==============================================================================
--- lld/trunk/ELF/MapFile.h (original)
+++ lld/trunk/ELF/MapFile.h Sat Oct 28 13:15:56 2017
@@ -10,12 +10,9 @@
 #ifndef LLD_ELF_MAPFILE_H
 #define LLD_ELF_MAPFILE_H
 
-#include <llvm/ADT/ArrayRef.h>
-
 namespace lld {
 namespace elf {
-class OutputSection;
-template <class ELFT> void writeMapFile();
+void writeMapFile();
 } // namespace elf
 } // namespace lld
 

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=316841&r1=316840&r2=316841&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Sat Oct 28 13:15:56 2017
@@ -445,14 +445,13 @@ static RelExpr fromPlt(RelExpr Expr) {
 // Returns true if a given shared symbol is in a read-only segment in a DSO.
 template <class ELFT> static bool isReadOnly(SharedSymbol *SS) {
   typedef typename ELFT::Phdr Elf_Phdr;
-  uint64_t Value = SS->getValue<ELFT>();
 
   // Determine if the symbol is read-only by scanning the DSO's program headers.
   const SharedFile<ELFT> *File = SS->getFile<ELFT>();
   for (const Elf_Phdr &Phdr : check(File->getObj().program_headers()))
     if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) &&
-        !(Phdr.p_flags & ELF::PF_W) && Value >= Phdr.p_vaddr &&
-        Value < Phdr.p_vaddr + Phdr.p_memsz)
+        !(Phdr.p_flags & ELF::PF_W) && SS->Value >= Phdr.p_vaddr &&
+        SS->Value < Phdr.p_vaddr + Phdr.p_memsz)
       return true;
   return false;
 }
@@ -467,12 +466,10 @@ static std::vector<SharedSymbol *> getSy
   typedef typename ELFT::Sym Elf_Sym;
 
   SharedFile<ELFT> *File = SS->getFile<ELFT>();
-  uint64_t Shndx = SS->getShndx<ELFT>();
-  uint64_t Value = SS->getValue<ELFT>();
 
   std::vector<SharedSymbol *> Ret;
   for (const Elf_Sym &S : File->getGlobalELFSyms()) {
-    if (S.st_shndx != Shndx || S.st_value != Value)
+    if (S.st_shndx != SS->Shndx || S.st_value != SS->Value)
       continue;
     StringRef Name = check(S.getName(File->getStringTable()));
     SymbolBody *Sym = Symtab->find(Name);
@@ -526,7 +523,7 @@ static std::vector<SharedSymbol *> getSy
 // define an accessor getV().
 template <class ELFT> static void addCopyRelSymbol(SharedSymbol *SS) {
   // Copy relocation against zero-sized symbol doesn't make sense.
-  uint64_t SymSize = SS->template getSize<ELFT>();
+  uint64_t SymSize = SS->getSize();
   if (SymSize == 0)
     fatal("cannot create a copy relocation for symbol " + toString(*SS));
 
@@ -534,7 +531,7 @@ template <class ELFT> static void addCop
   // memory protection by reserving space in the .bss.rel.ro section.
   bool IsReadOnly = isReadOnly<ELFT>(SS);
   BssSection *Sec = make<BssSection>(IsReadOnly ? ".bss.rel.ro" : ".bss",
-                                     SymSize, SS->getAlignment<ELFT>());
+                                     SymSize, SS->Alignment);
   if (IsReadOnly)
     InX::BssRelRo->getParent()->addSection(Sec);
   else
@@ -1014,7 +1011,7 @@ static void scanRelocs(InputSectionBase
 
     // The size is not going to change, so we fold it in here.
     if (Expr == R_SIZE)
-      Addend += Body.getSize<ELFT>();
+      Addend += Body.getSize();
 
     // If the produced value is a constant, we just remember to write it
     // when outputting this section. We also have to do it if the format

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=316841&r1=316840&r2=316841&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Sat Oct 28 13:15:56 2017
@@ -498,7 +498,7 @@ Symbol *SymbolTable::addRegular(StringRe
 
 template <typename ELFT>
 void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> *File,
-                            const typename ELFT::Sym &Sym,
+                            const typename ELFT::Sym &Sym, uint32_t Alignment,
                             const typename ELFT::Verdef *Verdef) {
   // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
   // as the visibility, which will leave the visibility in the symbol table
@@ -516,8 +516,9 @@ void SymbolTable::addShared(StringRef Na
   // in the same DSO.
   if (WasInserted || ((Body->isUndefined() || Body->isLazy()) &&
                       Body->getVisibility() == STV_DEFAULT)) {
-    replaceBody<SharedSymbol>(S, File, Name, Sym.st_other, Sym.getType(), &Sym,
-                              Verdef);
+    replaceBody<SharedSymbol>(S, File, Name, Sym.st_other, Sym.getType(),
+                              Sym.st_value, Sym.st_size, Alignment,
+                              Sym.st_shndx, Verdef);
     if (!S->isWeak())
       File->IsUsed = true;
   }
@@ -881,15 +882,19 @@ template void SymbolTable::addLazyObject
 
 template void SymbolTable::addShared<ELF32LE>(StringRef, SharedFile<ELF32LE> *,
                                               const typename ELF32LE::Sym &,
+                                              uint32_t Alignment,
                                               const typename ELF32LE::Verdef *);
 template void SymbolTable::addShared<ELF32BE>(StringRef, SharedFile<ELF32BE> *,
                                               const typename ELF32BE::Sym &,
+                                              uint32_t Alignment,
                                               const typename ELF32BE::Verdef *);
 template void SymbolTable::addShared<ELF64LE>(StringRef, SharedFile<ELF64LE> *,
                                               const typename ELF64LE::Sym &,
+                                              uint32_t Alignment,
                                               const typename ELF64LE::Verdef *);
 template void SymbolTable::addShared<ELF64BE>(StringRef, SharedFile<ELF64BE> *,
                                               const typename ELF64BE::Sym &,
+                                              uint32_t Alignment,
                                               const typename ELF64BE::Verdef *);
 
 template void SymbolTable::fetchIfLazy<ELF32LE>(StringRef);

Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=316841&r1=316840&r2=316841&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Sat Oct 28 13:15:56 2017
@@ -60,7 +60,7 @@ public:
 
   template <class ELFT>
   void addShared(StringRef Name, SharedFile<ELFT> *F,
-                 const typename ELFT::Sym &Sym,
+                 const typename ELFT::Sym &Sym, uint32_t Alignment,
                  const typename ELFT::Verdef *Verdef);
 
   template <class ELFT>

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=316841&r1=316840&r2=316841&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Sat Oct 28 13:15:56 2017
@@ -174,13 +174,13 @@ uint64_t SymbolBody::getPltVA() const {
          PltIndex * Target->PltEntrySize;
 }
 
-template <class ELFT> typename ELFT::uint SymbolBody::getSize() const {
+uint64_t SymbolBody::getSize() const {
   if (const auto *C = dyn_cast<DefinedCommon>(this))
     return C->Size;
   if (const auto *DR = dyn_cast<DefinedRegular>(this))
     return DR->Size;
   if (const auto *S = dyn_cast<SharedSymbol>(this))
-    return S->getSize<ELFT>();
+    return S->Size;
   return 0;
 }
 
@@ -261,17 +261,6 @@ template <class ELFT> bool DefinedRegula
          (Hdr->e_flags & EF_MIPS_PIC);
 }
 
-// If a shared symbol is referred via a copy relocation, its alignment
-// becomes part of the ABI. This function returns a symbol alignment.
-// Because symbols don't have alignment attributes, we need to infer that.
-template <class ELFT> uint32_t SharedSymbol::getAlignment() const {
-  SharedFile<ELFT> *File = getFile<ELFT>();
-  uint32_t SecAlign = File->getSection(getSym<ELFT>())->sh_addralign;
-  uint64_t SymValue = getSym<ELFT>().st_value;
-  uint32_t SymAlign = uint32_t(1) << countTrailingZeros(SymValue);
-  return std::min(SecAlign, SymAlign);
-}
-
 InputFile *Lazy::fetch() {
   if (auto *S = dyn_cast<LazyArchive>(this))
     return S->fetch();
@@ -346,17 +335,7 @@ std::string lld::toString(const SymbolBo
   return B.getName();
 }
 
-template uint32_t SymbolBody::template getSize<ELF32LE>() const;
-template uint32_t SymbolBody::template getSize<ELF32BE>() const;
-template uint64_t SymbolBody::template getSize<ELF64LE>() const;
-template uint64_t SymbolBody::template getSize<ELF64BE>() const;
-
 template bool DefinedRegular::template isMipsPIC<ELF32LE>() const;
 template bool DefinedRegular::template isMipsPIC<ELF32BE>() const;
 template bool DefinedRegular::template isMipsPIC<ELF64LE>() const;
 template bool DefinedRegular::template isMipsPIC<ELF64BE>() const;
-
-template uint32_t SharedSymbol::template getAlignment<ELF32LE>() const;
-template uint32_t SharedSymbol::template getAlignment<ELF32BE>() const;
-template uint32_t SharedSymbol::template getAlignment<ELF64LE>() const;
-template uint32_t SharedSymbol::template getAlignment<ELF64BE>() const;

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=316841&r1=316840&r2=316841&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Sat Oct 28 13:15:56 2017
@@ -93,7 +93,7 @@ public:
   uint64_t getGotPltOffset() const;
   uint64_t getGotPltVA() const;
   uint64_t getPltVA() const;
-  template <class ELFT> typename ELFT::uint getSize() const;
+  uint64_t getSize() const;
   OutputSection *getOutputSection() const;
 
   uint32_t DynsymIndex = 0;
@@ -218,10 +218,12 @@ class SharedSymbol : public Defined {
 public:
   static bool classof(const SymbolBody *S) { return S->kind() == SharedKind; }
 
-  SharedSymbol(StringRef Name, uint8_t StOther, uint8_t Type,
-               const void *ElfSym, const void *Verdef)
+  SharedSymbol(StringRef Name, uint8_t StOther, uint8_t Type, uint64_t Value,
+               uint64_t Size, uint32_t Alignment, uint64_t Shndx,
+               const void *Verdef)
       : Defined(SharedKind, Name, /*IsLocal=*/false, StOther, Type),
-        Verdef(Verdef), ElfSym(ElfSym) {
+        Verdef(Verdef), Value(Value), Size(Size), Shndx(Shndx),
+        Alignment(Alignment) {
     // GNU ifunc is a mechanism to allow user-supplied functions to
     // resolve PLT slot values at load-time. This is contrary to the
     // regualr symbol resolution scheme in which symbols are resolved just
@@ -246,18 +248,6 @@ public:
     return cast<SharedFile<ELFT>>(SymbolBody::getFile());
   }
 
-  template <class ELFT> uint64_t getShndx() const {
-    return getSym<ELFT>().st_shndx;
-  }
-
-  template <class ELFT> uint64_t getValue() const {
-    return getSym<ELFT>().st_value;
-  }
-
-  template <class ELFT> uint64_t getSize() const {
-    return getSym<ELFT>().st_size;
-  }
-
   template <class ELFT> uint32_t getAlignment() const;
 
   // This field is a pointer to the symbol's version definition.
@@ -266,12 +256,10 @@ public:
   // If not null, there is a copy relocation to this section.
   InputSection *CopyRelSec = nullptr;
 
-private:
-  template <class ELFT> const typename ELFT::Sym &getSym() const {
-    return *(const typename ELFT::Sym *)ElfSym;
-  }
-
-  const void *ElfSym;
+  uint64_t Value; // st_value
+  uint64_t Size;  // st_size
+  uint64_t Shndx; // st_shndx
+  uint32_t Alignment;
 };
 
 // This represents a symbol that is not yet in the link, but we know where to

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=316841&r1=316840&r2=316841&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Sat Oct 28 13:15:56 2017
@@ -82,7 +82,7 @@ template <class ELFT> void elf::createCo
     // don't have to care about DefinedCommon symbols beyond this point.
     replaceBody<DefinedRegular>(S, Sym->getFile(), Sym->getName(),
                                 static_cast<bool>(Sym->isLocal()), Sym->StOther,
-                                Sym->Type, 0, Sym->getSize<ELFT>(), Section);
+                                Sym->Type, 0, Sym->getSize(), Section);
   }
 }
 
@@ -1615,7 +1615,7 @@ template <class ELFT> void SymbolTableSe
     if (ESym->st_shndx == SHN_UNDEF)
       ESym->st_size = 0;
     else
-      ESym->st_size = Body->getSize<ELFT>();
+      ESym->st_size = Body->getSize();
 
     // st_value is usually an address of a symbol, but that has a
     // special meaining for uninstantiated common symbols (this can

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=316841&r1=316840&r2=316841&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Sat Oct 28 13:15:56 2017
@@ -248,7 +248,7 @@ template <class ELFT> void Writer<ELFT>:
     return;
 
   // Handle -Map option.
-  writeMapFile<ELFT>();
+  writeMapFile();
   if (errorCount())
     return;
 




More information about the llvm-commits mailing list