diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -2191,7 +2191,7 @@ // This code may add new undefined symbols to the link, which may enqueue more // symbol resolution tasks, so we need to continue executing tasks until we // converge. - do { + auto updateLinkLoop = [&] { // Windows specific -- if entry point is not found, // search for its mangled names. if (config->entry) @@ -2231,6 +2231,10 @@ // Windows specific -- if __load_config_used can be resolved, resolve it. if (ctx.symtab.findUnderscore("_load_config_used")) addUndefined(mangle("_load_config_used")); + }; + + do { + updateLinkLoop(); } while (run()); if (args.hasArg(OPT_include_optional)) { @@ -2238,14 +2242,19 @@ for (auto *arg : args.filtered(OPT_include_optional)) if (isa_and_nonnull(ctx.symtab.find(arg->getValue()))) addUndefined(arg->getValue()); - while (run()); + do { + updateLinkLoop(); + } while (run()); } // Create wrapped symbols for -wrap option. std::vector wrapped = addWrappedSymbols(ctx, args); // Load more object files that might be needed for wrapped symbols. - if (!wrapped.empty()) - while (run()); + if (!wrapped.empty()) { + do { + updateLinkLoop(); + } while (run()); + } if (config->autoImport || config->stdcallFixup) { // MinGW specific. diff --git a/lld/test/COFF/includeoptional-export.s b/lld/test/COFF/includeoptional-export.s new file mode 100644 --- /dev/null +++ b/lld/test/COFF/includeoptional-export.s @@ -0,0 +1,51 @@ +// REQUIRES: x86 +// RUN: split-file %s %t.dir + +// RUN: llvm-mc -filetype=obj -triple=x86_64-win32-gnu %t.dir/main.s -o %t.main.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-win32-gnu %t.dir/lib1.s -o %t.lib1.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-win32-gnu %t.dir/lib2.s -o %t.lib2.o + +// RUN: rm -f %t.lib.a +// RUN: llvm-ar cru %t.lib.a %t.lib1.o %t.lib2.o +// RUN: lld-link -dll -out:%t-1.dll -entry:entry %t.main.o %t.lib.a +// RUN: lld-link -dll -out:%t-2.dll -entry:entry %t.main.o %t.lib.a -includeoptional:libfunc + +// RUN: llvm-readobj --coff-exports %t-1.dll | FileCheck --implicit-check-not=Name: %s --check-prefix=CHECK-DEFAULT +// RUN: llvm-readobj --coff-exports %t-2.dll | FileCheck --implicit-check-not=Name: %s --check-prefix=CHECK-INCLUDEOPTIONAL + +// CHECK-DEFAULT: Name: +// CHECK-DEFAULT: Name: myfunc + +// CHECK-INCLUDEOPTIONAL: Name: +// CHECK-INCLUDEOPTIONAL: Name: libfunc +// CHECK-INCLUDEOPTIONAL: Name: myfunc +// CHECK-INCLUDEOPTIONAL: Name: otherlibfunc + +#--- main.s +.global entry +entry: + ret + +.global myfunc +myfunc: + ret + +.section .drectve +.ascii "-export:myfunc " + +#--- lib1.s +.global libfunc +libfunc: + call otherlibfunc + ret + +.section .drectve +.ascii "-export:libfunc " + +#--- lib2.s +.global otherlibfunc +otherlibfunc: + ret + +.section .drectve +.ascii "-export:otherlibfunc "