Index: include/llvm/BinaryFormat/Wasm.h =================================================================== --- include/llvm/BinaryFormat/Wasm.h +++ include/llvm/BinaryFormat/Wasm.h @@ -313,6 +313,7 @@ const unsigned WASM_SYMBOL_UNDEFINED = 0x10; const unsigned WASM_SYMBOL_EXPORTED = 0x20; const unsigned WASM_SYMBOL_EXPLICIT_NAME = 0x40; +const unsigned WASM_SYMBOL_NO_STRIP = 0x80; #define WASM_RELOC(name, value) name = value, Index: include/llvm/MC/MCSymbolWasm.h =================================================================== --- include/llvm/MC/MCSymbolWasm.h +++ include/llvm/MC/MCSymbolWasm.h @@ -47,11 +47,11 @@ wasm::WasmSymbolType getType() const { return Type; } void setType(wasm::WasmSymbolType type) { Type = type; } - bool isExported() const { - return getFlags() & wasm::WASM_SYMBOL_EXPORTED; + bool isNoStrip() const { + return getFlags() & wasm::WASM_SYMBOL_NO_STRIP; } - void setExported() const { - modifyFlags(wasm::WASM_SYMBOL_EXPORTED, wasm::WASM_SYMBOL_EXPORTED); + void setNoStrip() const { + modifyFlags(wasm::WASM_SYMBOL_NO_STRIP, wasm::WASM_SYMBOL_NO_STRIP); } bool isWeak() const { return IsWeak; } Index: include/llvm/MC/MCWasmObjectWriter.h =================================================================== --- include/llvm/MC/MCWasmObjectWriter.h +++ include/llvm/MC/MCWasmObjectWriter.h @@ -20,9 +20,10 @@ class MCWasmObjectTargetWriter : public MCObjectTargetWriter { const unsigned Is64Bit : 1; + const unsigned IsEmscripten : 1; protected: - explicit MCWasmObjectTargetWriter(bool Is64Bit_); + explicit MCWasmObjectTargetWriter(bool Is64Bit_, bool IsEmscripten); public: virtual ~MCWasmObjectTargetWriter(); @@ -38,6 +39,7 @@ /// \name Accessors /// @{ bool is64Bit() const { return Is64Bit; } + bool isEmscripten() const { return IsEmscripten; } /// @} }; Index: lib/MC/MCWasmObjectTargetWriter.cpp =================================================================== --- lib/MC/MCWasmObjectTargetWriter.cpp +++ lib/MC/MCWasmObjectTargetWriter.cpp @@ -10,8 +10,9 @@ using namespace llvm; -MCWasmObjectTargetWriter::MCWasmObjectTargetWriter(bool Is64Bit) - : Is64Bit(Is64Bit) {} +MCWasmObjectTargetWriter::MCWasmObjectTargetWriter(bool Is64Bit, + bool IsEmscripten) + : Is64Bit(Is64Bit), IsEmscripten(IsEmscripten) {} // Pin the vtable to this object file MCWasmObjectTargetWriter::~MCWasmObjectTargetWriter() = default; Index: lib/MC/MCWasmStreamer.cpp =================================================================== --- lib/MC/MCWasmStreamer.cpp +++ lib/MC/MCWasmStreamer.cpp @@ -122,7 +122,7 @@ break; case MCSA_NoDeadStrip: - Symbol->setExported(); + Symbol->setNoStrip(); break; default: Index: lib/MC/WasmObjectWriter.cpp =================================================================== --- lib/MC/WasmObjectWriter.cpp +++ lib/MC/WasmObjectWriter.cpp @@ -270,6 +270,7 @@ // TargetObjectWriter wrappers. bool is64Bit() const { return TargetObjectWriter->is64Bit(); } + bool isEmscripten() const { return TargetObjectWriter->isEmscripten(); } void startSection(SectionBookkeeping &Section, unsigned SectionId); void startCustomSection(SectionBookkeeping &Section, StringRef Name); @@ -1486,8 +1487,12 @@ Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL; if (WS.isUndefined()) Flags |= wasm::WASM_SYMBOL_UNDEFINED; - if (WS.isExported()) - Flags |= wasm::WASM_SYMBOL_EXPORTED; + if (WS.isNoStrip()) { + Flags |= wasm::WASM_SYMBOL_NO_STRIP; + if (isEmscripten()) { + Flags |= wasm::WASM_SYMBOL_EXPORTED; + } + } if (WS.getName() != WS.getImportName()) Flags |= wasm::WASM_SYMBOL_EXPLICIT_NAME; Index: lib/ObjectYAML/WasmYAML.cpp =================================================================== --- lib/ObjectYAML/WasmYAML.cpp +++ lib/ObjectYAML/WasmYAML.cpp @@ -535,6 +535,7 @@ BCaseMask(UNDEFINED, UNDEFINED); BCaseMask(EXPORTED, EXPORTED); BCaseMask(EXPLICIT_NAME, EXPLICIT_NAME); + BCaseMask(NO_STRIP, NO_STRIP); #undef BCaseMask } Index: lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp =================================================================== --- lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp +++ lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp @@ -31,10 +31,12 @@ class WebAssemblyAsmBackend final : public MCAsmBackend { bool Is64Bit; + bool IsEmscripten; public: - explicit WebAssemblyAsmBackend(bool Is64Bit) - : MCAsmBackend(support::little), Is64Bit(Is64Bit) {} + explicit WebAssemblyAsmBackend(bool Is64Bit, bool IsEmscripten) + : MCAsmBackend(support::little), Is64Bit(Is64Bit), + IsEmscripten(IsEmscripten) {} unsigned getNumFixupKinds() const override { return WebAssembly::NumTargetFixupKinds; @@ -123,11 +125,11 @@ std::unique_ptr WebAssemblyAsmBackend::createObjectTargetWriter() const { - return createWebAssemblyWasmObjectWriter(Is64Bit); + return createWebAssemblyWasmObjectWriter(Is64Bit, IsEmscripten); } } // end anonymous namespace MCAsmBackend *llvm::createWebAssemblyAsmBackend(const Triple &TT) { - return new WebAssemblyAsmBackend(TT.isArch64Bit()); + return new WebAssemblyAsmBackend(TT.isArch64Bit(), TT.isOSEmscripten()); } Index: lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h =================================================================== --- lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h +++ lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h @@ -38,7 +38,7 @@ MCAsmBackend *createWebAssemblyAsmBackend(const Triple &TT); std::unique_ptr -createWebAssemblyWasmObjectWriter(bool Is64Bit); +createWebAssemblyWasmObjectWriter(bool Is64Bit, bool IsEmscripten); namespace WebAssembly { enum OperandType { Index: lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp =================================================================== --- lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp +++ lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp @@ -31,7 +31,7 @@ namespace { class WebAssemblyWasmObjectWriter final : public MCWasmObjectTargetWriter { public: - explicit WebAssemblyWasmObjectWriter(bool Is64Bit); + explicit WebAssemblyWasmObjectWriter(bool Is64Bit, bool IsEmscripten); private: unsigned getRelocType(const MCValue &Target, @@ -39,8 +39,9 @@ }; } // end anonymous namespace -WebAssemblyWasmObjectWriter::WebAssemblyWasmObjectWriter(bool Is64Bit) - : MCWasmObjectTargetWriter(Is64Bit) {} +WebAssemblyWasmObjectWriter::WebAssemblyWasmObjectWriter(bool Is64Bit, + bool IsEmscripten) + : MCWasmObjectTargetWriter(Is64Bit, IsEmscripten) {} static const MCSection *getFixupSection(const MCExpr *Expr) { if (auto SyExp = dyn_cast(Expr)) { @@ -116,6 +117,6 @@ } std::unique_ptr -llvm::createWebAssemblyWasmObjectWriter(bool Is64Bit) { - return llvm::make_unique(Is64Bit); +llvm::createWebAssemblyWasmObjectWriter(bool Is64Bit, bool IsEmscripten) { + return llvm::make_unique(Is64Bit, IsEmscripten); } Index: lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp =================================================================== --- lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp @@ -83,13 +83,22 @@ // WebAssembly Lowering public interface. //===----------------------------------------------------------------------===// -static Reloc::Model getEffectiveRelocModel(Optional RM) { +static Reloc::Model getEffectiveRelocModel(Optional RM, + const Triple &TT) { if (!RM.hasValue()) { // Default to static relocation model. This should always be more optimial // than PIC since the static linker can determine all global addresses and // assume direct function calls. return Reloc::Static; } + + if (!TT.isOSEmscripten()) { + // Relocation modes other than static are currently implemented in a way + // that only works for Emscripten, so disable them if we aren't targeting + // Emscripten. + return Reloc::Static; + } + return *RM; } @@ -102,7 +111,7 @@ : LLVMTargetMachine(T, TT.isArch64Bit() ? "e-m:e-p:64:64-i64:64-n32:64-S128" : "e-m:e-p:32:32-i64:64-n32:64-S128", - TT, CPU, FS, Options, getEffectiveRelocModel(RM), + TT, CPU, FS, Options, getEffectiveRelocModel(RM, TT), getEffectiveCodeModel(CM, CodeModel::Large), OL), TLOF(new WebAssemblyTargetObjectFile()) { // WebAssembly type-checks instructions, but a noreturn function with a return Index: test/CodeGen/WebAssembly/address-offsets.ll =================================================================== --- test/CodeGen/WebAssembly/address-offsets.ll +++ test/CodeGen/WebAssembly/address-offsets.ll @@ -6,7 +6,7 @@ ; a variety of circumstances. target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" -target triple = "wasm32-unknown-unknown" +target triple = "wasm32-unknown-emscripten" @g = external global [0 x i32], align 4 Index: test/CodeGen/WebAssembly/call-pic.ll =================================================================== --- test/CodeGen/WebAssembly/call-pic.ll +++ test/CodeGen/WebAssembly/call-pic.ll @@ -1,7 +1,7 @@ ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -relocation-model=pic -fast-isel=1 | FileCheck %s ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -relocation-model=pic -fast-isel=0 | FileCheck %s target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" -target triple = "wasm32-unknown-unknown" +target triple = "wasm32-unknown-emscripten" declare i32 @foo() declare i32 @bar() Index: test/CodeGen/WebAssembly/load-store-pic.ll =================================================================== --- test/CodeGen/WebAssembly/load-store-pic.ll +++ test/CodeGen/WebAssembly/load-store-pic.ll @@ -6,7 +6,7 @@ ; We test here both with and without fast-isel. target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" -target triple = "wasm32-unknown-unknown" +target triple = "wasm32-unknown-emscripten" @hidden_global = external hidden global i32 @hidden_global_array = external hidden global [10 x i32] Index: test/MC/WebAssembly/no-dead-strip.ll =================================================================== --- test/MC/WebAssembly/no-dead-strip.ll +++ test/MC/WebAssembly/no-dead-strip.ll @@ -13,8 +13,8 @@ ; CHECK-NEXT: Symbol { ; CHECK-NEXT: Name: foo ; CHECK-NEXT: Type: FUNCTION (0x0) -; CHECK-NEXT: Flags [ (0x20) -; CHECK-NEXT: EXPORTED (0x20) +; CHECK-NEXT: Flags [ (0x80) +; CHECK-NEXT: NO_STRIP (0x80) ; CHECK-NEXT: ] ; CHECK-NEXT: ElementIndex: 0x0 ; CHECK-NEXT: } Index: tools/llvm-readobj/WasmDumper.cpp =================================================================== --- tools/llvm-readobj/WasmDumper.cpp +++ tools/llvm-readobj/WasmDumper.cpp @@ -51,6 +51,7 @@ ENUM_ENTRY(UNDEFINED), ENUM_ENTRY(EXPORTED), ENUM_ENTRY(EXPLICIT_NAME), + ENUM_ENTRY(NO_STRIP), #undef ENUM_ENTRY };