]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/llvm/Object/Wasm.h
Vendor import of llvm trunk r321414:
[FreeBSD/FreeBSD.git] / include / llvm / Object / Wasm.h
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
32 namespace llvm {
33 namespace object {
34
35 class WasmSymbol {
36 public:
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
112 struct 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
122 struct WasmSegment {
123   uint32_t SectionOffset;
124   wasm::WasmDataSegment Data;
125 };
126
127 class WasmObjectFile : public ObjectFile {
128
129 public:
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
206 private:
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
266 inline 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