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 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 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.value(); 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.value(); 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.value(); } 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.value(); 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.value(); 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