Home | History | Annotate | Download | only in Object
      1 //===- WasmObjectFile.h - Wasm object file implementation -------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file declares the WasmObjectFile class, which implements the ObjectFile
     11 // interface for Wasm files.
     12 //
     13 // See: https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md
     14 //
     15 //===----------------------------------------------------------------------===//
     16 
     17 #ifndef LLVM_OBJECT_WASM_H
     18 #define LLVM_OBJECT_WASM_H
     19 
     20 #include "llvm/ADT/ArrayRef.h"
     21 #include "llvm/ADT/StringRef.h"
     22 #include "llvm/BinaryFormat/Wasm.h"
     23 #include "llvm/Object/Binary.h"
     24 #include "llvm/Object/ObjectFile.h"
     25 #include "llvm/Support/Error.h"
     26 #include "llvm/Support/MemoryBuffer.h"
     27 #include <cstddef>
     28 #include <cstdint>
     29 #include <vector>
     30 
     31 namespace llvm {
     32 namespace object {
     33 
     34 class WasmSymbol {
     35 public:
     36   enum class SymbolType {
     37     FUNCTION_IMPORT,
     38     FUNCTION_EXPORT,
     39     GLOBAL_IMPORT,
     40     GLOBAL_EXPORT,
     41     DEBUG_FUNCTION_NAME,
     42   };
     43 
     44   WasmSymbol(StringRef Name, SymbolType Type, uint32_t Section,
     45              uint32_t ElementIndex)
     46       : Name(Name), Type(Type), Section(Section), ElementIndex(ElementIndex) {}
     47 
     48   StringRef Name;
     49   SymbolType Type;
     50   uint32_t Section;
     51   uint32_t ElementIndex;
     52 };
     53 
     54 class WasmSection {
     55 public:
     56   WasmSection() = default;
     57 
     58   uint32_t Type = 0; // Section type (See below)
     59   uint32_t Offset = 0; // Offset with in the file
     60   StringRef Name; // Section name (User-defined sections only)
     61   ArrayRef<uint8_t> Content; // Section content
     62   std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section
     63 };
     64 
     65 class WasmObjectFile : public ObjectFile {
     66 public:
     67   WasmObjectFile(MemoryBufferRef Object, Error &Err);
     68 
     69   const wasm::WasmObjectHeader &getHeader() const;
     70   const WasmSymbol &getWasmSymbol(const DataRefImpl &Symb) const;
     71   const WasmSymbol &getWasmSymbol(const SymbolRef &Symbol) const;
     72   const WasmSection &getWasmSection(const SectionRef &Section) const;
     73   const wasm::WasmRelocation &getWasmRelocation(const RelocationRef& Ref) const;
     74 
     75   static bool classof(const Binary *v) { return v->isWasm(); }
     76 
     77   const std::vector<wasm::WasmSignature>& types() const { return Signatures; }
     78   const std::vector<uint32_t>& functionTypes() const { return FunctionTypes; }
     79   const std::vector<wasm::WasmImport>& imports() const { return Imports; }
     80   const std::vector<wasm::WasmTable>& tables() const { return Tables; }
     81   const std::vector<wasm::WasmLimits>& memories() const { return Memories; }
     82   const std::vector<wasm::WasmGlobal>& globals() const { return Globals; }
     83   const std::vector<wasm::WasmExport>& exports() const { return Exports; }
     84 
     85   uint32_t getNumberOfSymbols() const {
     86     return Symbols.size();
     87   }
     88 
     89   const std::vector<wasm::WasmElemSegment>& elements() const {
     90     return ElemSegments;
     91   }
     92 
     93   const std::vector<wasm::WasmDataSegment>& dataSegments() const {
     94     return DataSegments;
     95   }
     96 
     97   const std::vector<wasm::WasmFunction>& functions() const { return Functions; }
     98   const ArrayRef<uint8_t>& code() const { return CodeSection; }
     99   uint32_t startFunction() const { return StartFunction; }
    100 
    101   void moveSymbolNext(DataRefImpl &Symb) const override;
    102 
    103   uint32_t getSymbolFlags(DataRefImpl Symb) const override;
    104 
    105   basic_symbol_iterator symbol_begin() const override;
    106 
    107   basic_symbol_iterator symbol_end() const override;
    108   Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
    109 
    110   Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
    111   uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
    112   uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
    113   uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
    114   Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
    115   Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
    116 
    117   // Overrides from SectionRef.
    118   void moveSectionNext(DataRefImpl &Sec) const override;
    119   std::error_code getSectionName(DataRefImpl Sec,
    120                                  StringRef &Res) const override;
    121   uint64_t getSectionAddress(DataRefImpl Sec) const override;
    122   uint64_t getSectionIndex(DataRefImpl Sec) const override;
    123   uint64_t getSectionSize(DataRefImpl Sec) const override;
    124   std::error_code getSectionContents(DataRefImpl Sec,
    125                                      StringRef &Res) const override;
    126   uint64_t getSectionAlignment(DataRefImpl Sec) const override;
    127   bool isSectionCompressed(DataRefImpl Sec) const override;
    128   bool isSectionText(DataRefImpl Sec) const override;
    129   bool isSectionData(DataRefImpl Sec) const override;
    130   bool isSectionBSS(DataRefImpl Sec) const override;
    131   bool isSectionVirtual(DataRefImpl Sec) const override;
    132   bool isSectionBitcode(DataRefImpl Sec) const override;
    133   relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
    134   relocation_iterator section_rel_end(DataRefImpl Sec) const override;
    135 
    136   // Overrides from RelocationRef.
    137   void moveRelocationNext(DataRefImpl &Rel) const override;
    138   uint64_t getRelocationOffset(DataRefImpl Rel) const override;
    139   symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
    140   uint64_t getRelocationType(DataRefImpl Rel) const override;
    141   void getRelocationTypeName(DataRefImpl Rel,
    142                              SmallVectorImpl<char> &Result) const override;
    143 
    144   section_iterator section_begin() const override;
    145   section_iterator section_end() const override;
    146   uint8_t getBytesInAddress() const override;
    147   StringRef getFileFormatName() const override;
    148   unsigned getArch() const override;
    149   SubtargetFeatures getFeatures() const override;
    150   bool isRelocatableObject() const override;
    151 
    152 private:
    153   const WasmSection &getWasmSection(DataRefImpl Ref) const;
    154   const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const;
    155 
    156   WasmSection* findCustomSectionByName(StringRef Name);
    157   WasmSection* findSectionByType(uint32_t Type);
    158 
    159   const uint8_t *getPtr(size_t Offset) const;
    160   Error parseSection(WasmSection &Sec);
    161   Error parseCustomSection(WasmSection &Sec, const uint8_t *Ptr,
    162                            const uint8_t *End);
    163 
    164   // Standard section types
    165   Error parseTypeSection(const uint8_t *Ptr, const uint8_t *End);
    166   Error parseImportSection(const uint8_t *Ptr, const uint8_t *End);
    167   Error parseFunctionSection(const uint8_t *Ptr, const uint8_t *End);
    168   Error parseTableSection(const uint8_t *Ptr, const uint8_t *End);
    169   Error parseMemorySection(const uint8_t *Ptr, const uint8_t *End);
    170   Error parseGlobalSection(const uint8_t *Ptr, const uint8_t *End);
    171   Error parseExportSection(const uint8_t *Ptr, const uint8_t *End);
    172   Error parseStartSection(const uint8_t *Ptr, const uint8_t *End);
    173   Error parseElemSection(const uint8_t *Ptr, const uint8_t *End);
    174   Error parseCodeSection(const uint8_t *Ptr, const uint8_t *End);
    175   Error parseDataSection(const uint8_t *Ptr, const uint8_t *End);
    176 
    177   // Custom section types
    178   Error parseNameSection(const uint8_t *Ptr, const uint8_t *End);
    179   Error parseRelocSection(StringRef Name, const uint8_t *Ptr,
    180                           const uint8_t *End);
    181 
    182   wasm::WasmObjectHeader Header;
    183   std::vector<WasmSection> Sections;
    184   std::vector<wasm::WasmSignature> Signatures;
    185   std::vector<uint32_t> FunctionTypes;
    186   std::vector<wasm::WasmTable> Tables;
    187   std::vector<wasm::WasmLimits> Memories;
    188   std::vector<wasm::WasmGlobal> Globals;
    189   std::vector<wasm::WasmImport> Imports;
    190   std::vector<wasm::WasmExport> Exports;
    191   std::vector<wasm::WasmElemSegment> ElemSegments;
    192   std::vector<wasm::WasmDataSegment> DataSegments;
    193   std::vector<WasmSymbol> Symbols;
    194   std::vector<wasm::WasmFunction> Functions;
    195   ArrayRef<uint8_t> CodeSection;
    196   uint32_t StartFunction = -1;
    197 };
    198 
    199 } // end namespace object
    200 } // end namespace llvm
    201 
    202 #endif // LLVM_OBJECT_WASM_H
    203