[lld] r341403 - [COFF] Allow exporting all symbols from system libraries specfied with -wholearchive:

Martin Storsjo via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 4 13:56:56 PDT 2018


Author: mstorsjo
Date: Tue Sep  4 13:56:56 2018
New Revision: 341403

URL: http://llvm.org/viewvc/llvm-project?rev=341403&view=rev
Log:
[COFF] Allow exporting all symbols from system libraries specfied with -wholearchive:

When building a shared libc++.dll, it pulls in libc++abi.a statically
with the --wholearchive flag. If such a build is done with
--export-all-symbols, it's reasonable to assume that everything
from that library also should be exported with the same rules as normal
local object files, even though we normally avoid autoexporting things
from libc++abi.a in other cases when linking a DLL (user code).

Differential Revision: https://reviews.llvm.org/D51529

Modified:
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/MinGW.cpp
    lld/trunk/COFF/MinGW.h
    lld/trunk/test/COFF/export-all.s

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=341403&r1=341402&r2=341403&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Tue Sep  4 13:56:56 2018
@@ -1198,10 +1198,14 @@ void LinkerDriver::link(ArrayRef<const c
     return;
 
   std::set<sys::fs::UniqueID> WholeArchives;
-  for (auto *Arg : Args.filtered(OPT_wholearchive_file))
-    if (Optional<StringRef> Path = doFindFile(Arg->getValue()))
+  AutoExporter Exporter;
+  for (auto *Arg : Args.filtered(OPT_wholearchive_file)) {
+    if (Optional<StringRef> Path = doFindFile(Arg->getValue())) {
       if (Optional<sys::fs::UniqueID> ID = getUniqueID(*Path))
         WholeArchives.insert(*ID);
+      Exporter.addWholeArchive(*Path);
+    }
+  }
 
   // A predicate returning true if a given path is an argument for
   // /wholearchive:, or /wholearchive is enabled globally.
@@ -1458,7 +1462,7 @@ void LinkerDriver::link(ArrayRef<const c
   // are chosen to be exported.
   if (Config->DLL && ((Config->MinGW && Config->Exports.empty()) ||
                       Args.hasArg(OPT_export_all_symbols))) {
-    AutoExporter Exporter;
+    Exporter.initSymbolExcludes();
 
     Symtab->forEachSymbol([=](Symbol *S) {
       auto *Def = dyn_cast<Defined>(S);

Modified: lld/trunk/COFF/MinGW.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/MinGW.cpp?rev=341403&r1=341402&r2=341403&view=diff
==============================================================================
--- lld/trunk/COFF/MinGW.cpp (original)
+++ lld/trunk/COFF/MinGW.cpp Tue Sep  4 13:56:56 2018
@@ -19,7 +19,7 @@ using namespace lld::coff;
 using namespace llvm;
 using namespace llvm::COFF;
 
-AutoExporter::AutoExporter() {
+void AutoExporter::initSymbolExcludes() {
   if (Config->Machine == I386) {
     ExcludeSymbols = {
         "__NULL_IMPORT_DESCRIPTOR",
@@ -53,7 +53,9 @@ AutoExporter::AutoExporter() {
         "DllMainCRTStartup",
     };
   }
+}
 
+AutoExporter::AutoExporter() {
   ExcludeLibs = {
       "libgcc",
       "libgcc_s",
@@ -90,6 +92,13 @@ AutoExporter::AutoExporter() {
   };
 }
 
+void AutoExporter::addWholeArchive(StringRef Path) {
+  StringRef LibName = sys::path::filename(Path);
+  // Drop the file extension, to match the processing below.
+  LibName = LibName.substr(0, LibName.rfind('.'));
+  ExcludeLibs.erase(LibName);
+}
+
 bool AutoExporter::shouldExport(Defined *Sym) const {
   if (!Sym || !Sym->isLive() || !Sym->getChunk())
     return false;

Modified: lld/trunk/COFF/MinGW.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/MinGW.h?rev=341403&r1=341402&r2=341403&view=diff
==============================================================================
--- lld/trunk/COFF/MinGW.h (original)
+++ lld/trunk/COFF/MinGW.h Tue Sep  4 13:56:56 2018
@@ -23,6 +23,10 @@ class AutoExporter {
 public:
   AutoExporter();
 
+  void initSymbolExcludes();
+
+  void addWholeArchive(StringRef Path);
+
   llvm::StringSet<> ExcludeSymbols;
   llvm::StringSet<> ExcludeLibs;
   llvm::StringSet<> ExcludeObjects;

Modified: lld/trunk/test/COFF/export-all.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/export-all.s?rev=341403&r1=341402&r2=341403&view=diff
==============================================================================
--- lld/trunk/test/COFF/export-all.s (original)
+++ lld/trunk/test/COFF/export-all.s Tue Sep  4 13:56:56 2018
@@ -77,6 +77,18 @@ __imp__unexported:
 # CHECK-EXCLUDE-NEXT: foobar @1
 # CHECK-EXCLUDE-NEXT: EOF
 
+# Test that libraries included with -wholearchive: are autoexported, even if
+# they are in a library that otherwise normally would be excluded.
+
+# RUN: lld-link -out:%t.dll -dll -entry:DllMainCRTStartup %t.main.obj -lldmingw %T/libs/crt2.o -wholearchive:%T/libs/libmingwex.a -output-def:%t.def
+# RUN: echo "EOF" >> %t.def
+# RUN: cat %t.def | FileCheck -check-prefix=CHECK-WHOLEARCHIVE %s
+
+# CHECK-WHOLEARCHIVE: EXPORTS
+# CHECK-WHOLEARCHIVE-NEXT: foobar @1
+# CHECK-WHOLEARCHIVE-NEXT: mingwfunc @2
+# CHECK-WHOLEARCHIVE-NEXT: EOF
+
 # Test that we handle import libraries together with -opt:noref.
 
 # RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj




More information about the llvm-commits mailing list