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