Index: lld/trunk/docs/ReleaseNotes.rst =================================================================== --- lld/trunk/docs/ReleaseNotes.rst +++ lld/trunk/docs/ReleaseNotes.rst @@ -44,4 +44,7 @@ WebAssembly Improvements ------------------------ -* ... +* `__data_end` and `__heap_base` are no longer exported by default, + as it's best to keep them internal when possible. They can be + explicitly exported with `--export=__data_end` and + `--export=__heap_base`, respectively. Index: lld/trunk/docs/WebAssembly.rst =================================================================== --- lld/trunk/docs/WebAssembly.rst +++ lld/trunk/docs/WebAssembly.rst @@ -109,7 +109,7 @@ and use these stub functions at the otherwise invalid call sites. The default behaviour is to generate these stub function and to produce -a warning. The ``--falal-warnings`` flag can be used to disable this behaviour +a warning. The ``--fatal-warnings`` flag can be used to disable this behaviour and error out if mismatched are found. Imports and Exports Index: lld/trunk/test/wasm/export.ll =================================================================== --- lld/trunk/test/wasm/export.ll +++ lld/trunk/test/wasm/export.ll @@ -1,8 +1,15 @@ +; Test in default mode ; RUN: llc -filetype=obj %s -o %t.o ; RUN: not wasm-ld --export=missing -o %t.wasm %t.o 2>&1 | FileCheck -check-prefix=CHECK-ERROR %s ; RUN: wasm-ld --export=hidden_function -o %t.wasm %t.o ; RUN: obj2yaml %t.wasm | FileCheck %s +; Now test in Emscripten mode +; RUN: llc -filetype=obj %s -o %t.o -mtriple=wasm32-unknown-emscripten +; RUN: not wasm-ld --export=missing -o %t.wasm %t.o 2>&1 | FileCheck -check-prefix=CHECK-ERROR %s +; RUN: wasm-ld --export=hidden_function -o %t.wasm %t.o +; RUN: obj2yaml %t.wasm | FileCheck %s --check-prefixes=CHECK,EMSCRIPTEN + @llvm.used = appending global [1 x i8*] [i8* bitcast (i32 ()* @used_function to i8*)], section "llvm.metadata" target triple = "wasm32-unknown-unknown" @@ -43,9 +50,9 @@ ; CHECK-NEXT: - Name: hidden_function ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 0 -; CHECK-NEXT: - Name: used_function -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 1 +; EMSCRIPTEN-NEXT: - Name: used_function +; EMSCRIPTEN-NEXT: Kind: FUNCTION +; EMSCRIPTEN-NEXT: Index: 1 ; CHECK-NEXT: - Name: _start ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 2 Index: lld/trunk/wasm/LTO.cpp =================================================================== --- lld/trunk/wasm/LTO.cpp +++ lld/trunk/wasm/LTO.cpp @@ -105,6 +105,7 @@ // be removed. r.Prevailing = !objSym.isUndefined() && sym->getFile() == &f; r.VisibleToRegularObj = config->relocatable || sym->isUsedInRegularObj || + sym->isNoStrip() || (r.Prevailing && sym->isExported()); if (r.Prevailing) undefine(sym); Index: lld/trunk/wasm/MarkLive.cpp =================================================================== --- lld/trunk/wasm/MarkLive.cpp +++ lld/trunk/wasm/MarkLive.cpp @@ -69,9 +69,9 @@ if (!config->entry.empty()) enqueue(symtab->find(config->entry)); - // We need to preserve any exported symbol + // We need to preserve any no-strip or exported symbol for (Symbol *sym : symtab->getSymbols()) - if (sym->isExported()) + if (sym->isNoStrip() || sym->isExported()) enqueue(sym); // For relocatable output, we need to preserve all the ctor functions Index: lld/trunk/wasm/Symbols.h =================================================================== --- lld/trunk/wasm/Symbols.h +++ lld/trunk/wasm/Symbols.h @@ -107,6 +107,10 @@ WasmSymbolType getWasmType() const; bool isExported() const; + // Indicates that the symbol is used in an __attribute__((used)) directive + // or similar. + bool isNoStrip() const; + const WasmSignature* getSignature() const; bool isInGOT() const { return gotIndex != INVALID_INDEX; } Index: lld/trunk/wasm/Symbols.cpp =================================================================== --- lld/trunk/wasm/Symbols.cpp +++ lld/trunk/wasm/Symbols.cpp @@ -155,6 +155,10 @@ return flags & WASM_SYMBOL_EXPORTED; } +bool Symbol::isNoStrip() const { + return flags & WASM_SYMBOL_NO_STRIP; +} + uint32_t FunctionSymbol::getFunctionIndex() const { if (auto *f = dyn_cast(this)) return f->function->getFunctionIndex();