File indexing completed on 2026-05-10 08:43:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_BINARYFORMAT_WASM_H
0015 #define LLVM_BINARYFORMAT_WASM_H
0016
0017 #include "llvm/ADT/ArrayRef.h"
0018 #include "llvm/ADT/SmallVector.h"
0019 #include "llvm/ADT/StringRef.h"
0020 #include <optional>
0021
0022 namespace llvm {
0023 namespace wasm {
0024
0025
0026 const char WasmMagic[] = {'\0', 'a', 's', 'm'};
0027
0028 const uint32_t WasmVersion = 0x1;
0029
0030 const uint32_t WasmMetadataVersion = 0x2;
0031
0032 const uint32_t WasmPageSize = 65536;
0033
0034 enum : unsigned {
0035 WASM_SEC_CUSTOM = 0,
0036 WASM_SEC_TYPE = 1,
0037 WASM_SEC_IMPORT = 2,
0038 WASM_SEC_FUNCTION = 3,
0039 WASM_SEC_TABLE = 4,
0040 WASM_SEC_MEMORY = 5,
0041 WASM_SEC_GLOBAL = 6,
0042 WASM_SEC_EXPORT = 7,
0043 WASM_SEC_START = 8,
0044 WASM_SEC_ELEM = 9,
0045 WASM_SEC_CODE = 10,
0046 WASM_SEC_DATA = 11,
0047 WASM_SEC_DATACOUNT = 12,
0048 WASM_SEC_TAG = 13,
0049 WASM_SEC_LAST_KNOWN = WASM_SEC_TAG,
0050 };
0051
0052
0053 enum : unsigned {
0054 WASM_TYPE_I32 = 0x7F,
0055 WASM_TYPE_I64 = 0x7E,
0056 WASM_TYPE_F32 = 0x7D,
0057 WASM_TYPE_F64 = 0x7C,
0058 WASM_TYPE_V128 = 0x7B,
0059 WASM_TYPE_NULLFUNCREF = 0x73,
0060 WASM_TYPE_NULLEXTERNREF = 0x72,
0061 WASM_TYPE_NULLEXNREF = 0x74,
0062 WASM_TYPE_NULLREF = 0x71,
0063 WASM_TYPE_FUNCREF = 0x70,
0064 WASM_TYPE_EXTERNREF = 0x6F,
0065 WASM_TYPE_EXNREF = 0x69,
0066 WASM_TYPE_ANYREF = 0x6E,
0067 WASM_TYPE_EQREF = 0x6D,
0068 WASM_TYPE_I31REF = 0x6C,
0069 WASM_TYPE_STRUCTREF = 0x6B,
0070 WASM_TYPE_ARRAYREF = 0x6A,
0071 WASM_TYPE_NONNULLABLE = 0x64,
0072 WASM_TYPE_NULLABLE = 0x63,
0073 WASM_TYPE_FUNC = 0x60,
0074 WASM_TYPE_ARRAY = 0x5E,
0075 WASM_TYPE_STRUCT = 0x5F,
0076 WASM_TYPE_SUB = 0x50,
0077 WASM_TYPE_SUB_FINAL = 0x4F,
0078 WASM_TYPE_REC = 0x4E,
0079 WASM_TYPE_NORESULT = 0x40,
0080 };
0081
0082
0083 enum : unsigned {
0084 WASM_EXTERNAL_FUNCTION = 0x0,
0085 WASM_EXTERNAL_TABLE = 0x1,
0086 WASM_EXTERNAL_MEMORY = 0x2,
0087 WASM_EXTERNAL_GLOBAL = 0x3,
0088 WASM_EXTERNAL_TAG = 0x4,
0089 };
0090
0091
0092 enum : unsigned {
0093 WASM_OPCODE_END = 0x0b,
0094 WASM_OPCODE_CALL = 0x10,
0095 WASM_OPCODE_LOCAL_GET = 0x20,
0096 WASM_OPCODE_LOCAL_SET = 0x21,
0097 WASM_OPCODE_LOCAL_TEE = 0x22,
0098 WASM_OPCODE_GLOBAL_GET = 0x23,
0099 WASM_OPCODE_GLOBAL_SET = 0x24,
0100 WASM_OPCODE_I32_STORE = 0x36,
0101 WASM_OPCODE_I64_STORE = 0x37,
0102 WASM_OPCODE_I32_CONST = 0x41,
0103 WASM_OPCODE_I64_CONST = 0x42,
0104 WASM_OPCODE_F32_CONST = 0x43,
0105 WASM_OPCODE_F64_CONST = 0x44,
0106 WASM_OPCODE_I32_ADD = 0x6a,
0107 WASM_OPCODE_I32_SUB = 0x6b,
0108 WASM_OPCODE_I32_MUL = 0x6c,
0109 WASM_OPCODE_I64_ADD = 0x7c,
0110 WASM_OPCODE_I64_SUB = 0x7d,
0111 WASM_OPCODE_I64_MUL = 0x7e,
0112 WASM_OPCODE_REF_NULL = 0xd0,
0113 WASM_OPCODE_REF_FUNC = 0xd2,
0114 WASM_OPCODE_GC_PREFIX = 0xfb,
0115 };
0116
0117
0118 enum : unsigned {
0119 WASM_OPCODE_STRUCT_NEW = 0x00,
0120 WASM_OPCODE_STRUCT_NEW_DEFAULT = 0x01,
0121 WASM_OPCODE_ARRAY_NEW = 0x06,
0122 WASM_OPCODE_ARRAY_NEW_DEFAULT = 0x07,
0123 WASM_OPCODE_ARRAY_NEW_FIXED = 0x08,
0124 WASM_OPCODE_REF_I31 = 0x1c,
0125
0126
0127 };
0128
0129
0130 enum : unsigned {
0131 WASM_OPCODE_BLOCK = 0x02,
0132 WASM_OPCODE_BR = 0x0c,
0133 WASM_OPCODE_BR_TABLE = 0x0e,
0134 WASM_OPCODE_RETURN = 0x0f,
0135 WASM_OPCODE_DROP = 0x1a,
0136 WASM_OPCODE_MISC_PREFIX = 0xfc,
0137 WASM_OPCODE_MEMORY_INIT = 0x08,
0138 WASM_OPCODE_MEMORY_FILL = 0x0b,
0139 WASM_OPCODE_DATA_DROP = 0x09,
0140 WASM_OPCODE_ATOMICS_PREFIX = 0xfe,
0141 WASM_OPCODE_ATOMIC_NOTIFY = 0x00,
0142 WASM_OPCODE_I32_ATOMIC_WAIT = 0x01,
0143 WASM_OPCODE_I32_ATOMIC_STORE = 0x17,
0144 WASM_OPCODE_I32_RMW_CMPXCHG = 0x48,
0145 };
0146
0147
0148 enum : unsigned {
0149 WASM_OPCODE_CATCH = 0x00,
0150 WASM_OPCODE_CATCH_REF = 0x01,
0151 WASM_OPCODE_CATCH_ALL = 0x02,
0152 WASM_OPCODE_CATCH_ALL_REF = 0x03,
0153 };
0154
0155 enum : unsigned {
0156 WASM_LIMITS_FLAG_NONE = 0x0,
0157 WASM_LIMITS_FLAG_HAS_MAX = 0x1,
0158 WASM_LIMITS_FLAG_IS_SHARED = 0x2,
0159 WASM_LIMITS_FLAG_IS_64 = 0x4,
0160 };
0161
0162 enum : unsigned {
0163 WASM_DATA_SEGMENT_IS_PASSIVE = 0x01,
0164 WASM_DATA_SEGMENT_HAS_MEMINDEX = 0x02,
0165 };
0166
0167 enum : unsigned {
0168 WASM_ELEM_SEGMENT_IS_PASSIVE = 0x01,
0169 WASM_ELEM_SEGMENT_IS_DECLARATIVE = 0x02,
0170 WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER = 0x02,
0171 WASM_ELEM_SEGMENT_HAS_INIT_EXPRS = 0x04,
0172 };
0173 const unsigned WASM_ELEM_SEGMENT_MASK_HAS_ELEM_DESC = 0x3;
0174
0175
0176 enum : uint8_t {
0177 WASM_FEATURE_PREFIX_USED = '+',
0178 WASM_FEATURE_PREFIX_DISALLOWED = '-',
0179 };
0180
0181
0182 enum : unsigned {
0183 WASM_NAMES_MODULE = 0,
0184 WASM_NAMES_FUNCTION = 1,
0185 WASM_NAMES_LOCAL = 2,
0186 WASM_NAMES_GLOBAL = 7,
0187 WASM_NAMES_DATA_SEGMENT = 9,
0188 };
0189
0190
0191 enum : unsigned {
0192 WASM_SEGMENT_INFO = 0x5,
0193 WASM_INIT_FUNCS = 0x6,
0194 WASM_COMDAT_INFO = 0x7,
0195 WASM_SYMBOL_TABLE = 0x8,
0196 };
0197
0198
0199 enum : unsigned {
0200 WASM_DYLINK_MEM_INFO = 0x1,
0201 WASM_DYLINK_NEEDED = 0x2,
0202 WASM_DYLINK_EXPORT_INFO = 0x3,
0203 WASM_DYLINK_IMPORT_INFO = 0x4,
0204 };
0205
0206
0207 enum : unsigned {
0208 WASM_COMDAT_DATA = 0x0,
0209 WASM_COMDAT_FUNCTION = 0x1,
0210
0211 WASM_COMDAT_SECTION = 0x5,
0212 };
0213
0214
0215 enum WasmSymbolType : unsigned {
0216 WASM_SYMBOL_TYPE_FUNCTION = 0x0,
0217 WASM_SYMBOL_TYPE_DATA = 0x1,
0218 WASM_SYMBOL_TYPE_GLOBAL = 0x2,
0219 WASM_SYMBOL_TYPE_SECTION = 0x3,
0220 WASM_SYMBOL_TYPE_TAG = 0x4,
0221 WASM_SYMBOL_TYPE_TABLE = 0x5,
0222 };
0223
0224 enum WasmSegmentFlag : unsigned {
0225 WASM_SEG_FLAG_STRINGS = 0x1,
0226 WASM_SEG_FLAG_TLS = 0x2,
0227 WASM_SEG_FLAG_RETAIN = 0x4,
0228 };
0229
0230
0231 enum WasmTagAttribute : uint8_t {
0232 WASM_TAG_ATTRIBUTE_EXCEPTION = 0x0,
0233 };
0234
0235 const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;
0236 const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0xc;
0237
0238 const unsigned WASM_SYMBOL_BINDING_GLOBAL = 0x0;
0239 const unsigned WASM_SYMBOL_BINDING_WEAK = 0x1;
0240 const unsigned WASM_SYMBOL_BINDING_LOCAL = 0x2;
0241 const unsigned WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0;
0242 const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4;
0243 const unsigned WASM_SYMBOL_UNDEFINED = 0x10;
0244 const unsigned WASM_SYMBOL_EXPORTED = 0x20;
0245 const unsigned WASM_SYMBOL_EXPLICIT_NAME = 0x40;
0246 const unsigned WASM_SYMBOL_NO_STRIP = 0x80;
0247 const unsigned WASM_SYMBOL_TLS = 0x100;
0248 const unsigned WASM_SYMBOL_ABSOLUTE = 0x200;
0249
0250 #define WASM_RELOC(name, value) name = value,
0251
0252 enum : unsigned {
0253 #include "WasmRelocs.def"
0254 };
0255
0256 #undef WASM_RELOC
0257
0258 struct WasmObjectHeader {
0259 StringRef Magic;
0260 uint32_t Version;
0261 };
0262
0263
0264 enum class ValType {
0265 I32 = WASM_TYPE_I32,
0266 I64 = WASM_TYPE_I64,
0267 F32 = WASM_TYPE_F32,
0268 F64 = WASM_TYPE_F64,
0269 V128 = WASM_TYPE_V128,
0270 FUNCREF = WASM_TYPE_FUNCREF,
0271 EXTERNREF = WASM_TYPE_EXTERNREF,
0272 EXNREF = WASM_TYPE_EXNREF,
0273
0274
0275 OTHERREF = 0xff,
0276 };
0277
0278 struct WasmDylinkImportInfo {
0279 StringRef Module;
0280 StringRef Field;
0281 uint32_t Flags;
0282 };
0283
0284 struct WasmDylinkExportInfo {
0285 StringRef Name;
0286 uint32_t Flags;
0287 };
0288
0289 struct WasmDylinkInfo {
0290 uint32_t MemorySize;
0291 uint32_t MemoryAlignment;
0292 uint32_t TableSize;
0293 uint32_t TableAlignment;
0294 std::vector<StringRef> Needed;
0295 std::vector<WasmDylinkImportInfo> ImportInfo;
0296 std::vector<WasmDylinkExportInfo> ExportInfo;
0297 };
0298
0299 struct WasmProducerInfo {
0300 std::vector<std::pair<std::string, std::string>> Languages;
0301 std::vector<std::pair<std::string, std::string>> Tools;
0302 std::vector<std::pair<std::string, std::string>> SDKs;
0303 };
0304
0305 struct WasmFeatureEntry {
0306 uint8_t Prefix;
0307 std::string Name;
0308 };
0309
0310 struct WasmExport {
0311 StringRef Name;
0312 uint8_t Kind;
0313 uint32_t Index;
0314 };
0315
0316 struct WasmLimits {
0317 uint8_t Flags;
0318 uint64_t Minimum;
0319 uint64_t Maximum;
0320 };
0321
0322 struct WasmTableType {
0323 ValType ElemType;
0324 WasmLimits Limits;
0325 };
0326
0327 struct WasmTable {
0328 uint32_t Index;
0329 WasmTableType Type;
0330 StringRef SymbolName;
0331 };
0332
0333 struct WasmInitExprMVP {
0334 uint8_t Opcode;
0335 union {
0336 int32_t Int32;
0337 int64_t Int64;
0338 uint32_t Float32;
0339 uint64_t Float64;
0340 uint32_t Global;
0341 } Value;
0342 };
0343
0344
0345
0346 struct WasmInitExpr {
0347 uint8_t Extended;
0348
0349 WasmInitExprMVP Inst;
0350 ArrayRef<uint8_t> Body;
0351 };
0352
0353 struct WasmGlobalType {
0354 uint8_t Type;
0355 bool Mutable;
0356 };
0357
0358 struct WasmGlobal {
0359 uint32_t Index;
0360 WasmGlobalType Type;
0361 WasmInitExpr InitExpr;
0362 StringRef SymbolName;
0363 uint32_t Offset;
0364 uint32_t Size;
0365 };
0366
0367 struct WasmTag {
0368 uint32_t Index;
0369 uint32_t SigIndex;
0370 StringRef SymbolName;
0371 };
0372
0373 struct WasmImport {
0374 StringRef Module;
0375 StringRef Field;
0376 uint8_t Kind;
0377 union {
0378 uint32_t SigIndex;
0379 WasmGlobalType Global;
0380 WasmTableType Table;
0381 WasmLimits Memory;
0382 };
0383 };
0384
0385 struct WasmLocalDecl {
0386 uint8_t Type;
0387 uint32_t Count;
0388 };
0389
0390 struct WasmFunction {
0391 uint32_t Index;
0392 uint32_t SigIndex;
0393 std::vector<WasmLocalDecl> Locals;
0394 ArrayRef<uint8_t> Body;
0395 uint32_t CodeSectionOffset;
0396 uint32_t Size;
0397 uint32_t CodeOffset;
0398 std::optional<StringRef> ExportName;
0399 StringRef SymbolName;
0400 StringRef DebugName;
0401 uint32_t Comdat;
0402 };
0403
0404 struct WasmDataSegment {
0405 uint32_t InitFlags;
0406
0407 uint32_t MemoryIndex;
0408
0409 WasmInitExpr Offset;
0410
0411 ArrayRef<uint8_t> Content;
0412 StringRef Name;
0413 uint32_t Alignment;
0414 uint32_t LinkingFlags;
0415 uint32_t Comdat;
0416 };
0417
0418
0419
0420 enum class ElemSegmentMode { Active, Passive, Declarative };
0421
0422
0423
0424
0425
0426
0427
0428 struct WasmElemSegment {
0429 uint32_t Flags;
0430 uint32_t TableNumber;
0431 ValType ElemKind;
0432 WasmInitExpr Offset;
0433 std::vector<uint32_t> Functions;
0434 };
0435
0436
0437
0438 struct WasmDataReference {
0439 uint32_t Segment;
0440 uint64_t Offset;
0441 uint64_t Size;
0442 };
0443
0444 struct WasmRelocation {
0445 uint8_t Type;
0446 uint32_t Index;
0447 uint64_t Offset;
0448 int64_t Addend;
0449 };
0450
0451 struct WasmInitFunc {
0452 uint32_t Priority;
0453 uint32_t Symbol;
0454 };
0455
0456 struct WasmSymbolInfo {
0457 StringRef Name;
0458 uint8_t Kind;
0459 uint32_t Flags;
0460
0461 std::optional<StringRef> ImportModule;
0462
0463 std::optional<StringRef> ImportName;
0464
0465 std::optional<StringRef> ExportName;
0466 union {
0467
0468
0469 uint32_t ElementIndex;
0470
0471 WasmDataReference DataRef;
0472 };
0473 };
0474
0475 enum class NameType {
0476 FUNCTION,
0477 GLOBAL,
0478 DATA_SEGMENT,
0479 };
0480
0481 struct WasmDebugName {
0482 NameType Type;
0483 uint32_t Index;
0484 StringRef Name;
0485 };
0486
0487
0488 struct WasmLinkingData {
0489 uint32_t Version;
0490 std::vector<WasmInitFunc> InitFunctions;
0491 std::vector<StringRef> Comdats;
0492
0493
0494
0495
0496 };
0497
0498 struct WasmSignature {
0499 SmallVector<ValType, 1> Returns;
0500 SmallVector<ValType, 4> Params;
0501
0502
0503
0504 enum { Function, Tag, Placeholder } Kind = Function;
0505
0506 enum { Plain, Empty, Tombstone } State = Plain;
0507
0508 WasmSignature(SmallVector<ValType, 1> &&InReturns,
0509 SmallVector<ValType, 4> &&InParams)
0510 : Returns(InReturns), Params(InParams) {}
0511 WasmSignature() = default;
0512 };
0513
0514
0515 inline bool operator==(const WasmSignature &LHS, const WasmSignature &RHS) {
0516 return LHS.State == RHS.State && LHS.Returns == RHS.Returns &&
0517 LHS.Params == RHS.Params;
0518 }
0519
0520 inline bool operator!=(const WasmSignature &LHS, const WasmSignature &RHS) {
0521 return !(LHS == RHS);
0522 }
0523
0524 inline bool operator==(const WasmGlobalType &LHS, const WasmGlobalType &RHS) {
0525 return LHS.Type == RHS.Type && LHS.Mutable == RHS.Mutable;
0526 }
0527
0528 inline bool operator!=(const WasmGlobalType &LHS, const WasmGlobalType &RHS) {
0529 return !(LHS == RHS);
0530 }
0531
0532 inline bool operator==(const WasmLimits &LHS, const WasmLimits &RHS) {
0533 return LHS.Flags == RHS.Flags && LHS.Minimum == RHS.Minimum &&
0534 (LHS.Flags & WASM_LIMITS_FLAG_HAS_MAX ? LHS.Maximum == RHS.Maximum
0535 : true);
0536 }
0537
0538 inline bool operator==(const WasmTableType &LHS, const WasmTableType &RHS) {
0539 return LHS.ElemType == RHS.ElemType && LHS.Limits == RHS.Limits;
0540 }
0541
0542 llvm::StringRef toString(WasmSymbolType type);
0543 llvm::StringRef relocTypetoString(uint32_t type);
0544 llvm::StringRef sectionTypeToString(uint32_t type);
0545 bool relocTypeHasAddend(uint32_t type);
0546
0547 }
0548 }
0549
0550 #endif