Skip to content

Commit b40ccc1

Browse files
committedOct 19, 2017
[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 llvm-svn: 316148
1 parent f5f153d commit b40ccc1

File tree

2 files changed

+105
-39
lines changed

2 files changed

+105
-39
lines changed
 

‎lld/COFF/Driver.cpp

+87-39
Original file line numberDiff line numberDiff line change
@@ -548,42 +548,92 @@ static void parseModuleDefs(StringRef Path) {
548548
}
549549
}
550550

551-
// Get a set of symbols not to automatically export
552-
// when exporting all global symbols for MinGW.
553-
static StringSet<> getExportExcludeSymbols() {
554-
if (Config->Machine == I386)
555-
return {
556-
"__NULL_IMPORT_DESCRIPTOR",
557-
"__pei386_runtime_relocator",
558-
"_do_pseudo_reloc",
559-
"_impure_ptr",
560-
"__impure_ptr",
561-
"__fmode",
562-
"_environ",
563-
"___dso_handle",
564-
// These are the MinGW names that differ from the standard
565-
// ones (lacking an extra underscore).
566-
"_DllMain@12",
567-
"_DllEntryPoint@12",
568-
"_DllMainCRTStartup@12",
569-
};
570-
571-
return {
572-
"_NULL_IMPORT_DESCRIPTOR",
573-
"_pei386_runtime_relocator",
574-
"do_pseudo_reloc",
575-
"impure_ptr",
576-
"_impure_ptr",
577-
"_fmode",
578-
"environ",
579-
"__dso_handle",
580-
// These are the MinGW names that differ from the standard
581-
// ones (lacking an extra underscore).
582-
"DllMain",
583-
"DllEntryPoint",
584-
"DllMainCRTStartup",
551+
// Logic for deciding what symbols to export, when exporting all
552+
// symbols for MinGW.
553+
class AutoExporter {
554+
public:
555+
AutoExporter() {
556+
if (Config->Machine == I386)
557+
ExcludeSymbols = {
558+
"__NULL_IMPORT_DESCRIPTOR",
559+
"__pei386_runtime_relocator",
560+
"_do_pseudo_reloc",
561+
"_impure_ptr",
562+
"__impure_ptr",
563+
"__fmode",
564+
"_environ",
565+
"___dso_handle",
566+
// These are the MinGW names that differ from the standard
567+
// ones (lacking an extra underscore).
568+
"_DllMain@12",
569+
"_DllEntryPoint@12",
570+
"_DllMainCRTStartup@12",
571+
};
572+
else
573+
ExcludeSymbols = {
574+
"_NULL_IMPORT_DESCRIPTOR",
575+
"_pei386_runtime_relocator",
576+
"do_pseudo_reloc",
577+
"impure_ptr",
578+
"_impure_ptr",
579+
"_fmode",
580+
"environ",
581+
"__dso_handle",
582+
// These are the MinGW names that differ from the standard
583+
// ones (lacking an extra underscore).
584+
"DllMain",
585+
"DllEntryPoint",
586+
"DllMainCRTStartup",
587+
};
588+
}
589+
590+
StringSet<> ExcludeSymbols;
591+
StringSet<> ExcludeLibs = {
592+
"libgcc",
593+
"libgcc_s",
594+
"libstdc++",
595+
"libmingw32",
596+
"libmingwex",
597+
"libg2c",
598+
"libsupc++",
599+
"libobjc",
600+
"libgcj",
601+
"libclang_rt.builtins-aarch64",
602+
"libclang_rt.builtins-arm",
603+
"libclang_rt.builtins-i386",
604+
"libclang_rt.builtins-x86_64",
605+
};
606+
StringSet<> ExcludeObjects = {
607+
"crt0.o",
608+
"crt1.o",
609+
"crt1u.o",
610+
"crt2.o",
611+
"crt2u.o",
612+
"dllcrt1.o",
613+
"dllcrt2.o",
614+
"gcrt0.o",
615+
"gcrt1.o",
616+
"gcrt2.o",
617+
"crtbegin.o",
618+
"crtend.o",
585619
};
586-
}
620+
621+
bool shouldExport(Defined *Sym) const {
622+
if (!Sym || !Sym->isLive() || !Sym->getChunk())
623+
return false;
624+
if (ExcludeSymbols.count(Sym->getName()))
625+
return false;
626+
StringRef LibName = sys::path::filename(Sym->getFile()->ParentName);
627+
// Drop the file extension.
628+
LibName = LibName.substr(0, LibName.rfind('.'));
629+
if (ExcludeLibs.count(LibName))
630+
return false;
631+
StringRef FileName = sys::path::filename(Sym->getFile()->getName());
632+
if (LibName.empty() && ExcludeObjects.count(FileName))
633+
return false;
634+
return true;
635+
}
636+
};
587637

588638
// This is MinGW specific.
589639
static void writeDefFile(StringRef Name) {
@@ -1259,13 +1309,11 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
12591309
// are chosen to be exported.
12601310
if (Config->DLL && ((Config->MinGW && Config->Exports.empty()) ||
12611311
Args.hasArg(OPT_export_all_symbols))) {
1262-
StringSet<> ExcludeSymbols = getExportExcludeSymbols();
1312+
AutoExporter Exporter;
12631313

12641314
Symtab->forEachSymbol([=](Symbol *S) {
12651315
auto *Def = dyn_cast<Defined>(S->body());
1266-
if (!Def || !Def->isLive() || !Def->getChunk())
1267-
return;
1268-
if (ExcludeSymbols.count(Def->getName()))
1316+
if (!Exporter.shouldExport(Def))
12691317
return;
12701318
Export E;
12711319
E.Name = Def->getName();

‎lld/test/COFF/export-all.s

+18
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,21 @@ _foobar:
3636
# CHECK2-DEF: exportfn1 @3
3737
# CHECK2-DEF: exportfn2 @4
3838
# CHECK2-DEF: exportfn3 @5
39+
40+
# Test ignoring certain object files and libs.
41+
42+
# RUN: echo -e ".global foobar\n.global DllMainCRTStartup\n.text\nDllMainCRTStartup:\nret\nfoobar:\ncall mingwfunc\ncall crtfunc\nret\n" > %t.main.s
43+
# RUN: llvm-mc -triple=x86_64-windows-gnu %t.main.s -filetype=obj -o %t.main.obj
44+
# RUN: mkdir -p %T/libs
45+
# RUN: echo -e ".global mingwfunc\n.text\nmingwfunc:\nret\n" > %T/libs/mingwfunc.s
46+
# RUN: llvm-mc -triple=x86_64-windows-gnu %T/libs/mingwfunc.s -filetype=obj -o %T/libs/mingwfunc.o
47+
# RUN: llvm-ar rcs %T/libs/libmingwex.a %T/libs/mingwfunc.o
48+
# RUN: echo -e ".global crtfunc\n.text\ncrtfunc:\nret\n" > %T/libs/crtfunc.s
49+
# RUN: llvm-mc -triple=x86_64-windows-gnu %T/libs/crtfunc.s -filetype=obj -o %T/libs/crt2.o
50+
# 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
51+
# RUN: echo "EOF" >> %t.def
52+
# RUN: cat %t.def | FileCheck -check-prefix=CHECK-EXCLUDE %s
53+
54+
# CHECK-EXCLUDE: EXPORTS
55+
# CHECK-EXCLUDE-NEXT: foobar @1
56+
# CHECK-EXCLUDE-NEXT: EOF

0 commit comments

Comments
 (0)
Please sign in to comment.