Wasm.h revision 327952
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, uint32_t FunctionType = 0) 47 : Name(Name), Type(Type), Section(Section), ElementIndex(ElementIndex), 48 FunctionType(FunctionType) {} 49 50 StringRef Name; 51 SymbolType Type; 52 uint32_t Section; 53 uint32_t Flags = 0; 54 55 // Index into either the function or global index space. 56 uint32_t ElementIndex; 57 58 // For function, the type index 59 uint32_t FunctionType; 60 61 // Symbols can be both exported and imported (in the case of the weakly 62 // defined symbol). In this the import index is stored as AltIndex. 63 uint32_t AltIndex = 0; 64 bool HasAltIndex = false; 65 66 void setAltIndex(uint32_t Index) { 67 HasAltIndex = true; 68 AltIndex = Index; 69 } 70 71 bool isFunction() const { 72 return Type == WasmSymbol::SymbolType::FUNCTION_IMPORT || 73 Type == WasmSymbol::SymbolType::FUNCTION_EXPORT || 74 Type == WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME; 75 } 76 77 78 bool isWeak() const { 79 return getBinding() == wasm::WASM_SYMBOL_BINDING_WEAK; 80 } 81 82 bool isGlobal() const { 83 return getBinding() == wasm::WASM_SYMBOL_BINDING_GLOBAL; 84 } 85 86 bool isLocal() const { 87 return getBinding() == wasm::WASM_SYMBOL_BINDING_LOCAL; 88 } 89 90 unsigned getBinding() const { 91 return Flags & wasm::WASM_SYMBOL_BINDING_MASK; 92 } 93 94 bool isHidden() const { 95 return getVisibility() == wasm::WASM_SYMBOL_VISIBILITY_HIDDEN; 96 } 97 98 unsigned getVisibility() const { 99 return Flags & wasm::WASM_SYMBOL_VISIBILITY_MASK; 100 } 101 102 void print(raw_ostream &Out) const { 103 Out << "Name=" << Name << ", Type=" << static_cast<int>(Type) 104 << ", Flags=" << Flags << " ElemIndex=" << ElementIndex; 105 } 106 107#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 108 LLVM_DUMP_METHOD void dump() const { print(dbgs()); } 109#endif 110}; 111 112struct WasmSection { 113 WasmSection() = default; 114 115 uint32_t Type = 0; // Section type (See below) 116 uint32_t Offset = 0; // Offset with in the file 117 StringRef Name; // Section name (User-defined sections only) 118 ArrayRef<uint8_t> Content; // Section content 119 std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section 120}; 121 122struct WasmSegment { 123 uint32_t SectionOffset; 124 wasm::WasmDataSegment Data; 125}; 126 127class WasmObjectFile : public ObjectFile { 128 129public: 130 WasmObjectFile(MemoryBufferRef Object, Error &Err); 131 132 const wasm::WasmObjectHeader &getHeader() const; 133 const WasmSymbol &getWasmSymbol(const DataRefImpl &Symb) const; 134 const WasmSymbol &getWasmSymbol(const SymbolRef &Symbol) const; 135 const WasmSection &getWasmSection(const SectionRef &Section) const; 136 const wasm::WasmRelocation &getWasmRelocation(const RelocationRef& Ref) const; 137 138 static bool classof(const Binary *v) { return v->isWasm(); } 139 140 ArrayRef<wasm::WasmSignature> types() const { return Signatures; } 141 ArrayRef<uint32_t> functionTypes() const { return FunctionTypes; } 142 ArrayRef<wasm::WasmImport> imports() const { return Imports; } 143 ArrayRef<wasm::WasmTable> tables() const { return Tables; } 144 ArrayRef<wasm::WasmLimits> memories() const { return Memories; } 145 ArrayRef<wasm::WasmGlobal> globals() const { return Globals; } 146 ArrayRef<wasm::WasmExport> exports() const { return Exports; } 147 const wasm::WasmLinkingData& linkingData() const { return LinkingData; } 148 uint32_t getNumberOfSymbols() const { return Symbols.size(); } 149 ArrayRef<wasm::WasmElemSegment> elements() const { return ElemSegments; } 150 ArrayRef<WasmSegment> dataSegments() const { return DataSegments; } 151 ArrayRef<wasm::WasmFunction> functions() const { return Functions; } 152 uint32_t startFunction() const { return StartFunction; } 153 154 void moveSymbolNext(DataRefImpl &Symb) const override; 155 156 uint32_t getSymbolFlags(DataRefImpl Symb) const override; 157 158 basic_symbol_iterator symbol_begin() const override; 159 160 basic_symbol_iterator symbol_end() const override; 161 Expected<StringRef> getSymbolName(DataRefImpl Symb) const override; 162 163 Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override; 164 uint64_t getWasmSymbolValue(const WasmSymbol& Sym) const; 165 uint64_t getSymbolValueImpl(DataRefImpl Symb) const override; 166 uint32_t getSymbolAlignment(DataRefImpl Symb) const override; 167 uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; 168 Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override; 169 Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override; 170 171 // Overrides from SectionRef. 172 void moveSectionNext(DataRefImpl &Sec) const override; 173 std::error_code getSectionName(DataRefImpl Sec, 174 StringRef &Res) const override; 175 uint64_t getSectionAddress(DataRefImpl Sec) const override; 176 uint64_t getSectionIndex(DataRefImpl Sec) const override; 177 uint64_t getSectionSize(DataRefImpl Sec) const override; 178 std::error_code getSectionContents(DataRefImpl Sec, 179 StringRef &Res) const override; 180 uint64_t getSectionAlignment(DataRefImpl Sec) const override; 181 bool isSectionCompressed(DataRefImpl Sec) const override; 182 bool isSectionText(DataRefImpl Sec) const override; 183 bool isSectionData(DataRefImpl Sec) const override; 184 bool isSectionBSS(DataRefImpl Sec) const override; 185 bool isSectionVirtual(DataRefImpl Sec) const override; 186 bool isSectionBitcode(DataRefImpl Sec) const override; 187 relocation_iterator section_rel_begin(DataRefImpl Sec) const override; 188 relocation_iterator section_rel_end(DataRefImpl Sec) const override; 189 190 // Overrides from RelocationRef. 191 void moveRelocationNext(DataRefImpl &Rel) const override; 192 uint64_t getRelocationOffset(DataRefImpl Rel) const override; 193 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; 194 uint64_t getRelocationType(DataRefImpl Rel) const override; 195 void getRelocationTypeName(DataRefImpl Rel, 196 SmallVectorImpl<char> &Result) const override; 197 198 section_iterator section_begin() const override; 199 section_iterator section_end() const override; 200 uint8_t getBytesInAddress() const override; 201 StringRef getFileFormatName() const override; 202 Triple::ArchType getArch() const override; 203 SubtargetFeatures getFeatures() const override; 204 bool isRelocatableObject() const override; 205 206private: 207 bool isValidFunctionIndex(uint32_t Index) const; 208 const WasmSection &getWasmSection(DataRefImpl Ref) const; 209 const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const; 210 211 WasmSection* findCustomSectionByName(StringRef Name); 212 WasmSection* findSectionByType(uint32_t Type); 213 214 const uint8_t *getPtr(size_t Offset) const; 215 Error parseSection(WasmSection &Sec); 216 Error parseCustomSection(WasmSection &Sec, const uint8_t *Ptr, 217 const uint8_t *End); 218 219 // Standard section types 220 Error parseTypeSection(const uint8_t *Ptr, const uint8_t *End); 221 Error parseImportSection(const uint8_t *Ptr, const uint8_t *End); 222 Error parseFunctionSection(const uint8_t *Ptr, const uint8_t *End); 223 Error parseTableSection(const uint8_t *Ptr, const uint8_t *End); 224 Error parseMemorySection(const uint8_t *Ptr, const uint8_t *End); 225 Error parseGlobalSection(const uint8_t *Ptr, const uint8_t *End); 226 Error parseExportSection(const uint8_t *Ptr, const uint8_t *End); 227 Error parseStartSection(const uint8_t *Ptr, const uint8_t *End); 228 Error parseElemSection(const uint8_t *Ptr, const uint8_t *End); 229 Error parseCodeSection(const uint8_t *Ptr, const uint8_t *End); 230 Error parseDataSection(const uint8_t *Ptr, const uint8_t *End); 231 232 // Custom section types 233 Error parseNameSection(const uint8_t *Ptr, const uint8_t *End); 234 Error parseLinkingSection(const uint8_t *Ptr, const uint8_t *End); 235 Error parseRelocSection(StringRef Name, const uint8_t *Ptr, 236 const uint8_t *End); 237 238 void populateSymbolTable(); 239 240 wasm::WasmObjectHeader Header; 241 std::vector<WasmSection> Sections; 242 std::vector<wasm::WasmSignature> Signatures; 243 std::vector<uint32_t> FunctionTypes; 244 std::vector<wasm::WasmTable> Tables; 245 std::vector<wasm::WasmLimits> Memories; 246 std::vector<wasm::WasmGlobal> Globals; 247 std::vector<wasm::WasmImport> Imports; 248 std::vector<wasm::WasmExport> Exports; 249 std::vector<wasm::WasmElemSegment> ElemSegments; 250 std::vector<WasmSegment> DataSegments; 251 std::vector<wasm::WasmFunction> Functions; 252 std::vector<WasmSymbol> Symbols; 253 uint32_t StartFunction = -1; 254 bool HasLinkingSection = false; 255 wasm::WasmLinkingData LinkingData; 256 uint32_t NumImportedGlobals = 0; 257 uint32_t NumImportedFunctions = 0; 258 uint32_t ImportSection = 0; 259 uint32_t ExportSection = 0; 260 261 StringMap<uint32_t> SymbolMap; 262}; 263 264} // end namespace object 265 266inline raw_ostream &operator<<(raw_ostream &OS, 267 const object::WasmSymbol &Sym) { 268 Sym.print(OS); 269 return OS; 270} 271 272} // end namespace llvm 273 274#endif // LLVM_OBJECT_WASM_H 275