diff --git a/lld/test/wasm/export-optional.s b/lld/test/wasm/export-optional.s new file mode 100644 --- /dev/null +++ b/lld/test/wasm/export-optional.s @@ -0,0 +1,31 @@ +# Test the --export of optional linker-synthetic symbols works. +# Specifically the __start_xxx and __end_xx symbols. + +# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o +# RUN: wasm-ld --export=__start_foo %t.o -o %t.wasm +# RUN: obj2yaml %t.wasm | FileCheck %s + + .globl _start +_start: + .functype _start () -> () + i32.load foo + drop + end_function + + .globl foo + .section foo,"",@ +foo: + .int32 42 + .size foo, 4 + +# CHECK: - Type: EXPORT +# CHECK-NEXT: Exports: +# CHECK-NEXT: - Name: memory +# CHECK-NEXT: Kind: MEMORY +# CHECK-NEXT: Index: 0 +# CHECK-NEXT: - Name: _start +# CHECK-NEXT: Kind: FUNCTION +# CHECK-NEXT: Index: 0 +# CHECK-NEXT: - Name: __start_foo +# CHECK-NEXT: Kind: GLOBAL +# CHECK-NEXT: Index: 1 diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -1015,11 +1015,6 @@ Symbol *sym = symtab->find(arg->getValue()); if (sym && sym->isDefined()) sym->forceExport = true; - else if (config->unresolvedSymbols == UnresolvedPolicy::ReportError) - error(Twine("symbol exported via --export not found: ") + - arg->getValue()); - else if (config->unresolvedSymbols == UnresolvedPolicy::Warn) - warn(Twine("symbol exported via --export not found: ") + arg->getValue()); } if (!config->relocatable && !config->isPic) { diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -1350,6 +1350,19 @@ addStartStopSymbols(seg); } + // Delay reporting error about explict exports until after addStartStopSymbols + // which can create optional symbols. + for (auto &entry : config->exportedSymbols) { + StringRef name = entry.first(); + Symbol *sym = symtab->find(name); + if (sym && sym->isDefined()) + sym->forceExport = true; + else if (config->unresolvedSymbols == UnresolvedPolicy::ReportError) + error(Twine("symbol exported via --export not found: ") + name); + else if (config->unresolvedSymbols == UnresolvedPolicy::Warn) + warn(Twine("symbol exported via --export not found: ") + name); + } + log("-- scanRelocations"); scanRelocations(); log("-- finalizeIndirectFunctionTable");