[lld] r245868 - Start recording the section of symbols in the symbol table.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 24 13:06:33 PDT 2015


Author: rafael
Date: Mon Aug 24 15:06:32 2015
New Revision: 245868

URL: http://llvm.org/viewvc/llvm-project?rev=245868&view=rev
Log:
Start recording the section of symbols in the symbol table.

Support for more than 64 K sections to follow shortly.

Modified:
    lld/trunk/ELF/Chunks.h
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/elf2/symbols.s

Modified: lld/trunk/ELF/Chunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Chunks.h?rev=245868&r1=245867&r2=245868&view=diff
==============================================================================
--- lld/trunk/ELF/Chunks.h (original)
+++ lld/trunk/ELF/Chunks.h Mon Aug 24 15:06:32 2015
@@ -17,6 +17,7 @@ namespace lld {
 namespace elf2 {
 
 template <class ELFT> class ObjectFile;
+template <class ELFT> class OutputSection;
 
 // A chunk corresponding a section of an input file.
 template <class ELFT> class SectionChunk {
@@ -43,6 +44,9 @@ public:
   uintX_t getAlign() { return Header->sh_addralign; }
   void setOutputSectionOff(uint64_t V) { OutputSectionOff = V; }
 
+  void setOutputSection(OutputSection<ELFT> *O) { Out = O; }
+  OutputSection<ELFT> *getOutputSection() const { return Out; }
+
 private:
   // The offset from beginning of the output sections this chunk was assigned
   // to. The writer sets a value.
@@ -51,6 +55,8 @@ private:
   // A file this chunk was created from.
   llvm::object::ELFFile<ELFT> *Obj;
 
+  OutputSection<ELFT> *Out = nullptr;
+
   const Elf_Shdr *Header;
 };
 

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=245868&r1=245867&r2=245868&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Mon Aug 24 15:06:32 2015
@@ -39,7 +39,8 @@ template <class ELFT> void elf2::ObjectF
 
 template <class ELFT> void elf2::ObjectFile<ELFT>::initializeChunks() {
   uint64_t Size = ELFObj->getNumSections();
-  Chunks.reserve(Size);
+  Chunks.resize(Size);
+  unsigned I = 0;
   for (const Elf_Shdr &Sec : ELFObj->sections()) {
     switch (Sec.sh_type) {
     case SHT_SYMTAB:
@@ -51,10 +52,10 @@ template <class ELFT> void elf2::ObjectF
     case SHT_REL:
       break;
     default:
-      auto *C = new (Alloc) SectionChunk<ELFT>(this->getObj(), &Sec);
-      Chunks.push_back(C);
+      Chunks[I] = new (Alloc) SectionChunk<ELFT>(this->getObj(), &Sec);
       break;
     }
+    ++I;
   }
 }
 
@@ -81,17 +82,18 @@ SymbolBody *elf2::ObjectFile<ELFT>::crea
   ErrorOr<StringRef> NameOrErr = Sym->getName(StringTable);
   error(NameOrErr.getError());
   StringRef Name = *NameOrErr;
+  uint16_t SecIndex = Sym->st_shndx;
   switch (Sym->getBinding()) {
   default:
     error("unexpected binding");
   case STB_GLOBAL:
     if (Sym->isUndefined())
       return new (Alloc) Undefined<ELFT>(Name, *Sym);
-    return new (Alloc) DefinedRegular<ELFT>(Name, *Sym);
+    return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, *Chunks[SecIndex]);
   case STB_WEAK:
     if (Sym->isUndefined())
       return new (Alloc) UndefinedWeak<ELFT>(Name, *Sym);
-    return new (Alloc) DefinedWeak<ELFT>(Name, *Sym);
+    return new (Alloc) DefinedWeak<ELFT>(Name, *Sym, *Chunks[SecIndex]);
   }
 }
 

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=245868&r1=245867&r2=245868&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Mon Aug 24 15:06:32 2015
@@ -10,6 +10,8 @@
 #ifndef LLD_ELF_SYMBOLS_H
 #define LLD_ELF_SYMBOLS_H
 
+#include "Chunks.h"
+
 #include "lld/Core/LLVM.h"
 #include "llvm/Object/ELF.h"
 
@@ -106,13 +108,16 @@ template <class ELFT> class Defined : pu
 public:
   typedef typename Base::Elf_Sym Elf_Sym;
 
-  explicit Defined(Kind K, StringRef N, const Elf_Sym &Sym)
-      : ELFSymbolBody<ELFT>(K, N, Sym) {}
+  explicit Defined(Kind K, StringRef N, const Elf_Sym &Sym,
+                   SectionChunk<ELFT> &Section)
+      : ELFSymbolBody<ELFT>(K, N, Sym), Section(Section) {}
 
   static bool classof(const SymbolBody *S) {
     Kind K = S->kind();
     return Base::DefinedFirst <= K && K <= Base::DefinedLast;
   }
+
+  const SectionChunk<ELFT> &Section;
 };
 
 // Regular defined symbols read from object file symbol tables.
@@ -121,8 +126,9 @@ template <class ELFT> class DefinedRegul
   typedef typename Base::Elf_Sym Elf_Sym;
 
 public:
-  explicit DefinedRegular(StringRef N, const Elf_Sym &Sym)
-      : Defined<ELFT>(Base::DefinedRegularKind, N, Sym) {}
+  explicit DefinedRegular(StringRef N, const Elf_Sym &Sym,
+                          SectionChunk<ELFT> &Section)
+      : Defined<ELFT>(Base::DefinedRegularKind, N, Sym, Section) {}
 
   static bool classof(const SymbolBody *S) {
     return S->kind() == Base::DefinedRegularKind;
@@ -134,8 +140,9 @@ template <class ELFT> class DefinedWeak
   typedef typename Base::Elf_Sym Elf_Sym;
 
 public:
-  explicit DefinedWeak(StringRef N, const Elf_Sym &Sym)
-      : Defined<ELFT>(Base::DefinedWeakKind, N, Sym) {}
+  explicit DefinedWeak(StringRef N, const Elf_Sym &Sym,
+                       SectionChunk<ELFT> &Section)
+      : Defined<ELFT>(Base::DefinedWeakKind, N, Sym, Section) {}
 
   static bool classof(const SymbolBody *S) {
     return S->kind() == Base::DefinedWeakKind;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=245868&r1=245867&r2=245868&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Aug 24 15:06:32 2015
@@ -51,6 +51,9 @@ public:
   StringRef getName() { return Name; }
   void setNameOffset(uintX_t Offset) { Header.sh_name = Offset; }
 
+  unsigned getSectionIndex() const { return SectionIndex; }
+  void setSectionIndex(unsigned I) { SectionIndex = I; }
+
   // Returns the size of the section in the output file.
   uintX_t getSize() { return Header.sh_size; }
   uintX_t getFlags() { return Header.sh_flags; }
@@ -63,11 +66,14 @@ public:
 protected:
   StringRef Name;
   HeaderT Header;
+  unsigned SectionIndex;
   ~OutputSectionBase() = default;
 };
+}
 
 template <class ELFT>
-class OutputSection final : public OutputSectionBase<ELFT::Is64Bits> {
+class lld::elf2::OutputSection final
+    : public OutputSectionBase<ELFT::Is64Bits> {
 public:
   typedef typename OutputSectionBase<ELFT::Is64Bits>::uintX_t uintX_t;
   OutputSection(StringRef Name, uint32_t sh_type, uintX_t sh_flags)
@@ -80,6 +86,7 @@ private:
   std::vector<SectionChunk<ELFT> *> Chunks;
 };
 
+namespace {
 template <bool Is64Bits>
 class StringTableSection final : public OutputSectionBase<Is64Bits> {
   llvm::StringTableBuilder &StrTabBuilder;
@@ -159,6 +166,11 @@ private:
   StringTableSection<ELFT::Is64Bits> StringTable;
 
   unsigned NumSections;
+
+  void addOutputSection(OutputSectionBase<ELFT::Is64Bits> *Sec) {
+    OutputSections.push_back(Sec);
+    Sec->setSectionIndex(OutputSections.size());
+  }
 };
 } // anonymous namespace
 
@@ -189,6 +201,7 @@ template <class ELFT> void Writer<ELFT>:
 template <class ELFT>
 void OutputSection<ELFT>::addChunk(SectionChunk<ELFT> *C) {
   Chunks.push_back(C);
+  C->setOutputSection(this);
   uint32_t Align = C->getAlign();
   if (Align > this->Header.sh_addralign)
     this->Header.sh_addralign = Align;
@@ -223,15 +236,22 @@ template <class ELFT> void SymbolTableSe
     uint8_t Binding;
     SymbolBody *Body = Sym->Body;
     uint8_t Type = 0;
+
+    const SectionChunk<ELFT> *Section = nullptr;
+
     switch (Body->kind()) {
     case SymbolBody::UndefinedKind:
     case SymbolBody::UndefinedSyntheticKind:
       llvm_unreachable("Should be defined by now");
-    case SymbolBody::DefinedRegularKind:
+    case SymbolBody::DefinedRegularKind: {
       Binding = STB_GLOBAL;
-      Type = cast<DefinedRegular<ELFT>>(Body)->Sym.getType();
+      auto *Def = cast<DefinedRegular<ELFT>>(Body);
+      Type = Def->Sym.getType();
+      Section = &Def->Section;
       break;
+    }
     case SymbolBody::DefinedWeakKind:
+      Section = &cast<Defined<ELFT>>(Body)->Section;
     case SymbolBody::UndefinedWeakKind:
       Binding = STB_WEAK;
       Type = cast<ELFSymbolBody<ELFT>>(Body)->Sym.getType();
@@ -239,6 +259,11 @@ template <class ELFT> void SymbolTableSe
     }
     ESym->setBindingAndType(Binding, Type);
 
+    if (Section) {
+      OutputSection<ELFT> *Out = Section->getOutputSection();
+      ESym->st_shndx = Out->getSectionIndex();
+    }
+
     Buf += sizeof(Elf_Sym);
   }
 }
@@ -294,6 +319,8 @@ template <class ELFT> void Writer<ELFT>:
   for (const std::unique_ptr<ObjectFileBase> &FileB : Symtab.ObjectFiles) {
     auto &File = cast<ObjectFile<ELFT>>(*FileB);
     for (SectionChunk<ELFT> *C : File.getChunks()) {
+      if (!C)
+        continue;
       const Elf_Shdr *H = C->getSectionHdr();
       SectionKey<ELFT::Is64Bits> Key{C->getSectionName(), H->sh_type,
                                      H->sh_flags};
@@ -301,7 +328,7 @@ template <class ELFT> void Writer<ELFT>:
       if (!Sec) {
         Sec = new (CAlloc.Allocate())
             OutputSection<ELFT>(Key.Name, Key.sh_type, Key.sh_flags);
-        OutputSections.push_back(Sec);
+        addOutputSection(Sec);
       }
       Sec->addChunk(C);
     }
@@ -325,8 +352,8 @@ template <class ELFT> void Writer<ELFT>:
   std::stable_sort(OutputSections.begin(), OutputSections.end(),
                    compSec<ELFT::Is64Bits>);
 
-  OutputSections.push_back(&SymTable);
-  OutputSections.push_back(&StringTable);
+  addOutputSection(&SymTable);
+  addOutputSection(&StringTable);
   StringTableIndex = OutputSections.size();
   SymTable.setStringTableIndex(StringTableIndex);
 

Modified: lld/trunk/test/elf2/symbols.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/symbols.s?rev=245868&r1=245867&r2=245868&view=diff
==============================================================================
--- lld/trunk/test/elf2/symbols.s (original)
+++ lld/trunk/test/elf2/symbols.s Mon Aug 24 15:06:32 2015
@@ -15,6 +15,10 @@ foo:
 .weak bar
 .long bar
 
+.data
+.globl zed
+zed:
+
 // CHECK:      Symbols [
 // CHECK-NEXT:   Symbol {
 // CHECK-NEXT:     Name:  (0)
@@ -26,13 +30,22 @@ foo:
 // CHECK-NEXT:     Section: Undefined (0x0)
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
+// CHECK-NEXT:     Name: zed
+// CHECK-NEXT:     Value: 0x0
+// CHECK-NEXT:     Size: 0
+// CHECK-NEXT:     Binding: Global (0x1)
+// CHECK-NEXT:     Type: None
+// CHECK-NEXT:     Other: 0
+// CHECK-NEXT:     Section: .data
+// CHECK-NEXT:   }
+// CHECK-NEXT:   Symbol {
 // CHECK-NEXT:     Name: _start
 // CHECK-NEXT:     Value: 0x0
 // CHECK-NEXT:     Size: 0
 // CHECK-NEXT:     Binding: Global (0x1)
 // CHECK-NEXT:     Type: Function
 // CHECK-NEXT:     Other: 0
-// CHECK-NEXT:     Section: Undefined (0x0)
+// CHECK-NEXT:     Section: .text
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
 // CHECK-NEXT:     Name: bar
@@ -50,6 +63,6 @@ foo:
 // CHECK-NEXT:     Binding: Weak (0x2)
 // CHECK-NEXT:     Type: Object
 // CHECK-NEXT:     Other: 0
-// CHECK-NEXT:     Section: Undefined (0x0)
+// CHECK-NEXT:     Section: .text
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]




More information about the llvm-commits mailing list