diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1208,9 +1208,24 @@ Export e; e.name = def->getName(); e.sym = def; - if (Chunk *c = def->getChunk()) - if (!(c->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)) - e.data = true; + auto *defReg = dyn_cast(s); + if (!defReg || defReg->data) { + if (Chunk *c = def->getChunk()) + if (!(c->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)) + e.data = true; + } else if (defReg) { + InputFile *file = defReg->getFile(); + if (BitcodeFile *bc = dyn_cast(file)) { + for (const lto::InputFile::Symbol &objSym : bc->obj->symbols()) { + if (objSym.getName() == e.name) { + if (!objSym.isExecutable()) + e.data = true; + break; + } + } + } + } + s->isUsedInRegularObj = true; config->exports.push_back(e); }); } @@ -2108,6 +2123,13 @@ if (errorCount()) return; + config->hadExplicitExports = !config->exports.empty(); + if (config->mingw) { + // In MinGW, all symbols are automatically exported if no symbols + // are chosen to be exported. + maybeExportMinGWSymbols(args); + } + // Do LTO by compiling bitcode input files to a set of native COFF files then // link those files (unless -thinlto-index-only was given, in which case we // resolve symbols and write indices, but don't generate native code or link). @@ -2132,12 +2154,7 @@ if (errorCount()) return; - config->hadExplicitExports = !config->exports.empty(); if (config->mingw) { - // In MinGW, all symbols are automatically exported if no symbols - // are chosen to be exported. - maybeExportMinGWSymbols(args); - // Make sure the crtend.o object is the last object file. This object // file can contain terminating section chunks that need to be placed // last. GNU ld processes files and static libraries explicitly in the diff --git a/lld/COFF/MinGW.cpp b/lld/COFF/MinGW.cpp --- a/lld/COFF/MinGW.cpp +++ b/lld/COFF/MinGW.cpp @@ -123,7 +123,7 @@ } bool AutoExporter::shouldExport(Defined *sym) const { - if (!sym || !sym->getChunk()) + if (!sym) return false; // Only allow the symbol kinds that make sense to export; in particular, diff --git a/lld/test/COFF/export-all-lto.ll b/lld/test/COFF/export-all-lto.ll new file mode 100644 --- /dev/null +++ b/lld/test/COFF/export-all-lto.ll @@ -0,0 +1,23 @@ +; REQUIRES: x86 + +; RUN: llvm-as %s -o %t.bc + +; RUN: lld-link -lldmingw -dll -out:%t.dll %t.bc -noentry -output-def:%t.def +; RUN: llvm-readobj --coff-exports %t.dll | grep Name: | FileCheck %s +; RUN: cat %t.def | FileCheck --check-prefix=IMPLIB %s + +; CHECK: Name: MyExtData +; CHECK: Name: MyLibFunc + +; IMPLIB: MyExtData @1 DATA +; IMPLIB: MyLibFunc @2{{$}} + +target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-w64-windows-gnu" + +@MyExtData = dso_local global i32 42, align 4 + +define dso_local void @MyLibFunc() { +entry: + ret void +}