Skip to content

Commit

Permalink
[LLD] [COFF] Fix export directives in object files from -includeoptional
Browse files Browse the repository at this point in the history
When an object file contains an export directive, we normally do some
amount of deferred processing of them at the end of the linking
process. The -includeoptional option was handled after this, and
any object files (defining new exports) weren't handled.

Move the handling of the -includeoptional into the same late loop
which does the fixups for e.g. export directives.

Ideally, this would also be done for object files that are pulled
in by the wrap options, and for mingw autoimports, but those changes
require more modifications, to make them safe for potentially
being executed multiple times.

This fixes #57243.

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

(cherry picked from commit af39e6f)
  • Loading branch information
mstorsjo authored and tru committed Aug 25, 2022
1 parent e6f03d1 commit 9c29291
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 8 deletions.
15 changes: 7 additions & 8 deletions lld/COFF/Driver.cpp
Expand Up @@ -2228,15 +2228,14 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// Windows specific -- if __load_config_used can be resolved, resolve it.
if (ctx.symtab.findUnderscore("_load_config_used"))
addUndefined(mangle("_load_config_used"));
} while (run());

if (args.hasArg(OPT_include_optional)) {
// Handle /includeoptional
for (auto *arg : args.filtered(OPT_include_optional))
if (isa_and_nonnull<LazyArchive>(ctx.symtab.find(arg->getValue())))
addUndefined(arg->getValue());
while (run());
}
if (args.hasArg(OPT_include_optional)) {
// Handle /includeoptional
for (auto *arg : args.filtered(OPT_include_optional))
if (isa_and_nonnull<LazyArchive>(ctx.symtab.find(arg->getValue())))
addUndefined(arg->getValue());
}
} while (run());

// Create wrapped symbols for -wrap option.
std::vector<WrappedSymbol> wrapped = addWrappedSymbols(ctx, args);
Expand Down
51 changes: 51 additions & 0 deletions 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 "

0 comments on commit 9c29291

Please sign in to comment.