1 //===- MCSymbolWasm.h -  ----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #ifndef LLVM_MC_MCSYMBOLWASM_H
9 #define LLVM_MC_MCSYMBOLWASM_H
10 
11 #include "llvm/BinaryFormat/Wasm.h"
12 #include "llvm/MC/MCSymbol.h"
13 
14 namespace llvm {
15 
16 class MCSymbolWasm : public MCSymbol {
17   std::optional<wasm::WasmSymbolType> Type;
18   bool IsWeak = false;
19   bool IsHidden = false;
20   bool IsComdat = false;
21   bool OmitFromLinkingSection = false;
22   mutable bool IsUsedInInitArray = false;
23   mutable bool IsUsedInGOT = false;
24   std::optional<StringRef> ImportModule;
25   std::optional<StringRef> ImportName;
26   std::optional<StringRef> ExportName;
27   wasm::WasmSignature *Signature = nullptr;
28   std::optional<wasm::WasmGlobalType> GlobalType;
29   std::optional<wasm::WasmTableType> TableType;
30 
31   /// An expression describing how to calculate the size of a symbol. If a
32   /// symbol has no size this field will be NULL.
33   const MCExpr *SymbolSize = nullptr;
34 
35 public:
MCSymbolWasm(const StringMapEntry<bool> * Name,bool isTemporary)36   MCSymbolWasm(const StringMapEntry<bool> *Name, bool isTemporary)
37       : MCSymbol(SymbolKindWasm, Name, isTemporary) {}
classof(const MCSymbol * S)38   static bool classof(const MCSymbol *S) { return S->isWasm(); }
39 
getSize()40   const MCExpr *getSize() const { return SymbolSize; }
setSize(const MCExpr * SS)41   void setSize(const MCExpr *SS) { SymbolSize = SS; }
42 
isFunction()43   bool isFunction() const { return Type == wasm::WASM_SYMBOL_TYPE_FUNCTION; }
44   // Data is the default value if not set.
isData()45   bool isData() const { return !Type || Type == wasm::WASM_SYMBOL_TYPE_DATA; }
isGlobal()46   bool isGlobal() const { return Type == wasm::WASM_SYMBOL_TYPE_GLOBAL; }
isTable()47   bool isTable() const { return Type == wasm::WASM_SYMBOL_TYPE_TABLE; }
isSection()48   bool isSection() const { return Type == wasm::WASM_SYMBOL_TYPE_SECTION; }
isTag()49   bool isTag() const { return Type == wasm::WASM_SYMBOL_TYPE_TAG; }
50 
getType()51   std::optional<wasm::WasmSymbolType> getType() const { return Type; }
52 
setType(wasm::WasmSymbolType type)53   void setType(wasm::WasmSymbolType type) { Type = type; }
54 
isExported()55   bool isExported() const {
56     return getFlags() & wasm::WASM_SYMBOL_EXPORTED;
57   }
setExported()58   void setExported() const {
59     modifyFlags(wasm::WASM_SYMBOL_EXPORTED, wasm::WASM_SYMBOL_EXPORTED);
60   }
61 
isNoStrip()62   bool isNoStrip() const {
63     return getFlags() & wasm::WASM_SYMBOL_NO_STRIP;
64   }
setNoStrip()65   void setNoStrip() const {
66     modifyFlags(wasm::WASM_SYMBOL_NO_STRIP, wasm::WASM_SYMBOL_NO_STRIP);
67   }
68 
isTLS()69   bool isTLS() const { return getFlags() & wasm::WASM_SYMBOL_TLS; }
setTLS()70   void setTLS() const {
71     modifyFlags(wasm::WASM_SYMBOL_TLS, wasm::WASM_SYMBOL_TLS);
72   }
73 
isWeak()74   bool isWeak() const { return IsWeak; }
setWeak(bool isWeak)75   void setWeak(bool isWeak) { IsWeak = isWeak; }
76 
isHidden()77   bool isHidden() const { return IsHidden; }
setHidden(bool isHidden)78   void setHidden(bool isHidden) { IsHidden = isHidden; }
79 
isComdat()80   bool isComdat() const { return IsComdat; }
setComdat(bool isComdat)81   void setComdat(bool isComdat) { IsComdat = isComdat; }
82 
83   // wasm-ld understands a finite set of symbol types.  This flag allows the
84   // compiler to avoid emitting symbol table entries that would confuse the
85   // linker, unless the user specifically requests the feature.
omitFromLinkingSection()86   bool omitFromLinkingSection() const { return OmitFromLinkingSection; }
setOmitFromLinkingSection()87   void setOmitFromLinkingSection() { OmitFromLinkingSection = true; }
88 
hasImportModule()89   bool hasImportModule() const { return ImportModule.has_value(); }
getImportModule()90   StringRef getImportModule() const {
91     if (ImportModule)
92       return *ImportModule;
93     // Use a default module name of "env" for now, for compatibility with
94     // existing tools.
95     // TODO(sbc): Find a way to specify a default value in the object format
96     // without picking a hardcoded value like this.
97     return "env";
98   }
setImportModule(StringRef Name)99   void setImportModule(StringRef Name) { ImportModule = Name; }
100 
hasImportName()101   bool hasImportName() const { return ImportName.has_value(); }
getImportName()102   StringRef getImportName() const {
103     if (ImportName)
104       return *ImportName;
105     return getName();
106   }
setImportName(StringRef Name)107   void setImportName(StringRef Name) { ImportName = Name; }
108 
hasExportName()109   bool hasExportName() const { return ExportName.has_value(); }
getExportName()110   StringRef getExportName() const { return *ExportName; }
setExportName(StringRef Name)111   void setExportName(StringRef Name) { ExportName = Name; }
112 
isFunctionTable()113   bool isFunctionTable() const {
114     return isTable() && hasTableType() &&
115            getTableType().ElemType == wasm::ValType::FUNCREF;
116   }
setFunctionTable()117   void setFunctionTable() {
118     setType(wasm::WASM_SYMBOL_TYPE_TABLE);
119     setTableType(wasm::ValType::FUNCREF);
120   }
121 
setUsedInGOT()122   void setUsedInGOT() const { IsUsedInGOT = true; }
isUsedInGOT()123   bool isUsedInGOT() const { return IsUsedInGOT; }
124 
setUsedInInitArray()125   void setUsedInInitArray() const { IsUsedInInitArray = true; }
isUsedInInitArray()126   bool isUsedInInitArray() const { return IsUsedInInitArray; }
127 
getSignature()128   const wasm::WasmSignature *getSignature() const { return Signature; }
setSignature(wasm::WasmSignature * Sig)129   void setSignature(wasm::WasmSignature *Sig) { Signature = Sig; }
130 
getGlobalType()131   const wasm::WasmGlobalType &getGlobalType() const {
132     assert(GlobalType);
133     return *GlobalType;
134   }
setGlobalType(wasm::WasmGlobalType GT)135   void setGlobalType(wasm::WasmGlobalType GT) { GlobalType = GT; }
136 
hasTableType()137   bool hasTableType() const { return TableType.has_value(); }
getTableType()138   const wasm::WasmTableType &getTableType() const {
139     assert(hasTableType());
140     return *TableType;
141   }
setTableType(wasm::WasmTableType TT)142   void setTableType(wasm::WasmTableType TT) { TableType = TT; }
setTableType(wasm::ValType VT)143   void setTableType(wasm::ValType VT) {
144     // Declare a table with element type VT and no limits (min size 0, no max
145     // size).
146     wasm::WasmLimits Limits = {wasm::WASM_LIMITS_FLAG_NONE, 0, 0};
147     setTableType({VT, Limits});
148   }
149 };
150 
151 } // end namespace llvm
152 
153 #endif // LLVM_MC_MCSYMBOLWASM_H
154