Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //===- Wasm.h - Wasm object file implementation -----------------*- 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 declares the WasmObjectFile class, which implements the ObjectFile
  10. // interface for Wasm files.
  11. //
  12. // See: https://github.com/WebAssembly/design/blob/main/BinaryEncoding.md
  13. //
  14. //===----------------------------------------------------------------------===//
  15.  
  16. #ifndef LLVM_OBJECT_WASM_H
  17. #define LLVM_OBJECT_WASM_H
  18.  
  19. #include "llvm/ADT/ArrayRef.h"
  20. #include "llvm/ADT/StringRef.h"
  21. #include "llvm/BinaryFormat/Wasm.h"
  22. #include "llvm/Config/llvm-config.h"
  23. #include "llvm/MC/MCSymbolWasm.h"
  24. #include "llvm/Object/Binary.h"
  25. #include "llvm/Object/ObjectFile.h"
  26. #include "llvm/Support/Error.h"
  27. #include "llvm/Support/MemoryBuffer.h"
  28. #include <cstddef>
  29. #include <cstdint>
  30. #include <vector>
  31.  
  32. namespace llvm {
  33. namespace object {
  34.  
  35. class WasmSymbol {
  36. public:
  37.   WasmSymbol(const wasm::WasmSymbolInfo &Info,
  38.              const wasm::WasmGlobalType *GlobalType,
  39.              const wasm::WasmTableType *TableType,
  40.              const wasm::WasmSignature *Signature)
  41.       : Info(Info), GlobalType(GlobalType), TableType(TableType),
  42.         Signature(Signature) {}
  43.  
  44.   const wasm::WasmSymbolInfo &Info;
  45.   const wasm::WasmGlobalType *GlobalType;
  46.   const wasm::WasmTableType *TableType;
  47.   const wasm::WasmSignature *Signature;
  48.  
  49.   bool isTypeFunction() const {
  50.     return Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION;
  51.   }
  52.  
  53.   bool isTypeTable() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_TABLE; }
  54.  
  55.   bool isTypeData() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA; }
  56.  
  57.   bool isTypeGlobal() const {
  58.     return Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL;
  59.   }
  60.  
  61.   bool isTypeSection() const {
  62.     return Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION;
  63.   }
  64.  
  65.   bool isTypeTag() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_TAG; }
  66.  
  67.   bool isDefined() const { return !isUndefined(); }
  68.  
  69.   bool isUndefined() const {
  70.     return (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) != 0;
  71.   }
  72.  
  73.   bool isBindingWeak() const {
  74.     return getBinding() == wasm::WASM_SYMBOL_BINDING_WEAK;
  75.   }
  76.  
  77.   bool isBindingGlobal() const {
  78.     return getBinding() == wasm::WASM_SYMBOL_BINDING_GLOBAL;
  79.   }
  80.  
  81.   bool isBindingLocal() const {
  82.     return getBinding() == wasm::WASM_SYMBOL_BINDING_LOCAL;
  83.   }
  84.  
  85.   unsigned getBinding() const {
  86.     return Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK;
  87.   }
  88.  
  89.   bool isHidden() const {
  90.     return getVisibility() == wasm::WASM_SYMBOL_VISIBILITY_HIDDEN;
  91.   }
  92.  
  93.   unsigned getVisibility() const {
  94.     return Info.Flags & wasm::WASM_SYMBOL_VISIBILITY_MASK;
  95.   }
  96.  
  97.   void print(raw_ostream &Out) const;
  98.  
  99. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  100.   LLVM_DUMP_METHOD void dump() const;
  101. #endif
  102. };
  103.  
  104. struct WasmSection {
  105.   WasmSection() = default;
  106.  
  107.   uint32_t Type = 0;         // Section type (See below)
  108.   uint32_t Offset = 0;       // Offset with in the file
  109.   StringRef Name;            // Section name (User-defined sections only)
  110.   uint32_t Comdat = UINT32_MAX; // From the "comdat info" section
  111.   ArrayRef<uint8_t> Content; // Section content
  112.   std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section
  113. };
  114.  
  115. struct WasmSegment {
  116.   uint32_t SectionOffset;
  117.   wasm::WasmDataSegment Data;
  118. };
  119.  
  120. class WasmObjectFile : public ObjectFile {
  121.  
  122. public:
  123.   WasmObjectFile(MemoryBufferRef Object, Error &Err);
  124.  
  125.   const wasm::WasmObjectHeader &getHeader() const;
  126.   const WasmSymbol &getWasmSymbol(const DataRefImpl &Symb) const;
  127.   const WasmSymbol &getWasmSymbol(const SymbolRef &Symbol) const;
  128.   const WasmSection &getWasmSection(const SectionRef &Section) const;
  129.   const wasm::WasmRelocation &getWasmRelocation(const RelocationRef &Ref) const;
  130.  
  131.   static bool classof(const Binary *v) { return v->isWasm(); }
  132.  
  133.   const wasm::WasmDylinkInfo &dylinkInfo() const { return DylinkInfo; }
  134.   const wasm::WasmProducerInfo &getProducerInfo() const { return ProducerInfo; }
  135.   ArrayRef<wasm::WasmFeatureEntry> getTargetFeatures() const {
  136.     return TargetFeatures;
  137.   }
  138.   ArrayRef<wasm::WasmSignature> types() const { return Signatures; }
  139.   ArrayRef<wasm::WasmImport> imports() const { return Imports; }
  140.   ArrayRef<wasm::WasmTable> tables() const { return Tables; }
  141.   ArrayRef<wasm::WasmLimits> memories() const { return Memories; }
  142.   ArrayRef<wasm::WasmGlobal> globals() const { return Globals; }
  143.   ArrayRef<wasm::WasmTag> tags() const { return Tags; }
  144.   ArrayRef<wasm::WasmExport> exports() const { return Exports; }
  145.   ArrayRef<WasmSymbol> syms() const { return Symbols; }
  146.   const wasm::WasmLinkingData &linkingData() const { return LinkingData; }
  147.   uint32_t getNumberOfSymbols() const { return Symbols.size(); }
  148.   ArrayRef<wasm::WasmElemSegment> elements() const { return ElemSegments; }
  149.   ArrayRef<WasmSegment> dataSegments() const { return DataSegments; }
  150.   ArrayRef<wasm::WasmFunction> functions() const { return Functions; }
  151.   ArrayRef<wasm::WasmDebugName> debugNames() const { return DebugNames; }
  152.   uint32_t startFunction() const { return StartFunction; }
  153.   uint32_t getNumImportedGlobals() const { return NumImportedGlobals; }
  154.   uint32_t getNumImportedTables() const { return NumImportedTables; }
  155.   uint32_t getNumImportedFunctions() const { return NumImportedFunctions; }
  156.   uint32_t getNumImportedTags() const { return NumImportedTags; }
  157.   uint32_t getNumSections() const { return Sections.size(); }
  158.   void moveSymbolNext(DataRefImpl &Symb) const override;
  159.  
  160.   Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
  161.  
  162.   basic_symbol_iterator symbol_begin() const override;
  163.  
  164.   basic_symbol_iterator symbol_end() const override;
  165.   Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
  166.  
  167.   Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
  168.   uint64_t getWasmSymbolValue(const WasmSymbol &Sym) const;
  169.   uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
  170.   uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
  171.   uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
  172.   Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
  173.   Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
  174.   uint32_t getSymbolSectionId(SymbolRef Sym) const;
  175.  
  176.   // Overrides from SectionRef.
  177.   void moveSectionNext(DataRefImpl &Sec) const override;
  178.   Expected<StringRef> getSectionName(DataRefImpl Sec) const override;
  179.   uint64_t getSectionAddress(DataRefImpl Sec) const override;
  180.   uint64_t getSectionIndex(DataRefImpl Sec) const override;
  181.   uint64_t getSectionSize(DataRefImpl Sec) const override;
  182.   Expected<ArrayRef<uint8_t>>
  183.   getSectionContents(DataRefImpl Sec) const override;
  184.   uint64_t getSectionAlignment(DataRefImpl Sec) const override;
  185.   bool isSectionCompressed(DataRefImpl Sec) const override;
  186.   bool isSectionText(DataRefImpl Sec) const override;
  187.   bool isSectionData(DataRefImpl Sec) const override;
  188.   bool isSectionBSS(DataRefImpl Sec) const override;
  189.   bool isSectionVirtual(DataRefImpl Sec) const override;
  190.   relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
  191.   relocation_iterator section_rel_end(DataRefImpl Sec) const override;
  192.  
  193.   // Overrides from RelocationRef.
  194.   void moveRelocationNext(DataRefImpl &Rel) const override;
  195.   uint64_t getRelocationOffset(DataRefImpl Rel) const override;
  196.   symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
  197.   uint64_t getRelocationType(DataRefImpl Rel) const override;
  198.   void getRelocationTypeName(DataRefImpl Rel,
  199.                              SmallVectorImpl<char> &Result) const override;
  200.  
  201.   section_iterator section_begin() const override;
  202.   section_iterator section_end() const override;
  203.   uint8_t getBytesInAddress() const override;
  204.   StringRef getFileFormatName() const override;
  205.   Triple::ArchType getArch() const override;
  206.   Expected<SubtargetFeatures> getFeatures() const override;
  207.   bool isRelocatableObject() const override;
  208.   bool isSharedObject() const;
  209.  
  210.   struct ReadContext {
  211.     const uint8_t *Start;
  212.     const uint8_t *Ptr;
  213.     const uint8_t *End;
  214.   };
  215.  
  216. private:
  217.   bool isValidFunctionIndex(uint32_t Index) const;
  218.   bool isDefinedFunctionIndex(uint32_t Index) const;
  219.   bool isValidGlobalIndex(uint32_t Index) const;
  220.   bool isValidTableNumber(uint32_t Index) const;
  221.   bool isDefinedGlobalIndex(uint32_t Index) const;
  222.   bool isDefinedTableNumber(uint32_t Index) const;
  223.   bool isValidTagIndex(uint32_t Index) const;
  224.   bool isDefinedTagIndex(uint32_t Index) const;
  225.   bool isValidFunctionSymbol(uint32_t Index) const;
  226.   bool isValidTableSymbol(uint32_t Index) const;
  227.   bool isValidGlobalSymbol(uint32_t Index) const;
  228.   bool isValidTagSymbol(uint32_t Index) const;
  229.   bool isValidDataSymbol(uint32_t Index) const;
  230.   bool isValidSectionSymbol(uint32_t Index) const;
  231.   wasm::WasmFunction &getDefinedFunction(uint32_t Index);
  232.   const wasm::WasmFunction &getDefinedFunction(uint32_t Index) const;
  233.   wasm::WasmGlobal &getDefinedGlobal(uint32_t Index);
  234.   wasm::WasmTag &getDefinedTag(uint32_t Index);
  235.  
  236.   const WasmSection &getWasmSection(DataRefImpl Ref) const;
  237.   const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const;
  238.   uint32_t getSymbolSectionIdImpl(const WasmSymbol &Symb) const;
  239.  
  240.   Error parseSection(WasmSection &Sec);
  241.   Error parseCustomSection(WasmSection &Sec, ReadContext &Ctx);
  242.  
  243.   // Standard section types
  244.   Error parseTypeSection(ReadContext &Ctx);
  245.   Error parseImportSection(ReadContext &Ctx);
  246.   Error parseFunctionSection(ReadContext &Ctx);
  247.   Error parseTableSection(ReadContext &Ctx);
  248.   Error parseMemorySection(ReadContext &Ctx);
  249.   Error parseTagSection(ReadContext &Ctx);
  250.   Error parseGlobalSection(ReadContext &Ctx);
  251.   Error parseExportSection(ReadContext &Ctx);
  252.   Error parseStartSection(ReadContext &Ctx);
  253.   Error parseElemSection(ReadContext &Ctx);
  254.   Error parseCodeSection(ReadContext &Ctx);
  255.   Error parseDataSection(ReadContext &Ctx);
  256.   Error parseDataCountSection(ReadContext &Ctx);
  257.  
  258.   // Custom section types
  259.   Error parseDylinkSection(ReadContext &Ctx);
  260.   Error parseDylink0Section(ReadContext &Ctx);
  261.   Error parseNameSection(ReadContext &Ctx);
  262.   Error parseLinkingSection(ReadContext &Ctx);
  263.   Error parseLinkingSectionSymtab(ReadContext &Ctx);
  264.   Error parseLinkingSectionComdat(ReadContext &Ctx);
  265.   Error parseProducersSection(ReadContext &Ctx);
  266.   Error parseTargetFeaturesSection(ReadContext &Ctx);
  267.   Error parseRelocSection(StringRef Name, ReadContext &Ctx);
  268.  
  269.   wasm::WasmObjectHeader Header;
  270.   std::vector<WasmSection> Sections;
  271.   wasm::WasmDylinkInfo DylinkInfo;
  272.   wasm::WasmProducerInfo ProducerInfo;
  273.   std::vector<wasm::WasmFeatureEntry> TargetFeatures;
  274.   std::vector<wasm::WasmSignature> Signatures;
  275.   std::vector<wasm::WasmTable> Tables;
  276.   std::vector<wasm::WasmLimits> Memories;
  277.   std::vector<wasm::WasmGlobal> Globals;
  278.   std::vector<wasm::WasmTag> Tags;
  279.   std::vector<wasm::WasmImport> Imports;
  280.   std::vector<wasm::WasmExport> Exports;
  281.   std::vector<wasm::WasmElemSegment> ElemSegments;
  282.   std::vector<WasmSegment> DataSegments;
  283.   std::optional<size_t> DataCount;
  284.   std::vector<wasm::WasmFunction> Functions;
  285.   std::vector<WasmSymbol> Symbols;
  286.   std::vector<wasm::WasmDebugName> DebugNames;
  287.   uint32_t StartFunction = -1;
  288.   bool HasLinkingSection = false;
  289.   bool HasDylinkSection = false;
  290.   bool HasMemory64 = false;
  291.   wasm::WasmLinkingData LinkingData;
  292.   uint32_t NumImportedGlobals = 0;
  293.   uint32_t NumImportedTables = 0;
  294.   uint32_t NumImportedFunctions = 0;
  295.   uint32_t NumImportedTags = 0;
  296.   uint32_t CodeSection = 0;
  297.   uint32_t DataSection = 0;
  298.   uint32_t TagSection = 0;
  299.   uint32_t GlobalSection = 0;
  300.   uint32_t TableSection = 0;
  301. };
  302.  
  303. class WasmSectionOrderChecker {
  304. public:
  305.   // We define orders for all core wasm sections and known custom sections.
  306.   enum : int {
  307.     // Sentinel, must be zero
  308.     WASM_SEC_ORDER_NONE = 0,
  309.  
  310.     // Core sections
  311.     WASM_SEC_ORDER_TYPE,
  312.     WASM_SEC_ORDER_IMPORT,
  313.     WASM_SEC_ORDER_FUNCTION,
  314.     WASM_SEC_ORDER_TABLE,
  315.     WASM_SEC_ORDER_MEMORY,
  316.     WASM_SEC_ORDER_TAG,
  317.     WASM_SEC_ORDER_GLOBAL,
  318.     WASM_SEC_ORDER_EXPORT,
  319.     WASM_SEC_ORDER_START,
  320.     WASM_SEC_ORDER_ELEM,
  321.     WASM_SEC_ORDER_DATACOUNT,
  322.     WASM_SEC_ORDER_CODE,
  323.     WASM_SEC_ORDER_DATA,
  324.  
  325.     // Custom sections
  326.     // "dylink" should be the very first section in the module
  327.     WASM_SEC_ORDER_DYLINK,
  328.     // "linking" section requires DATA section in order to validate data symbols
  329.     WASM_SEC_ORDER_LINKING,
  330.     // Must come after "linking" section in order to validate reloc indexes.
  331.     WASM_SEC_ORDER_RELOC,
  332.     // "name" section must appear after DATA. Comes after "linking" to allow
  333.     // symbol table to set default function name.
  334.     WASM_SEC_ORDER_NAME,
  335.     // "producers" section must appear after "name" section.
  336.     WASM_SEC_ORDER_PRODUCERS,
  337.     // "target_features" section must appear after producers section
  338.     WASM_SEC_ORDER_TARGET_FEATURES,
  339.  
  340.     // Must be last
  341.     WASM_NUM_SEC_ORDERS
  342.  
  343.   };
  344.  
  345.   // Sections that may or may not be present, but cannot be predecessors
  346.   static int DisallowedPredecessors[WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS];
  347.  
  348.   bool isValidSectionOrder(unsigned ID, StringRef CustomSectionName = "");
  349.  
  350. private:
  351.   bool Seen[WASM_NUM_SEC_ORDERS] = {}; // Sections that have been seen already
  352.  
  353.   // Returns -1 for unknown sections.
  354.   int getSectionOrder(unsigned ID, StringRef CustomSectionName = "");
  355. };
  356.  
  357. } // end namespace object
  358.  
  359. inline raw_ostream &operator<<(raw_ostream &OS, const object::WasmSymbol &Sym) {
  360.   Sym.print(OS);
  361.   return OS;
  362. }
  363.  
  364. } // end namespace llvm
  365.  
  366. #endif // LLVM_OBJECT_WASM_H
  367.