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