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   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   Optional<StringRef> ImportModule;
25   Optional<StringRef> ImportName;
26   Optional<StringRef> ExportName;
27   wasm::WasmSignature *Signature = nullptr;
28   Optional<wasm::WasmGlobalType> GlobalType;
29   Optional<wasm::WasmTableType> TableType;
30   Optional<wasm::WasmTagType> TagType;
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 StringMapEntry<bool> * Name,bool isTemporary)37   MCSymbolWasm(const StringMapEntry<bool> *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   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 
isWeak()70   bool isWeak() const { return IsWeak; }
setWeak(bool isWeak)71   void setWeak(bool isWeak) { IsWeak = isWeak; }
72 
isHidden()73   bool isHidden() const { return IsHidden; }
setHidden(bool isHidden)74   void setHidden(bool isHidden) { IsHidden = isHidden; }
75 
isComdat()76   bool isComdat() const { return IsComdat; }
setComdat(bool isComdat)77   void setComdat(bool isComdat) { IsComdat = isComdat; }
78 
79   // wasm-ld understands a finite set of symbol types.  This flag allows the
80   // compiler to avoid emitting symbol table entries that would confuse the
81   // linker, unless the user specifically requests the feature.
omitFromLinkingSection()82   bool omitFromLinkingSection() const { return OmitFromLinkingSection; }
setOmitFromLinkingSection()83   void setOmitFromLinkingSection() { OmitFromLinkingSection = true; }
84 
hasImportModule()85   bool hasImportModule() const { return ImportModule.hasValue(); }
getImportModule()86   StringRef getImportModule() const {
87     if (ImportModule.hasValue())
88       return ImportModule.getValue();
89     // Use a default module name of "env" for now, for compatibility with
90     // existing tools.
91     // TODO(sbc): Find a way to specify a default value in the object format
92     // without picking a hardcoded value like this.
93     return "env";
94   }
setImportModule(StringRef Name)95   void setImportModule(StringRef Name) { ImportModule = Name; }
96 
hasImportName()97   bool hasImportName() const { return ImportName.hasValue(); }
getImportName()98   StringRef getImportName() const {
99     if (ImportName.hasValue())
100       return ImportName.getValue();
101     return getName();
102   }
setImportName(StringRef Name)103   void setImportName(StringRef Name) { ImportName = Name; }
104 
hasExportName()105   bool hasExportName() const { return ExportName.hasValue(); }
getExportName()106   StringRef getExportName() const { return ExportName.getValue(); }
setExportName(StringRef Name)107   void setExportName(StringRef Name) { ExportName = Name; }
108 
isFunctionTable()109   bool isFunctionTable() const {
110     return isTable() && hasTableType() &&
111            getTableType().ElemType == wasm::WASM_TYPE_FUNCREF;
112   }
setFunctionTable()113   void setFunctionTable() {
114     setType(wasm::WASM_SYMBOL_TYPE_TABLE);
115     setTableType(wasm::ValType::FUNCREF);
116   }
117 
setUsedInGOT()118   void setUsedInGOT() const { IsUsedInGOT = true; }
isUsedInGOT()119   bool isUsedInGOT() const { return IsUsedInGOT; }
120 
setUsedInInitArray()121   void setUsedInInitArray() const { IsUsedInInitArray = true; }
isUsedInInitArray()122   bool isUsedInInitArray() const { return IsUsedInInitArray; }
123 
getSignature()124   const wasm::WasmSignature *getSignature() const { return Signature; }
setSignature(wasm::WasmSignature * Sig)125   void setSignature(wasm::WasmSignature *Sig) { Signature = Sig; }
126 
getGlobalType()127   const wasm::WasmGlobalType &getGlobalType() const {
128     assert(GlobalType.hasValue());
129     return GlobalType.getValue();
130   }
setGlobalType(wasm::WasmGlobalType GT)131   void setGlobalType(wasm::WasmGlobalType GT) { GlobalType = GT; }
132 
hasTableType()133   bool hasTableType() const { return TableType.hasValue(); }
getTableType()134   const wasm::WasmTableType &getTableType() const {
135     assert(hasTableType());
136     return TableType.getValue();
137   }
setTableType(wasm::WasmTableType TT)138   void setTableType(wasm::WasmTableType TT) { TableType = TT; }
setTableType(wasm::ValType VT)139   void setTableType(wasm::ValType VT) {
140     // Declare a table with element type VT and no limits (min size 0, no max
141     // size).
142     wasm::WasmLimits Limits = {wasm::WASM_LIMITS_FLAG_NONE, 0, 0};
143     setTableType({uint8_t(VT), Limits});
144   }
145 
getTagType()146   const wasm::WasmTagType &getTagType() const {
147     assert(TagType.hasValue());
148     return TagType.getValue();
149   }
setTagType(wasm::WasmTagType ET)150   void setTagType(wasm::WasmTagType ET) { TagType = ET; }
151 };
152 
153 } // end namespace llvm
154 
155 #endif // LLVM_MC_MCSYMBOLWASM_H
156