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