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:
36   MCSymbolWasm(const StringMapEntry<bool> *Name, bool isTemporary)
37       : MCSymbol(SymbolKindWasm, Name, isTemporary) {}
38   static bool classof(const MCSymbol *S) { return S->isWasm(); }
39 
40   const MCExpr *getSize() const { return SymbolSize; }
41   void setSize(const MCExpr *SS) { SymbolSize = SS; }
42 
43   bool isFunction() const { return Type == wasm::WASM_SYMBOL_TYPE_FUNCTION; }
44   // Data is the default value if not set.
45   bool isData() const { return !Type || Type == wasm::WASM_SYMBOL_TYPE_DATA; }
46   bool isGlobal() const { return Type == wasm::WASM_SYMBOL_TYPE_GLOBAL; }
47   bool isTable() const { return Type == wasm::WASM_SYMBOL_TYPE_TABLE; }
48   bool isSection() const { return Type == wasm::WASM_SYMBOL_TYPE_SECTION; }
49   bool isTag() const { return Type == wasm::WASM_SYMBOL_TYPE_TAG; }
50 
51   std::optional<wasm::WasmSymbolType> getType() const { return Type; }
52 
53   void setType(wasm::WasmSymbolType type) { Type = type; }
54 
55   bool isExported() const {
56     return getFlags() & wasm::WASM_SYMBOL_EXPORTED;
57   }
58   void setExported() const {
59     modifyFlags(wasm::WASM_SYMBOL_EXPORTED, wasm::WASM_SYMBOL_EXPORTED);
60   }
61 
62   bool isNoStrip() const {
63     return getFlags() & wasm::WASM_SYMBOL_NO_STRIP;
64   }
65   void setNoStrip() const {
66     modifyFlags(wasm::WASM_SYMBOL_NO_STRIP, wasm::WASM_SYMBOL_NO_STRIP);
67   }
68 
69   bool isTLS() const { return getFlags() & wasm::WASM_SYMBOL_TLS; }
70   void setTLS() const {
71     modifyFlags(wasm::WASM_SYMBOL_TLS, wasm::WASM_SYMBOL_TLS);
72   }
73 
74   bool isWeak() const { return IsWeak; }
75   void setWeak(bool isWeak) { IsWeak = isWeak; }
76 
77   bool isHidden() const { return IsHidden; }
78   void setHidden(bool isHidden) { IsHidden = isHidden; }
79 
80   bool isComdat() const { return 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.
86   bool omitFromLinkingSection() const { return OmitFromLinkingSection; }
87   void setOmitFromLinkingSection() { OmitFromLinkingSection = true; }
88 
89   bool hasImportModule() const { return ImportModule.has_value(); }
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   }
99   void setImportModule(StringRef Name) { ImportModule = Name; }
100 
101   bool hasImportName() const { return ImportName.has_value(); }
102   StringRef getImportName() const {
103     if (ImportName)
104       return *ImportName;
105     return getName();
106   }
107   void setImportName(StringRef Name) { ImportName = Name; }
108 
109   bool hasExportName() const { return ExportName.has_value(); }
110   StringRef getExportName() const { return *ExportName; }
111   void setExportName(StringRef Name) { ExportName = Name; }
112 
113   bool isFunctionTable() const {
114     return isTable() && hasTableType() &&
115            getTableType().ElemType == wasm::WASM_TYPE_FUNCREF;
116   }
117   void setFunctionTable() {
118     setType(wasm::WASM_SYMBOL_TYPE_TABLE);
119     setTableType(wasm::ValType::FUNCREF);
120   }
121 
122   void setUsedInGOT() const { IsUsedInGOT = true; }
123   bool isUsedInGOT() const { return IsUsedInGOT; }
124 
125   void setUsedInInitArray() const { IsUsedInInitArray = true; }
126   bool isUsedInInitArray() const { return IsUsedInInitArray; }
127 
128   const wasm::WasmSignature *getSignature() const { return Signature; }
129   void setSignature(wasm::WasmSignature *Sig) { Signature = Sig; }
130 
131   const wasm::WasmGlobalType &getGlobalType() const {
132     assert(GlobalType);
133     return *GlobalType;
134   }
135   void setGlobalType(wasm::WasmGlobalType GT) { GlobalType = GT; }
136 
137   bool hasTableType() const { return TableType.has_value(); }
138   const wasm::WasmTableType &getTableType() const {
139     assert(hasTableType());
140     return *TableType;
141   }
142   void setTableType(wasm::WasmTableType TT) { TableType = TT; }
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({uint8_t(VT), Limits});
148   }
149 };
150 
151 } // end namespace llvm
152 
153 #endif // LLVM_MC_MCSYMBOLWASM_H
154