From: Sam Clegg Date: Thu, 30 Nov 2017 22:34:58 +0000 (+0000) Subject: Add visibility flag to Wasm symbol flags X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2b1b9e5ead1e07380d9e6ecba279c0e5166b567e;p=llvm Add visibility flag to Wasm symbol flags The LLVM "hidden" flag needs to be passed through the Wasm intermediate objects in order for the linker to apply it to the final Wasm object. The corresponding change in LLD is here: https://github.com/WebAssembly/lld/pull/14 Patch by Nicholas Wilson Differential Revision: https://reviews.llvm.org/D40442 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@319488 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/BinaryFormat/Wasm.h b/include/llvm/BinaryFormat/Wasm.h index 26475c27df3..f3a58026ed7 100644 --- a/include/llvm/BinaryFormat/Wasm.h +++ b/include/llvm/BinaryFormat/Wasm.h @@ -190,11 +190,15 @@ enum : unsigned { }; const unsigned WASM_SYMBOL_BINDING_MASK = 0x3; +const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0x4; enum : unsigned { WASM_SYMBOL_BINDING_GLOBAL = 0x0, WASM_SYMBOL_BINDING_WEAK = 0x1, WASM_SYMBOL_BINDING_LOCAL = 0x2, + + WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0, + WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4, }; #define WASM_RELOC(name, value) name = value, diff --git a/include/llvm/MC/MCSymbolWasm.h b/include/llvm/MC/MCSymbolWasm.h index 9bae6c582fa..309ebf96d1b 100644 --- a/include/llvm/MC/MCSymbolWasm.h +++ b/include/llvm/MC/MCSymbolWasm.h @@ -18,6 +18,7 @@ class MCSymbolWasm : public MCSymbol { private: bool IsFunction = false; bool IsWeak = false; + bool IsHidden = false; std::string ModuleName; SmallVector Returns; SmallVector Params; @@ -45,6 +46,9 @@ public: bool isWeak() const { return IsWeak; } void setWeak(bool isWeak) { IsWeak = isWeak; } + bool isHidden() const { return IsHidden; } + void setHidden(bool isHidden) { IsHidden = isHidden; } + const StringRef getModuleName() const { return ModuleName; } const SmallVector &getReturns() const { diff --git a/include/llvm/Object/Wasm.h b/include/llvm/Object/Wasm.h index e138faeed34..504f1b49031 100644 --- a/include/llvm/Object/Wasm.h +++ b/include/llvm/Object/Wasm.h @@ -81,6 +81,14 @@ public: return Flags & wasm::WASM_SYMBOL_BINDING_MASK; } + bool isHidden() const { + return getVisibility() == wasm::WASM_SYMBOL_VISIBILITY_HIDDEN; + } + + unsigned getVisibility() const { + return Flags & wasm::WASM_SYMBOL_VISIBILITY_MASK; + } + void print(raw_ostream &Out) const { Out << "Name=" << Name << ", Type=" << static_cast(Type) << ", Flags=" << Flags << " ElemIndex=" << ElementIndex diff --git a/lib/MC/MCWasmStreamer.cpp b/lib/MC/MCWasmStreamer.cpp index 287b7cf7b23..ef2a5621512 100644 --- a/lib/MC/MCWasmStreamer.cpp +++ b/lib/MC/MCWasmStreamer.cpp @@ -98,10 +98,13 @@ bool MCWasmStreamer::EmitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) { case MCSA_WeakDefAutoPrivate: case MCSA_Invalid: case MCSA_IndirectSymbol: - case MCSA_Hidden: case MCSA_Protected: return false; + case MCSA_Hidden: + Symbol->setHidden(true); + break; + case MCSA_Weak: case MCSA_WeakReference: Symbol->setWeak(true); diff --git a/lib/MC/WasmObjectWriter.cpp b/lib/MC/WasmObjectWriter.cpp index 6e9088b9d0d..42521ac72e2 100644 --- a/lib/MC/WasmObjectWriter.cpp +++ b/lib/MC/WasmObjectWriter.cpp @@ -1180,10 +1180,14 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm, << S.isExternal() << " isTemporary=" << S.isTemporary() << " isFunction=" << WS.isFunction() << " isWeak=" << WS.isWeak() + << " isHidden=" << WS.isHidden() << " isVariable=" << WS.isVariable() << "\n"); - if (WS.isWeak()) - SymbolFlags.emplace_back(WS.getName(), wasm::WASM_SYMBOL_BINDING_WEAK); + if (WS.isWeak() || WS.isHidden()) { + uint32_t Flags = (WS.isWeak() ? wasm::WASM_SYMBOL_BINDING_WEAK : 0) | + (WS.isHidden() ? wasm::WASM_SYMBOL_VISIBILITY_HIDDEN : 0); + SymbolFlags.emplace_back(WS.getName(), Flags); + } if (WS.isVariable()) continue; diff --git a/lib/Object/WasmObjectFile.cpp b/lib/Object/WasmObjectFile.cpp index 86ce9c2209c..70ac598b897 100644 --- a/lib/Object/WasmObjectFile.cpp +++ b/lib/Object/WasmObjectFile.cpp @@ -378,7 +378,7 @@ Error WasmObjectFile::parseLinkingSection(const uint8_t *Ptr, Symbols[SymIndex].Flags = Flags; DEBUG(dbgs() << "Set symbol flags index:" << SymIndex << " name:" - << Symbols[SymIndex].Name << " exptected:" + << Symbols[SymIndex].Name << " expected:" << Symbol << " flags: " << Flags << "\n"); } break; @@ -766,6 +766,8 @@ uint32_t WasmObjectFile::getSymbolFlags(DataRefImpl Symb) const { Result |= SymbolRef::SF_Weak; if (!Sym.isLocal()) Result |= SymbolRef::SF_Global; + if (Sym.isHidden()) + Result |= SymbolRef::SF_Hidden; switch (Sym.Type) { case WasmSymbol::SymbolType::FUNCTION_IMPORT: diff --git a/test/MC/WebAssembly/visibility.ll b/test/MC/WebAssembly/visibility.ll new file mode 100644 index 00000000000..b445bf45e29 --- /dev/null +++ b/test/MC/WebAssembly/visibility.ll @@ -0,0 +1,23 @@ +; RUN: llc -mtriple wasm32-unknown-unknown-wasm -filetype=obj %s -o - | obj2yaml | FileCheck %s + +; Function with __attribute__((visibility("default"))) +define void @defaultVis() #0 { +entry: + ret void +} + +; Function with __attribute__((visibility("hidden"))) +define hidden void @hiddenVis() #0 { +entry: + ret void +} + +; CHECK: - Type: CUSTOM + +; CHECK: - Type: CUSTOM +; CHECK-NEXT: Name: linking +; CHECK-NEXT: DataSize: 0 +; CHECK-NEXT: SymbolInfo: +; CHECK-NEXT: - Name: hiddenVis +; CHECK-NEXT: Flags: 4 +; CHECK-NEXT: ...