[lld] r248347 - Implement --export-dynamic.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 22 16:38:38 PDT 2015


Author: rafael
Date: Tue Sep 22 18:38:23 2015
New Revision: 248347

URL: http://llvm.org/viewvc/llvm-project?rev=248347&view=rev
Log:
Implement --export-dynamic.

Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Options.td
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/elf2/shared.s

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=248347&r1=248346&r2=248347&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Tue Sep 22 18:38:23 2015
@@ -22,6 +22,7 @@ struct Configuration {
   bool Shared = false;
   bool DiscardAll = false;
   bool DiscardLocals = false;
+  bool ExportDynamic = false;
 };
 
 extern Configuration *Config;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=248347&r1=248346&r2=248347&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Tue Sep 22 18:38:23 2015
@@ -88,6 +88,9 @@ void LinkerDriver::link(ArrayRef<const c
   if (Args.hasArg(OPT_discard_locals))
     Config->DiscardLocals = true;
 
+  if (Args.hasArg(OPT_export_dynamic))
+    Config->ExportDynamic = true;
+
   // Create a list of input files.
   std::vector<MemoryBufferRef> Inputs;
 

Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=248347&r1=248346&r2=248347&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Tue Sep 22 18:38:23 2015
@@ -27,3 +27,6 @@ def discard_locals : Flag<["-"], "discar
 
 def alias_discard_locals: Flag<["-"], "X">,
      Alias<discard_locals>;
+
+def export_dynamic : Flag<["--"], "export-dynamic">,
+     HelpText<"Put symbols in the dynamic symbol table">;

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=248347&r1=248346&r2=248347&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Tue Sep 22 18:38:23 2015
@@ -272,6 +272,12 @@ bool lld::elf2::includeInSymtab(const Sy
   return true;
 }
 
+bool lld::elf2::includeInDynamicSymtab(const SymbolBody &B) {
+  if (Config->ExportDynamic || Config->Shared)
+    return true;
+  return B.isUsedInDynamicReloc();
+}
+
 template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
   const OutputSection<ELFT> *Out = nullptr;
   const InputSection<ELFT> *Section = nullptr;
@@ -315,8 +321,10 @@ template <class ELFT> void SymbolTableSe
     SymbolBody *Body = Sym->Body;
     if (!includeInSymtab(*Body))
       continue;
-    const Elf_Sym &InputSym = cast<ELFSymbolBody<ELFT>>(Body)->Sym;
+    if (StrTabSec.isDynamic() && !includeInDynamicSymtab(*Body))
+      continue;
 
+    const Elf_Sym &InputSym = cast<ELFSymbolBody<ELFT>>(Body)->Sym;
     auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
     ESym->st_name = StrTabSec.getFileOff(Name);
 

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=248347&r1=248346&r2=248347&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Tue Sep 22 18:38:23 2015
@@ -39,6 +39,7 @@ getLocalSymVA(const typename llvm::objec
               const ObjectFile<ELFT> &File);
 
 bool includeInSymtab(const SymbolBody &B);
+bool includeInDynamicSymtab(const SymbolBody &B);
 
 // This represents a section in an output file.
 // Different sub classes represent different types of sections. Some contain

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=248347&r1=248346&r2=248347&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Tue Sep 22 18:38:23 2015
@@ -57,6 +57,8 @@ public:
   bool isLazy() const { return SymbolKind == LazyKind; }
   bool isShared() const { return SymbolKind == SharedKind; }
   bool isUsedInRegularObj() const { return IsUsedInRegularObj; }
+  bool isUsedInDynamicReloc() const { return IsUsedInDynamicReloc; }
+  void setUsedInDynamicReloc() { IsUsedInDynamicReloc = true; }
 
   // Returns the symbol name.
   StringRef getName() const { return Name; }
@@ -97,12 +99,14 @@ protected:
       : SymbolKind(K), IsWeak(IsWeak), MostConstrainingVisibility(Visibility),
         Name(Name) {
     IsUsedInRegularObj = K != SharedKind && K != LazyKind;
+    IsUsedInDynamicReloc = 0;
   }
 
   const unsigned SymbolKind : 8;
   const unsigned IsWeak : 1;
   unsigned MostConstrainingVisibility : 2;
   unsigned IsUsedInRegularObj : 1;
+  unsigned IsUsedInDynamicReloc : 1;
   unsigned DynamicSymbolTableIndex = 0;
   unsigned GotIndex = -1;
   unsigned PltIndex = -1;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=248347&r1=248346&r2=248347&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Sep 22 18:38:23 2015
@@ -267,6 +267,7 @@ void Writer<ELFT>::scanRelocs(
         continue;
       GotSec.addEntry(Body);
     }
+    S->setUsedInDynamicReloc();
     RelaDynSec.addReloc({C, RI});
   }
 }
@@ -302,28 +303,7 @@ template <class ELFT> void Writer<ELFT>:
     return Sec;
   };
 
-  // FIXME: Try to avoid the extra walk over all global symbols.
   const SymbolTable &Symtab = SymTabSec.getSymTable();
-  std::vector<DefinedCommon<ELFT> *> CommonSymbols;
-  for (auto &P : Symtab.getSymbols()) {
-    StringRef Name = P.first;
-    SymbolBody *Body = P.second->Body;
-    if (Body->isStrongUndefined())
-      error(Twine("undefined symbol: ") + Name);
-
-    if (auto *C = dyn_cast<DefinedCommon<ELFT>>(Body))
-      CommonSymbols.push_back(C);
-    if (!includeInSymtab(*Body))
-      continue;
-    SymTabSec.addSymbol(Name);
-
-    // FIXME: This adds way too much to the dynamic symbol table. We only
-    // need to add the symbols use by dynamic relocations when producing
-    // an executable (ignoring --export-dynamic).
-    if (needsDynamicSections())
-      HashSec.addSymbol(Body);
-  }
-
   for (const std::unique_ptr<ObjectFileBase> &FileB : Symtab.getObjectFiles()) {
     auto &File = cast<ObjectFile<ELFT>>(*FileB);
     if (!Config->DiscardAll) {
@@ -345,6 +325,24 @@ template <class ELFT> void Writer<ELFT>:
     }
   }
 
+  // FIXME: Try to avoid the extra walk over all global symbols.
+  std::vector<DefinedCommon<ELFT> *> CommonSymbols;
+  for (auto &P : Symtab.getSymbols()) {
+    StringRef Name = P.first;
+    SymbolBody *Body = P.second->Body;
+    if (Body->isStrongUndefined())
+      error(Twine("undefined symbol: ") + Name);
+
+    if (auto *C = dyn_cast<DefinedCommon<ELFT>>(Body))
+      CommonSymbols.push_back(C);
+    if (!includeInSymtab(*Body))
+      continue;
+    SymTabSec.addSymbol(Name);
+
+    if (needsDynamicSections() && includeInDynamicSymtab(*Body))
+      HashSec.addSymbol(Body);
+  }
+
   BSSSec = getSection(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
   SymTabSec.setBssSec(BSSSec);
   DynSymSec.setBssSec(BSSSec);

Modified: lld/trunk/test/elf2/shared.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/shared.s?rev=248347&r1=248346&r2=248347&view=diff
==============================================================================
--- lld/trunk/test/elf2/shared.s (original)
+++ lld/trunk/test/elf2/shared.s Tue Sep 22 18:38:23 2015
@@ -2,8 +2,10 @@
 // RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o
 // RUN: lld -flavor gnu2 -shared %t2.o -o %t2.so
 // RUN: llvm-readobj -s %t2.so | FileCheck --check-prefix=SO %s
-// RUN: lld -flavor gnu2 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -rpath foo -rpath bar %t.o %t2.so -o %t
+// RUN: lld -flavor gnu2 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t
 // RUN: llvm-readobj --program-headers --dynamic-table -t -s -dyn-symbols -section-data -hash-table %t | FileCheck %s
+// RUN: lld -flavor gnu2 %t.o %t2.so -o %t2
+// RUN: llvm-readobj -dyn-symbols %t2 | FileCheck --check-prefix=DONT_EXPORT %s
 // REQUIRES: x86
 
 // Make sure .symtab is properly aligned.
@@ -195,6 +197,36 @@
 // CHECK-NEXT:   }
 // CHECK-NEXT: ]
 
+// DONT_EXPORT:      DynamicSymbols [
+// DONT_EXPORT-NEXT:   Symbol {
+// DONT_EXPORT-NEXT:     Name: @ (0)
+// DONT_EXPORT-NEXT:     Value: 0x0
+// DONT_EXPORT-NEXT:     Size: 0
+// DONT_EXPORT-NEXT:     Binding: Local (0x0)
+// DONT_EXPORT-NEXT:     Type: None (0x0)
+// DONT_EXPORT-NEXT:     Other: 0
+// DONT_EXPORT-NEXT:     Section: Undefined (0x0)
+// DONT_EXPORT-NEXT:   }
+// DONT_EXPORT-NEXT:   Symbol {
+// DONT_EXPORT-NEXT:     Name: bar@
+// DONT_EXPORT-NEXT:     Value: 0x0
+// DONT_EXPORT-NEXT:     Size: 0
+// DONT_EXPORT-NEXT:     Binding: Global
+// DONT_EXPORT-NEXT:     Type: Function
+// DONT_EXPORT-NEXT:     Other: 0
+// DONT_EXPORT-NEXT:     Section: Undefined
+// DONT_EXPORT-NEXT:   }
+// DONT_EXPORT-NEXT:   Symbol {
+// DONT_EXPORT-NEXT:     Name: zed@
+// DONT_EXPORT-NEXT:     Value: 0x0
+// DONT_EXPORT-NEXT:     Size: 0
+// DONT_EXPORT-NEXT:     Binding: Global
+// DONT_EXPORT-NEXT:     Type: None
+// DONT_EXPORT-NEXT:     Other: 0
+// DONT_EXPORT-NEXT:     Section: Undefinedx
+// DONT_EXPORT-NEXT:   }
+// DONT_EXPORT-NEXT: ]
+
 // CHECK:      DynamicSection [
 // CHECK-NEXT:   Tag        Type                 Name/Value
 // CHECK-NEXT:   0x00000011 REL                  [[RELADDR]]




More information about the llvm-commits mailing list