Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- Wasm.h - Wasm object file format -------------------------*- 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. //
  9. // This file defines manifest constants for the wasm object file format.
  10. // See: https://github.com/WebAssembly/design/blob/main/BinaryEncoding.md
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_BINARYFORMAT_WASM_H
  15. #define LLVM_BINARYFORMAT_WASM_H
  16.  
  17. #include "llvm/ADT/ArrayRef.h"
  18. #include "llvm/ADT/SmallVector.h"
  19. #include "llvm/ADT/StringRef.h"
  20. #include <optional>
  21.  
  22. namespace llvm {
  23. namespace wasm {
  24.  
  25. // Object file magic string.
  26. const char WasmMagic[] = {'\0', 'a', 's', 'm'};
  27. // Wasm binary format version
  28. const uint32_t WasmVersion = 0x1;
  29. // Wasm linking metadata version
  30. const uint32_t WasmMetadataVersion = 0x2;
  31. // Wasm uses a 64k page size
  32. const uint32_t WasmPageSize = 65536;
  33.  
  34. struct WasmObjectHeader {
  35.   StringRef Magic;
  36.   uint32_t Version;
  37. };
  38.  
  39. struct WasmDylinkImportInfo {
  40.   StringRef Module;
  41.   StringRef Field;
  42.   uint32_t Flags;
  43. };
  44.  
  45. struct WasmDylinkExportInfo {
  46.   StringRef Name;
  47.   uint32_t Flags;
  48. };
  49.  
  50. struct WasmDylinkInfo {
  51.   uint32_t MemorySize; // Memory size in bytes
  52.   uint32_t MemoryAlignment;  // P2 alignment of memory
  53.   uint32_t TableSize;  // Table size in elements
  54.   uint32_t TableAlignment;  // P2 alignment of table
  55.   std::vector<StringRef> Needed; // Shared library dependencies
  56.   std::vector<WasmDylinkImportInfo> ImportInfo;
  57.   std::vector<WasmDylinkExportInfo> ExportInfo;
  58. };
  59.  
  60. struct WasmProducerInfo {
  61.   std::vector<std::pair<std::string, std::string>> Languages;
  62.   std::vector<std::pair<std::string, std::string>> Tools;
  63.   std::vector<std::pair<std::string, std::string>> SDKs;
  64. };
  65.  
  66. struct WasmFeatureEntry {
  67.   uint8_t Prefix;
  68.   std::string Name;
  69. };
  70.  
  71. struct WasmExport {
  72.   StringRef Name;
  73.   uint8_t Kind;
  74.   uint32_t Index;
  75. };
  76.  
  77. struct WasmLimits {
  78.   uint8_t Flags;
  79.   uint64_t Minimum;
  80.   uint64_t Maximum;
  81. };
  82.  
  83. struct WasmTableType {
  84.   uint8_t ElemType;
  85.   WasmLimits Limits;
  86. };
  87.  
  88. struct WasmTable {
  89.   uint32_t Index;
  90.   WasmTableType Type;
  91.   StringRef SymbolName; // from the "linking" section
  92. };
  93.  
  94. struct WasmInitExprMVP {
  95.   uint8_t Opcode;
  96.   union {
  97.     int32_t Int32;
  98.     int64_t Int64;
  99.     uint32_t Float32;
  100.     uint64_t Float64;
  101.     uint32_t Global;
  102.   } Value;
  103. };
  104.  
  105. struct WasmInitExpr {
  106.   uint8_t Extended; // Set to non-zero if extended const is used (i.e. more than
  107.                     // one instruction)
  108.   WasmInitExprMVP Inst;
  109.   ArrayRef<uint8_t> Body;
  110. };
  111.  
  112. struct WasmGlobalType {
  113.   uint8_t Type;
  114.   bool Mutable;
  115. };
  116.  
  117. struct WasmGlobal {
  118.   uint32_t Index;
  119.   WasmGlobalType Type;
  120.   WasmInitExpr InitExpr;
  121.   StringRef SymbolName; // from the "linking" section
  122. };
  123.  
  124. struct WasmTag {
  125.   uint32_t Index;
  126.   uint32_t SigIndex;
  127.   StringRef SymbolName; // from the "linking" section
  128. };
  129.  
  130. struct WasmImport {
  131.   StringRef Module;
  132.   StringRef Field;
  133.   uint8_t Kind;
  134.   union {
  135.     uint32_t SigIndex;
  136.     WasmGlobalType Global;
  137.     WasmTableType Table;
  138.     WasmLimits Memory;
  139.   };
  140. };
  141.  
  142. struct WasmLocalDecl {
  143.   uint8_t Type;
  144.   uint32_t Count;
  145. };
  146.  
  147. struct WasmFunction {
  148.   uint32_t Index;
  149.   uint32_t SigIndex;
  150.   std::vector<WasmLocalDecl> Locals;
  151.   ArrayRef<uint8_t> Body;
  152.   uint32_t CodeSectionOffset;
  153.   uint32_t Size;
  154.   uint32_t CodeOffset;  // start of Locals and Body
  155.   std::optional<StringRef> ExportName; // from the "export" section
  156.   StringRef SymbolName; // from the "linking" section
  157.   StringRef DebugName;  // from the "name" section
  158.   uint32_t Comdat;      // from the "comdat info" section
  159. };
  160.  
  161. struct WasmDataSegment {
  162.   uint32_t InitFlags;
  163.   // Present if InitFlags & WASM_DATA_SEGMENT_HAS_MEMINDEX.
  164.   uint32_t MemoryIndex;
  165.   // Present if InitFlags & WASM_DATA_SEGMENT_IS_PASSIVE == 0.
  166.   WasmInitExpr Offset;
  167.  
  168.   ArrayRef<uint8_t> Content;
  169.   StringRef Name; // from the "segment info" section
  170.   uint32_t Alignment;
  171.   uint32_t LinkingFlags;
  172.   uint32_t Comdat; // from the "comdat info" section
  173. };
  174.  
  175. struct WasmElemSegment {
  176.   uint32_t Flags;
  177.   uint32_t TableNumber;
  178.   uint8_t ElemKind;
  179.   WasmInitExpr Offset;
  180.   std::vector<uint32_t> Functions;
  181. };
  182.  
  183. // Represents the location of a Wasm data symbol within a WasmDataSegment, as
  184. // the index of the segment, and the offset and size within the segment.
  185. struct WasmDataReference {
  186.   uint32_t Segment;
  187.   uint64_t Offset;
  188.   uint64_t Size;
  189. };
  190.  
  191. struct WasmRelocation {
  192.   uint8_t Type;    // The type of the relocation.
  193.   uint32_t Index;  // Index into either symbol or type index space.
  194.   uint64_t Offset; // Offset from the start of the section.
  195.   int64_t Addend;  // A value to add to the symbol.
  196. };
  197.  
  198. struct WasmInitFunc {
  199.   uint32_t Priority;
  200.   uint32_t Symbol;
  201. };
  202.  
  203. struct WasmSymbolInfo {
  204.   StringRef Name;
  205.   uint8_t Kind;
  206.   uint32_t Flags;
  207.   // For undefined symbols the module of the import
  208.   std::optional<StringRef> ImportModule;
  209.   // For undefined symbols the name of the import
  210.   std::optional<StringRef> ImportName;
  211.   // For symbols to be exported from the final module
  212.   std::optional<StringRef> ExportName;
  213.   union {
  214.     // For function, table, or global symbols, the index in function, table, or
  215.     // global index space.
  216.     uint32_t ElementIndex;
  217.     // For a data symbols, the address of the data relative to segment.
  218.     WasmDataReference DataRef;
  219.   };
  220. };
  221.  
  222. enum class NameType {
  223.   FUNCTION,
  224.   GLOBAL,
  225.   DATA_SEGMENT,
  226. };
  227.  
  228. struct WasmDebugName {
  229.   NameType Type;
  230.   uint32_t Index;
  231.   StringRef Name;
  232. };
  233.  
  234. struct WasmLinkingData {
  235.   uint32_t Version;
  236.   std::vector<WasmInitFunc> InitFunctions;
  237.   std::vector<StringRef> Comdats;
  238.   std::vector<WasmSymbolInfo> SymbolTable;
  239. };
  240.  
  241. enum : unsigned {
  242.   WASM_SEC_CUSTOM = 0,     // Custom / User-defined section
  243.   WASM_SEC_TYPE = 1,       // Function signature declarations
  244.   WASM_SEC_IMPORT = 2,     // Import declarations
  245.   WASM_SEC_FUNCTION = 3,   // Function declarations
  246.   WASM_SEC_TABLE = 4,      // Indirect function table and other tables
  247.   WASM_SEC_MEMORY = 5,     // Memory attributes
  248.   WASM_SEC_GLOBAL = 6,     // Global declarations
  249.   WASM_SEC_EXPORT = 7,     // Exports
  250.   WASM_SEC_START = 8,      // Start function declaration
  251.   WASM_SEC_ELEM = 9,       // Elements section
  252.   WASM_SEC_CODE = 10,      // Function bodies (code)
  253.   WASM_SEC_DATA = 11,      // Data segments
  254.   WASM_SEC_DATACOUNT = 12, // Data segment count
  255.   WASM_SEC_TAG = 13,       // Tag declarations
  256.   WASM_SEC_LAST_KNOWN = WASM_SEC_TAG,
  257. };
  258.  
  259. // Type immediate encodings used in various contexts.
  260. enum : unsigned {
  261.   WASM_TYPE_I32 = 0x7F,
  262.   WASM_TYPE_I64 = 0x7E,
  263.   WASM_TYPE_F32 = 0x7D,
  264.   WASM_TYPE_F64 = 0x7C,
  265.   WASM_TYPE_V128 = 0x7B,
  266.   WASM_TYPE_FUNCREF = 0x70,
  267.   WASM_TYPE_EXTERNREF = 0x6F,
  268.   WASM_TYPE_FUNC = 0x60,
  269.   WASM_TYPE_NORESULT = 0x40, // for blocks with no result values
  270. };
  271.  
  272. // Kinds of externals (for imports and exports).
  273. enum : unsigned {
  274.   WASM_EXTERNAL_FUNCTION = 0x0,
  275.   WASM_EXTERNAL_TABLE = 0x1,
  276.   WASM_EXTERNAL_MEMORY = 0x2,
  277.   WASM_EXTERNAL_GLOBAL = 0x3,
  278.   WASM_EXTERNAL_TAG = 0x4,
  279. };
  280.  
  281. // Opcodes used in initializer expressions.
  282. enum : unsigned {
  283.   WASM_OPCODE_END = 0x0b,
  284.   WASM_OPCODE_CALL = 0x10,
  285.   WASM_OPCODE_LOCAL_GET = 0x20,
  286.   WASM_OPCODE_LOCAL_SET = 0x21,
  287.   WASM_OPCODE_LOCAL_TEE = 0x22,
  288.   WASM_OPCODE_GLOBAL_GET = 0x23,
  289.   WASM_OPCODE_GLOBAL_SET = 0x24,
  290.   WASM_OPCODE_I32_STORE = 0x36,
  291.   WASM_OPCODE_I64_STORE = 0x37,
  292.   WASM_OPCODE_I32_CONST = 0x41,
  293.   WASM_OPCODE_I64_CONST = 0x42,
  294.   WASM_OPCODE_F32_CONST = 0x43,
  295.   WASM_OPCODE_F64_CONST = 0x44,
  296.   WASM_OPCODE_I32_ADD = 0x6a,
  297.   WASM_OPCODE_I32_SUB = 0x6b,
  298.   WASM_OPCODE_I32_MUL = 0x6c,
  299.   WASM_OPCODE_I64_ADD = 0x7c,
  300.   WASM_OPCODE_I64_SUB = 0x7d,
  301.   WASM_OPCODE_I64_MUL = 0x7e,
  302.   WASM_OPCODE_REF_NULL = 0xd0,
  303. };
  304.  
  305. // Opcodes used in synthetic functions.
  306. enum : unsigned {
  307.   WASM_OPCODE_BLOCK = 0x02,
  308.   WASM_OPCODE_BR = 0x0c,
  309.   WASM_OPCODE_BR_TABLE = 0x0e,
  310.   WASM_OPCODE_RETURN = 0x0f,
  311.   WASM_OPCODE_DROP = 0x1a,
  312.   WASM_OPCODE_MISC_PREFIX = 0xfc,
  313.   WASM_OPCODE_MEMORY_INIT = 0x08,
  314.   WASM_OPCODE_MEMORY_FILL = 0x0b,
  315.   WASM_OPCODE_DATA_DROP = 0x09,
  316.   WASM_OPCODE_ATOMICS_PREFIX = 0xfe,
  317.   WASM_OPCODE_ATOMIC_NOTIFY = 0x00,
  318.   WASM_OPCODE_I32_ATOMIC_WAIT = 0x01,
  319.   WASM_OPCODE_I32_ATOMIC_STORE = 0x17,
  320.   WASM_OPCODE_I32_RMW_CMPXCHG = 0x48,
  321. };
  322.  
  323. enum : unsigned {
  324.   WASM_LIMITS_FLAG_NONE = 0x0,
  325.   WASM_LIMITS_FLAG_HAS_MAX = 0x1,
  326.   WASM_LIMITS_FLAG_IS_SHARED = 0x2,
  327.   WASM_LIMITS_FLAG_IS_64 = 0x4,
  328. };
  329.  
  330. enum : unsigned {
  331.   WASM_DATA_SEGMENT_IS_PASSIVE = 0x01,
  332.   WASM_DATA_SEGMENT_HAS_MEMINDEX = 0x02,
  333. };
  334.  
  335. enum : unsigned {
  336.   WASM_ELEM_SEGMENT_IS_PASSIVE = 0x01,
  337.   WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER = 0x02,
  338.   WASM_ELEM_SEGMENT_HAS_INIT_EXPRS = 0x04,
  339. };
  340. const unsigned WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND = 0x3;
  341.  
  342. // Feature policy prefixes used in the custom "target_features" section
  343. enum : uint8_t {
  344.   WASM_FEATURE_PREFIX_USED = '+',
  345.   WASM_FEATURE_PREFIX_REQUIRED = '=',
  346.   WASM_FEATURE_PREFIX_DISALLOWED = '-',
  347. };
  348.  
  349. // Kind codes used in the custom "name" section
  350. enum : unsigned {
  351.   WASM_NAMES_FUNCTION = 1,
  352.   WASM_NAMES_LOCAL = 2,
  353.   WASM_NAMES_GLOBAL = 7,
  354.   WASM_NAMES_DATA_SEGMENT = 9,
  355. };
  356.  
  357. // Kind codes used in the custom "linking" section
  358. enum : unsigned {
  359.   WASM_SEGMENT_INFO = 0x5,
  360.   WASM_INIT_FUNCS = 0x6,
  361.   WASM_COMDAT_INFO = 0x7,
  362.   WASM_SYMBOL_TABLE = 0x8,
  363. };
  364.  
  365. // Kind codes used in the custom "dylink" section
  366. enum : unsigned {
  367.   WASM_DYLINK_MEM_INFO = 0x1,
  368.   WASM_DYLINK_NEEDED = 0x2,
  369.   WASM_DYLINK_EXPORT_INFO = 0x3,
  370.   WASM_DYLINK_IMPORT_INFO = 0x4,
  371. };
  372.  
  373. // Kind codes used in the custom "linking" section in the WASM_COMDAT_INFO
  374. enum : unsigned {
  375.   WASM_COMDAT_DATA = 0x0,
  376.   WASM_COMDAT_FUNCTION = 0x1,
  377.   // GLOBAL, TAG, and TABLE are in here but LLVM doesn't use them yet.
  378.   WASM_COMDAT_SECTION = 0x5,
  379. };
  380.  
  381. // Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE
  382. enum WasmSymbolType : unsigned {
  383.   WASM_SYMBOL_TYPE_FUNCTION = 0x0,
  384.   WASM_SYMBOL_TYPE_DATA = 0x1,
  385.   WASM_SYMBOL_TYPE_GLOBAL = 0x2,
  386.   WASM_SYMBOL_TYPE_SECTION = 0x3,
  387.   WASM_SYMBOL_TYPE_TAG = 0x4,
  388.   WASM_SYMBOL_TYPE_TABLE = 0x5,
  389. };
  390.  
  391. enum WasmSegmentFlag : unsigned {
  392.   WASM_SEG_FLAG_STRINGS = 0x1,
  393.   WASM_SEG_FLAG_TLS = 0x2,
  394. };
  395.  
  396. // Kinds of tag attributes.
  397. enum WasmTagAttribute : uint8_t {
  398.   WASM_TAG_ATTRIBUTE_EXCEPTION = 0x0,
  399. };
  400.  
  401. const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;
  402. const unsigned WASM_SYMBOL_VISIBILITY_MASK = 0xc;
  403.  
  404. const unsigned WASM_SYMBOL_BINDING_GLOBAL = 0x0;
  405. const unsigned WASM_SYMBOL_BINDING_WEAK = 0x1;
  406. const unsigned WASM_SYMBOL_BINDING_LOCAL = 0x2;
  407. const unsigned WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0;
  408. const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4;
  409. const unsigned WASM_SYMBOL_UNDEFINED = 0x10;
  410. const unsigned WASM_SYMBOL_EXPORTED = 0x20;
  411. const unsigned WASM_SYMBOL_EXPLICIT_NAME = 0x40;
  412. const unsigned WASM_SYMBOL_NO_STRIP = 0x80;
  413. const unsigned WASM_SYMBOL_TLS = 0x100;
  414.  
  415. #define WASM_RELOC(name, value) name = value,
  416.  
  417. enum : unsigned {
  418. #include "WasmRelocs.def"
  419. };
  420.  
  421. #undef WASM_RELOC
  422.  
  423. // Subset of types that a value can have
  424. enum class ValType {
  425.   I32 = WASM_TYPE_I32,
  426.   I64 = WASM_TYPE_I64,
  427.   F32 = WASM_TYPE_F32,
  428.   F64 = WASM_TYPE_F64,
  429.   V128 = WASM_TYPE_V128,
  430.   FUNCREF = WASM_TYPE_FUNCREF,
  431.   EXTERNREF = WASM_TYPE_EXTERNREF,
  432. };
  433.  
  434. struct WasmSignature {
  435.   SmallVector<ValType, 1> Returns;
  436.   SmallVector<ValType, 4> Params;
  437.   // Support empty and tombstone instances, needed by DenseMap.
  438.   enum { Plain, Empty, Tombstone } State = Plain;
  439.  
  440.   WasmSignature(SmallVector<ValType, 1> &&InReturns,
  441.                 SmallVector<ValType, 4> &&InParams)
  442.       : Returns(InReturns), Params(InParams) {}
  443.   WasmSignature() = default;
  444. };
  445.  
  446. // Useful comparison operators
  447. inline bool operator==(const WasmSignature &LHS, const WasmSignature &RHS) {
  448.   return LHS.State == RHS.State && LHS.Returns == RHS.Returns &&
  449.          LHS.Params == RHS.Params;
  450. }
  451.  
  452. inline bool operator!=(const WasmSignature &LHS, const WasmSignature &RHS) {
  453.   return !(LHS == RHS);
  454. }
  455.  
  456. inline bool operator==(const WasmGlobalType &LHS, const WasmGlobalType &RHS) {
  457.   return LHS.Type == RHS.Type && LHS.Mutable == RHS.Mutable;
  458. }
  459.  
  460. inline bool operator!=(const WasmGlobalType &LHS, const WasmGlobalType &RHS) {
  461.   return !(LHS == RHS);
  462. }
  463.  
  464. inline bool operator==(const WasmLimits &LHS, const WasmLimits &RHS) {
  465.   return LHS.Flags == RHS.Flags && LHS.Minimum == RHS.Minimum &&
  466.          (LHS.Flags & WASM_LIMITS_FLAG_HAS_MAX ? LHS.Maximum == RHS.Maximum
  467.                                                : true);
  468. }
  469.  
  470. inline bool operator==(const WasmTableType &LHS, const WasmTableType &RHS) {
  471.   return LHS.ElemType == RHS.ElemType && LHS.Limits == RHS.Limits;
  472. }
  473.  
  474. llvm::StringRef toString(WasmSymbolType type);
  475. llvm::StringRef relocTypetoString(uint32_t type);
  476. llvm::StringRef sectionTypeToString(uint32_t type);
  477. bool relocTypeHasAddend(uint32_t type);
  478.  
  479. } // end namespace wasm
  480. } // end namespace llvm
  481.  
  482. #endif
  483.