aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Storsjo <martin@martin.st>2017-10-19 06:56:04 +0000
committerMartin Storsjo <martin@martin.st>2017-10-19 06:56:04 +0000
commite67a331833b6e5b1d5547803d5c2fc68cf85e686 (patch)
tree806f9e1bb6531a5c1393ec5dd7a28bb742f81271
parente39d7f34f08a299c69560d59dd6b26817607c162 (diff)
[COFF] Exclude certain static libraries and object files when exporting all symbols
This more or less matches what GNU ld does. Differential Revision: https://reviews.llvm.org/D38937 git-svn-id: https://llvm.org/svn/llvm-project/lld/trunk@316148 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--COFF/Driver.cpp126
-rw-r--r--test/COFF/export-all.s18
2 files changed, 105 insertions, 39 deletions
diff --git a/COFF/Driver.cpp b/COFF/Driver.cpp
index b202090d0..20b27b107 100644
--- a/COFF/Driver.cpp
+++ b/COFF/Driver.cpp
@@ -548,42 +548,92 @@ static void parseModuleDefs(StringRef Path) {
}
}
-// Get a set of symbols not to automatically export
-// when exporting all global symbols for MinGW.
-static StringSet<> getExportExcludeSymbols() {
- if (Config->Machine == I386)
- return {
- "__NULL_IMPORT_DESCRIPTOR",
- "__pei386_runtime_relocator",
- "_do_pseudo_reloc",
- "_impure_ptr",
- "__impure_ptr",
- "__fmode",
- "_environ",
- "___dso_handle",
- // These are the MinGW names that differ from the standard
- // ones (lacking an extra underscore).
- "_DllMain@12",
- "_DllEntryPoint@12",
- "_DllMainCRTStartup@12",
- };
-
- return {
- "_NULL_IMPORT_DESCRIPTOR",
- "_pei386_runtime_relocator",
- "do_pseudo_reloc",
- "impure_ptr",
- "_impure_ptr",
- "_fmode",
- "environ",
- "__dso_handle",
- // These are the MinGW names that differ from the standard
- // ones (lacking an extra underscore).
- "DllMain",
- "DllEntryPoint",
- "DllMainCRTStartup",
+// Logic for deciding what symbols to export, when exporting all
+// symbols for MinGW.
+class AutoExporter {
+public:
+ AutoExporter() {
+ if (Config->Machine == I386)
+ ExcludeSymbols = {
+ "__NULL_IMPORT_DESCRIPTOR",
+ "__pei386_runtime_relocator",
+ "_do_pseudo_reloc",
+ "_impure_ptr",
+ "__impure_ptr",
+ "__fmode",
+ "_environ",
+ "___dso_handle",
+ // These are the MinGW names that differ from the standard
+ // ones (lacking an extra underscore).
+ "_DllMain@12",
+ "_DllEntryPoint@12",
+ "_DllMainCRTStartup@12",
+ };
+ else
+ ExcludeSymbols = {
+ "_NULL_IMPORT_DESCRIPTOR",
+ "_pei386_runtime_relocator",
+ "do_pseudo_reloc",
+ "impure_ptr",
+ "_impure_ptr",
+ "_fmode",
+ "environ",
+ "__dso_handle",
+ // These are the MinGW names that differ from the standard
+ // ones (lacking an extra underscore).
+ "DllMain",
+ "DllEntryPoint",
+ "DllMainCRTStartup",
+ };
+ }
+
+ StringSet<> ExcludeSymbols;
+ StringSet<> ExcludeLibs = {
+ "libgcc",
+ "libgcc_s",
+ "libstdc++",
+ "libmingw32",
+ "libmingwex",
+ "libg2c",
+ "libsupc++",
+ "libobjc",
+ "libgcj",
+ "libclang_rt.builtins-aarch64",
+ "libclang_rt.builtins-arm",
+ "libclang_rt.builtins-i386",
+ "libclang_rt.builtins-x86_64",
+ };
+ StringSet<> ExcludeObjects = {
+ "crt0.o",
+ "crt1.o",
+ "crt1u.o",
+ "crt2.o",
+ "crt2u.o",
+ "dllcrt1.o",
+ "dllcrt2.o",
+ "gcrt0.o",
+ "gcrt1.o",
+ "gcrt2.o",
+ "crtbegin.o",
+ "crtend.o",
};
-}
+
+ bool shouldExport(Defined *Sym) const {
+ if (!Sym || !Sym->isLive() || !Sym->getChunk())
+ return false;
+ if (ExcludeSymbols.count(Sym->getName()))
+ return false;
+ StringRef LibName = sys::path::filename(Sym->getFile()->ParentName);
+ // Drop the file extension.
+ LibName = LibName.substr(0, LibName.rfind('.'));
+ if (ExcludeLibs.count(LibName))
+ return false;
+ StringRef FileName = sys::path::filename(Sym->getFile()->getName());
+ if (LibName.empty() && ExcludeObjects.count(FileName))
+ return false;
+ return true;
+ }
+};
// This is MinGW specific.
static void writeDefFile(StringRef Name) {
@@ -1259,13 +1309,11 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
// are chosen to be exported.
if (Config->DLL && ((Config->MinGW && Config->Exports.empty()) ||
Args.hasArg(OPT_export_all_symbols))) {
- StringSet<> ExcludeSymbols = getExportExcludeSymbols();
+ AutoExporter Exporter;
Symtab->forEachSymbol([=](Symbol *S) {
auto *Def = dyn_cast<Defined>(S->body());
- if (!Def || !Def->isLive() || !Def->getChunk())
- return;
- if (ExcludeSymbols.count(Def->getName()))
+ if (!Exporter.shouldExport(Def))
return;
Export E;
E.Name = Def->getName();
diff --git a/test/COFF/export-all.s b/test/COFF/export-all.s
index d0da7ad59..6d2a64094 100644
--- a/test/COFF/export-all.s
+++ b/test/COFF/export-all.s
@@ -36,3 +36,21 @@ _foobar:
# CHECK2-DEF: exportfn1 @3
# CHECK2-DEF: exportfn2 @4
# CHECK2-DEF: exportfn3 @5
+
+# Test ignoring certain object files and libs.
+
+# RUN: echo -e ".global foobar\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\nfoobar:\ncall mingwfunc\ncall crtfunc\nret\n" > %t.main.s
+# RUN: llvm-mc -triple=x86_64-windows-gnu %t.main.s -filetype=obj -o %t.main.obj
+# RUN: mkdir -p %T/libs
+# RUN: echo -e ".global mingwfunc\n.text\nmingwfunc:\nret\n" > %T/libs/mingwfunc.s
+# RUN: llvm-mc -triple=x86_64-windows-gnu %T/libs/mingwfunc.s -filetype=obj -o %T/libs/mingwfunc.o
+# RUN: llvm-ar rcs %T/libs/libmingwex.a %T/libs/mingwfunc.o
+# RUN: echo -e ".global crtfunc\n.text\ncrtfunc:\nret\n" > %T/libs/crtfunc.s
+# RUN: llvm-mc -triple=x86_64-windows-gnu %T/libs/crtfunc.s -filetype=obj -o %T/libs/crt2.o
+# RUN: lld-link -out:%t.dll -dll -entry:DllMainCRTStartup %t.main.obj -lldmingw %T/libs/crt2.o %T/libs/libmingwex.a -output-def:%t.def
+# RUN: echo "EOF" >> %t.def
+# RUN: cat %t.def | FileCheck -check-prefix=CHECK-EXCLUDE %s
+
+# CHECK-EXCLUDE: EXPORTS
+# CHECK-EXCLUDE-NEXT: foobar @1
+# CHECK-EXCLUDE-NEXT: EOF