]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/Object/Wasm.h
MFV r348971,r348977:
[FreeBSD/FreeBSD.git] / contrib / llvm / 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/StringMap.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/BinaryFormat/Wasm.h"
24 #include "llvm/Config/llvm-config.h"
25 #include "llvm/MC/MCSymbolWasm.h"
26 #include "llvm/Object/Binary.h"
27 #include "llvm/Object/ObjectFile.h"
28 #include "llvm/Support/Error.h"
29 #include "llvm/Support/MemoryBuffer.h"
30 #include <cstddef>
31 #include <cstdint>
32 #include <vector>
33
34 namespace llvm {
35 namespace object {
36
37 class WasmSymbol {
38 public:
39   WasmSymbol(const wasm::WasmSymbolInfo &Info,
40              const wasm::WasmGlobalType *GlobalType,
41              const wasm::WasmEventType *EventType,
42              const wasm::WasmSignature *Signature)
43       : Info(Info), GlobalType(GlobalType), EventType(EventType),
44         Signature(Signature) {}
45
46   const wasm::WasmSymbolInfo &Info;
47   const wasm::WasmGlobalType *GlobalType;
48   const wasm::WasmEventType *EventType;
49   const wasm::WasmSignature *Signature;
50
51   bool isTypeFunction() const {
52     return Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION;
53   }
54
55   bool isTypeData() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA; }
56
57   bool isTypeGlobal() const {
58     return Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL;
59   }
60
61   bool isTypeSection() const {
62     return Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION;
63   }
64
65   bool isTypeEvent() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_EVENT; }
66
67   bool isDefined() const { return !isUndefined(); }
68
69   bool isUndefined() const {
70     return (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) != 0;
71   }
72
73   bool isBindingWeak() const {
74     return getBinding() == wasm::WASM_SYMBOL_BINDING_WEAK;
75   }
76
77   bool isBindingGlobal() const {
78     return getBinding() == wasm::WASM_SYMBOL_BINDING_GLOBAL;
79   }
80
81   bool isBindingLocal() const {
82     return getBinding() == wasm::WASM_SYMBOL_BINDING_LOCAL;
83   }
84
85   unsigned getBinding() const {
86     return Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK;
87   }
88
89   bool isHidden() const {
90     return getVisibility() == wasm::WASM_SYMBOL_VISIBILITY_HIDDEN;
91   }
92
93   unsigned getVisibility() const {
94     return Info.Flags & wasm::WASM_SYMBOL_VISIBILITY_MASK;
95   }
96
97   void print(raw_ostream &Out) const;
98
99 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
100   LLVM_DUMP_METHOD void dump() const;
101 #endif
102 };
103
104 struct WasmSection {
105   WasmSection() = default;
106
107   uint32_t Type = 0;         // Section type (See below)
108   uint32_t Offset = 0;       // Offset with in the file
109   StringRef Name;            // Section name (User-defined sections only)
110   ArrayRef<uint8_t> Content; // Section content
111   std::vector<wasm::WasmRelocation> Relocations; // Relocations for this section
112 };
113
114 struct WasmSegment {
115   uint32_t SectionOffset;
116   wasm::WasmDataSegment Data;
117 };
118
119 class WasmObjectFile : public ObjectFile {
120
121 public:
122   WasmObjectFile(MemoryBufferRef Object, Error &Err);
123
124   const wasm::WasmObjectHeader &getHeader() const;
125   const WasmSymbol &getWasmSymbol(const DataRefImpl &Symb) const;
126   const WasmSymbol &getWasmSymbol(const SymbolRef &Symbol) const;
127   const WasmSection &getWasmSection(const SectionRef &Section) const;
128   const wasm::WasmRelocation &getWasmRelocation(const RelocationRef &Ref) const;
129
130   static bool classof(const Binary *v) { return v->isWasm(); }
131
132   const wasm::WasmDylinkInfo &dylinkInfo() const { return DylinkInfo; }
133   ArrayRef<wasm::WasmSignature> types() const { return Signatures; }
134   ArrayRef<uint32_t> functionTypes() const { return FunctionTypes; }
135   ArrayRef<wasm::WasmImport> imports() const { return Imports; }
136   ArrayRef<wasm::WasmTable> tables() const { return Tables; }
137   ArrayRef<wasm::WasmLimits> memories() const { return Memories; }
138   ArrayRef<wasm::WasmGlobal> globals() const { return Globals; }
139   ArrayRef<wasm::WasmEvent> events() const { return Events; }
140   ArrayRef<wasm::WasmExport> exports() const { return Exports; }
141   ArrayRef<WasmSymbol> syms() const { return Symbols; }
142   const wasm::WasmLinkingData &linkingData() const { return LinkingData; }
143   uint32_t getNumberOfSymbols() const { return Symbols.size(); }
144   ArrayRef<wasm::WasmElemSegment> elements() const { return ElemSegments; }
145   ArrayRef<WasmSegment> dataSegments() const { return DataSegments; }
146   ArrayRef<wasm::WasmFunction> functions() const { return Functions; }
147   ArrayRef<wasm::WasmFunctionName> debugNames() const { return DebugNames; }
148   uint32_t startFunction() const { return StartFunction; }
149   uint32_t getNumImportedGlobals() const { return NumImportedGlobals; }
150   uint32_t getNumImportedFunctions() const { return NumImportedFunctions; }
151   uint32_t getNumImportedEvents() const { return NumImportedEvents; }
152
153   void moveSymbolNext(DataRefImpl &Symb) const override;
154
155   uint32_t getSymbolFlags(DataRefImpl Symb) const override;
156
157   basic_symbol_iterator symbol_begin() const override;
158
159   basic_symbol_iterator symbol_end() const override;
160   Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
161
162   Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
163   uint64_t getWasmSymbolValue(const WasmSymbol &Sym) const;
164   uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
165   uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
166   uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
167   Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
168   Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
169
170   // Overrides from SectionRef.
171   void moveSectionNext(DataRefImpl &Sec) const override;
172   std::error_code getSectionName(DataRefImpl Sec,
173                                  StringRef &Res) const override;
174   uint64_t getSectionAddress(DataRefImpl Sec) const override;
175   uint64_t getSectionIndex(DataRefImpl Sec) const override;
176   uint64_t getSectionSize(DataRefImpl Sec) const override;
177   std::error_code getSectionContents(DataRefImpl Sec,
178                                      StringRef &Res) const override;
179   uint64_t getSectionAlignment(DataRefImpl Sec) const override;
180   bool isSectionCompressed(DataRefImpl Sec) const override;
181   bool isSectionText(DataRefImpl Sec) const override;
182   bool isSectionData(DataRefImpl Sec) const override;
183   bool isSectionBSS(DataRefImpl Sec) const override;
184   bool isSectionVirtual(DataRefImpl Sec) const override;
185   bool isSectionBitcode(DataRefImpl Sec) const override;
186   relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
187   relocation_iterator section_rel_end(DataRefImpl Sec) const override;
188
189   // Overrides from RelocationRef.
190   void moveRelocationNext(DataRefImpl &Rel) const override;
191   uint64_t getRelocationOffset(DataRefImpl Rel) const override;
192   symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
193   uint64_t getRelocationType(DataRefImpl Rel) const override;
194   void getRelocationTypeName(DataRefImpl Rel,
195                              SmallVectorImpl<char> &Result) const override;
196
197   section_iterator section_begin() const override;
198   section_iterator section_end() const override;
199   uint8_t getBytesInAddress() const override;
200   StringRef getFileFormatName() const override;
201   Triple::ArchType getArch() const override;
202   SubtargetFeatures getFeatures() const override;
203   bool isRelocatableObject() const override;
204   bool isSharedObject() const;
205
206   struct ReadContext {
207     const uint8_t *Start;
208     const uint8_t *Ptr;
209     const uint8_t *End;
210   };
211
212 private:
213   bool isValidFunctionIndex(uint32_t Index) const;
214   bool isDefinedFunctionIndex(uint32_t Index) const;
215   bool isValidGlobalIndex(uint32_t Index) const;
216   bool isDefinedGlobalIndex(uint32_t Index) const;
217   bool isValidEventIndex(uint32_t Index) const;
218   bool isDefinedEventIndex(uint32_t Index) const;
219   bool isValidFunctionSymbol(uint32_t Index) const;
220   bool isValidGlobalSymbol(uint32_t Index) const;
221   bool isValidEventSymbol(uint32_t Index) const;
222   bool isValidDataSymbol(uint32_t Index) const;
223   bool isValidSectionSymbol(uint32_t Index) const;
224   wasm::WasmFunction &getDefinedFunction(uint32_t Index);
225   wasm::WasmGlobal &getDefinedGlobal(uint32_t Index);
226   wasm::WasmEvent &getDefinedEvent(uint32_t Index);
227
228   const WasmSection &getWasmSection(DataRefImpl Ref) const;
229   const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const;
230
231   const uint8_t *getPtr(size_t Offset) const;
232   Error parseSection(WasmSection &Sec);
233   Error parseCustomSection(WasmSection &Sec, ReadContext &Ctx);
234
235   // Standard section types
236   Error parseTypeSection(ReadContext &Ctx);
237   Error parseImportSection(ReadContext &Ctx);
238   Error parseFunctionSection(ReadContext &Ctx);
239   Error parseTableSection(ReadContext &Ctx);
240   Error parseMemorySection(ReadContext &Ctx);
241   Error parseGlobalSection(ReadContext &Ctx);
242   Error parseEventSection(ReadContext &Ctx);
243   Error parseExportSection(ReadContext &Ctx);
244   Error parseStartSection(ReadContext &Ctx);
245   Error parseElemSection(ReadContext &Ctx);
246   Error parseCodeSection(ReadContext &Ctx);
247   Error parseDataSection(ReadContext &Ctx);
248
249   // Custom section types
250   Error parseDylinkSection(ReadContext &Ctx);
251   Error parseNameSection(ReadContext &Ctx);
252   Error parseLinkingSection(ReadContext &Ctx);
253   Error parseLinkingSectionSymtab(ReadContext &Ctx);
254   Error parseLinkingSectionComdat(ReadContext &Ctx);
255   Error parseRelocSection(StringRef Name, ReadContext &Ctx);
256
257   wasm::WasmObjectHeader Header;
258   std::vector<WasmSection> Sections;
259   wasm::WasmDylinkInfo DylinkInfo;
260   std::vector<wasm::WasmSignature> Signatures;
261   std::vector<uint32_t> FunctionTypes;
262   std::vector<wasm::WasmTable> Tables;
263   std::vector<wasm::WasmLimits> Memories;
264   std::vector<wasm::WasmGlobal> Globals;
265   std::vector<wasm::WasmEvent> Events;
266   std::vector<wasm::WasmImport> Imports;
267   std::vector<wasm::WasmExport> Exports;
268   std::vector<wasm::WasmElemSegment> ElemSegments;
269   std::vector<WasmSegment> DataSegments;
270   std::vector<wasm::WasmFunction> Functions;
271   std::vector<WasmSymbol> Symbols;
272   std::vector<wasm::WasmFunctionName> DebugNames;
273   uint32_t StartFunction = -1;
274   bool HasLinkingSection = false;
275   bool HasDylinkSection = false;
276   wasm::WasmLinkingData LinkingData;
277   uint32_t NumImportedGlobals = 0;
278   uint32_t NumImportedFunctions = 0;
279   uint32_t NumImportedEvents = 0;
280   uint32_t CodeSection = 0;
281   uint32_t DataSection = 0;
282   uint32_t GlobalSection = 0;
283   uint32_t EventSection = 0;
284 };
285
286 class WasmSectionOrderChecker {
287 public:
288   // We define orders for all core wasm sections and known custom sections.
289   enum : int {
290     // Core sections
291     // The order of standard sections is precisely given by the spec.
292     WASM_SEC_ORDER_TYPE = 1,
293     WASM_SEC_ORDER_IMPORT = 2,
294     WASM_SEC_ORDER_FUNCTION = 3,
295     WASM_SEC_ORDER_TABLE = 4,
296     WASM_SEC_ORDER_MEMORY = 5,
297     WASM_SEC_ORDER_GLOBAL = 6,
298     WASM_SEC_ORDER_EVENT = 7,
299     WASM_SEC_ORDER_EXPORT = 8,
300     WASM_SEC_ORDER_START = 9,
301     WASM_SEC_ORDER_ELEM = 10,
302     WASM_SEC_ORDER_DATACOUNT = 11,
303     WASM_SEC_ORDER_CODE = 12,
304     WASM_SEC_ORDER_DATA = 13,
305
306     // Custom sections
307     // "dylink" should be the very first section in the module
308     WASM_SEC_ORDER_DYLINK = 0,
309     // "linking" section requires DATA section in order to validate data symbols
310     WASM_SEC_ORDER_LINKING = 100,
311     // Must come after "linking" section in order to validate reloc indexes.
312     WASM_SEC_ORDER_RELOC = 101,
313     // "name" section must appear after DATA. Comes after "linking" to allow
314     // symbol table to set default function name.
315     WASM_SEC_ORDER_NAME = 102,
316     // "producers" section must appear after "name" section.
317     WASM_SEC_ORDER_PRODUCERS = 103
318   };
319
320   bool isValidSectionOrder(unsigned ID, StringRef CustomSectionName = "");
321
322 private:
323   int LastOrder = -1; // Lastly seen known section's order
324
325   // Returns -1 for unknown sections.
326   int getSectionOrder(unsigned ID, StringRef CustomSectionName = "");
327 };
328
329 } // end namespace object
330
331 inline raw_ostream &operator<<(raw_ostream &OS, const object::WasmSymbol &Sym) {
332   Sym.print(OS);
333   return OS;
334 }
335
336 } // end namespace llvm
337
338 #endif // LLVM_OBJECT_WASM_H