Index: include/llvm/BinaryFormat/Wasm.h =================================================================== --- include/llvm/BinaryFormat/Wasm.h +++ include/llvm/BinaryFormat/Wasm.h @@ -289,6 +289,7 @@ const unsigned WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0; const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4; const unsigned WASM_SYMBOL_UNDEFINED = 0x10; +const unsigned WASM_SYMBOL_EXPORTED = 0x20; #define WASM_RELOC(name, value) name = value, Index: include/llvm/MC/MCSymbolWasm.h =================================================================== --- include/llvm/MC/MCSymbolWasm.h +++ include/llvm/MC/MCSymbolWasm.h @@ -46,6 +46,13 @@ wasm::WasmSymbolType getType() const { return Type; } void setType(wasm::WasmSymbolType type) { Type = type; } + bool isExported() const { + return getFlags() & wasm::WASM_SYMBOL_EXPORTED; + } + void setExported() const { + modifyFlags(wasm::WASM_SYMBOL_EXPORTED, wasm::WASM_SYMBOL_EXPORTED); + } + bool isWeak() const { return IsWeak; } void setWeak(bool isWeak) { IsWeak = isWeak; } Index: lib/MC/MCAsmInfoWasm.cpp =================================================================== --- lib/MC/MCAsmInfoWasm.cpp +++ lib/MC/MCAsmInfoWasm.cpp @@ -18,6 +18,7 @@ MCAsmInfoWasm::MCAsmInfoWasm() { HasIdentDirective = true; + HasNoDeadStrip = true; WeakRefDirective = "\t.weak\t"; PrivateGlobalPrefix = ".L"; PrivateLabelPrefix = ".L"; Index: lib/MC/MCWasmStreamer.cpp =================================================================== --- lib/MC/MCWasmStreamer.cpp +++ lib/MC/MCWasmStreamer.cpp @@ -121,6 +121,10 @@ case MCSA_Cold: break; + case MCSA_NoDeadStrip: + Symbol->setExported(); + break; + default: // unrecognized directive llvm_unreachable("unexpected MCSymbolAttr"); Index: lib/MC/WasmObjectWriter.cpp =================================================================== --- lib/MC/WasmObjectWriter.cpp +++ lib/MC/WasmObjectWriter.cpp @@ -1454,6 +1454,8 @@ Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL; if (WS.isUndefined()) Flags |= wasm::WASM_SYMBOL_UNDEFINED; + if (WS.isExported()) + Flags |= wasm::WASM_SYMBOL_EXPORTED; wasm::WasmSymbolInfo Info; Info.Name = WS.getName(); Index: lib/ObjectYAML/WasmYAML.cpp =================================================================== --- lib/ObjectYAML/WasmYAML.cpp +++ lib/ObjectYAML/WasmYAML.cpp @@ -486,6 +486,7 @@ // BCaseMask(VISIBILITY_MASK, VISIBILITY_DEFAULT); BCaseMask(VISIBILITY_MASK, VISIBILITY_HIDDEN); BCaseMask(UNDEFINED, UNDEFINED); + BCaseMask(EXPORTED, EXPORTED); #undef BCaseMask } Index: test/MC/WebAssembly/no-dead-strip.ll =================================================================== --- /dev/null +++ test/MC/WebAssembly/no-dead-strip.ll @@ -0,0 +1,21 @@ +; RUN: llc -filetype=obj -wasm-keep-registers %s -o - | llvm-readobj --symbols | FileCheck %s + +target triple = "wasm32-unknown-unknown" + +@llvm.used = appending global [1 x i8*] [i8* bitcast (i32 ()* @foo to i8*)], section "llvm.metadata" + +define i32 @foo() { +entry: + ret i32 0 +} + +; CHECK: Symbols [ +; CHECK-NEXT: Symbol { +; CHECK-NEXT: Name: foo +; CHECK-NEXT: Type: FUNCTION (0x0) +; CHECK-NEXT: Flags [ (0x20) +; CHECK-NEXT: EXPORTED (0x20) +; CHECK-NEXT: ] +; CHECK-NEXT: ElementIndex: 0x0 +; CHECK-NEXT: } +; CHECK-NEXT: ] Index: tools/llvm-readobj/WasmDumper.cpp =================================================================== --- tools/llvm-readobj/WasmDumper.cpp +++ tools/llvm-readobj/WasmDumper.cpp @@ -211,6 +211,7 @@ { "VISIBILITY_DEFAULT", wasm::WASM_SYMBOL_VISIBILITY_DEFAULT }, { "VISIBILITY_HIDDEN", wasm::WASM_SYMBOL_VISIBILITY_HIDDEN }, { "UNDEFINED", wasm::WASM_SYMBOL_UNDEFINED }, + { "EXPORTED", wasm::WASM_SYMBOL_EXPORTED }, }; void WasmDumper::printSymbol(const SymbolRef &Sym) {