Wasm.h revision 321369
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/ADT/StringMap.h" 23#include "llvm/BinaryFormat/Wasm.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 32namespace llvm { 33namespace object { 34 35class WasmSymbol { 36public: 37 enum class SymbolType { 38 FUNCTION_IMPORT, 39 FUNCTION_EXPORT, 40 GLOBAL_IMPORT, 41 GLOBAL_EXPORT, 42 DEBUG_FUNCTION_NAME, 43 }; 44 45 WasmSymbol(StringRef Name, SymbolType Type, uint32_t Section, 46 uint32_t ElementIndex) 47 : Name(Name), Type(Type), Section(Section), ElementIndex(ElementIndex) {} 48 49 StringRef Name; 50 SymbolType Type; 51 uint32_t Section; 52 uint32_t Flags = 0; 53 54 // Index into the imports, exports or functions array of the object depending 55 // on the type 56 uint32_t ElementIndex; 57 58 bool isWeak() const { 59 return Flags & wasm::WASM_SYMBOL_FLAG_WEAK; 60 } 61 62 void print(raw_ostream &Out) const { 63 Out << "Name=" << Name << ", Type=" << static_cast<int>(Type) 64 << ", Flags=" << Flags << " ElemIndex=" << ElementIndex; 65 } 66 67#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 68 LLVM_DUMP_METHOD void dump() const { print(dbgs()); } 69#endif 70}; 71 72struct WasmSection { 73 WasmSection() = default; 74 75 uint32_t Type = 0; // Section type (See below) 76 uint32_t Offset = 0; // Offset with in the file 77 StringRef Name; // Section name (User-defined sections only) 78 ArrayRef<uint8_t> Content; // Section content 79 std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section 80}; 81 82struct WasmSegment { 83 uint32_t SectionOffset; 84 wasm::WasmDataSegment Data; 85}; 86 87class WasmObjectFile : public ObjectFile { 88 89public: 90 WasmObjectFile(MemoryBufferRef Object, Error &Err); 91 92 const wasm::WasmObjectHeader &getHeader() const; 93 const WasmSymbol &getWasmSymbol(const DataRefImpl &Symb) const; 94 const WasmSymbol &getWasmSymbol(const SymbolRef &Symbol) const; 95 const WasmSection &getWasmSection(const SectionRef &Section) const; 96 const wasm::WasmRelocation &getWasmRelocation(const RelocationRef& Ref) const; 97 98 static bool classof(const Binary *v) { return v->isWasm(); } 99 100 const std::vector<wasm::WasmSignature>& types() const { return Signatures; } 101 const std::vector<uint32_t>& functionTypes() const { return FunctionTypes; } 102 const std::vector<wasm::WasmImport>& imports() const { return Imports; } 103 const std::vector<wasm::WasmTable>& tables() const { return Tables; } 104 const std::vector<wasm::WasmLimits>& memories() const { return Memories; } 105 const std::vector<wasm::WasmGlobal>& globals() const { return Globals; } 106 const std::vector<wasm::WasmExport>& exports() const { return Exports; } 107 const wasm::WasmLinkingData& linkingData() const { return LinkingData; } 108 109 uint32_t getNumberOfSymbols() const { 110 return Symbols.size(); 111 } 112 113 const std::vector<wasm::WasmElemSegment>& elements() const { 114 return ElemSegments; 115 } 116 117 const std::vector<WasmSegment>& dataSegments() const { 118 return DataSegments; 119 } 120 121 const std::vector<wasm::WasmFunction>& functions() const { return Functions; } 122 const ArrayRef<uint8_t>& code() const { return CodeSection; } 123 uint32_t startFunction() const { return StartFunction; } 124 125 void moveSymbolNext(DataRefImpl &Symb) const override; 126 127 uint32_t getSymbolFlags(DataRefImpl Symb) const override; 128 129 basic_symbol_iterator symbol_begin() const override; 130 131 basic_symbol_iterator symbol_end() const override; 132 Expected<StringRef> getSymbolName(DataRefImpl Symb) const override; 133 134 Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override; 135 uint64_t getSymbolValueImpl(DataRefImpl Symb) const override; 136 uint32_t getSymbolAlignment(DataRefImpl Symb) const override; 137 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; 138 Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override; 139 Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override; 140 141 // Overrides from SectionRef. 142 void moveSectionNext(DataRefImpl &Sec) const override; 143 std::error_code getSectionName(DataRefImpl Sec, 144 StringRef &Res) const override; 145 uint64_t getSectionAddress(DataRefImpl Sec) const override; 146 uint64_t getSectionIndex(DataRefImpl Sec) const override; 147 uint64_t getSectionSize(DataRefImpl Sec) const override; 148 std::error_code getSectionContents(DataRefImpl Sec, 149 StringRef &Res) const override; 150 uint64_t getSectionAlignment(DataRefImpl Sec) const override; 151 bool isSectionCompressed(DataRefImpl Sec) const override; 152 bool isSectionText(DataRefImpl Sec) const override; 153 bool isSectionData(DataRefImpl Sec) const override; 154 bool isSectionBSS(DataRefImpl Sec) const override; 155 bool isSectionVirtual(DataRefImpl Sec) const override; 156 bool isSectionBitcode(DataRefImpl Sec) const override; 157 relocation_iterator section_rel_begin(DataRefImpl Sec) const override; 158 relocation_iterator section_rel_end(DataRefImpl Sec) const override; 159 160 // Overrides from RelocationRef. 161 void moveRelocationNext(DataRefImpl &Rel) const override; 162 uint64_t getRelocationOffset(DataRefImpl Rel) const override; 163 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; 164 uint64_t getRelocationType(DataRefImpl Rel) const override; 165 void getRelocationTypeName(DataRefImpl Rel, 166 SmallVectorImpl<char> &Result) const override; 167 168 section_iterator section_begin() const override; 169 section_iterator section_end() const override; 170 uint8_t getBytesInAddress() const override; 171 StringRef getFileFormatName() const override; 172 unsigned getArch() const override; 173 SubtargetFeatures getFeatures() const override; 174 bool isRelocatableObject() const override; 175 176private: 177 const WasmSection &getWasmSection(DataRefImpl Ref) const; 178 const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const; 179 180 WasmSection* findCustomSectionByName(StringRef Name); 181 WasmSection* findSectionByType(uint32_t Type); 182 183 const uint8_t *getPtr(size_t Offset) const; 184 Error parseSection(WasmSection &Sec); 185 Error parseCustomSection(WasmSection &Sec, const uint8_t *Ptr, 186 const uint8_t *End); 187 188 // Standard section types 189 Error parseTypeSection(const uint8_t *Ptr, const uint8_t *End); 190 Error parseImportSection(const uint8_t *Ptr, const uint8_t *End); 191 Error parseFunctionSection(const uint8_t *Ptr, const uint8_t *End); 192 Error parseTableSection(const uint8_t *Ptr, const uint8_t *End); 193 Error parseMemorySection(const uint8_t *Ptr, const uint8_t *End); 194 Error parseGlobalSection(const uint8_t *Ptr, const uint8_t *End); 195 Error parseExportSection(const uint8_t *Ptr, const uint8_t *End); 196 Error parseStartSection(const uint8_t *Ptr, const uint8_t *End); 197 Error parseElemSection(const uint8_t *Ptr, const uint8_t *End); 198 Error parseCodeSection(const uint8_t *Ptr, const uint8_t *End); 199 Error parseDataSection(const uint8_t *Ptr, const uint8_t *End); 200 201 // Custom section types 202 Error parseNameSection(const uint8_t *Ptr, const uint8_t *End); 203 Error parseLinkingSection(const uint8_t *Ptr, const uint8_t *End); 204 Error parseRelocSection(StringRef Name, const uint8_t *Ptr, 205 const uint8_t *End); 206 207 wasm::WasmObjectHeader Header; 208 std::vector<WasmSection> Sections; 209 std::vector<wasm::WasmSignature> Signatures; 210 std::vector<uint32_t> FunctionTypes; 211 std::vector<wasm::WasmTable> Tables; 212 std::vector<wasm::WasmLimits> Memories; 213 std::vector<wasm::WasmGlobal> Globals; 214 std::vector<wasm::WasmImport> Imports; 215 std::vector<wasm::WasmExport> Exports; 216 std::vector<wasm::WasmElemSegment> ElemSegments; 217 std::vector<WasmSegment> DataSegments; 218 std::vector<wasm::WasmFunction> Functions; 219 std::vector<WasmSymbol> Symbols; 220 ArrayRef<uint8_t> CodeSection; 221 uint32_t StartFunction = -1; 222 bool HasLinkingSection = false; 223 wasm::WasmLinkingData LinkingData; 224 225 StringMap<uint32_t> SymbolMap; 226}; 227 228} // end namespace object 229 230inline raw_ostream &operator<<(raw_ostream &OS, 231 const object::WasmSymbol &Sym) { 232 Sym.print(OS); 233 return OS; 234} 235 236} // end namespace llvm 237 238#endif // LLVM_OBJECT_WASM_H 239