LLVM  7.0.0svn
WasmObjectFile.cpp
Go to the documentation of this file.
1 //===- WasmObjectFile.cpp - Wasm object file implementation ---------------===//
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 #include "llvm/ADT/ArrayRef.h"
11 #include "llvm/ADT/DenseSet.h"
12 #include "llvm/ADT/STLExtras.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/ADT/StringSet.h"
15 #include "llvm/ADT/Triple.h"
16 #include "llvm/BinaryFormat/Wasm.h"
18 #include "llvm/Object/Binary.h"
19 #include "llvm/Object/Error.h"
20 #include "llvm/Object/ObjectFile.h"
22 #include "llvm/Object/Wasm.h"
23 #include "llvm/Support/Endian.h"
24 #include "llvm/Support/Error.h"
26 #include "llvm/Support/LEB128.h"
27 #include <algorithm>
28 #include <cassert>
29 #include <cstdint>
30 #include <cstring>
31 #include <system_error>
32 
33 #define DEBUG_TYPE "wasm-object"
34 
35 using namespace llvm;
36 using namespace object;
37 
38 void WasmSymbol::print(raw_ostream &Out) const {
39  Out << "Name=" << Info.Name
40  << ", Kind=" << toString(wasm::WasmSymbolType(Info.Kind))
41  << ", Flags=" << Info.Flags;
42  if (!isTypeData()) {
43  Out << ", ElemIndex=" << Info.ElementIndex;
44  } else if (isDefined()) {
45  Out << ", Segment=" << Info.DataRef.Segment;
46  Out << ", Offset=" << Info.DataRef.Offset;
47  Out << ", Size=" << Info.DataRef.Size;
48  }
49 }
50 
51 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
53 #endif
54 
57  Error Err = Error::success();
58  auto ObjectFile = llvm::make_unique<WasmObjectFile>(Buffer, Err);
59  if (Err)
60  return std::move(Err);
61 
62  return std::move(ObjectFile);
63 }
64 
65 #define VARINT7_MAX ((1<<7)-1)
66 #define VARINT7_MIN (-(1<<7))
67 #define VARUINT7_MAX (1<<7)
68 #define VARUINT1_MAX (1)
69 
70 static uint8_t readUint8(const uint8_t *&Ptr) { return *Ptr++; }
71 
72 static uint32_t readUint32(const uint8_t *&Ptr) {
73  uint32_t Result = support::endian::read32le(Ptr);
74  Ptr += sizeof(Result);
75  return Result;
76 }
77 
78 static int32_t readFloat32(const uint8_t *&Ptr) {
79  int32_t Result = 0;
80  memcpy(&Result, Ptr, sizeof(Result));
81  Ptr += sizeof(Result);
82  return Result;
83 }
84 
85 static int64_t readFloat64(const uint8_t *&Ptr) {
86  int64_t Result = 0;
87  memcpy(&Result, Ptr, sizeof(Result));
88  Ptr += sizeof(Result);
89  return Result;
90 }
91 
92 static uint64_t readULEB128(const uint8_t *&Ptr) {
93  unsigned Count;
94  uint64_t Result = decodeULEB128(Ptr, &Count);
95  Ptr += Count;
96  return Result;
97 }
98 
99 static StringRef readString(const uint8_t *&Ptr) {
100  uint32_t StringLen = readULEB128(Ptr);
101  StringRef Return = StringRef(reinterpret_cast<const char *>(Ptr), StringLen);
102  Ptr += StringLen;
103  return Return;
104 }
105 
106 static int64_t readLEB128(const uint8_t *&Ptr) {
107  unsigned Count;
108  uint64_t Result = decodeSLEB128(Ptr, &Count);
109  Ptr += Count;
110  return Result;
111 }
112 
113 static uint8_t readVaruint1(const uint8_t *&Ptr) {
114  int64_t result = readLEB128(Ptr);
115  if (result > VARUINT1_MAX || result < 0)
116  report_fatal_error("LEB is outside Varuint1 range");
117  return result;
118 }
119 
120 static int32_t readVarint32(const uint8_t *&Ptr) {
121  int64_t result = readLEB128(Ptr);
122  if (result > INT32_MAX || result < INT32_MIN)
123  report_fatal_error("LEB is outside Varint32 range");
124  return result;
125 }
126 
127 static uint32_t readVaruint32(const uint8_t *&Ptr) {
128  uint64_t result = readULEB128(Ptr);
129  if (result > UINT32_MAX)
130  report_fatal_error("LEB is outside Varuint32 range");
131  return result;
132 }
133 
134 static int64_t readVarint64(const uint8_t *&Ptr) {
135  return readLEB128(Ptr);
136 }
137 
138 static uint8_t readOpcode(const uint8_t *&Ptr) {
139  return readUint8(Ptr);
140 }
141 
142 static Error readInitExpr(wasm::WasmInitExpr &Expr, const uint8_t *&Ptr) {
143  Expr.Opcode = readOpcode(Ptr);
144 
145  switch (Expr.Opcode) {
147  Expr.Value.Int32 = readVarint32(Ptr);
148  break;
150  Expr.Value.Int64 = readVarint64(Ptr);
151  break;
153  Expr.Value.Float32 = readFloat32(Ptr);
154  break;
156  Expr.Value.Float64 = readFloat64(Ptr);
157  break;
159  Expr.Value.Global = readULEB128(Ptr);
160  break;
161  default:
162  return make_error<GenericBinaryError>("Invalid opcode in init_expr",
164  }
165 
166  uint8_t EndOpcode = readOpcode(Ptr);
167  if (EndOpcode != wasm::WASM_OPCODE_END) {
168  return make_error<GenericBinaryError>("Invalid init_expr",
170  }
171  return Error::success();
172 }
173 
174 static wasm::WasmLimits readLimits(const uint8_t *&Ptr) {
175  wasm::WasmLimits Result;
176  Result.Flags = readVaruint1(Ptr);
177  Result.Initial = readVaruint32(Ptr);
179  Result.Maximum = readVaruint32(Ptr);
180  return Result;
181 }
182 
183 static wasm::WasmTable readTable(const uint8_t *&Ptr) {
184  wasm::WasmTable Table;
185  Table.ElemType = readUint8(Ptr);
186  Table.Limits = readLimits(Ptr);
187  return Table;
188 }
189 
190 static Error readSection(WasmSection &Section, const uint8_t *&Ptr,
191  const uint8_t *Start, const uint8_t *Eof) {
192  Section.Offset = Ptr - Start;
193  Section.Type = readUint8(Ptr);
194  uint32_t Size = readVaruint32(Ptr);
195  if (Size == 0)
196  return make_error<StringError>("Zero length section",
198  if (Ptr + Size > Eof)
199  return make_error<StringError>("Section too large",
201  if (Section.Type == wasm::WASM_SEC_CUSTOM) {
202  const uint8_t *NameStart = Ptr;
203  Section.Name = readString(Ptr);
204  Size -= Ptr - NameStart;
205  }
206  Section.Content = ArrayRef<uint8_t>(Ptr, Size);
207  Ptr += Size;
208  return Error::success();
209 }
210 
212  : ObjectFile(Binary::ID_Wasm, Buffer) {
213  ErrorAsOutParameter ErrAsOutParam(&Err);
214  Header.Magic = getData().substr(0, 4);
215  if (Header.Magic != StringRef("\0asm", 4)) {
216  Err = make_error<StringError>("Bad magic number",
218  return;
219  }
220 
221  const uint8_t *Eof = getPtr(getData().size());
222  const uint8_t *Ptr = getPtr(4);
223 
224  if (Ptr + 4 > Eof) {
225  Err = make_error<StringError>("Missing version number",
227  return;
228  }
229 
230  Header.Version = readUint32(Ptr);
231  if (Header.Version != wasm::WasmVersion) {
232  Err = make_error<StringError>("Bad version number",
234  return;
235  }
236 
237  WasmSection Sec;
238  while (Ptr < Eof) {
239  if ((Err = readSection(Sec, Ptr, getPtr(0), Eof)))
240  return;
241  if ((Err = parseSection(Sec)))
242  return;
243 
244  Sections.push_back(Sec);
245  }
246 }
247 
248 Error WasmObjectFile::parseSection(WasmSection &Sec) {
249  const uint8_t* Start = Sec.Content.data();
250  const uint8_t* End = Start + Sec.Content.size();
251  switch (Sec.Type) {
253  return parseCustomSection(Sec, Start, End);
254  case wasm::WASM_SEC_TYPE:
255  return parseTypeSection(Start, End);
257  return parseImportSection(Start, End);
259  return parseFunctionSection(Start, End);
261  return parseTableSection(Start, End);
263  return parseMemorySection(Start, End);
265  return parseGlobalSection(Start, End);
267  return parseExportSection(Start, End);
269  return parseStartSection(Start, End);
270  case wasm::WASM_SEC_ELEM:
271  return parseElemSection(Start, End);
272  case wasm::WASM_SEC_CODE:
273  return parseCodeSection(Start, End);
274  case wasm::WASM_SEC_DATA:
275  return parseDataSection(Start, End);
276  default:
277  return make_error<GenericBinaryError>("Bad section type",
279  }
280 }
281 
282 Error WasmObjectFile::parseNameSection(const uint8_t *Ptr, const uint8_t *End) {
284  if (Functions.size() != FunctionTypes.size()) {
285  return make_error<GenericBinaryError>("Names must come after code section",
287  }
288 
289  while (Ptr < End) {
290  uint8_t Type = readUint8(Ptr);
291  uint32_t Size = readVaruint32(Ptr);
292  const uint8_t *SubSectionEnd = Ptr + Size;
293  switch (Type) {
295  uint32_t Count = readVaruint32(Ptr);
296  while (Count--) {
298  if (!Seen.insert(Index).second)
299  return make_error<GenericBinaryError>("Function named more than once",
301  StringRef Name = readString(Ptr);
302  if (!isValidFunctionIndex(Index) || Name.empty())
303  return make_error<GenericBinaryError>("Invalid name entry",
305  DebugNames.push_back(wasm::WasmFunctionName{Index, Name});
306  if (isDefinedFunctionIndex(Index))
307  getDefinedFunction(Index).DebugName = Name;
308  }
309  break;
310  }
311  // Ignore local names for now
313  default:
314  Ptr += Size;
315  break;
316  }
317  if (Ptr != SubSectionEnd)
318  return make_error<GenericBinaryError>("Name sub-section ended prematurely",
320  }
321 
322  if (Ptr != End)
323  return make_error<GenericBinaryError>("Name section ended prematurely",
325  return Error::success();
326 }
327 
328 Error WasmObjectFile::parseLinkingSection(const uint8_t *Ptr,
329  const uint8_t *End) {
330  HasLinkingSection = true;
331  if (Functions.size() != FunctionTypes.size()) {
332  return make_error<GenericBinaryError>(
333  "Linking data must come after code section", object_error::parse_failed);
334  }
335 
336  LinkingData.Version = readVaruint32(Ptr);
337  if (LinkingData.Version != wasm::WasmMetadataVersion) {
338  return make_error<GenericBinaryError>(
339  "Unexpected metadata version: " + Twine(LinkingData.Version) +
340  " (Expected: " + Twine(wasm::WasmMetadataVersion) + ")",
342  }
343 
344  while (Ptr < End) {
345  uint8_t Type = readUint8(Ptr);
346  uint32_t Size = readVaruint32(Ptr);
347  const uint8_t *SubSectionEnd = Ptr + Size;
348  switch (Type) {
350  if (Error Err = parseLinkingSectionSymtab(Ptr, SubSectionEnd))
351  return Err;
352  break;
354  uint32_t Count = readVaruint32(Ptr);
355  if (Count > DataSegments.size())
356  return make_error<GenericBinaryError>("Too many segment names",
358  for (uint32_t i = 0; i < Count; i++) {
359  DataSegments[i].Data.Name = readString(Ptr);
360  DataSegments[i].Data.Alignment = readVaruint32(Ptr);
361  DataSegments[i].Data.Flags = readVaruint32(Ptr);
362  }
363  break;
364  }
365  case wasm::WASM_INIT_FUNCS: {
366  uint32_t Count = readVaruint32(Ptr);
367  LinkingData.InitFunctions.reserve(Count);
368  for (uint32_t i = 0; i < Count; i++) {
370  Init.Priority = readVaruint32(Ptr);
371  Init.Symbol = readVaruint32(Ptr);
372  if (!isValidFunctionSymbol(Init.Symbol))
373  return make_error<GenericBinaryError>("Invalid function symbol: " +
374  Twine(Init.Symbol),
376  LinkingData.InitFunctions.emplace_back(Init);
377  }
378  break;
379  }
381  if (Error Err = parseLinkingSectionComdat(Ptr, SubSectionEnd))
382  return Err;
383  break;
384  default:
385  Ptr += Size;
386  break;
387  }
388  if (Ptr != SubSectionEnd)
389  return make_error<GenericBinaryError>(
390  "Linking sub-section ended prematurely", object_error::parse_failed);
391  }
392  if (Ptr != End)
393  return make_error<GenericBinaryError>("Linking section ended prematurely",
395  return Error::success();
396 }
397 
398 Error WasmObjectFile::parseLinkingSectionSymtab(const uint8_t *&Ptr,
399  const uint8_t *End) {
400  uint32_t Count = readVaruint32(Ptr);
401  LinkingData.SymbolTable.reserve(Count);
402  Symbols.reserve(Count);
403  StringSet<> SymbolNames;
404 
405  std::vector<wasm::WasmImport *> ImportedGlobals;
406  std::vector<wasm::WasmImport *> ImportedFunctions;
407  ImportedGlobals.reserve(Imports.size());
408  ImportedFunctions.reserve(Imports.size());
409  for (auto &I : Imports) {
410  if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
411  ImportedFunctions.emplace_back(&I);
412  else if (I.Kind == wasm::WASM_EXTERNAL_GLOBAL)
413  ImportedGlobals.emplace_back(&I);
414  }
415 
416  while (Count--) {
418  const wasm::WasmSignature *FunctionType = nullptr;
419  const wasm::WasmGlobalType *GlobalType = nullptr;
420 
421  Info.Kind = readUint8(Ptr);
422  Info.Flags = readVaruint32(Ptr);
423  bool IsDefined = (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0;
424 
425  switch (Info.Kind) {
427  Info.ElementIndex = readVaruint32(Ptr);
428  if (!isValidFunctionIndex(Info.ElementIndex) ||
429  IsDefined != isDefinedFunctionIndex(Info.ElementIndex))
430  return make_error<GenericBinaryError>("invalid function symbol index",
432  if (IsDefined) {
433  Info.Name = readString(Ptr);
434  unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions;
435  FunctionType = &Signatures[FunctionTypes[FuncIndex]];
436  wasm::WasmFunction &Function = Functions[FuncIndex];
437  if (Function.SymbolName.empty())
438  Function.SymbolName = Info.Name;
439  } else {
440  wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex];
441  FunctionType = &Signatures[Import.SigIndex];
442  Info.Name = Import.Field;
443  Info.Module = Import.Module;
444  }
445  break;
446 
448  Info.ElementIndex = readVaruint32(Ptr);
449  if (!isValidGlobalIndex(Info.ElementIndex) ||
450  IsDefined != isDefinedGlobalIndex(Info.ElementIndex))
451  return make_error<GenericBinaryError>("invalid global symbol index",
453  if (!IsDefined &&
456  return make_error<GenericBinaryError>("undefined weak global symbol",
458  if (IsDefined) {
459  Info.Name = readString(Ptr);
460  unsigned GlobalIndex = Info.ElementIndex - NumImportedGlobals;
461  wasm::WasmGlobal &Global = Globals[GlobalIndex];
462  GlobalType = &Global.Type;
463  if (Global.SymbolName.empty())
464  Global.SymbolName = Info.Name;
465  } else {
466  wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex];
467  Info.Name = Import.Field;
468  GlobalType = &Import.Global;
469  }
470  break;
471 
473  Info.Name = readString(Ptr);
474  if (IsDefined) {
476  if (Index >= DataSegments.size())
477  return make_error<GenericBinaryError>("invalid data symbol index",
480  uint32_t Size = readVaruint32(Ptr);
481  if (Offset + Size > DataSegments[Index].Data.Content.size())
482  return make_error<GenericBinaryError>("invalid data symbol offset",
485  }
486  break;
487 
489  if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
491  return make_error<GenericBinaryError>(
492  "Section symbols must have local binding",
494  Info.ElementIndex = readVaruint32(Ptr);
495  // Use somewhat unique section name as symbol name.
496  StringRef SectionName = Sections[Info.ElementIndex].Name;
497  Info.Name = SectionName;
498  break;
499  }
500 
501  default:
502  return make_error<GenericBinaryError>("Invalid symbol type",
504  }
505 
506  if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
508  !SymbolNames.insert(Info.Name).second)
509  return make_error<GenericBinaryError>("Duplicate symbol name " +
510  Twine(Info.Name),
512  LinkingData.SymbolTable.emplace_back(Info);
513  Symbols.emplace_back(LinkingData.SymbolTable.back(), FunctionType,
514  GlobalType);
515  LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");
516  }
517 
518  return Error::success();
519 }
520 
521 Error WasmObjectFile::parseLinkingSectionComdat(const uint8_t *&Ptr,
522  const uint8_t *End)
523 {
524  uint32_t ComdatCount = readVaruint32(Ptr);
525  StringSet<> ComdatSet;
526  for (unsigned ComdatIndex = 0; ComdatIndex < ComdatCount; ++ComdatIndex) {
527  StringRef Name = readString(Ptr);
528  if (Name.empty() || !ComdatSet.insert(Name).second)
529  return make_error<GenericBinaryError>("Bad/duplicate COMDAT name " + Twine(Name),
531  LinkingData.Comdats.emplace_back(Name);
532  uint32_t Flags = readVaruint32(Ptr);
533  if (Flags != 0)
534  return make_error<GenericBinaryError>("Unsupported COMDAT flags",
536 
537  uint32_t EntryCount = readVaruint32(Ptr);
538  while (EntryCount--) {
539  unsigned Kind = readVaruint32(Ptr);
540  unsigned Index = readVaruint32(Ptr);
541  switch (Kind) {
542  default:
543  return make_error<GenericBinaryError>("Invalid COMDAT entry type",
546  if (Index >= DataSegments.size())
547  return make_error<GenericBinaryError>("COMDAT data index out of range",
549  if (DataSegments[Index].Data.Comdat != UINT32_MAX)
550  return make_error<GenericBinaryError>("Data segment in two COMDATs",
552  DataSegments[Index].Data.Comdat = ComdatIndex;
553  break;
555  if (!isDefinedFunctionIndex(Index))
556  return make_error<GenericBinaryError>("COMDAT function index out of range",
558  if (getDefinedFunction(Index).Comdat != UINT32_MAX)
559  return make_error<GenericBinaryError>("Function in two COMDATs",
561  getDefinedFunction(Index).Comdat = ComdatIndex;
562  break;
563  }
564  }
565  }
566  return Error::success();
567 }
568 
569 Error WasmObjectFile::parseRelocSection(StringRef Name, const uint8_t *Ptr,
570  const uint8_t *End) {
571  uint32_t SectionIndex = readVaruint32(Ptr);
572  if (SectionIndex >= Sections.size())
573  return make_error<GenericBinaryError>("Invalid section index",
575  WasmSection& Section = Sections[SectionIndex];
576  uint32_t RelocCount = readVaruint32(Ptr);
577  uint32_t EndOffset = Section.Content.size();
578  while (RelocCount--) {
579  wasm::WasmRelocation Reloc = {};
580  Reloc.Type = readVaruint32(Ptr);
581  Reloc.Offset = readVaruint32(Ptr);
582  Reloc.Index = readVaruint32(Ptr);
583  switch (Reloc.Type) {
584  case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
585  case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
586  case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
587  if (!isValidFunctionSymbol(Reloc.Index))
588  return make_error<GenericBinaryError>("Bad relocation function index",
590  break;
591  case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
592  if (Reloc.Index >= Signatures.size())
593  return make_error<GenericBinaryError>("Bad relocation type index",
595  break;
596  case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
597  if (!isValidGlobalSymbol(Reloc.Index))
598  return make_error<GenericBinaryError>("Bad relocation global index",
600  break;
601  case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
602  case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
603  case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
604  if (!isValidDataSymbol(Reloc.Index))
605  return make_error<GenericBinaryError>("Bad relocation data index",
607  Reloc.Addend = readVarint32(Ptr);
608  break;
609  case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
610  if (!isValidFunctionSymbol(Reloc.Index))
611  return make_error<GenericBinaryError>("Bad relocation function index",
613  Reloc.Addend = readVarint32(Ptr);
614  break;
615  case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
616  if (!isValidSectionSymbol(Reloc.Index))
617  return make_error<GenericBinaryError>("Bad relocation section index",
619  Reloc.Addend = readVarint32(Ptr);
620  break;
621  default:
622  return make_error<GenericBinaryError>("Bad relocation type: " +
623  Twine(Reloc.Type),
625  }
626 
627  // Relocations must fit inside the section, and must appear in order. They
628  // also shouldn't overlap a function/element boundary, but we don't bother
629  // to check that.
630  uint64_t Size = 5;
631  if (Reloc.Type == wasm::R_WEBASSEMBLY_TABLE_INDEX_I32 ||
632  Reloc.Type == wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32 ||
633  Reloc.Type == wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32 ||
634  Reloc.Type == wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32)
635  Size = 4;
636  if (Reloc.Offset + Size > EndOffset)
637  return make_error<GenericBinaryError>("Bad relocation offset",
639 
640  Section.Relocations.push_back(Reloc);
641  }
642  if (Ptr != End)
643  return make_error<GenericBinaryError>("Reloc section ended prematurely",
645  return Error::success();
646 }
647 
648 Error WasmObjectFile::parseCustomSection(WasmSection &Sec,
649  const uint8_t *Ptr, const uint8_t *End) {
650  if (Sec.Name == "name") {
651  if (Error Err = parseNameSection(Ptr, End))
652  return Err;
653  } else if (Sec.Name == "linking") {
654  if (Error Err = parseLinkingSection(Ptr, End))
655  return Err;
656  } else if (Sec.Name.startswith("reloc.")) {
657  if (Error Err = parseRelocSection(Sec.Name, Ptr, End))
658  return Err;
659  }
660  return Error::success();
661 }
662 
663 Error WasmObjectFile::parseTypeSection(const uint8_t *Ptr, const uint8_t *End) {
664  uint32_t Count = readVaruint32(Ptr);
665  Signatures.reserve(Count);
666  while (Count--) {
669  uint8_t Form = readUint8(Ptr);
670  if (Form != wasm::WASM_TYPE_FUNC) {
671  return make_error<GenericBinaryError>("Invalid signature type",
673  }
674  uint32_t ParamCount = readVaruint32(Ptr);
675  Sig.ParamTypes.reserve(ParamCount);
676  while (ParamCount--) {
677  uint32_t ParamType = readUint8(Ptr);
678  Sig.ParamTypes.push_back(ParamType);
679  }
680  uint32_t ReturnCount = readVaruint32(Ptr);
681  if (ReturnCount) {
682  if (ReturnCount != 1) {
683  return make_error<GenericBinaryError>(
684  "Multiple return types not supported", object_error::parse_failed);
685  }
686  Sig.ReturnType = readUint8(Ptr);
687  }
688  Signatures.push_back(Sig);
689  }
690  if (Ptr != End)
691  return make_error<GenericBinaryError>("Type section ended prematurely",
693  return Error::success();
694 }
695 
696 Error WasmObjectFile::parseImportSection(const uint8_t *Ptr, const uint8_t *End) {
697  uint32_t Count = readVaruint32(Ptr);
698  Imports.reserve(Count);
699  for (uint32_t i = 0; i < Count; i++) {
700  wasm::WasmImport Im;
701  Im.Module = readString(Ptr);
702  Im.Field = readString(Ptr);
703  Im.Kind = readUint8(Ptr);
704  switch (Im.Kind) {
706  NumImportedFunctions++;
707  Im.SigIndex = readVaruint32(Ptr);
708  break;
710  NumImportedGlobals++;
711  Im.Global.Type = readUint8(Ptr);
712  Im.Global.Mutable = readVaruint1(Ptr);
713  break;
715  Im.Memory = readLimits(Ptr);
716  break;
718  Im.Table = readTable(Ptr);
720  return make_error<GenericBinaryError>("Invalid table element type",
722  break;
723  default:
724  return make_error<GenericBinaryError>(
725  "Unexpected import kind", object_error::parse_failed);
726  }
727  Imports.push_back(Im);
728  }
729  if (Ptr != End)
730  return make_error<GenericBinaryError>("Import section ended prematurely",
732  return Error::success();
733 }
734 
735 Error WasmObjectFile::parseFunctionSection(const uint8_t *Ptr, const uint8_t *End) {
736  uint32_t Count = readVaruint32(Ptr);
737  FunctionTypes.reserve(Count);
738  uint32_t NumTypes = Signatures.size();
739  while (Count--) {
740  uint32_t Type = readVaruint32(Ptr);
741  if (Type >= NumTypes)
742  return make_error<GenericBinaryError>("Invalid function type",
744  FunctionTypes.push_back(Type);
745  }
746  if (Ptr != End)
747  return make_error<GenericBinaryError>("Function section ended prematurely",
749  return Error::success();
750 }
751 
752 Error WasmObjectFile::parseTableSection(const uint8_t *Ptr, const uint8_t *End) {
753  uint32_t Count = readVaruint32(Ptr);
754  Tables.reserve(Count);
755  while (Count--) {
756  Tables.push_back(readTable(Ptr));
757  if (Tables.back().ElemType != wasm::WASM_TYPE_ANYFUNC) {
758  return make_error<GenericBinaryError>("Invalid table element type",
760  }
761  }
762  if (Ptr != End)
763  return make_error<GenericBinaryError>("Table section ended prematurely",
765  return Error::success();
766 }
767 
768 Error WasmObjectFile::parseMemorySection(const uint8_t *Ptr, const uint8_t *End) {
769  uint32_t Count = readVaruint32(Ptr);
770  Memories.reserve(Count);
771  while (Count--) {
772  Memories.push_back(readLimits(Ptr));
773  }
774  if (Ptr != End)
775  return make_error<GenericBinaryError>("Memory section ended prematurely",
777  return Error::success();
778 }
779 
780 Error WasmObjectFile::parseGlobalSection(const uint8_t *Ptr, const uint8_t *End) {
781  GlobalSection = Sections.size();
782  uint32_t Count = readVaruint32(Ptr);
783  Globals.reserve(Count);
784  while (Count--) {
785  wasm::WasmGlobal Global;
786  Global.Index = NumImportedGlobals + Globals.size();
787  Global.Type.Type = readUint8(Ptr);
788  Global.Type.Mutable = readVaruint1(Ptr);
789  if (Error Err = readInitExpr(Global.InitExpr, Ptr))
790  return Err;
791  Globals.push_back(Global);
792  }
793  if (Ptr != End)
794  return make_error<GenericBinaryError>("Global section ended prematurely",
796  return Error::success();
797 }
798 
799 Error WasmObjectFile::parseExportSection(const uint8_t *Ptr, const uint8_t *End) {
800  uint32_t Count = readVaruint32(Ptr);
801  Exports.reserve(Count);
802  for (uint32_t i = 0; i < Count; i++) {
803  wasm::WasmExport Ex;
804  Ex.Name = readString(Ptr);
805  Ex.Kind = readUint8(Ptr);
806  Ex.Index = readVaruint32(Ptr);
807  switch (Ex.Kind) {
809  if (!isValidFunctionIndex(Ex.Index))
810  return make_error<GenericBinaryError>("Invalid function export",
812  break;
814  if (!isValidGlobalIndex(Ex.Index))
815  return make_error<GenericBinaryError>("Invalid global export",
817  break;
820  break;
821  default:
822  return make_error<GenericBinaryError>(
823  "Unexpected export kind", object_error::parse_failed);
824  }
825  Exports.push_back(Ex);
826  }
827  if (Ptr != End)
828  return make_error<GenericBinaryError>("Export section ended prematurely",
830  return Error::success();
831 }
832 
833 bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const {
834  return Index < NumImportedFunctions + FunctionTypes.size();
835 }
836 
837 bool WasmObjectFile::isDefinedFunctionIndex(uint32_t Index) const {
838  return Index >= NumImportedFunctions && isValidFunctionIndex(Index);
839 }
840 
841 bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const {
842  return Index < NumImportedGlobals + Globals.size();
843 }
844 
845 bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const {
846  return Index >= NumImportedGlobals && isValidGlobalIndex(Index);
847 }
848 
849 bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
850  return Index < Symbols.size() && Symbols[Index].isTypeFunction();
851 }
852 
853 bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const {
854  return Index < Symbols.size() && Symbols[Index].isTypeGlobal();
855 }
856 
857 bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
858  return Index < Symbols.size() && Symbols[Index].isTypeData();
859 }
860 
861 bool WasmObjectFile::isValidSectionSymbol(uint32_t Index) const {
862  return Index < Symbols.size() && Symbols[Index].isTypeSection();
863 }
864 
865 wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) {
866  assert(isDefinedFunctionIndex(Index));
867  return Functions[Index - NumImportedFunctions];
868 }
869 
870 wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) {
871  assert(isDefinedGlobalIndex(Index));
872  return Globals[Index - NumImportedGlobals];
873 }
874 
875 Error WasmObjectFile::parseStartSection(const uint8_t *Ptr, const uint8_t *End) {
876  StartFunction = readVaruint32(Ptr);
877  if (!isValidFunctionIndex(StartFunction))
878  return make_error<GenericBinaryError>("Invalid start function",
880  return Error::success();
881 }
882 
883 Error WasmObjectFile::parseCodeSection(const uint8_t *Ptr, const uint8_t *End) {
884  CodeSection = Sections.size();
885  const uint8_t *CodeSectionStart = Ptr;
886  uint32_t FunctionCount = readVaruint32(Ptr);
887  if (FunctionCount != FunctionTypes.size()) {
888  return make_error<GenericBinaryError>("Invalid function count",
890  }
891 
892  while (FunctionCount--) {
894  const uint8_t *FunctionStart = Ptr;
895  uint32_t Size = readVaruint32(Ptr);
896  const uint8_t *FunctionEnd = Ptr + Size;
897 
898  Function.CodeOffset = Ptr - FunctionStart;
899  Function.Index = NumImportedFunctions + Functions.size();
900  Function.CodeSectionOffset = FunctionStart - CodeSectionStart;
901  Function.Size = FunctionEnd - FunctionStart;
902 
903  uint32_t NumLocalDecls = readVaruint32(Ptr);
904  Function.Locals.reserve(NumLocalDecls);
905  while (NumLocalDecls--) {
906  wasm::WasmLocalDecl Decl;
907  Decl.Count = readVaruint32(Ptr);
908  Decl.Type = readUint8(Ptr);
909  Function.Locals.push_back(Decl);
910  }
911 
912  uint32_t BodySize = FunctionEnd - Ptr;
913  Function.Body = ArrayRef<uint8_t>(Ptr, BodySize);
914  // This will be set later when reading in the linking metadata section.
915  Function.Comdat = UINT32_MAX;
916  Ptr += BodySize;
917  assert(Ptr == FunctionEnd);
918  Functions.push_back(Function);
919  }
920  if (Ptr != End)
921  return make_error<GenericBinaryError>("Code section ended prematurely",
923  return Error::success();
924 }
925 
926 Error WasmObjectFile::parseElemSection(const uint8_t *Ptr, const uint8_t *End) {
927  uint32_t Count = readVaruint32(Ptr);
928  ElemSegments.reserve(Count);
929  while (Count--) {
930  wasm::WasmElemSegment Segment;
931  Segment.TableIndex = readVaruint32(Ptr);
932  if (Segment.TableIndex != 0) {
933  return make_error<GenericBinaryError>("Invalid TableIndex",
935  }
936  if (Error Err = readInitExpr(Segment.Offset, Ptr))
937  return Err;
938  uint32_t NumElems = readVaruint32(Ptr);
939  while (NumElems--) {
940  Segment.Functions.push_back(readVaruint32(Ptr));
941  }
942  ElemSegments.push_back(Segment);
943  }
944  if (Ptr != End)
945  return make_error<GenericBinaryError>("Elem section ended prematurely",
947  return Error::success();
948 }
949 
950 Error WasmObjectFile::parseDataSection(const uint8_t *Ptr, const uint8_t *End) {
951  DataSection = Sections.size();
952  const uint8_t *Start = Ptr;
953  uint32_t Count = readVaruint32(Ptr);
954  DataSegments.reserve(Count);
955  while (Count--) {
956  WasmSegment Segment;
957  Segment.Data.MemoryIndex = readVaruint32(Ptr);
958  if (Error Err = readInitExpr(Segment.Data.Offset, Ptr))
959  return Err;
960  uint32_t Size = readVaruint32(Ptr);
961  if (Size > End - Ptr)
962  return make_error<GenericBinaryError>("Invalid segment size",
964  Segment.Data.Content = ArrayRef<uint8_t>(Ptr, Size);
965  // The rest of these Data fields are set later, when reading in the linking
966  // metadata section.
967  Segment.Data.Alignment = 0;
968  Segment.Data.Flags = 0;
969  Segment.Data.Comdat = UINT32_MAX;
970  Segment.SectionOffset = Ptr - Start;
971  Ptr += Size;
972  DataSegments.push_back(Segment);
973  }
974  if (Ptr != End)
975  return make_error<GenericBinaryError>("Data section ended prematurely",
977  return Error::success();
978 }
979 
980 const uint8_t *WasmObjectFile::getPtr(size_t Offset) const {
981  return reinterpret_cast<const uint8_t *>(getData().substr(Offset, 1).data());
982 }
983 
985  return Header;
986 }
987 
988 void WasmObjectFile::moveSymbolNext(DataRefImpl &Symb) const { Symb.d.a++; }
989 
991  uint32_t Result = SymbolRef::SF_None;
992  const WasmSymbol &Sym = getWasmSymbol(Symb);
993 
994  LLVM_DEBUG(dbgs() << "getSymbolFlags: ptr=" << &Sym << " " << Sym << "\n");
995  if (Sym.isBindingWeak())
996  Result |= SymbolRef::SF_Weak;
997  if (!Sym.isBindingLocal())
998  Result |= SymbolRef::SF_Global;
999  if (Sym.isHidden())
1000  Result |= SymbolRef::SF_Hidden;
1001  if (!Sym.isDefined())
1002  Result |= SymbolRef::SF_Undefined;
1003  if (Sym.isTypeFunction())
1004  Result |= SymbolRef::SF_Executable;
1005  return Result;
1006 }
1007 
1009  DataRefImpl Ref;
1010  Ref.d.a = 0;
1011  return BasicSymbolRef(Ref, this);
1012 }
1013 
1015  DataRefImpl Ref;
1016  Ref.d.a = Symbols.size();
1017  return BasicSymbolRef(Ref, this);
1018 }
1019 
1021  return Symbols[Symb.d.a];
1022 }
1023 
1024 const WasmSymbol &WasmObjectFile::getWasmSymbol(const SymbolRef &Symb) const {
1025  return getWasmSymbol(Symb.getRawDataRefImpl());
1026 }
1027 
1029  return getWasmSymbol(Symb).Info.Name;
1030 }
1031 
1033  return getSymbolValue(Symb);
1034 }
1035 
1037  switch (Sym.Info.Kind) {
1040  return Sym.Info.ElementIndex;
1042  // The value of a data symbol is the segment offset, plus the symbol
1043  // offset within the segment.
1044  uint32_t SegmentIndex = Sym.Info.DataRef.Segment;
1045  const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data;
1047  return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset;
1048  }
1050  return 0;
1051  }
1052  llvm_unreachable("invalid symbol type");
1053 }
1054 
1056  return getWasmSymbolValue(getWasmSymbol(Symb));
1057 }
1058 
1060  llvm_unreachable("not yet implemented");
1061  return 0;
1062 }
1063 
1065  llvm_unreachable("not yet implemented");
1066  return 0;
1067 }
1068 
1071  const WasmSymbol &Sym = getWasmSymbol(Symb);
1072 
1073  switch (Sym.Info.Kind) {
1075  return SymbolRef::ST_Function;
1077  return SymbolRef::ST_Other;
1079  return SymbolRef::ST_Data;
1081  return SymbolRef::ST_Debug;
1082  }
1083 
1084  llvm_unreachable("Unknown WasmSymbol::SymbolType");
1085  return SymbolRef::ST_Other;
1086 }
1087 
1090  const WasmSymbol& Sym = getWasmSymbol(Symb);
1091  if (Sym.isUndefined())
1092  return section_end();
1093 
1094  DataRefImpl Ref;
1095  switch (Sym.Info.Kind) {
1097  Ref.d.a = CodeSection;
1098  break;
1100  Ref.d.a = GlobalSection;
1101  break;
1103  Ref.d.a = DataSection;
1104  break;
1106  Ref.d.a = Sym.Info.ElementIndex;
1107  break;
1108  }
1109  default:
1110  llvm_unreachable("Unknown WasmSymbol::SymbolType");
1111  }
1112  return section_iterator(SectionRef(Ref, this));
1113 }
1114 
1115 void WasmObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; }
1116 
1118  StringRef &Res) const {
1119  const WasmSection &S = Sections[Sec.d.a];
1120 #define ECase(X) \
1121  case wasm::WASM_SEC_##X: \
1122  Res = #X; \
1123  break
1124  switch (S.Type) {
1125  ECase(TYPE);
1126  ECase(IMPORT);
1127  ECase(FUNCTION);
1128  ECase(TABLE);
1129  ECase(MEMORY);
1130  ECase(GLOBAL);
1131  ECase(EXPORT);
1132  ECase(START);
1133  ECase(ELEM);
1134  ECase(CODE);
1135  ECase(DATA);
1136  case wasm::WASM_SEC_CUSTOM:
1137  Res = S.Name;
1138  break;
1139  default:
1141  }
1142 #undef ECase
1143  return std::error_code();
1144 }
1145 
1146 uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const { return 0; }
1147 
1149  return Sec.d.a;
1150 }
1151 
1153  const WasmSection &S = Sections[Sec.d.a];
1154  return S.Content.size();
1155 }
1156 
1158  StringRef &Res) const {
1159  const WasmSection &S = Sections[Sec.d.a];
1160  // This will never fail since wasm sections can never be empty (user-sections
1161  // must have a name and non-user sections each have a defined structure).
1162  Res = StringRef(reinterpret_cast<const char *>(S.Content.data()),
1163  S.Content.size());
1164  return std::error_code();
1165 }
1166 
1168  return 1;
1169 }
1170 
1172  return false;
1173 }
1174 
1176  return getWasmSection(Sec).Type == wasm::WASM_SEC_CODE;
1177 }
1178 
1180  return getWasmSection(Sec).Type == wasm::WASM_SEC_DATA;
1181 }
1182 
1183 bool WasmObjectFile::isSectionBSS(DataRefImpl Sec) const { return false; }
1184 
1185 bool WasmObjectFile::isSectionVirtual(DataRefImpl Sec) const { return false; }
1186 
1187 bool WasmObjectFile::isSectionBitcode(DataRefImpl Sec) const { return false; }
1188 
1190  DataRefImpl RelocRef;
1191  RelocRef.d.a = Ref.d.a;
1192  RelocRef.d.b = 0;
1193  return relocation_iterator(RelocationRef(RelocRef, this));
1194 }
1195 
1197  const WasmSection &Sec = getWasmSection(Ref);
1198  DataRefImpl RelocRef;
1199  RelocRef.d.a = Ref.d.a;
1200  RelocRef.d.b = Sec.Relocations.size();
1201  return relocation_iterator(RelocationRef(RelocRef, this));
1202 }
1203 
1205  Rel.d.b++;
1206 }
1207 
1209  const wasm::WasmRelocation &Rel = getWasmRelocation(Ref);
1210  return Rel.Offset;
1211 }
1212 
1214  const wasm::WasmRelocation &Rel = getWasmRelocation(Ref);
1215  if (Rel.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB)
1216  return symbol_end();
1217  DataRefImpl Sym;
1218  Sym.d.a = Rel.Index;
1219  Sym.d.b = 0;
1220  return symbol_iterator(SymbolRef(Sym, this));
1221 }
1222 
1224  const wasm::WasmRelocation &Rel = getWasmRelocation(Ref);
1225  return Rel.Type;
1226 }
1227 
1229  DataRefImpl Ref, SmallVectorImpl<char> &Result) const {
1230  const wasm::WasmRelocation& Rel = getWasmRelocation(Ref);
1231  StringRef Res = "Unknown";
1232 
1233 #define WASM_RELOC(name, value) \
1234  case wasm::name: \
1235  Res = #name; \
1236  break;
1237 
1238  switch (Rel.Type) {
1239 #include "llvm/BinaryFormat/WasmRelocs.def"
1240  }
1241 
1242 #undef WASM_RELOC
1243 
1244  Result.append(Res.begin(), Res.end());
1245 }
1246 
1248  DataRefImpl Ref;
1249  Ref.d.a = 0;
1250  return section_iterator(SectionRef(Ref, this));
1251 }
1252 
1254  DataRefImpl Ref;
1255  Ref.d.a = Sections.size();
1256  return section_iterator(SectionRef(Ref, this));
1257 }
1258 
1259 uint8_t WasmObjectFile::getBytesInAddress() const { return 4; }
1260 
1262 
1264 
1266  return SubtargetFeatures();
1267 }
1268 
1270  return HasLinkingSection;
1271 }
1272 
1274  assert(Ref.d.a < Sections.size());
1275  return Sections[Ref.d.a];
1276 }
1277 
1278 const WasmSection &
1280  return getWasmSection(Section.getRawDataRefImpl());
1281 }
1282 
1283 const wasm::WasmRelocation &
1285  return getWasmRelocation(Ref.getRawDataRefImpl());
1286 }
1287 
1288 const wasm::WasmRelocation &
1290  assert(Ref.d.a < Sections.size());
1291  const WasmSection& Sec = Sections[Ref.d.a];
1292  assert(Ref.d.b < Sec.Relocations.size());
1293  return Sec.Relocations[Ref.d.b];
1294 }
bool isTypeData() const
Definition: Wasm.h:51
bool isSectionText(DataRefImpl Sec) const override
uint64_t getRelocationType(DataRefImpl Rel) const override
std::vector< WasmInitFunc > InitFunctions
Definition: Wasm.h:168
uint64_t getSectionAddress(DataRefImpl Sec) const override
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override
WasmSymbolType
Definition: Wasm.h:252
union llvm::wasm::WasmInitExpr::@133 Value
#define VARUINT1_MAX
friend class SymbolRef
Definition: ObjectFile.h:208
StringRef getFileFormatName() const override
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:115
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
uint64_t getSectionSize(DataRefImpl Sec) const override
section_iterator section_begin() const override
const unsigned WASM_SYMBOL_BINDING_LOCAL
Definition: Wasm.h:264
friend class SectionRef
Definition: ObjectFile.h:222
const WasmSymbol & getWasmSymbol(const DataRefImpl &Symb) const
WasmGlobalType Type
Definition: Wasm.h:77
Implements a dense probed hash-table based set.
Definition: DenseSet.h:221
static Error readInitExpr(wasm::WasmInitExpr &Expr, const uint8_t *&Ptr)
uint32_t SectionOffset
Definition: Wasm.h:109
const uint32_t WasmMetadataVersion
Definition: Wasm.h:28
static wasm::WasmLimits readLimits(const uint8_t *&Ptr)
This class is the base class for all object file types.
Definition: ObjectFile.h:190
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
std::error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override
std::vector< StringRef > Comdats
Definition: Wasm.h:169
std::error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override
static StringRef readString(const uint8_t *&Ptr)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:128
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
StringRef SymbolName
Definition: Wasm.h:106
static int64_t readVarint64(const uint8_t *&Ptr)
const unsigned WASM_SYMBOL_UNDEFINED
Definition: Wasm.h:267
std::vector< wasm::WasmRelocation > Relocations
Definition: Wasm.h:105
std::string toString(Error E)
Write all error messages (if any) in E to a string.
Definition: Error.h:947
uint64_t getRelocationOffset(DataRefImpl Rel) const override
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
DataRefImpl getRawDataRefImpl() const
Definition: SymbolicFile.h:205
static int32_t readFloat32(const uint8_t *&Ptr)
WasmTable Table
Definition: Wasm.h:89
int64_t decodeSLEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a SLEB128 value.
Definition: LEB128.h:162
This is a value type class that represents a single relocation in the list of relocations in the obje...
Definition: ObjectFile.h:52
The access may reference the value stored in memory.
static Error readSection(WasmSection &Section, const uint8_t *&Ptr, const uint8_t *Start, const uint8_t *Eof)
StringRef Module
Definition: Wasm.h:83
uint32_t CodeOffset
Definition: Wasm.h:105
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
Definition: Compiler.h:449
static int64_t readLEB128(const uint8_t *&Ptr)
const uint32_t WasmVersion
Definition: Wasm.h:26
ArrayRef< uint8_t > Content
Definition: Wasm.h:114
content_iterator< SectionRef > section_iterator
Definition: ObjectFile.h:48
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:267
Class to represent function types.
Definition: DerivedTypes.h:103
ArrayRef< uint8_t > Body
Definition: Wasm.h:102
wasm::WasmDataSegment Data
Definition: Wasm.h:110
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:133
static uint32_t readVaruint32(const uint8_t *&Ptr)
uint32_t Initial
Definition: Wasm.h:50
bool isSectionBitcode(DataRefImpl Sec) const override
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
Triple::ArchType getArch() const override
uint64_t getSectionIndex(DataRefImpl Sec) const override
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:598
uint32_t SigIndex
Definition: Wasm.h:87
WasmLimits Memory
Definition: Wasm.h:90
void moveSectionNext(DataRefImpl &Sec) const override
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
std::vector< uint32_t > Functions
Definition: Wasm.h:124
bool isBindingLocal() const
Definition: Wasm.h:75
static int64_t readFloat64(const uint8_t *&Ptr)
Import information from summary.
LLVM_DUMP_METHOD void dump() const
ArrayRef< uint8_t > Content
Definition: Wasm.h:104
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
uint64_t getWasmSymbolValue(const WasmSymbol &Sym) const
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
section_iterator section_end() const override
static uint8_t readOpcode(const uint8_t *&Ptr)
uint8_t ElemType
Definition: Wasm.h:55
const unsigned WASM_SYMBOL_BINDING_WEAK
Definition: Wasm.h:263
uint32_t CodeSectionOffset
Definition: Wasm.h:103
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a ULEB128 value.
Definition: LEB128.h:129
static int32_t readVarint32(const uint8_t *&Ptr)
static const unsigned End
WasmInitExpr Offset
Definition: Wasm.h:113
const wasm::WasmRelocation & getWasmRelocation(const RelocationRef &Ref) const
uint64_t getSectionAlignment(DataRefImpl Sec) const override
bool isSectionBSS(DataRefImpl Sec) const override
StringRef DebugName
Definition: Wasm.h:107
static uint8_t readVaruint1(const uint8_t *&Ptr)
DataRefImpl getRawDataRefImpl() const
Definition: ObjectFile.h:457
bool isSectionData(DataRefImpl Sec) const override
bool isDefined() const
Definition: Wasm.h:61
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::pair< typename base::iterator, bool > insert(StringRef Key)
Definition: StringSet.h:38
const T * data() const
Definition: ArrayRef.h:146
struct llvm::object::DataRefImpl::@258 d
basic_symbol_iterator symbol_begin() const override
static Expected< std::unique_ptr< WasmObjectFile > > createWasmObjectFile(MemoryBufferRef Object)
SubtargetFeatures getFeatures() const override
bool isSectionCompressed(DataRefImpl Sec) const override
static ErrorSuccess success()
Create a success value.
Definition: Error.h:313
static uint64_t readULEB128(const uint8_t *&Ptr)
friend class RelocationRef
Definition: ObjectFile.h:246
WasmInitExpr InitExpr
Definition: Wasm.h:78
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
Definition: STLExtras.h:1032
std::vector< uint8_t > ParamTypes
Definition: Wasm.h:38
void moveSymbolNext(DataRefImpl &Symb) const override
uint64_t getSymbolValue(DataRefImpl Symb) const
Definition: ObjectFile.cpp:51
const wasm::WasmSymbolInfo & Info
Definition: Wasm.h:43
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
bool isTypeFunction() const
Definition: Wasm.h:47
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
MemoryBufferRef Data
Definition: Binary.h:37
Manages the enabling and disabling of subtarget specific features.
const wasm::WasmObjectHeader & getHeader() const
Helper for Errors used as out-parameters.
Definition: Error.h:1002
This is a value type class that represents a single symbol in the list of symbols in the object file...
Definition: ObjectFile.h:129
iterator begin() const
Definition: StringRef.h:106
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:396
WasmLimits Limits
Definition: Wasm.h:56
WasmGlobalType Global
Definition: Wasm.h:88
const unsigned WASM_SYMBOL_BINDING_MASK
Definition: Wasm.h:259
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
void moveRelocationNext(DataRefImpl &Rel) const override
#define I(x, y, z)
Definition: MD5.cpp:58
uint32_t read32le(const void *P)
Definition: Endian.h:369
bool isHidden() const
Definition: Wasm.h:83
This is a value type class that represents a single symbol in the list of symbols in the object file...
Definition: SymbolicFile.h:99
static wasm::WasmTable readTable(const uint8_t *&Ptr)
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
uint32_t Index
Definition: Wasm.h:45
static uint32_t readUint32(const uint8_t *&Ptr)
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isUndefined() const
Definition: Wasm.h:63
WasmDataReference DataRef
Definition: Wasm.h:157
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
uint32_t Index
Definition: Wasm.h:76
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
content_iterator< RelocationRef > relocation_iterator
Definition: ObjectFile.h:77
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition: StringSet.h:28
const char SectionName[]
Definition: AMDGPUPTNote.h:24
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
StringRef Name
Definition: Wasm.h:43
const WasmSection & getWasmSection(const SectionRef &Section) const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
bool isSectionVirtual(DataRefImpl Sec) const override
StringRef SymbolName
Definition: Wasm.h:79
Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override
uint32_t getSymbolFlags(DataRefImpl Symb) const override
#define LLVM_DEBUG(X)
Definition: Debug.h:119
static uint8_t readUint8(const uint8_t *&Ptr)
std::vector< WasmSymbolInfo > SymbolTable
Definition: Wasm.h:170
iterator end() const
Definition: StringRef.h:108
std::vector< WasmLocalDecl > Locals
Definition: Wasm.h:101
bool isBindingWeak() const
Definition: Wasm.h:67
StringRef getData() const
Definition: Binary.cpp:39
WasmInitExpr Offset
Definition: Wasm.h:123
uint32_t Maximum
Definition: Wasm.h:51
#define ECase(X)
relocation_iterator section_rel_end(DataRefImpl Sec) const override
DataRefImpl getRawDataRefImpl() const
Definition: ObjectFile.h:495
StringRef Field
Definition: Wasm.h:84
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:81
WasmObjectFile(MemoryBufferRef Object, Error &Err)
void print(raw_ostream &Out) const
basic_symbol_iterator symbol_end() const override