LLVM  14.0.0git
WasmObjectFile.cpp
Go to the documentation of this file.
1 //===- WasmObjectFile.cpp - Wasm object file implementation ---------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/ADT/ArrayRef.h"
10 #include "llvm/ADT/DenseSet.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/SmallSet.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/ADT/StringSet.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/ADT/Triple.h"
17 #include "llvm/BinaryFormat/Wasm.h"
19 #include "llvm/Object/Binary.h"
20 #include "llvm/Object/Error.h"
21 #include "llvm/Object/ObjectFile.h"
23 #include "llvm/Object/Wasm.h"
24 #include "llvm/Support/Endian.h"
25 #include "llvm/Support/Error.h"
27 #include "llvm/Support/LEB128.h"
29 #include <algorithm>
30 #include <cassert>
31 #include <cstdint>
32 #include <cstring>
33 #include <system_error>
34 
35 #define DEBUG_TYPE "wasm-object"
36 
37 using namespace llvm;
38 using namespace object;
39 
40 void WasmSymbol::print(raw_ostream &Out) const {
41  Out << "Name=" << Info.Name
42  << ", Kind=" << toString(wasm::WasmSymbolType(Info.Kind)) << ", Flags=0x"
44  if (!isTypeData()) {
45  Out << ", ElemIndex=" << Info.ElementIndex;
46  } else if (isDefined()) {
47  Out << ", Segment=" << Info.DataRef.Segment;
48  Out << ", Offset=" << Info.DataRef.Offset;
49  Out << ", Size=" << Info.DataRef.Size;
50  }
51 }
52 
53 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
55 #endif
56 
59  Error Err = Error::success();
60  auto ObjectFile = std::make_unique<WasmObjectFile>(Buffer, Err);
61  if (Err)
62  return std::move(Err);
63 
64  return std::move(ObjectFile);
65 }
66 
67 #define VARINT7_MAX ((1 << 7) - 1)
68 #define VARINT7_MIN (-(1 << 7))
69 #define VARUINT7_MAX (1 << 7)
70 #define VARUINT1_MAX (1)
71 
72 static uint8_t readUint8(WasmObjectFile::ReadContext &Ctx) {
73  if (Ctx.Ptr == Ctx.End)
74  report_fatal_error("EOF while reading uint8");
75  return *Ctx.Ptr++;
76 }
77 
78 static uint32_t readUint32(WasmObjectFile::ReadContext &Ctx) {
79  if (Ctx.Ptr + 4 > Ctx.End)
80  report_fatal_error("EOF while reading uint32");
81  uint32_t Result = support::endian::read32le(Ctx.Ptr);
82  Ctx.Ptr += 4;
83  return Result;
84 }
85 
86 static int32_t readFloat32(WasmObjectFile::ReadContext &Ctx) {
87  if (Ctx.Ptr + 4 > Ctx.End)
88  report_fatal_error("EOF while reading float64");
89  int32_t Result = 0;
90  memcpy(&Result, Ctx.Ptr, sizeof(Result));
91  Ctx.Ptr += sizeof(Result);
92  return Result;
93 }
94 
95 static int64_t readFloat64(WasmObjectFile::ReadContext &Ctx) {
96  if (Ctx.Ptr + 8 > Ctx.End)
97  report_fatal_error("EOF while reading float64");
98  int64_t Result = 0;
99  memcpy(&Result, Ctx.Ptr, sizeof(Result));
100  Ctx.Ptr += sizeof(Result);
101  return Result;
102 }
103 
104 static uint64_t readULEB128(WasmObjectFile::ReadContext &Ctx) {
105  unsigned Count;
106  const char *Error = nullptr;
107  uint64_t Result = decodeULEB128(Ctx.Ptr, &Count, Ctx.End, &Error);
108  if (Error)
110  Ctx.Ptr += Count;
111  return Result;
112 }
113 
114 static StringRef readString(WasmObjectFile::ReadContext &Ctx) {
115  uint32_t StringLen = readULEB128(Ctx);
116  if (Ctx.Ptr + StringLen > Ctx.End)
117  report_fatal_error("EOF while reading string");
118  StringRef Return =
119  StringRef(reinterpret_cast<const char *>(Ctx.Ptr), StringLen);
120  Ctx.Ptr += StringLen;
121  return Return;
122 }
123 
124 static int64_t readLEB128(WasmObjectFile::ReadContext &Ctx) {
125  unsigned Count;
126  const char *Error = nullptr;
127  uint64_t Result = decodeSLEB128(Ctx.Ptr, &Count, Ctx.End, &Error);
128  if (Error)
130  Ctx.Ptr += Count;
131  return Result;
132 }
133 
134 static uint8_t readVaruint1(WasmObjectFile::ReadContext &Ctx) {
135  int64_t Result = readLEB128(Ctx);
136  if (Result > VARUINT1_MAX || Result < 0)
137  report_fatal_error("LEB is outside Varuint1 range");
138  return Result;
139 }
140 
141 static int32_t readVarint32(WasmObjectFile::ReadContext &Ctx) {
142  int64_t Result = readLEB128(Ctx);
143  if (Result > INT32_MAX || Result < INT32_MIN)
144  report_fatal_error("LEB is outside Varint32 range");
145  return Result;
146 }
147 
148 static uint32_t readVaruint32(WasmObjectFile::ReadContext &Ctx) {
149  uint64_t Result = readULEB128(Ctx);
150  if (Result > UINT32_MAX)
151  report_fatal_error("LEB is outside Varuint32 range");
152  return Result;
153 }
154 
155 static int64_t readVarint64(WasmObjectFile::ReadContext &Ctx) {
156  return readLEB128(Ctx);
157 }
158 
159 static uint64_t readVaruint64(WasmObjectFile::ReadContext &Ctx) {
160  return readULEB128(Ctx);
161 }
162 
163 static uint8_t readOpcode(WasmObjectFile::ReadContext &Ctx) {
164  return readUint8(Ctx);
165 }
166 
168  WasmObjectFile::ReadContext &Ctx) {
169  Expr.Opcode = readOpcode(Ctx);
170 
171  switch (Expr.Opcode) {
173  Expr.Value.Int32 = readVarint32(Ctx);
174  break;
176  Expr.Value.Int64 = readVarint64(Ctx);
177  break;
179  Expr.Value.Float32 = readFloat32(Ctx);
180  break;
182  Expr.Value.Float64 = readFloat64(Ctx);
183  break;
185  Expr.Value.Global = readULEB128(Ctx);
186  break;
188  wasm::ValType Ty = static_cast<wasm::ValType>(readULEB128(Ctx));
189  if (Ty != wasm::ValType::EXTERNREF) {
190  return make_error<GenericBinaryError>("invalid type for ref.null",
192  }
193  break;
194  }
195  default:
196  return make_error<GenericBinaryError>("invalid opcode in init_expr",
198  }
199 
200  uint8_t EndOpcode = readOpcode(Ctx);
201  if (EndOpcode != wasm::WASM_OPCODE_END) {
202  return make_error<GenericBinaryError>("invalid init_expr",
204  }
205  return Error::success();
206 }
207 
208 static wasm::WasmLimits readLimits(WasmObjectFile::ReadContext &Ctx) {
209  wasm::WasmLimits Result;
210  Result.Flags = readVaruint32(Ctx);
211  Result.Minimum = readVaruint64(Ctx);
212  if (Result.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
213  Result.Maximum = readVaruint64(Ctx);
214  return Result;
215 }
216 
217 static wasm::WasmTableType readTableType(WasmObjectFile::ReadContext &Ctx) {
218  wasm::WasmTableType TableType;
219  TableType.ElemType = readUint8(Ctx);
220  TableType.Limits = readLimits(Ctx);
221  return TableType;
222 }
223 
224 static Error readSection(WasmSection &Section, WasmObjectFile::ReadContext &Ctx,
225  WasmSectionOrderChecker &Checker) {
226  Section.Offset = Ctx.Ptr - Ctx.Start;
227  Section.Type = readUint8(Ctx);
228  LLVM_DEBUG(dbgs() << "readSection type=" << Section.Type << "\n");
229  uint32_t Size = readVaruint32(Ctx);
230  if (Size == 0)
231  return make_error<StringError>("zero length section",
233  if (Ctx.Ptr + Size > Ctx.End)
234  return make_error<StringError>("section too large",
236  if (Section.Type == wasm::WASM_SEC_CUSTOM) {
237  WasmObjectFile::ReadContext SectionCtx;
238  SectionCtx.Start = Ctx.Ptr;
239  SectionCtx.Ptr = Ctx.Ptr;
240  SectionCtx.End = Ctx.Ptr + Size;
241 
242  Section.Name = readString(SectionCtx);
243 
244  uint32_t SectionNameSize = SectionCtx.Ptr - SectionCtx.Start;
245  Ctx.Ptr += SectionNameSize;
246  Size -= SectionNameSize;
247  }
248 
249  if (!Checker.isValidSectionOrder(Section.Type, Section.Name)) {
250  return make_error<StringError>("out of order section type: " +
251  llvm::to_string(Section.Type),
253  }
254 
255  Section.Content = ArrayRef<uint8_t>(Ctx.Ptr, Size);
256  Ctx.Ptr += Size;
257  return Error::success();
258 }
259 
261  : ObjectFile(Binary::ID_Wasm, Buffer) {
262  ErrorAsOutParameter ErrAsOutParam(&Err);
263  Header.Magic = getData().substr(0, 4);
264  if (Header.Magic != StringRef("\0asm", 4)) {
265  Err = make_error<StringError>("invalid magic number",
267  return;
268  }
269 
270  ReadContext Ctx;
271  Ctx.Start = getData().bytes_begin();
272  Ctx.Ptr = Ctx.Start + 4;
273  Ctx.End = Ctx.Start + getData().size();
274 
275  if (Ctx.Ptr + 4 > Ctx.End) {
276  Err = make_error<StringError>("missing version number",
278  return;
279  }
280 
281  Header.Version = readUint32(Ctx);
282  if (Header.Version != wasm::WasmVersion) {
283  Err = make_error<StringError>("invalid version number: " +
284  Twine(Header.Version),
286  return;
287  }
288 
289  WasmSectionOrderChecker Checker;
290  while (Ctx.Ptr < Ctx.End) {
291  WasmSection Sec;
292  if ((Err = readSection(Sec, Ctx, Checker)))
293  return;
294  if ((Err = parseSection(Sec)))
295  return;
296 
297  Sections.push_back(Sec);
298  }
299 }
300 
301 Error WasmObjectFile::parseSection(WasmSection &Sec) {
302  ReadContext Ctx;
303  Ctx.Start = Sec.Content.data();
304  Ctx.End = Ctx.Start + Sec.Content.size();
305  Ctx.Ptr = Ctx.Start;
306  switch (Sec.Type) {
308  return parseCustomSection(Sec, Ctx);
309  case wasm::WASM_SEC_TYPE:
310  return parseTypeSection(Ctx);
312  return parseImportSection(Ctx);
314  return parseFunctionSection(Ctx);
316  return parseTableSection(Ctx);
318  return parseMemorySection(Ctx);
319  case wasm::WASM_SEC_TAG:
320  return parseTagSection(Ctx);
322  return parseGlobalSection(Ctx);
324  return parseExportSection(Ctx);
326  return parseStartSection(Ctx);
327  case wasm::WASM_SEC_ELEM:
328  return parseElemSection(Ctx);
329  case wasm::WASM_SEC_CODE:
330  return parseCodeSection(Ctx);
331  case wasm::WASM_SEC_DATA:
332  return parseDataSection(Ctx);
334  return parseDataCountSection(Ctx);
335  default:
336  return make_error<GenericBinaryError>(
337  "invalid section type: " + Twine(Sec.Type), object_error::parse_failed);
338  }
339 }
340 
341 Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) {
342  // Legacy "dylink" section support.
343  // See parseDylink0Section for the current "dylink.0" section parsing.
344  HasDylinkSection = true;
345  DylinkInfo.MemorySize = readVaruint32(Ctx);
346  DylinkInfo.MemoryAlignment = readVaruint32(Ctx);
347  DylinkInfo.TableSize = readVaruint32(Ctx);
348  DylinkInfo.TableAlignment = readVaruint32(Ctx);
349  uint32_t Count = readVaruint32(Ctx);
350  while (Count--) {
351  DylinkInfo.Needed.push_back(readString(Ctx));
352  }
353 
354  if (Ctx.Ptr != Ctx.End)
355  return make_error<GenericBinaryError>("dylink section ended prematurely",
357  return Error::success();
358 }
359 
360 Error WasmObjectFile::parseDylink0Section(ReadContext &Ctx) {
361  // See
362  // https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
363  HasDylinkSection = true;
364 
365  const uint8_t *OrigEnd = Ctx.End;
366  while (Ctx.Ptr < OrigEnd) {
367  Ctx.End = OrigEnd;
368  uint8_t Type = readUint8(Ctx);
369  uint32_t Size = readVaruint32(Ctx);
370  LLVM_DEBUG(dbgs() << "readSubsection type=" << int(Type) << " size=" << Size
371  << "\n");
372  Ctx.End = Ctx.Ptr + Size;
373  uint32_t Count;
374  switch (Type) {
376  DylinkInfo.MemorySize = readVaruint32(Ctx);
377  DylinkInfo.MemoryAlignment = readVaruint32(Ctx);
378  DylinkInfo.TableSize = readVaruint32(Ctx);
379  DylinkInfo.TableAlignment = readVaruint32(Ctx);
380  break;
382  Count = readVaruint32(Ctx);
383  while (Count--) {
384  DylinkInfo.Needed.push_back(readString(Ctx));
385  }
386  break;
388  uint32_t Count = readVaruint32(Ctx);
389  while (Count--) {
390  DylinkInfo.ExportInfo.push_back({readString(Ctx), readVaruint32(Ctx)});
391  }
392  break;
393  }
395  uint32_t Count = readVaruint32(Ctx);
396  while (Count--) {
397  DylinkInfo.ImportInfo.push_back(
398  {readString(Ctx), readString(Ctx), readVaruint32(Ctx)});
399  }
400  break;
401  }
402  default:
403  LLVM_DEBUG(dbgs() << "unknown dylink.0 sub-section: " << Type << "\n");
404  Ctx.Ptr += Size;
405  break;
406  }
407  if (Ctx.Ptr != Ctx.End) {
408  return make_error<GenericBinaryError>(
409  "dylink.0 sub-section ended prematurely", object_error::parse_failed);
410  }
411  }
412 
413  if (Ctx.Ptr != Ctx.End)
414  return make_error<GenericBinaryError>("dylink.0 section ended prematurely",
416  return Error::success();
417 }
418 
419 Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
420  llvm::DenseSet<uint64_t> SeenFunctions;
421  llvm::DenseSet<uint64_t> SeenGlobals;
422  llvm::DenseSet<uint64_t> SeenSegments;
423  if (Functions.size() && !SeenCodeSection) {
424  return make_error<GenericBinaryError>("names must come after code section",
426  }
427 
428  while (Ctx.Ptr < Ctx.End) {
429  uint8_t Type = readUint8(Ctx);
430  uint32_t Size = readVaruint32(Ctx);
431  const uint8_t *SubSectionEnd = Ctx.Ptr + Size;
432  switch (Type) {
436  uint32_t Count = readVaruint32(Ctx);
437  while (Count--) {
439  StringRef Name = readString(Ctx);
442  if (!SeenFunctions.insert(Index).second)
443  return make_error<GenericBinaryError>(
444  "function named more than once", object_error::parse_failed);
445  if (!isValidFunctionIndex(Index) || Name.empty())
446  return make_error<GenericBinaryError>("invalid name entry",
448 
449  if (isDefinedFunctionIndex(Index))
450  getDefinedFunction(Index).DebugName = Name;
451  } else if (Type == wasm::WASM_NAMES_GLOBAL) {
452  nameType = wasm::NameType::GLOBAL;
453  if (!SeenGlobals.insert(Index).second)
454  return make_error<GenericBinaryError>("global named more than once",
456  if (!isValidGlobalIndex(Index) || Name.empty())
457  return make_error<GenericBinaryError>("invalid name entry",
459  } else {
460  nameType = wasm::NameType::DATA_SEGMENT;
461  if (!SeenSegments.insert(Index).second)
462  return make_error<GenericBinaryError>(
463  "segment named more than once", object_error::parse_failed);
464  if (Index > DataSegments.size())
465  return make_error<GenericBinaryError>("invalid named data segment",
467  }
468  DebugNames.push_back(wasm::WasmDebugName{nameType, Index, Name});
469  }
470  break;
471  }
472  // Ignore local names for now
474  default:
475  Ctx.Ptr += Size;
476  break;
477  }
478  if (Ctx.Ptr != SubSectionEnd)
479  return make_error<GenericBinaryError>(
480  "name sub-section ended prematurely", object_error::parse_failed);
481  }
482 
483  if (Ctx.Ptr != Ctx.End)
484  return make_error<GenericBinaryError>("name section ended prematurely",
486  return Error::success();
487 }
488 
489 Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {
490  HasLinkingSection = true;
491  if (Functions.size() && !SeenCodeSection) {
492  return make_error<GenericBinaryError>(
493  "linking data must come after code section",
495  }
496 
497  LinkingData.Version = readVaruint32(Ctx);
498  if (LinkingData.Version != wasm::WasmMetadataVersion) {
499  return make_error<GenericBinaryError>(
500  "unexpected metadata version: " + Twine(LinkingData.Version) +
501  " (Expected: " + Twine(wasm::WasmMetadataVersion) + ")",
503  }
504 
505  const uint8_t *OrigEnd = Ctx.End;
506  while (Ctx.Ptr < OrigEnd) {
507  Ctx.End = OrigEnd;
508  uint8_t Type = readUint8(Ctx);
509  uint32_t Size = readVaruint32(Ctx);
510  LLVM_DEBUG(dbgs() << "readSubsection type=" << int(Type) << " size=" << Size
511  << "\n");
512  Ctx.End = Ctx.Ptr + Size;
513  switch (Type) {
515  if (Error Err = parseLinkingSectionSymtab(Ctx))
516  return Err;
517  break;
519  uint32_t Count = readVaruint32(Ctx);
520  if (Count > DataSegments.size())
521  return make_error<GenericBinaryError>("too many segment names",
523  for (uint32_t I = 0; I < Count; I++) {
524  DataSegments[I].Data.Name = readString(Ctx);
525  DataSegments[I].Data.Alignment = readVaruint32(Ctx);
526  DataSegments[I].Data.LinkingFlags = readVaruint32(Ctx);
527  }
528  break;
529  }
530  case wasm::WASM_INIT_FUNCS: {
531  uint32_t Count = readVaruint32(Ctx);
532  LinkingData.InitFunctions.reserve(Count);
533  for (uint32_t I = 0; I < Count; I++) {
535  Init.Priority = readVaruint32(Ctx);
536  Init.Symbol = readVaruint32(Ctx);
537  if (!isValidFunctionSymbol(Init.Symbol))
538  return make_error<GenericBinaryError>("invalid function symbol: " +
539  Twine(Init.Symbol),
541  LinkingData.InitFunctions.emplace_back(Init);
542  }
543  break;
544  }
546  if (Error Err = parseLinkingSectionComdat(Ctx))
547  return Err;
548  break;
549  default:
550  Ctx.Ptr += Size;
551  break;
552  }
553  if (Ctx.Ptr != Ctx.End)
554  return make_error<GenericBinaryError>(
555  "linking sub-section ended prematurely", object_error::parse_failed);
556  }
557  if (Ctx.Ptr != OrigEnd)
558  return make_error<GenericBinaryError>("linking section ended prematurely",
560  return Error::success();
561 }
562 
563 Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
564  uint32_t Count = readVaruint32(Ctx);
565  LinkingData.SymbolTable.reserve(Count);
566  Symbols.reserve(Count);
567  StringSet<> SymbolNames;
568 
569  std::vector<wasm::WasmImport *> ImportedGlobals;
570  std::vector<wasm::WasmImport *> ImportedFunctions;
571  std::vector<wasm::WasmImport *> ImportedTags;
572  std::vector<wasm::WasmImport *> ImportedTables;
573  ImportedGlobals.reserve(Imports.size());
574  ImportedFunctions.reserve(Imports.size());
575  ImportedTags.reserve(Imports.size());
576  ImportedTables.reserve(Imports.size());
577  for (auto &I : Imports) {
578  if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
579  ImportedFunctions.emplace_back(&I);
580  else if (I.Kind == wasm::WASM_EXTERNAL_GLOBAL)
581  ImportedGlobals.emplace_back(&I);
582  else if (I.Kind == wasm::WASM_EXTERNAL_TAG)
583  ImportedTags.emplace_back(&I);
584  else if (I.Kind == wasm::WASM_EXTERNAL_TABLE)
585  ImportedTables.emplace_back(&I);
586  }
587 
588  while (Count--) {
590  const wasm::WasmSignature *Signature = nullptr;
591  const wasm::WasmGlobalType *GlobalType = nullptr;
592  const wasm::WasmTableType *TableType = nullptr;
593 
594  Info.Kind = readUint8(Ctx);
595  Info.Flags = readVaruint32(Ctx);
596  bool IsDefined = (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0;
597 
598  switch (Info.Kind) {
600  Info.ElementIndex = readVaruint32(Ctx);
601  if (!isValidFunctionIndex(Info.ElementIndex) ||
602  IsDefined != isDefinedFunctionIndex(Info.ElementIndex))
603  return make_error<GenericBinaryError>("invalid function symbol index",
605  if (IsDefined) {
606  Info.Name = readString(Ctx);
607  unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions;
608  wasm::WasmFunction &Function = Functions[FuncIndex];
609  Signature = &Signatures[Function.SigIndex];
610  if (Function.SymbolName.empty())
611  Function.SymbolName = Info.Name;
612  } else {
613  wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex];
614  if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
615  Info.Name = readString(Ctx);
616  Info.ImportName = Import.Field;
617  } else {
618  Info.Name = Import.Field;
619  }
620  Signature = &Signatures[Import.SigIndex];
621  if (!Import.Module.empty()) {
622  Info.ImportModule = Import.Module;
623  }
624  }
625  break;
626 
628  Info.ElementIndex = readVaruint32(Ctx);
629  if (!isValidGlobalIndex(Info.ElementIndex) ||
630  IsDefined != isDefinedGlobalIndex(Info.ElementIndex))
631  return make_error<GenericBinaryError>("invalid global symbol index",
633  if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
635  return make_error<GenericBinaryError>("undefined weak global symbol",
637  if (IsDefined) {
638  Info.Name = readString(Ctx);
639  unsigned GlobalIndex = Info.ElementIndex - NumImportedGlobals;
640  wasm::WasmGlobal &Global = Globals[GlobalIndex];
641  GlobalType = &Global.Type;
642  if (Global.SymbolName.empty())
643  Global.SymbolName = Info.Name;
644  } else {
645  wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex];
646  if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
647  Info.Name = readString(Ctx);
648  Info.ImportName = Import.Field;
649  } else {
650  Info.Name = Import.Field;
651  }
652  GlobalType = &Import.Global;
653  if (!Import.Module.empty()) {
654  Info.ImportModule = Import.Module;
655  }
656  }
657  break;
658 
660  Info.ElementIndex = readVaruint32(Ctx);
661  if (!isValidTableNumber(Info.ElementIndex) ||
662  IsDefined != isDefinedTableNumber(Info.ElementIndex))
663  return make_error<GenericBinaryError>("invalid table symbol index",
665  if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
667  return make_error<GenericBinaryError>("undefined weak table symbol",
669  if (IsDefined) {
670  Info.Name = readString(Ctx);
671  unsigned TableNumber = Info.ElementIndex - NumImportedTables;
672  wasm::WasmTable &Table = Tables[TableNumber];
673  TableType = &Table.Type;
674  if (Table.SymbolName.empty())
675  Table.SymbolName = Info.Name;
676  } else {
677  wasm::WasmImport &Import = *ImportedTables[Info.ElementIndex];
678  if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
679  Info.Name = readString(Ctx);
680  Info.ImportName = Import.Field;
681  } else {
682  Info.Name = Import.Field;
683  }
684  TableType = &Import.Table;
685  if (!Import.Module.empty()) {
686  Info.ImportModule = Import.Module;
687  }
688  }
689  break;
690 
692  Info.Name = readString(Ctx);
693  if (IsDefined) {
694  auto Index = readVaruint32(Ctx);
695  if (Index >= DataSegments.size())
696  return make_error<GenericBinaryError>("invalid data symbol index",
698  auto Offset = readVaruint64(Ctx);
699  auto Size = readVaruint64(Ctx);
700  size_t SegmentSize = DataSegments[Index].Data.Content.size();
701  if (Offset > SegmentSize)
702  return make_error<GenericBinaryError>(
703  "invalid data symbol offset: `" + Info.Name + "` (offset: " +
704  Twine(Offset) + " segment size: " + Twine(SegmentSize) + ")",
707  }
708  break;
709 
711  if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
713  return make_error<GenericBinaryError>(
714  "section symbols must have local binding",
716  Info.ElementIndex = readVaruint32(Ctx);
717  // Use somewhat unique section name as symbol name.
718  StringRef SectionName = Sections[Info.ElementIndex].Name;
719  Info.Name = SectionName;
720  break;
721  }
722 
724  Info.ElementIndex = readVaruint32(Ctx);
725  if (!isValidTagIndex(Info.ElementIndex) ||
726  IsDefined != isDefinedTagIndex(Info.ElementIndex))
727  return make_error<GenericBinaryError>("invalid tag symbol index",
729  if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
731  return make_error<GenericBinaryError>("undefined weak global symbol",
733  if (IsDefined) {
734  Info.Name = readString(Ctx);
735  unsigned TagIndex = Info.ElementIndex - NumImportedTags;
736  wasm::WasmTag &Tag = Tags[TagIndex];
737  Signature = &Signatures[Tag.SigIndex];
738  if (Tag.SymbolName.empty())
739  Tag.SymbolName = Info.Name;
740 
741  } else {
742  wasm::WasmImport &Import = *ImportedTags[Info.ElementIndex];
743  if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
744  Info.Name = readString(Ctx);
745  Info.ImportName = Import.Field;
746  } else {
747  Info.Name = Import.Field;
748  }
749  Signature = &Signatures[Import.SigIndex];
750  if (!Import.Module.empty()) {
751  Info.ImportModule = Import.Module;
752  }
753  }
754  break;
755  }
756 
757  default:
758  return make_error<GenericBinaryError>("invalid symbol type: " +
759  Twine(unsigned(Info.Kind)),
761  }
762 
763  if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
765  !SymbolNames.insert(Info.Name).second)
766  return make_error<GenericBinaryError>("duplicate symbol name " +
767  Twine(Info.Name),
769  LinkingData.SymbolTable.emplace_back(Info);
770  Symbols.emplace_back(LinkingData.SymbolTable.back(), GlobalType, TableType,
771  Signature);
772  LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");
773  }
774 
775  return Error::success();
776 }
777 
778 Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
779  uint32_t ComdatCount = readVaruint32(Ctx);
780  StringSet<> ComdatSet;
781  for (unsigned ComdatIndex = 0; ComdatIndex < ComdatCount; ++ComdatIndex) {
782  StringRef Name = readString(Ctx);
783  if (Name.empty() || !ComdatSet.insert(Name).second)
784  return make_error<GenericBinaryError>("bad/duplicate COMDAT name " +
785  Twine(Name),
787  LinkingData.Comdats.emplace_back(Name);
788  uint32_t Flags = readVaruint32(Ctx);
789  if (Flags != 0)
790  return make_error<GenericBinaryError>("unsupported COMDAT flags",
792 
793  uint32_t EntryCount = readVaruint32(Ctx);
794  while (EntryCount--) {
795  unsigned Kind = readVaruint32(Ctx);
796  unsigned Index = readVaruint32(Ctx);
797  switch (Kind) {
798  default:
799  return make_error<GenericBinaryError>("invalid COMDAT entry type",
802  if (Index >= DataSegments.size())
803  return make_error<GenericBinaryError>(
804  "COMDAT data index out of range", object_error::parse_failed);
805  if (DataSegments[Index].Data.Comdat != UINT32_MAX)
806  return make_error<GenericBinaryError>("data segment in two COMDATs",
808  DataSegments[Index].Data.Comdat = ComdatIndex;
809  break;
811  if (!isDefinedFunctionIndex(Index))
812  return make_error<GenericBinaryError>(
813  "COMDAT function index out of range", object_error::parse_failed);
814  if (getDefinedFunction(Index).Comdat != UINT32_MAX)
815  return make_error<GenericBinaryError>("function in two COMDATs",
817  getDefinedFunction(Index).Comdat = ComdatIndex;
818  break;
820  if (Index >= Sections.size())
821  return make_error<GenericBinaryError>(
822  "COMDAT section index out of range", object_error::parse_failed);
823  if (Sections[Index].Type != wasm::WASM_SEC_CUSTOM)
824  return make_error<GenericBinaryError>(
825  "non-custom section in a COMDAT", object_error::parse_failed);
826  Sections[Index].Comdat = ComdatIndex;
827  break;
828  }
829  }
830  }
831  return Error::success();
832 }
833 
834 Error WasmObjectFile::parseProducersSection(ReadContext &Ctx) {
835  llvm::SmallSet<StringRef, 3> FieldsSeen;
836  uint32_t Fields = readVaruint32(Ctx);
837  for (size_t I = 0; I < Fields; ++I) {
838  StringRef FieldName = readString(Ctx);
839  if (!FieldsSeen.insert(FieldName).second)
840  return make_error<GenericBinaryError>(
841  "producers section does not have unique fields",
843  std::vector<std::pair<std::string, std::string>> *ProducerVec = nullptr;
844  if (FieldName == "language") {
845  ProducerVec = &ProducerInfo.Languages;
846  } else if (FieldName == "processed-by") {
847  ProducerVec = &ProducerInfo.Tools;
848  } else if (FieldName == "sdk") {
849  ProducerVec = &ProducerInfo.SDKs;
850  } else {
851  return make_error<GenericBinaryError>(
852  "producers section field is not named one of language, processed-by, "
853  "or sdk",
855  }
856  uint32_t ValueCount = readVaruint32(Ctx);
857  llvm::SmallSet<StringRef, 8> ProducersSeen;
858  for (size_t J = 0; J < ValueCount; ++J) {
859  StringRef Name = readString(Ctx);
861  if (!ProducersSeen.insert(Name).second) {
862  return make_error<GenericBinaryError>(
863  "producers section contains repeated producer",
865  }
866  ProducerVec->emplace_back(std::string(Name), std::string(Version));
867  }
868  }
869  if (Ctx.Ptr != Ctx.End)
870  return make_error<GenericBinaryError>("producers section ended prematurely",
872  return Error::success();
873 }
874 
875 Error WasmObjectFile::parseTargetFeaturesSection(ReadContext &Ctx) {
876  llvm::SmallSet<std::string, 8> FeaturesSeen;
877  uint32_t FeatureCount = readVaruint32(Ctx);
878  for (size_t I = 0; I < FeatureCount; ++I) {
879  wasm::WasmFeatureEntry Feature;
880  Feature.Prefix = readUint8(Ctx);
881  switch (Feature.Prefix) {
885  break;
886  default:
887  return make_error<GenericBinaryError>("unknown feature policy prefix",
889  }
890  Feature.Name = std::string(readString(Ctx));
891  if (!FeaturesSeen.insert(Feature.Name).second)
892  return make_error<GenericBinaryError>(
893  "target features section contains repeated feature \"" +
894  Feature.Name + "\"",
896  TargetFeatures.push_back(Feature);
897  }
898  if (Ctx.Ptr != Ctx.End)
899  return make_error<GenericBinaryError>(
900  "target features section ended prematurely",
902  return Error::success();
903 }
904 
905 Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
906  uint32_t SectionIndex = readVaruint32(Ctx);
907  if (SectionIndex >= Sections.size())
908  return make_error<GenericBinaryError>("invalid section index",
910  WasmSection &Section = Sections[SectionIndex];
911  uint32_t RelocCount = readVaruint32(Ctx);
912  uint32_t EndOffset = Section.Content.size();
913  uint32_t PreviousOffset = 0;
914  while (RelocCount--) {
915  wasm::WasmRelocation Reloc = {};
916  uint32_t type = readVaruint32(Ctx);
917  Reloc.Type = type;
918  Reloc.Offset = readVaruint32(Ctx);
919  if (Reloc.Offset < PreviousOffset)
920  return make_error<GenericBinaryError>("relocations not in offset order",
922  PreviousOffset = Reloc.Offset;
923  Reloc.Index = readVaruint32(Ctx);
924  switch (type) {
925  case wasm::R_WASM_FUNCTION_INDEX_LEB:
926  case wasm::R_WASM_TABLE_INDEX_SLEB:
927  case wasm::R_WASM_TABLE_INDEX_SLEB64:
928  case wasm::R_WASM_TABLE_INDEX_I32:
929  case wasm::R_WASM_TABLE_INDEX_I64:
930  case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
931  case wasm::R_WASM_TABLE_INDEX_REL_SLEB64:
932  if (!isValidFunctionSymbol(Reloc.Index))
933  return make_error<GenericBinaryError>(
934  "invalid relocation function index", object_error::parse_failed);
935  break;
936  case wasm::R_WASM_TABLE_NUMBER_LEB:
937  if (!isValidTableSymbol(Reloc.Index))
938  return make_error<GenericBinaryError>("invalid relocation table index",
940  break;
941  case wasm::R_WASM_TYPE_INDEX_LEB:
942  if (Reloc.Index >= Signatures.size())
943  return make_error<GenericBinaryError>("invalid relocation type index",
945  break;
946  case wasm::R_WASM_GLOBAL_INDEX_LEB:
947  // R_WASM_GLOBAL_INDEX_LEB are can be used against function and data
948  // symbols to refer to their GOT entries.
949  if (!isValidGlobalSymbol(Reloc.Index) &&
950  !isValidDataSymbol(Reloc.Index) &&
951  !isValidFunctionSymbol(Reloc.Index))
952  return make_error<GenericBinaryError>("invalid relocation global index",
954  break;
955  case wasm::R_WASM_GLOBAL_INDEX_I32:
956  if (!isValidGlobalSymbol(Reloc.Index))
957  return make_error<GenericBinaryError>("invalid relocation global index",
959  break;
960  case wasm::R_WASM_TAG_INDEX_LEB:
961  if (!isValidTagSymbol(Reloc.Index))
962  return make_error<GenericBinaryError>("invalid relocation tag index",
964  break;
965  case wasm::R_WASM_MEMORY_ADDR_LEB:
966  case wasm::R_WASM_MEMORY_ADDR_SLEB:
967  case wasm::R_WASM_MEMORY_ADDR_I32:
968  case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
969  case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
970  case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
971  if (!isValidDataSymbol(Reloc.Index))
972  return make_error<GenericBinaryError>("invalid relocation data index",
974  Reloc.Addend = readVarint32(Ctx);
975  break;
976  case wasm::R_WASM_MEMORY_ADDR_LEB64:
977  case wasm::R_WASM_MEMORY_ADDR_SLEB64:
978  case wasm::R_WASM_MEMORY_ADDR_I64:
979  case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
980  case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64:
981  if (!isValidDataSymbol(Reloc.Index))
982  return make_error<GenericBinaryError>("invalid relocation data index",
984  Reloc.Addend = readVarint64(Ctx);
985  break;
986  case wasm::R_WASM_FUNCTION_OFFSET_I32:
987  if (!isValidFunctionSymbol(Reloc.Index))
988  return make_error<GenericBinaryError>(
989  "invalid relocation function index", object_error::parse_failed);
990  Reloc.Addend = readVarint32(Ctx);
991  break;
992  case wasm::R_WASM_FUNCTION_OFFSET_I64:
993  if (!isValidFunctionSymbol(Reloc.Index))
994  return make_error<GenericBinaryError>(
995  "invalid relocation function index", object_error::parse_failed);
996  Reloc.Addend = readVarint64(Ctx);
997  break;
998  case wasm::R_WASM_SECTION_OFFSET_I32:
999  if (!isValidSectionSymbol(Reloc.Index))
1000  return make_error<GenericBinaryError>(
1001  "invalid relocation section index", object_error::parse_failed);
1002  Reloc.Addend = readVarint32(Ctx);
1003  break;
1004  default:
1005  return make_error<GenericBinaryError>("invalid relocation type: " +
1006  Twine(type),
1008  }
1009 
1010  // Relocations must fit inside the section, and must appear in order. They
1011  // also shouldn't overlap a function/element boundary, but we don't bother
1012  // to check that.
1013  uint64_t Size = 5;
1014  if (Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LEB64 ||
1015  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_SLEB64 ||
1016  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_REL_SLEB64)
1017  Size = 10;
1018  if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I32 ||
1019  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I32 ||
1020  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LOCREL_I32 ||
1021  Reloc.Type == wasm::R_WASM_SECTION_OFFSET_I32 ||
1022  Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||
1023  Reloc.Type == wasm::R_WASM_GLOBAL_INDEX_I32)
1024  Size = 4;
1025  if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I64 ||
1026  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I64 ||
1027  Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I64)
1028  Size = 8;
1029  if (Reloc.Offset + Size > EndOffset)
1030  return make_error<GenericBinaryError>("invalid relocation offset",
1032 
1033  Section.Relocations.push_back(Reloc);
1034  }
1035  if (Ctx.Ptr != Ctx.End)
1036  return make_error<GenericBinaryError>("reloc section ended prematurely",
1038  return Error::success();
1039 }
1040 
1041 Error WasmObjectFile::parseCustomSection(WasmSection &Sec, ReadContext &Ctx) {
1042  if (Sec.Name == "dylink") {
1043  if (Error Err = parseDylinkSection(Ctx))
1044  return Err;
1045  } else if (Sec.Name == "dylink.0") {
1046  if (Error Err = parseDylink0Section(Ctx))
1047  return Err;
1048  } else if (Sec.Name == "name") {
1049  if (Error Err = parseNameSection(Ctx))
1050  return Err;
1051  } else if (Sec.Name == "linking") {
1052  if (Error Err = parseLinkingSection(Ctx))
1053  return Err;
1054  } else if (Sec.Name == "producers") {
1055  if (Error Err = parseProducersSection(Ctx))
1056  return Err;
1057  } else if (Sec.Name == "target_features") {
1058  if (Error Err = parseTargetFeaturesSection(Ctx))
1059  return Err;
1060  } else if (Sec.Name.startswith("reloc.")) {
1061  if (Error Err = parseRelocSection(Sec.Name, Ctx))
1062  return Err;
1063  }
1064  return Error::success();
1065 }
1066 
1067 Error WasmObjectFile::parseTypeSection(ReadContext &Ctx) {
1068  uint32_t Count = readVaruint32(Ctx);
1069  Signatures.reserve(Count);
1070  while (Count--) {
1071  wasm::WasmSignature Sig;
1072  uint8_t Form = readUint8(Ctx);
1073  if (Form != wasm::WASM_TYPE_FUNC) {
1074  return make_error<GenericBinaryError>("invalid signature type",
1076  }
1077  uint32_t ParamCount = readVaruint32(Ctx);
1078  Sig.Params.reserve(ParamCount);
1079  while (ParamCount--) {
1080  uint32_t ParamType = readUint8(Ctx);
1081  Sig.Params.push_back(wasm::ValType(ParamType));
1082  }
1083  uint32_t ReturnCount = readVaruint32(Ctx);
1084  while (ReturnCount--) {
1085  uint32_t ReturnType = readUint8(Ctx);
1086  Sig.Returns.push_back(wasm::ValType(ReturnType));
1087  }
1088  Signatures.push_back(std::move(Sig));
1089  }
1090  if (Ctx.Ptr != Ctx.End)
1091  return make_error<GenericBinaryError>("type section ended prematurely",
1093  return Error::success();
1094 }
1095 
1096 Error WasmObjectFile::parseImportSection(ReadContext &Ctx) {
1097  uint32_t Count = readVaruint32(Ctx);
1098  uint32_t NumTypes = Signatures.size();
1099  Imports.reserve(Count);
1100  for (uint32_t I = 0; I < Count; I++) {
1101  wasm::WasmImport Im;
1102  Im.Module = readString(Ctx);
1103  Im.Field = readString(Ctx);
1104  Im.Kind = readUint8(Ctx);
1105  switch (Im.Kind) {
1107  NumImportedFunctions++;
1108  Im.SigIndex = readVaruint32(Ctx);
1109  if (Im.SigIndex >= NumTypes)
1110  return make_error<GenericBinaryError>("invalid function type",
1112  break;
1114  NumImportedGlobals++;
1115  Im.Global.Type = readUint8(Ctx);
1116  Im.Global.Mutable = readVaruint1(Ctx);
1117  break;
1119  Im.Memory = readLimits(Ctx);
1121  HasMemory64 = true;
1122  break;
1124  Im.Table = readTableType(Ctx);
1125  NumImportedTables++;
1126  auto ElemType = Im.Table.ElemType;
1127  if (ElemType != wasm::WASM_TYPE_FUNCREF &&
1128  ElemType != wasm::WASM_TYPE_EXTERNREF)
1129  return make_error<GenericBinaryError>("invalid table element type",
1131  break;
1132  }
1134  NumImportedTags++;
1135  if (readUint8(Ctx) != 0) // Reserved 'attribute' field
1136  return make_error<GenericBinaryError>("invalid attribute",
1138  Im.SigIndex = readVaruint32(Ctx);
1139  if (Im.SigIndex >= NumTypes)
1140  return make_error<GenericBinaryError>("invalid tag type",
1142  break;
1143  default:
1144  return make_error<GenericBinaryError>("unexpected import kind",
1146  }
1147  Imports.push_back(Im);
1148  }
1149  if (Ctx.Ptr != Ctx.End)
1150  return make_error<GenericBinaryError>("import section ended prematurely",
1152  return Error::success();
1153 }
1154 
1155 Error WasmObjectFile::parseFunctionSection(ReadContext &Ctx) {
1156  uint32_t Count = readVaruint32(Ctx);
1157  Functions.reserve(Count);
1158  uint32_t NumTypes = Signatures.size();
1159  while (Count--) {
1160  uint32_t Type = readVaruint32(Ctx);
1161  if (Type >= NumTypes)
1162  return make_error<GenericBinaryError>("invalid function type",
1165  F.SigIndex = Type;
1166  Functions.push_back(F);
1167  }
1168  if (Ctx.Ptr != Ctx.End)
1169  return make_error<GenericBinaryError>("function section ended prematurely",
1171  return Error::success();
1172 }
1173 
1174 Error WasmObjectFile::parseTableSection(ReadContext &Ctx) {
1175  TableSection = Sections.size();
1176  uint32_t Count = readVaruint32(Ctx);
1177  Tables.reserve(Count);
1178  while (Count--) {
1180  T.Type = readTableType(Ctx);
1181  T.Index = NumImportedTables + Tables.size();
1182  Tables.push_back(T);
1183  auto ElemType = Tables.back().Type.ElemType;
1184  if (ElemType != wasm::WASM_TYPE_FUNCREF &&
1185  ElemType != wasm::WASM_TYPE_EXTERNREF) {
1186  return make_error<GenericBinaryError>("invalid table element type",
1188  }
1189  }
1190  if (Ctx.Ptr != Ctx.End)
1191  return make_error<GenericBinaryError>("table section ended prematurely",
1193  return Error::success();
1194 }
1195 
1196 Error WasmObjectFile::parseMemorySection(ReadContext &Ctx) {
1197  uint32_t Count = readVaruint32(Ctx);
1198  Memories.reserve(Count);
1199  while (Count--) {
1200  auto Limits = readLimits(Ctx);
1201  if (Limits.Flags & wasm::WASM_LIMITS_FLAG_IS_64)
1202  HasMemory64 = true;
1203  Memories.push_back(Limits);
1204  }
1205  if (Ctx.Ptr != Ctx.End)
1206  return make_error<GenericBinaryError>("memory section ended prematurely",
1208  return Error::success();
1209 }
1210 
1211 Error WasmObjectFile::parseTagSection(ReadContext &Ctx) {
1212  TagSection = Sections.size();
1213  uint32_t Count = readVaruint32(Ctx);
1214  Tags.reserve(Count);
1215  uint32_t NumTypes = Signatures.size();
1216  while (Count--) {
1217  if (readUint8(Ctx) != 0) // Reserved 'attribute' field
1218  return make_error<GenericBinaryError>("invalid attribute",
1220  uint32_t Type = readVaruint32(Ctx);
1221  if (Type >= NumTypes)
1222  return make_error<GenericBinaryError>("invalid tag type",
1225  Tag.Index = NumImportedTags + Tags.size();
1226  Tag.SigIndex = Type;
1227  Tags.push_back(Tag);
1228  }
1229 
1230  if (Ctx.Ptr != Ctx.End)
1231  return make_error<GenericBinaryError>("tag section ended prematurely",
1233  return Error::success();
1234 }
1235 
1236 Error WasmObjectFile::parseGlobalSection(ReadContext &Ctx) {
1237  GlobalSection = Sections.size();
1238  uint32_t Count = readVaruint32(Ctx);
1239  Globals.reserve(Count);
1240  while (Count--) {
1242  Global.Index = NumImportedGlobals + Globals.size();
1243  Global.Type.Type = readUint8(Ctx);
1244  Global.Type.Mutable = readVaruint1(Ctx);
1245  if (Error Err = readInitExpr(Global.InitExpr, Ctx))
1246  return Err;
1247  Globals.push_back(Global);
1248  }
1249  if (Ctx.Ptr != Ctx.End)
1250  return make_error<GenericBinaryError>("global section ended prematurely",
1252  return Error::success();
1253 }
1254 
1255 Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
1256  uint32_t Count = readVaruint32(Ctx);
1257  Exports.reserve(Count);
1258  for (uint32_t I = 0; I < Count; I++) {
1259  wasm::WasmExport Ex;
1260  Ex.Name = readString(Ctx);
1261  Ex.Kind = readUint8(Ctx);
1262  Ex.Index = readVaruint32(Ctx);
1263  switch (Ex.Kind) {
1265 
1266  if (!isDefinedFunctionIndex(Ex.Index))
1267  return make_error<GenericBinaryError>("invalid function export",
1269  getDefinedFunction(Ex.Index).ExportName = Ex.Name;
1270  break;
1272  if (!isValidGlobalIndex(Ex.Index))
1273  return make_error<GenericBinaryError>("invalid global export",
1275  break;
1277  if (!isValidTagIndex(Ex.Index))
1278  return make_error<GenericBinaryError>("invalid tag export",
1280  break;
1283  break;
1284  default:
1285  return make_error<GenericBinaryError>("unexpected export kind",
1287  }
1288  Exports.push_back(Ex);
1289  }
1290  if (Ctx.Ptr != Ctx.End)
1291  return make_error<GenericBinaryError>("export section ended prematurely",
1293  return Error::success();
1294 }
1295 
1296 bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const {
1297  return Index < NumImportedFunctions + Functions.size();
1298 }
1299 
1300 bool WasmObjectFile::isDefinedFunctionIndex(uint32_t Index) const {
1301  return Index >= NumImportedFunctions && isValidFunctionIndex(Index);
1302 }
1303 
1304 bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const {
1305  return Index < NumImportedGlobals + Globals.size();
1306 }
1307 
1308 bool WasmObjectFile::isValidTableNumber(uint32_t Index) const {
1309  return Index < NumImportedTables + Tables.size();
1310 }
1311 
1312 bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const {
1313  return Index >= NumImportedGlobals && isValidGlobalIndex(Index);
1314 }
1315 
1316 bool WasmObjectFile::isDefinedTableNumber(uint32_t Index) const {
1317  return Index >= NumImportedTables && isValidTableNumber(Index);
1318 }
1319 
1320 bool WasmObjectFile::isValidTagIndex(uint32_t Index) const {
1321  return Index < NumImportedTags + Tags.size();
1322 }
1323 
1324 bool WasmObjectFile::isDefinedTagIndex(uint32_t Index) const {
1325  return Index >= NumImportedTags && isValidTagIndex(Index);
1326 }
1327 
1328 bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
1329  return Index < Symbols.size() && Symbols[Index].isTypeFunction();
1330 }
1331 
1332 bool WasmObjectFile::isValidTableSymbol(uint32_t Index) const {
1333  return Index < Symbols.size() && Symbols[Index].isTypeTable();
1334 }
1335 
1336 bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const {
1337  return Index < Symbols.size() && Symbols[Index].isTypeGlobal();
1338 }
1339 
1340 bool WasmObjectFile::isValidTagSymbol(uint32_t Index) const {
1341  return Index < Symbols.size() && Symbols[Index].isTypeTag();
1342 }
1343 
1344 bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
1345  return Index < Symbols.size() && Symbols[Index].isTypeData();
1346 }
1347 
1348 bool WasmObjectFile::isValidSectionSymbol(uint32_t Index) const {
1349  return Index < Symbols.size() && Symbols[Index].isTypeSection();
1350 }
1351 
1352 wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) {
1353  assert(isDefinedFunctionIndex(Index));
1354  return Functions[Index - NumImportedFunctions];
1355 }
1356 
1357 const wasm::WasmFunction &
1358 WasmObjectFile::getDefinedFunction(uint32_t Index) const {
1359  assert(isDefinedFunctionIndex(Index));
1360  return Functions[Index - NumImportedFunctions];
1361 }
1362 
1363 wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) {
1364  assert(isDefinedGlobalIndex(Index));
1365  return Globals[Index - NumImportedGlobals];
1366 }
1367 
1368 wasm::WasmTag &WasmObjectFile::getDefinedTag(uint32_t Index) {
1369  assert(isDefinedTagIndex(Index));
1370  return Tags[Index - NumImportedTags];
1371 }
1372 
1373 Error WasmObjectFile::parseStartSection(ReadContext &Ctx) {
1374  StartFunction = readVaruint32(Ctx);
1375  if (!isValidFunctionIndex(StartFunction))
1376  return make_error<GenericBinaryError>("invalid start function",
1378  return Error::success();
1379 }
1380 
1381 Error WasmObjectFile::parseCodeSection(ReadContext &Ctx) {
1382  SeenCodeSection = true;
1383  CodeSection = Sections.size();
1384  uint32_t FunctionCount = readVaruint32(Ctx);
1385  if (FunctionCount != Functions.size()) {
1386  return make_error<GenericBinaryError>("invalid function count",
1388  }
1389 
1390  for (uint32_t i = 0; i < FunctionCount; i++) {
1391  wasm::WasmFunction& Function = Functions[i];
1392  const uint8_t *FunctionStart = Ctx.Ptr;
1393  uint32_t Size = readVaruint32(Ctx);
1394  const uint8_t *FunctionEnd = Ctx.Ptr + Size;
1395 
1396  Function.CodeOffset = Ctx.Ptr - FunctionStart;
1397  Function.Index = NumImportedFunctions + i;
1398  Function.CodeSectionOffset = FunctionStart - Ctx.Start;
1399  Function.Size = FunctionEnd - FunctionStart;
1400 
1401  uint32_t NumLocalDecls = readVaruint32(Ctx);
1402  Function.Locals.reserve(NumLocalDecls);
1403  while (NumLocalDecls--) {
1404  wasm::WasmLocalDecl Decl;
1405  Decl.Count = readVaruint32(Ctx);
1406  Decl.Type = readUint8(Ctx);
1407  Function.Locals.push_back(Decl);
1408  }
1409 
1410  uint32_t BodySize = FunctionEnd - Ctx.Ptr;
1411  Function.Body = ArrayRef<uint8_t>(Ctx.Ptr, BodySize);
1412  // This will be set later when reading in the linking metadata section.
1413  Function.Comdat = UINT32_MAX;
1414  Ctx.Ptr += BodySize;
1415  assert(Ctx.Ptr == FunctionEnd);
1416  }
1417  if (Ctx.Ptr != Ctx.End)
1418  return make_error<GenericBinaryError>("code section ended prematurely",
1420  return Error::success();
1421 }
1422 
1423 Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
1424  uint32_t Count = readVaruint32(Ctx);
1425  ElemSegments.reserve(Count);
1426  while (Count--) {
1427  wasm::WasmElemSegment Segment;
1428  Segment.Flags = readVaruint32(Ctx);
1429 
1433  if (Segment.Flags & ~SupportedFlags)
1434  return make_error<GenericBinaryError>(
1435  "Unsupported flags for element segment", object_error::parse_failed);
1436 
1438  Segment.TableNumber = readVaruint32(Ctx);
1439  else
1440  Segment.TableNumber = 0;
1441  if (!isValidTableNumber(Segment.TableNumber))
1442  return make_error<GenericBinaryError>("invalid TableNumber",
1444 
1445  if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_IS_PASSIVE) {
1447  Segment.Offset.Value.Int32 = 0;
1448  } else {
1449  if (Error Err = readInitExpr(Segment.Offset, Ctx))
1450  return Err;
1451  }
1452 
1454  Segment.ElemKind = readUint8(Ctx);
1456  if (Segment.ElemKind != uint8_t(wasm::ValType::FUNCREF) &&
1457  Segment.ElemKind != uint8_t(wasm::ValType::EXTERNREF)) {
1458  return make_error<GenericBinaryError>("invalid reference type",
1460  }
1461  } else {
1462  if (Segment.ElemKind != 0)
1463  return make_error<GenericBinaryError>("invalid elemtype",
1465  Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF);
1466  }
1467  } else {
1468  Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF);
1469  }
1470 
1472  return make_error<GenericBinaryError>(
1473  "elem segment init expressions not yet implemented",
1475 
1476  uint32_t NumElems = readVaruint32(Ctx);
1477  while (NumElems--) {
1478  Segment.Functions.push_back(readVaruint32(Ctx));
1479  }
1480  ElemSegments.push_back(Segment);
1481  }
1482  if (Ctx.Ptr != Ctx.End)
1483  return make_error<GenericBinaryError>("elem section ended prematurely",
1485  return Error::success();
1486 }
1487 
1488 Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
1489  DataSection = Sections.size();
1490  uint32_t Count = readVaruint32(Ctx);
1491  if (DataCount && Count != DataCount.getValue())
1492  return make_error<GenericBinaryError>(
1493  "number of data segments does not match DataCount section");
1494  DataSegments.reserve(Count);
1495  while (Count--) {
1496  WasmSegment Segment;
1497  Segment.Data.InitFlags = readVaruint32(Ctx);
1498  Segment.Data.MemoryIndex =
1499  (Segment.Data.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX)
1500  ? readVaruint32(Ctx)
1501  : 0;
1502  if ((Segment.Data.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) {
1503  if (Error Err = readInitExpr(Segment.Data.Offset, Ctx))
1504  return Err;
1505  } else {
1506  Segment.Data.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST;
1507  Segment.Data.Offset.Value.Int32 = 0;
1508  }
1509  uint32_t Size = readVaruint32(Ctx);
1510  if (Size > (size_t)(Ctx.End - Ctx.Ptr))
1511  return make_error<GenericBinaryError>("invalid segment size",
1513  Segment.Data.Content = ArrayRef<uint8_t>(Ctx.Ptr, Size);
1514  // The rest of these Data fields are set later, when reading in the linking
1515  // metadata section.
1516  Segment.Data.Alignment = 0;
1517  Segment.Data.LinkingFlags = 0;
1518  Segment.Data.Comdat = UINT32_MAX;
1519  Segment.SectionOffset = Ctx.Ptr - Ctx.Start;
1520  Ctx.Ptr += Size;
1521  DataSegments.push_back(Segment);
1522  }
1523  if (Ctx.Ptr != Ctx.End)
1524  return make_error<GenericBinaryError>("data section ended prematurely",
1526  return Error::success();
1527 }
1528 
1529 Error WasmObjectFile::parseDataCountSection(ReadContext &Ctx) {
1530  DataCount = readVaruint32(Ctx);
1531  return Error::success();
1532 }
1533 
1535  return Header;
1536 }
1537 
1538 void WasmObjectFile::moveSymbolNext(DataRefImpl &Symb) const { Symb.d.b++; }
1539 
1541  uint32_t Result = SymbolRef::SF_None;
1542  const WasmSymbol &Sym = getWasmSymbol(Symb);
1543 
1544  LLVM_DEBUG(dbgs() << "getSymbolFlags: ptr=" << &Sym << " " << Sym << "\n");
1545  if (Sym.isBindingWeak())
1546  Result |= SymbolRef::SF_Weak;
1547  if (!Sym.isBindingLocal())
1548  Result |= SymbolRef::SF_Global;
1549  if (Sym.isHidden())
1550  Result |= SymbolRef::SF_Hidden;
1551  if (!Sym.isDefined())
1552  Result |= SymbolRef::SF_Undefined;
1553  if (Sym.isTypeFunction())
1554  Result |= SymbolRef::SF_Executable;
1555  return Result;
1556 }
1557 
1559  DataRefImpl Ref;
1560  Ref.d.a = 1; // Arbitrary non-zero value so that Ref.p is non-null
1561  Ref.d.b = 0; // Symbol index
1562  return BasicSymbolRef(Ref, this);
1563 }
1564 
1566  DataRefImpl Ref;
1567  Ref.d.a = 1; // Arbitrary non-zero value so that Ref.p is non-null
1568  Ref.d.b = Symbols.size(); // Symbol index
1569  return BasicSymbolRef(Ref, this);
1570 }
1571 
1573  return Symbols[Symb.d.b];
1574 }
1575 
1576 const WasmSymbol &WasmObjectFile::getWasmSymbol(const SymbolRef &Symb) const {
1577  return getWasmSymbol(Symb.getRawDataRefImpl());
1578 }
1579 
1581  return getWasmSymbol(Symb).Info.Name;
1582 }
1583 
1585  auto &Sym = getWasmSymbol(Symb);
1586  if (Sym.Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION &&
1587  isDefinedFunctionIndex(Sym.Info.ElementIndex))
1588  return getDefinedFunction(Sym.Info.ElementIndex).CodeSectionOffset;
1589  else
1590  return getSymbolValue(Symb);
1591 }
1592 
1594  switch (Sym.Info.Kind) {
1599  return Sym.Info.ElementIndex;
1601  // The value of a data symbol is the segment offset, plus the symbol
1602  // offset within the segment.
1603  uint32_t SegmentIndex = Sym.Info.DataRef.Segment;
1604  const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data;
1605  if (Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST) {
1606  return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset;
1607  } else if (Segment.Offset.Opcode == wasm::WASM_OPCODE_I64_CONST) {
1608  return Segment.Offset.Value.Int64 + Sym.Info.DataRef.Offset;
1609  } else {
1610  llvm_unreachable("unknown init expr opcode");
1611  }
1612  }
1614  return 0;
1615  }
1616  llvm_unreachable("invalid symbol type");
1617 }
1618 
1620  return getWasmSymbolValue(getWasmSymbol(Symb));
1621 }
1622 
1624  llvm_unreachable("not yet implemented");
1625  return 0;
1626 }
1627 
1629  llvm_unreachable("not yet implemented");
1630  return 0;
1631 }
1632 
1635  const WasmSymbol &Sym = getWasmSymbol(Symb);
1636 
1637  switch (Sym.Info.Kind) {
1639  return SymbolRef::ST_Function;
1641  return SymbolRef::ST_Other;
1643  return SymbolRef::ST_Data;
1645  return SymbolRef::ST_Debug;
1647  return SymbolRef::ST_Other;
1649  return SymbolRef::ST_Other;
1650  }
1651 
1652  llvm_unreachable("unknown WasmSymbol::SymbolType");
1653  return SymbolRef::ST_Other;
1654 }
1655 
1658  const WasmSymbol &Sym = getWasmSymbol(Symb);
1659  if (Sym.isUndefined())
1660  return section_end();
1661 
1662  DataRefImpl Ref;
1663  Ref.d.a = getSymbolSectionIdImpl(Sym);
1664  return section_iterator(SectionRef(Ref, this));
1665 }
1666 
1668  const WasmSymbol &Sym = getWasmSymbol(Symb);
1669  return getSymbolSectionIdImpl(Sym);
1670 }
1671 
1672 uint32_t WasmObjectFile::getSymbolSectionIdImpl(const WasmSymbol &Sym) const {
1673  switch (Sym.Info.Kind) {
1675  return CodeSection;
1677  return GlobalSection;
1679  return DataSection;
1681  return Sym.Info.ElementIndex;
1683  return TagSection;
1685  return TableSection;
1686  default:
1687  llvm_unreachable("unknown WasmSymbol::SymbolType");
1688  }
1689 }
1690 
1691 void WasmObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; }
1692 
1694  const WasmSection &S = Sections[Sec.d.a];
1695 #define ECase(X) \
1696  case wasm::WASM_SEC_##X: \
1697  return #X;
1698  switch (S.Type) {
1699  ECase(TYPE);
1700  ECase(IMPORT);
1701  ECase(FUNCTION);
1702  ECase(TABLE);
1703  ECase(MEMORY);
1704  ECase(GLOBAL);
1705  ECase(TAG);
1706  ECase(EXPORT);
1707  ECase(START);
1708  ECase(ELEM);
1709  ECase(CODE);
1710  ECase(DATA);
1711  ECase(DATACOUNT);
1712  case wasm::WASM_SEC_CUSTOM:
1713  return S.Name;
1714  default:
1716  }
1717 #undef ECase
1718 }
1719 
1721 
1723  return Sec.d.a;
1724 }
1725 
1727  const WasmSection &S = Sections[Sec.d.a];
1728  return S.Content.size();
1729 }
1730 
1733  const WasmSection &S = Sections[Sec.d.a];
1734  // This will never fail since wasm sections can never be empty (user-sections
1735  // must have a name and non-user sections each have a defined structure).
1736  return S.Content;
1737 }
1738 
1740  return 1;
1741 }
1742 
1744  return false;
1745 }
1746 
1748  return getWasmSection(Sec).Type == wasm::WASM_SEC_CODE;
1749 }
1750 
1752  return getWasmSection(Sec).Type == wasm::WASM_SEC_DATA;
1753 }
1754 
1755 bool WasmObjectFile::isSectionBSS(DataRefImpl Sec) const { return false; }
1756 
1757 bool WasmObjectFile::isSectionVirtual(DataRefImpl Sec) const { return false; }
1758 
1760  DataRefImpl RelocRef;
1761  RelocRef.d.a = Ref.d.a;
1762  RelocRef.d.b = 0;
1763  return relocation_iterator(RelocationRef(RelocRef, this));
1764 }
1765 
1767  const WasmSection &Sec = getWasmSection(Ref);
1768  DataRefImpl RelocRef;
1769  RelocRef.d.a = Ref.d.a;
1770  RelocRef.d.b = Sec.Relocations.size();
1771  return relocation_iterator(RelocationRef(RelocRef, this));
1772 }
1773 
1775 
1778  return Rel.Offset;
1779 }
1780 
1783  if (Rel.Type == wasm::R_WASM_TYPE_INDEX_LEB)
1784  return symbol_end();
1785  DataRefImpl Sym;
1786  Sym.d.a = 1;
1787  Sym.d.b = Rel.Index;
1788  return symbol_iterator(SymbolRef(Sym, this));
1789 }
1790 
1793  return Rel.Type;
1794 }
1795 
1797  DataRefImpl Ref, SmallVectorImpl<char> &Result) const {
1799  StringRef Res = "Unknown";
1800 
1801 #define WASM_RELOC(name, value) \
1802  case wasm::name: \
1803  Res = #name; \
1804  break;
1805 
1806  switch (Rel.Type) {
1807 #include "llvm/BinaryFormat/WasmRelocs.def"
1808  }
1809 
1810 #undef WASM_RELOC
1811 
1812  Result.append(Res.begin(), Res.end());
1813 }
1814 
1816  DataRefImpl Ref;
1817  Ref.d.a = 0;
1818  return section_iterator(SectionRef(Ref, this));
1819 }
1820 
1822  DataRefImpl Ref;
1823  Ref.d.a = Sections.size();
1824  return section_iterator(SectionRef(Ref, this));
1825 }
1826 
1828  return HasMemory64 ? 8 : 4;
1829 }
1830 
1832 
1834  return HasMemory64 ? Triple::wasm64 : Triple::wasm32;
1835 }
1836 
1838  return SubtargetFeatures();
1839 }
1840 
1841 bool WasmObjectFile::isRelocatableObject() const { return HasLinkingSection; }
1842 
1843 bool WasmObjectFile::isSharedObject() const { return HasDylinkSection; }
1844 
1846  assert(Ref.d.a < Sections.size());
1847  return Sections[Ref.d.a];
1848 }
1849 
1850 const WasmSection &
1852  return getWasmSection(Section.getRawDataRefImpl());
1853 }
1854 
1855 const wasm::WasmRelocation &
1857  return getWasmRelocation(Ref.getRawDataRefImpl());
1858 }
1859 
1860 const wasm::WasmRelocation &
1862  assert(Ref.d.a < Sections.size());
1863  const WasmSection &Sec = Sections[Ref.d.a];
1864  assert(Ref.d.b < Sec.Relocations.size());
1865  return Sec.Relocations[Ref.d.b];
1866 }
1867 
1868 int WasmSectionOrderChecker::getSectionOrder(unsigned ID,
1869  StringRef CustomSectionName) {
1870  switch (ID) {
1871  case wasm::WASM_SEC_CUSTOM:
1872  return StringSwitch<unsigned>(CustomSectionName)
1873  .Case("dylink", WASM_SEC_ORDER_DYLINK)
1874  .Case("dylink.0", WASM_SEC_ORDER_DYLINK)
1875  .Case("linking", WASM_SEC_ORDER_LINKING)
1876  .StartsWith("reloc.", WASM_SEC_ORDER_RELOC)
1877  .Case("name", WASM_SEC_ORDER_NAME)
1878  .Case("producers", WASM_SEC_ORDER_PRODUCERS)
1879  .Case("target_features", WASM_SEC_ORDER_TARGET_FEATURES)
1881  case wasm::WASM_SEC_TYPE:
1882  return WASM_SEC_ORDER_TYPE;
1883  case wasm::WASM_SEC_IMPORT:
1884  return WASM_SEC_ORDER_IMPORT;
1886  return WASM_SEC_ORDER_FUNCTION;
1887  case wasm::WASM_SEC_TABLE:
1888  return WASM_SEC_ORDER_TABLE;
1889  case wasm::WASM_SEC_MEMORY:
1890  return WASM_SEC_ORDER_MEMORY;
1891  case wasm::WASM_SEC_GLOBAL:
1892  return WASM_SEC_ORDER_GLOBAL;
1893  case wasm::WASM_SEC_EXPORT:
1894  return WASM_SEC_ORDER_EXPORT;
1895  case wasm::WASM_SEC_START:
1896  return WASM_SEC_ORDER_START;
1897  case wasm::WASM_SEC_ELEM:
1898  return WASM_SEC_ORDER_ELEM;
1899  case wasm::WASM_SEC_CODE:
1900  return WASM_SEC_ORDER_CODE;
1901  case wasm::WASM_SEC_DATA:
1902  return WASM_SEC_ORDER_DATA;
1904  return WASM_SEC_ORDER_DATACOUNT;
1905  case wasm::WASM_SEC_TAG:
1906  return WASM_SEC_ORDER_TAG;
1907  default:
1908  return WASM_SEC_ORDER_NONE;
1909  }
1910 }
1911 
1912 // Represents the edges in a directed graph where any node B reachable from node
1913 // A is not allowed to appear before A in the section ordering, but may appear
1914 // afterward.
1916  [WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS] = {
1917  // WASM_SEC_ORDER_NONE
1918  {},
1919  // WASM_SEC_ORDER_TYPE
1920  {WASM_SEC_ORDER_TYPE, WASM_SEC_ORDER_IMPORT},
1921  // WASM_SEC_ORDER_IMPORT
1922  {WASM_SEC_ORDER_IMPORT, WASM_SEC_ORDER_FUNCTION},
1923  // WASM_SEC_ORDER_FUNCTION
1924  {WASM_SEC_ORDER_FUNCTION, WASM_SEC_ORDER_TABLE},
1925  // WASM_SEC_ORDER_TABLE
1926  {WASM_SEC_ORDER_TABLE, WASM_SEC_ORDER_MEMORY},
1927  // WASM_SEC_ORDER_MEMORY
1928  {WASM_SEC_ORDER_MEMORY, WASM_SEC_ORDER_TAG},
1929  // WASM_SEC_ORDER_TAG
1930  {WASM_SEC_ORDER_TAG, WASM_SEC_ORDER_GLOBAL},
1931  // WASM_SEC_ORDER_GLOBAL
1932  {WASM_SEC_ORDER_GLOBAL, WASM_SEC_ORDER_EXPORT},
1933  // WASM_SEC_ORDER_EXPORT
1934  {WASM_SEC_ORDER_EXPORT, WASM_SEC_ORDER_START},
1935  // WASM_SEC_ORDER_START
1936  {WASM_SEC_ORDER_START, WASM_SEC_ORDER_ELEM},
1937  // WASM_SEC_ORDER_ELEM
1938  {WASM_SEC_ORDER_ELEM, WASM_SEC_ORDER_DATACOUNT},
1939  // WASM_SEC_ORDER_DATACOUNT
1940  {WASM_SEC_ORDER_DATACOUNT, WASM_SEC_ORDER_CODE},
1941  // WASM_SEC_ORDER_CODE
1942  {WASM_SEC_ORDER_CODE, WASM_SEC_ORDER_DATA},
1943  // WASM_SEC_ORDER_DATA
1944  {WASM_SEC_ORDER_DATA, WASM_SEC_ORDER_LINKING},
1945 
1946  // Custom Sections
1947  // WASM_SEC_ORDER_DYLINK
1948  {WASM_SEC_ORDER_DYLINK, WASM_SEC_ORDER_TYPE},
1949  // WASM_SEC_ORDER_LINKING
1950  {WASM_SEC_ORDER_LINKING, WASM_SEC_ORDER_RELOC, WASM_SEC_ORDER_NAME},
1951  // WASM_SEC_ORDER_RELOC (can be repeated)
1952  {},
1953  // WASM_SEC_ORDER_NAME
1954  {WASM_SEC_ORDER_NAME, WASM_SEC_ORDER_PRODUCERS},
1955  // WASM_SEC_ORDER_PRODUCERS
1956  {WASM_SEC_ORDER_PRODUCERS, WASM_SEC_ORDER_TARGET_FEATURES},
1957  // WASM_SEC_ORDER_TARGET_FEATURES
1958  {WASM_SEC_ORDER_TARGET_FEATURES}};
1959 
1961  StringRef CustomSectionName) {
1962  int Order = getSectionOrder(ID, CustomSectionName);
1963  if (Order == WASM_SEC_ORDER_NONE)
1964  return true;
1965 
1966  // Disallowed predecessors we need to check for
1968 
1969  // Keep track of completed checks to avoid repeating work
1970  bool Checked[WASM_NUM_SEC_ORDERS] = {};
1971 
1972  int Curr = Order;
1973  while (true) {
1974  // Add new disallowed predecessors to work list
1975  for (size_t I = 0;; ++I) {
1976  int Next = DisallowedPredecessors[Curr][I];
1977  if (Next == WASM_SEC_ORDER_NONE)
1978  break;
1979  if (Checked[Next])
1980  continue;
1981  WorkList.push_back(Next);
1982  Checked[Next] = true;
1983  }
1984 
1985  if (WorkList.empty())
1986  break;
1987 
1988  // Consider next disallowed predecessor
1989  Curr = WorkList.pop_back_val();
1990  if (Seen[Curr])
1991  return false;
1992  }
1993 
1994  // Have not seen any disallowed predecessors
1995  Seen[Order] = true;
1996  return true;
1997 }
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_IMPORT
@ WASM_SEC_ORDER_IMPORT
Definition: Wasm.h:313
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:67
i
i
Definition: README.txt:29
llvm::object::WasmSectionOrderChecker
Definition: Wasm.h:304
llvm::wasm::WasmImport::Memory
WasmLimits Memory
Definition: Wasm.h:131
llvm::wasm::WASM_SYMBOL_TYPE_SECTION
@ WASM_SYMBOL_TYPE_SECTION
Definition: Wasm.h:372
llvm::object::WasmSectionOrderChecker::WASM_NUM_SEC_ORDERS
@ WASM_NUM_SEC_ORDERS
Definition: Wasm.h:342
llvm::wasm::WasmTag
Definition: Wasm.h:117
llvm::wasm::WasmDataSegment::Offset
WasmInitExpr Offset
Definition: Wasm.h:159
llvm::wasm::WASM_INIT_FUNCS
@ WASM_INIT_FUNCS
Definition: Wasm.h:346
llvm::StringSwitch::StartsWith
StringSwitch & StartsWith(StringLiteral S, T Value)
Definition: StringSwitch.h:81
LLVM_DUMP_METHOD
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:506
llvm::object::Kind
Kind
Definition: COFFModuleDefinition.cpp:33
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::wasm::WASM_DYLINK_NEEDED
@ WASM_DYLINK_NEEDED
Definition: Wasm.h:354
llvm::wasm::WasmElemSegment::Offset
WasmInitExpr Offset
Definition: Wasm.h:172
llvm::wasm::WASM_NAMES_FUNCTION
@ WASM_NAMES_FUNCTION
Definition: Wasm.h:337
llvm::object::WasmObjectFile::WasmObjectFile
WasmObjectFile(MemoryBufferRef Object, Error &Err)
Definition: WasmObjectFile.cpp:260
llvm::StringRef::empty
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
llvm::wasm::NameType
NameType
Definition: Wasm.h:215
llvm::object::DataRefImpl::a
uint32_t a
Definition: SymbolicFile.h:37
llvm::object::WasmObjectFile::symbol_begin
basic_symbol_iterator symbol_begin() const override
Definition: WasmObjectFile.cpp:1558
llvm::wasm::WASM_SEC_CUSTOM
@ WASM_SEC_CUSTOM
Definition: Wasm.h:235
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_DATA
@ WASM_SEC_ORDER_DATA
Definition: Wasm.h:324
type
llvm::wasm::WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND
const unsigned WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND
Definition: Wasm.h:326
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_START
@ WASM_SEC_ORDER_START
Definition: Wasm.h:320
llvm::object::WasmObjectFile::getFeatures
SubtargetFeatures getFeatures() const override
Definition: WasmObjectFile.cpp:1837
llvm::object::WasmObjectFile::ReadContext::Start
const uint8_t * Start
Definition: Wasm.h:211
llvm::Triple::wasm32
@ wasm32
Definition: Triple.h:99
llvm::Function::empty
bool empty() const
Definition: Function.h:740
T
llvm::object::WasmSection::Content
ArrayRef< uint8_t > Content
Definition: Wasm.h:111
llvm::Function
Definition: Function.h:62
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_LINKING
@ WASM_SEC_ORDER_LINKING
Definition: Wasm.h:330
StringRef.h
llvm::StringSwitch::Default
LLVM_NODISCARD R Default(T Value)
Definition: StringSwitch.h:181
llvm::wasm::WasmVersion
const uint32_t WasmVersion
Definition: Wasm.h:28
TAG
static constexpr auto TAG
Definition: OpenMPOpt.cpp:148
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_PRODUCERS
@ WASM_SEC_ORDER_PRODUCERS
Definition: Wasm.h:337
llvm::object::ObjectFile::RelocationRef
friend class RelocationRef
Definition: ObjectFile.h:286
llvm::wasm::WASM_SEC_DATACOUNT
@ WASM_SEC_DATACOUNT
Definition: Wasm.h:247
llvm::toString
std::string toString(Error E)
Write all error messages (if any) in E to a string.
Definition: Error.h:1020
llvm::object::WasmObjectFile::getBytesInAddress
uint8_t getBytesInAddress() const override
The number of bytes used to represent an address in this object file format.
Definition: WasmObjectFile.cpp:1827
llvm::wasm::WasmFeatureEntry
Definition: Wasm.h:66
llvm::object::WasmSectionOrderChecker::isValidSectionOrder
bool isValidSectionOrder(unsigned ID, StringRef CustomSectionName="")
Definition: WasmObjectFile.cpp:1960
llvm::object::ObjectFile::createWasmObjectFile
static Expected< std::unique_ptr< WasmObjectFile > > createWasmObjectFile(MemoryBufferRef Object)
Definition: WasmObjectFile.cpp:58
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::wasm::WasmObjectHeader::Version
uint32_t Version
Definition: Wasm.h:36
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_TARGET_FEATURES
@ WASM_SEC_ORDER_TARGET_FEATURES
Definition: Wasm.h:339
llvm::object::WasmSymbol::Info
const wasm::WasmSymbolInfo & Info
Definition: Wasm.h:44
llvm::dwarf::Form
Form
Definition: Dwarf.h:131
llvm::wasm::WASM_COMDAT_FUNCTION
@ WASM_COMDAT_FUNCTION
Definition: Wasm.h:362
ErrorHandling.h
llvm::wasm::WasmLinkingData::SymbolTable
std::vector< WasmSymbolInfo > SymbolTable
Definition: Wasm.h:231
llvm::object::WasmSymbol::isDefined
bool isDefined() const
Definition: Wasm.h:67
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
readVaruint32
static uint32_t readVaruint32(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:148
llvm::wasm::WasmFunction::Comdat
uint32_t Comdat
Definition: Wasm.h:151
llvm::wasm::WASM_SYMBOL_BINDING_LOCAL
const unsigned WASM_SYMBOL_BINDING_LOCAL
Definition: Wasm.h:392
llvm::wasm::WASM_SYMBOL_TYPE_TABLE
@ WASM_SYMBOL_TYPE_TABLE
Definition: Wasm.h:374
llvm::wasm::WASM_SEC_ELEM
@ WASM_SEC_ELEM
Definition: Wasm.h:244
llvm::wasm::WASM_SYMBOL_TYPE_GLOBAL
@ WASM_SYMBOL_TYPE_GLOBAL
Definition: Wasm.h:371
llvm::object::WasmSection
Definition: Wasm.h:104
Error.h
llvm::wasm::WasmRelocation
Definition: Wasm.h:184
llvm::wasm::WasmImport::Table
WasmTableType Table
Definition: Wasm.h:130
llvm::object::WasmSymbol::isTypeFunction
bool isTypeFunction() const
Definition: Wasm.h:49
llvm::object::ObjectFile::getSymbolValue
Expected< uint64_t > getSymbolValue(DataRefImpl Symb) const
Definition: ObjectFile.cpp:57
llvm::object::relocation_iterator
content_iterator< RelocationRef > relocation_iterator
Definition: ObjectFile.h:76
llvm::wasm::WasmDylinkInfo::ImportInfo
std::vector< WasmDylinkImportInfo > ImportInfo
Definition: Wasm.h:56
llvm::wasm::WASM_SEC_GLOBAL
@ WASM_SEC_GLOBAL
Definition: Wasm.h:241
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::object::WasmObjectFile::isSectionCompressed
bool isSectionCompressed(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1743
llvm::wasm::WasmImport::SigIndex
uint32_t SigIndex
Definition: Wasm.h:128
llvm::object::Binary::Data
MemoryBufferRef Data
Definition: Binary.h:37
readVaruint1
static uint8_t readVaruint1(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:134
llvm::wasm::WASM_LIMITS_FLAG_IS_64
@ WASM_LIMITS_FLAG_IS_64
Definition: Wasm.h:313
llvm::wasm::WASM_OPCODE_I32_CONST
@ WASM_OPCODE_I32_CONST
Definition: Wasm.h:283
llvm::SmallSet
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
llvm::wasm::WasmElemSegment::ElemKind
uint8_t ElemKind
Definition: Wasm.h:171
llvm::object::WasmObjectFile::getSectionName
Expected< StringRef > getSectionName(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1693
llvm::wasm::WASM_TYPE_EXTERNREF
@ WASM_TYPE_EXTERNREF
Definition: Wasm.h:259
llvm::wasm::WASM_SYMBOL_UNDEFINED
const unsigned WASM_SYMBOL_UNDEFINED
Definition: Wasm.h:395
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::object::WasmObjectFile::getSymbolValueImpl
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1619
llvm::object::WasmObjectFile::getRelocationTypeName
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
Definition: WasmObjectFile.cpp:1796
llvm::object::WasmObjectFile::isSectionBSS
bool isSectionBSS(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1755
llvm::wasm::WasmSymbolInfo::Kind
uint8_t Kind
Definition: Wasm.h:198
llvm::StringSet::insert
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition: StringSet.h:33
llvm::object::SymbolRef::ST_Data
@ ST_Data
Definition: ObjectFile.h:173
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
STLExtras.h
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:635
llvm::wasm::WasmFunction
Definition: Wasm.h:140
llvm::object::BasicSymbolRef::SF_Weak
@ SF_Weak
Definition: SymbolicFile.h:110
llvm::wasm::WasmExport::Kind
uint8_t Kind
Definition: Wasm.h:73
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:104
SymbolicFile.h
llvm::object::WasmObjectFile::isRelocatableObject
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
Definition: WasmObjectFile.cpp:1841
llvm::object::WasmObjectFile::getArch
Triple::ArchType getArch() const override
Definition: WasmObjectFile.cpp:1833
llvm::wasm::WasmDataReference::Offset
uint64_t Offset
Definition: Wasm.h:180
llvm::detail::DenseSetImpl::insert
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
llvm::wasm::WasmDataReference
Definition: Wasm.h:178
readInitExpr
static Error readInitExpr(wasm::WasmInitExpr &Expr, WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:167
llvm::wasm::WasmExport::Index
uint32_t Index
Definition: Wasm.h:74
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_NAME
@ WASM_SEC_ORDER_NAME
Definition: Wasm.h:335
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::object::BasicSymbolRef::SF_Executable
@ SF_Executable
Definition: SymbolicFile.h:120
llvm::ArrayRef::data
const T * data() const
Definition: ArrayRef.h:162
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::object::WasmObjectFile::moveSectionNext
void moveSectionNext(DataRefImpl &Sec) const override
Definition: WasmObjectFile.cpp:1691
llvm::wasm::WasmRelocation::Offset
uint64_t Offset
Definition: Wasm.h:187
llvm::object::WasmSymbol::isHidden
bool isHidden() const
Definition: Wasm.h:89
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_GLOBAL
@ WASM_SEC_ORDER_GLOBAL
Definition: Wasm.h:318
llvm::ARMBuildAttrs::Section
@ Section
Legacy Tags.
Definition: ARMBuildAttributes.h:78
llvm::StringRef::substr
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:611
llvm::wasm::WASM_SEGMENT_INFO
@ WASM_SEGMENT_INFO
Definition: Wasm.h:345
readULEB128
static uint64_t readULEB128(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:104
readVarint32
static int32_t readVarint32(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:141
llvm::wasm::WasmElemSegment::TableNumber
uint32_t TableNumber
Definition: Wasm.h:170
llvm::decodeULEB128
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:128
llvm::wasm::WASM_SYMBOL_BINDING_WEAK
const unsigned WASM_SYMBOL_BINDING_WEAK
Definition: Wasm.h:391
llvm::wasm::WasmFunction::DebugName
StringRef DebugName
Definition: Wasm.h:150
llvm::object::WasmSection::Type
uint32_t Type
Definition: Wasm.h:107
Error.h
SubtargetFeature.h
llvm::wasm::WasmInitExpr::Global
uint32_t Global
Definition: Wasm.h:101
llvm::Triple::ArchType
ArchType
Definition: Triple.h:47
llvm::object::WasmObjectFile::ReadContext::End
const uint8_t * End
Definition: Wasm.h:213
llvm::ModRefInfo::Ref
@ Ref
The access may reference the value stored in memory.
llvm::object::WasmObjectFile::ReadContext::Ptr
const uint8_t * Ptr
Definition: Wasm.h:212
llvm::wasm::WASM_SEC_CODE
@ WASM_SEC_CODE
Definition: Wasm.h:245
llvm::wasm::WASM_SEC_TYPE
@ WASM_SEC_TYPE
Definition: Wasm.h:236
llvm::wasm::WasmGlobalType::Mutable
bool Mutable
Definition: Wasm.h:107
llvm::wasm::WasmLimits
Definition: Wasm.h:77
llvm::object::BasicSymbolRef::getRawDataRefImpl
DataRefImpl getRawDataRefImpl() const
Definition: SymbolicFile.h:206
llvm::wasm::WasmRelocation::Addend
int64_t Addend
Definition: Wasm.h:188
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_TAG
@ WASM_SEC_ORDER_TAG
Definition: Wasm.h:317
llvm::wasm::WasmInitExpr::Float64
uint64_t Float64
Definition: Wasm.h:100
llvm::wasm::WasmTableType::ElemType
uint8_t ElemType
Definition: Wasm.h:84
llvm::object::WasmObjectFile::getWasmRelocation
const wasm::WasmRelocation & getWasmRelocation(const RelocationRef &Ref) const
Definition: WasmObjectFile.cpp:1856
llvm::object::BasicSymbolRef
This is a value type class that represents a single symbol in the list of symbols in the object file.
Definition: SymbolicFile.h:101
llvm::object::WasmSymbol
Definition: Wasm.h:35
llvm::wasm::WasmFeatureEntry::Prefix
uint8_t Prefix
Definition: Wasm.h:67
llvm::wasm::WASM_SEC_IMPORT
@ WASM_SEC_IMPORT
Definition: Wasm.h:237
llvm::object::WasmObjectFile::isSectionText
bool isSectionText(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1747
llvm::object::WasmObjectFile::getSymbolAlignment
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1623
llvm::SubtargetFeatures
Manages the enabling and disabling of subtarget specific features.
Definition: SubtargetFeature.h:183
llvm::wasm::WasmInitExpr::Int64
int64_t Int64
Definition: Wasm.h:98
llvm::object::WasmObjectFile::getSymbolSectionId
uint32_t getSymbolSectionId(SymbolRef Sym) const
Definition: WasmObjectFile.cpp:1667
readUint8
static uint8_t readUint8(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:72
llvm::wasm::WasmGlobalType
Definition: Wasm.h:105
DenseSet.h
llvm::wasm::WasmFunction::CodeSectionOffset
uint32_t CodeSectionOffset
Definition: Wasm.h:145
llvm::wasm::WasmProducerInfo::Languages
std::vector< std::pair< std::string, std::string > > Languages
Definition: Wasm.h:61
llvm::wasm::WASM_EXTERNAL_MEMORY
@ WASM_EXTERNAL_MEMORY
Definition: Wasm.h:268
llvm::wasm::WASM_NAMES_DATA_SEGMENT
@ WASM_NAMES_DATA_SEGMENT
Definition: Wasm.h:340
llvm::wasm::WasmTable::SymbolName
StringRef SymbolName
Definition: Wasm.h:91
llvm::object::WasmObjectFile::getSymbolSection
Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1657
llvm::wasm::WASM_ELEM_SEGMENT_IS_PASSIVE
@ WASM_ELEM_SEGMENT_IS_PASSIVE
Definition: Wasm.h:322
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
llvm::wasm::WasmDylinkInfo::MemoryAlignment
uint32_t MemoryAlignment
Definition: Wasm.h:52
llvm::wasm::WasmDataReference::Size
uint64_t Size
Definition: Wasm.h:181
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::AMDGPU::ElfNote::SectionName
const char SectionName[]
Definition: AMDGPUPTNote.h:24
llvm::ErrorAsOutParameter
Helper for Errors used as out-parameters.
Definition: Error.h:1089
llvm::object::object_error::parse_failed
@ parse_failed
llvm::wasm::WASM_SYMBOL_TYPE_FUNCTION
@ WASM_SYMBOL_TYPE_FUNCTION
Definition: Wasm.h:369
llvm::object::WasmObjectFile::moveRelocationNext
void moveRelocationNext(DataRefImpl &Rel) const override
Definition: WasmObjectFile.cpp:1774
llvm::wasm::WASM_OPCODE_F64_CONST
@ WASM_OPCODE_F64_CONST
Definition: Wasm.h:286
llvm::wasm::WasmMetadataVersion
const uint32_t WasmMetadataVersion
Definition: Wasm.h:30
llvm::wasm::NameType::FUNCTION
@ FUNCTION
llvm::wasm::ValType
ValType
Definition: Wasm.h:410
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:991
llvm::wasm::WasmLocalDecl::Type
uint8_t Type
Definition: Wasm.h:136
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::wasm::WASM_NAMES_LOCAL
@ WASM_NAMES_LOCAL
Definition: Wasm.h:338
llvm::wasm::WasmTable::Type
WasmTableType Type
Definition: Wasm.h:90
llvm::Comdat
Definition: Comdat.h:31
llvm::object::WasmSymbol::isUndefined
bool isUndefined() const
Definition: Wasm.h:69
llvm::wasm::WASM_OPCODE_END
@ WASM_OPCODE_END
Definition: Wasm.h:275
llvm::wasm::WasmSymbolInfo::Name
StringRef Name
Definition: Wasm.h:197
llvm::object::WasmObjectFile::getHeader
const wasm::WasmObjectHeader & getHeader() const
Definition: WasmObjectFile.cpp:1534
Wasm.h
llvm::wasm::WasmImport::Field
StringRef Field
Definition: Wasm.h:125
llvm::wasm::WasmSymbolInfo::ElementIndex
uint32_t ElementIndex
Definition: Wasm.h:209
llvm::object::WasmSymbol::print
void print(raw_ostream &Out) const
Definition: WasmObjectFile.cpp:40
llvm::PassSummaryAction::Import
@ Import
Import information from summary.
llvm::wasm::WasmInitExpr::Float32
uint32_t Float32
Definition: Wasm.h:99
llvm::object::WasmObjectFile::getSectionIndex
uint64_t getSectionIndex(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1722
llvm::wasm::WasmObjectHeader::Magic
StringRef Magic
Definition: Wasm.h:35
readLEB128
static int64_t readLEB128(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:124
llvm::wasm::NameType::GLOBAL
@ GLOBAL
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_CODE
@ WASM_SEC_ORDER_CODE
Definition: Wasm.h:323
llvm::wasm::WasmLinkingData::Comdats
std::vector< StringRef > Comdats
Definition: Wasm.h:230
llvm::wasm::WasmLimits::Flags
uint8_t Flags
Definition: Wasm.h:78
llvm::wasm::WASM_EXTERNAL_TABLE
@ WASM_EXTERNAL_TABLE
Definition: Wasm.h:267
llvm::wasm::WASM_OPCODE_F32_CONST
@ WASM_OPCODE_F32_CONST
Definition: Wasm.h:285
llvm::object::SectionRef
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:80
llvm::wasm::WasmRelocation::Type
uint8_t Type
Definition: Wasm.h:185
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_MEMORY
@ WASM_SEC_ORDER_MEMORY
Definition: Wasm.h:316
llvm::DenseSet< uint64_t >
llvm::object::ObjectFile::SymbolRef
friend class SymbolRef
Definition: ObjectFile.h:246
llvm::object::DataRefImpl::d
struct llvm::object::DataRefImpl::@321 d
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_TYPE
@ WASM_SEC_ORDER_TYPE
Definition: Wasm.h:312
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
type
AMD64 Optimization Manual has some nice information about optimizing integer multiplication by a constant How much of it applies to Intel s X86 implementation There are definite trade offs to xmm0 cvttss2siq rdx jb L3 subss xmm0 rax cvttss2siq rdx xorq rdx rax ret instead of xmm1 cvttss2siq rcx movaps xmm2 subss xmm2 cvttss2siq rax rdx xorq rax ucomiss xmm0 cmovb rax ret Seems like the jb branch has high likelihood of being taken It would have saved a few instructions It s not possible to reference and DH registers in an instruction requiring REX prefix divb and mulb both produce results in AH If isel emits a CopyFromReg which gets turned into a movb and that can be allocated a r8b r15b To get around isel emits a CopyFromReg from AX and then right shift it down by and truncate it It s not pretty but it works We need some register allocation magic to make the hack go which would often require a callee saved register Callees usually need to keep this value live for most of their body so it doesn t add a significant burden on them We currently implement this in however this is suboptimal because it means that it would be quite awkward to implement the optimization for callers A better implementation would be to relax the LLVM IR rules for sret arguments to allow a function with an sret argument to have a non void return type
Definition: README-X86-64.txt:70
llvm::Twine::utohexstr
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:408
llvm::object::WasmSymbol::isBindingWeak
bool isBindingWeak() const
Definition: Wasm.h:73
llvm::wasm::WasmInitExpr::Value
union llvm::wasm::WasmInitExpr::@164 Value
llvm::wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER
@ WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER
Definition: Wasm.h:323
Index
uint32_t Index
Definition: ELFObjHandler.cpp:84
uint64_t
llvm::object::WasmObjectFile::getSymbolType
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1634
llvm::object::symbol_iterator
Definition: ObjectFile.h:207
llvm::StringRef::end
iterator end() const
Definition: StringRef.h:130
llvm::wasm::WasmElemSegment::Functions
std::vector< uint32_t > Functions
Definition: Wasm.h:173
llvm::object::SymbolRef::ST_Function
@ ST_Function
Definition: ObjectFile.h:176
llvm::wasm::ValType::EXTERNREF
@ EXTERNREF
llvm::wasm::WasmExport::Name
StringRef Name
Definition: Wasm.h:72
llvm::object::WasmObjectFile::section_begin
section_iterator section_begin() const override
Definition: WasmObjectFile.cpp:1815
llvm::wasm::WASM_SYMBOL_EXPLICIT_NAME
const unsigned WASM_SYMBOL_EXPLICIT_NAME
Definition: Wasm.h:397
LEB128.h
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::object::WasmSymbol::isTypeData
bool isTypeData() const
Definition: Wasm.h:55
llvm::object::BasicSymbolRef::SF_None
@ SF_None
Definition: SymbolicFile.h:107
llvm::wasm::WasmLocalDecl
Definition: Wasm.h:135
llvm::wasm::WASM_DYLINK_MEM_INFO
@ WASM_DYLINK_MEM_INFO
Definition: Wasm.h:353
llvm::wasm::ValType::FUNCREF
@ FUNCREF
llvm::object::ObjectFile::SectionRef
friend class SectionRef
Definition: ObjectFile.h:260
readUint32
static uint32_t readUint32(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:78
llvm::wasm::WasmProducerInfo::Tools
std::vector< std::pair< std::string, std::string > > Tools
Definition: Wasm.h:62
llvm::object::WasmObjectFile::getSymbolFlags
Expected< uint32_t > getSymbolFlags(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1540
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::object::BasicSymbolRef::SF_Undefined
@ SF_Undefined
Definition: SymbolicFile.h:108
llvm::wasm::WasmSignature::Returns
SmallVector< ValType, 1 > Returns
Definition: Wasm.h:421
llvm::wasm::WasmDylinkInfo::TableSize
uint32_t TableSize
Definition: Wasm.h:53
llvm::wasm::WasmImport
Definition: Wasm.h:123
ArrayRef.h
llvm::wasm::WASM_SYMBOL_TYPE_TAG
@ WASM_SYMBOL_TYPE_TAG
Definition: Wasm.h:373
llvm::wasm::WASM_DATA_SEGMENT_IS_PASSIVE
@ WASM_DATA_SEGMENT_IS_PASSIVE
Definition: Wasm.h:317
llvm::object::SymbolRef::ST_Debug
@ ST_Debug
Definition: ObjectFile.h:174
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::wasm::WASM_SEC_START
@ WASM_SEC_START
Definition: Wasm.h:243
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_NONE
@ WASM_SEC_ORDER_NONE
Definition: Wasm.h:309
llvm::wasm::WasmDebugName
Definition: Wasm.h:221
ObjectFile.h
llvm::object::WasmObjectFile::getSectionAddress
uint64_t getSectionAddress(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1720
readFloat64
static int64_t readFloat64(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:95
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::object::content_iterator
Definition: SymbolicFile.h:67
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_FUNCTION
@ WASM_SEC_ORDER_FUNCTION
Definition: Wasm.h:314
llvm::object::WasmObjectFile::getWasmSymbolValue
uint64_t getWasmSymbolValue(const WasmSymbol &Sym) const
Definition: WasmObjectFile.cpp:1593
llvm::object::WasmObjectFile::isSharedObject
bool isSharedObject() const
Definition: WasmObjectFile.cpp:1843
llvm::StringRef::bytes_begin
const unsigned char * bytes_begin() const
Definition: StringRef.h:132
llvm::ARM::WinEH::ReturnType
ReturnType
Definition: ARMWinEH.h:25
llvm::wasm::WASM_SEC_FUNCTION
@ WASM_SEC_FUNCTION
Definition: Wasm.h:238
llvm::object::WasmObjectFile::getSymbolName
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1580
llvm::wasm::WASM_SEC_TAG
@ WASM_SEC_TAG
Definition: Wasm.h:248
Triple.h
llvm::wasm::WASM_COMDAT_INFO
@ WASM_COMDAT_INFO
Definition: Wasm.h:347
llvm::StringSet
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition: StringSet.h:22
llvm::wasm::WasmElemSegment::Flags
uint32_t Flags
Definition: Wasm.h:169
llvm::wasm::WasmInitExpr::Int32
int32_t Int32
Definition: Wasm.h:97
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_EXPORT
@ WASM_SEC_ORDER_EXPORT
Definition: Wasm.h:319
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_TABLE
@ WASM_SEC_ORDER_TABLE
Definition: Wasm.h:315
llvm::ArrayRef< uint8_t >
llvm::object::section_iterator
content_iterator< SectionRef > section_iterator
Definition: ObjectFile.h:47
llvm::wasm::WasmDylinkInfo::ExportInfo
std::vector< WasmDylinkExportInfo > ExportInfo
Definition: Wasm.h:57
llvm::wasm::WASM_COMDAT_DATA
@ WASM_COMDAT_DATA
Definition: Wasm.h:361
readVarint64
static int64_t readVarint64(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:155
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::object::ObjectFile
This class is the base class for all object file types.
Definition: ObjectFile.h:228
llvm::object::Binary
Definition: Binary.h:32
llvm::object::WasmObjectFile::getSectionContents
Expected< ArrayRef< uint8_t > > getSectionContents(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1732
llvm::wasm::WASM_SEC_EXPORT
@ WASM_SEC_EXPORT
Definition: Wasm.h:242
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
llvm::wasm::WasmObjectHeader
Definition: Wasm.h:34
llvm::wasm::WasmGlobal
Definition: Wasm.h:110
uint32_t
llvm::wasm::WASM_SYMBOL_BINDING_MASK
const unsigned WASM_SYMBOL_BINDING_MASK
Definition: Wasm.h:387
llvm::wasm::WasmSymbolType
WasmSymbolType
Definition: Wasm.h:368
llvm::wasm::WASM_TYPE_FUNC
@ WASM_TYPE_FUNC
Definition: Wasm.h:260
llvm::wasm::WASM_SEC_DATA
@ WASM_SEC_DATA
Definition: Wasm.h:246
llvm::wasm::WASM_OPCODE_REF_NULL
@ WASM_OPCODE_REF_NULL
Definition: Wasm.h:289
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::object::DataRefImpl
Definition: SymbolicFile.h:33
llvm::object::WasmObjectFile::isSectionVirtual
bool isSectionVirtual(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1757
llvm::wasm::WasmTableType::Limits
WasmLimits Limits
Definition: Wasm.h:85
llvm::wasm::WasmSymbolInfo
Definition: Wasm.h:196
llvm::SmallSet::insert
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:180
llvm::wasm::WasmDylinkInfo::Needed
std::vector< StringRef > Needed
Definition: Wasm.h:55
llvm::wasm::WasmImport::Global
WasmGlobalType Global
Definition: Wasm.h:129
llvm::wasm::WasmGlobalType::Type
uint8_t Type
Definition: Wasm.h:106
llvm::object::object_error::invalid_section_index
@ invalid_section_index
llvm::Init
Definition: Record.h:271
readSection
static Error readSection(WasmSection &Section, WasmObjectFile::ReadContext &Ctx, WasmSectionOrderChecker &Checker)
Definition: WasmObjectFile.cpp:224
llvm::wasm::WasmSymbolInfo::DataRef
WasmDataReference DataRef
Definition: Wasm.h:211
llvm::object::WasmObjectFile::isSectionData
bool isSectionData(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1751
llvm::object::WasmObjectFile::getSectionSize
uint64_t getSectionSize(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1726
llvm::wasm::WasmProducerInfo::SDKs
std::vector< std::pair< std::string, std::string > > SDKs
Definition: Wasm.h:63
llvm::object::WasmObjectFile::getWasmSection
const WasmSection & getWasmSection(const SectionRef &Section) const
Definition: WasmObjectFile.cpp:1851
StringSet.h
llvm::wasm::WASM_SEC_MEMORY
@ WASM_SEC_MEMORY
Definition: Wasm.h:240
llvm::object::WasmObjectFile::ReadContext
Definition: Wasm.h:210
llvm::object::WasmObjectFile::getSectionAlignment
uint64_t getSectionAlignment(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1739
llvm::wasm::WasmDataReference::Segment
uint32_t Segment
Definition: Wasm.h:179
llvm::wasm::WASM_EXTERNAL_FUNCTION
@ WASM_EXTERNAL_FUNCTION
Definition: Wasm.h:266
llvm::object::WasmObjectFile::moveSymbolNext
void moveSymbolNext(DataRefImpl &Symb) const override
Definition: WasmObjectFile.cpp:1538
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
readFloat32
static int32_t readFloat32(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:86
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1231
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::wasm::WASM_FEATURE_PREFIX_DISALLOWED
@ WASM_FEATURE_PREFIX_DISALLOWED
Definition: Wasm.h:332
llvm::object::WasmObjectFile::getRelocationSymbol
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
Definition: WasmObjectFile.cpp:1781
llvm::wasm::WASM_OPCODE_I64_CONST
@ WASM_OPCODE_I64_CONST
Definition: Wasm.h:284
VARUINT1_MAX
#define VARUINT1_MAX
Definition: WasmObjectFile.cpp:70
llvm::wasm::WasmLinkingData::InitFunctions
std::vector< WasmInitFunc > InitFunctions
Definition: Wasm.h:229
llvm::SectionName
Definition: DWARFSection.h:21
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::wasm::WASM_EXTERNAL_GLOBAL
@ WASM_EXTERNAL_GLOBAL
Definition: Wasm.h:269
llvm::wasm::WasmDylinkInfo::MemorySize
uint32_t MemorySize
Definition: Wasm.h:51
llvm::object::WasmObjectFile::getWasmSymbol
const WasmSymbol & getWasmSymbol(const DataRefImpl &Symb) const
Definition: WasmObjectFile.cpp:1572
llvm::wasm::WasmInitFunc
Definition: Wasm.h:191
llvm::wasm::WasmSymbolInfo::Flags
uint32_t Flags
Definition: Wasm.h:199
llvm::wasm::WasmLocalDecl::Count
uint32_t Count
Definition: Wasm.h:137
readOpcode
static uint8_t readOpcode(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:163
readTableType
static wasm::WasmTableType readTableType(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:217
llvm::object::WasmObjectFile::section_end
section_iterator section_end() const override
Definition: WasmObjectFile.cpp:1821
llvm::wasm::WasmDataSegment
Definition: Wasm.h:154
llvm::wasm::WASM_OPCODE_GLOBAL_GET
@ WASM_OPCODE_GLOBAL_GET
Definition: Wasm.h:279
llvm::object::WasmObjectFile::getSymbolAddress
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1584
llvm::object::WasmObjectFile::getRelocationOffset
uint64_t getRelocationOffset(DataRefImpl Rel) const override
Definition: WasmObjectFile.cpp:1776
llvm::object::WasmObjectFile::symbol_end
basic_symbol_iterator symbol_end() const override
Definition: WasmObjectFile.cpp:1565
llvm::wasm::WasmInitExpr
Definition: Wasm.h:94
llvm::wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS
@ WASM_ELEM_SEGMENT_HAS_INIT_EXPRS
Definition: Wasm.h:324
StringSwitch.h
llvm::wasm::WasmFunction::ExportName
Optional< StringRef > ExportName
Definition: Wasm.h:148
llvm::wasm::WASM_LIMITS_FLAG_HAS_MAX
@ WASM_LIMITS_FLAG_HAS_MAX
Definition: Wasm.h:311
llvm::object::WasmObjectFile::section_rel_begin
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1759
llvm::wasm::WasmLinkingData::Version
uint32_t Version
Definition: Wasm.h:228
Wasm.h
llvm::object::SymbolRef::ST_Other
@ ST_Other
Definition: ObjectFile.h:177
llvm::wasm::WasmTable
Definition: Wasm.h:88
llvm::wasm::NameType::DATA_SEGMENT
@ DATA_SEGMENT
llvm::wasm::WASM_SEC_TABLE
@ WASM_SEC_TABLE
Definition: Wasm.h:239
llvm::decodeSLEB128
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:161
Binary.h
llvm::wasm::WasmImport::Module
StringRef Module
Definition: Wasm.h:124
llvm::wasm::WasmRelocation::Index
uint32_t Index
Definition: Wasm.h:186
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_ELEM
@ WASM_SEC_ORDER_ELEM
Definition: Wasm.h:321
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_DYLINK
@ WASM_SEC_ORDER_DYLINK
Definition: Wasm.h:328
llvm::support::endian::read32le
uint32_t read32le(const void *P)
Definition: Endian.h:381
llvm::object::WasmObjectFile::getCommonSymbolSizeImpl
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1628
llvm::wasm::WasmElemSegment
Definition: Wasm.h:168
llvm::wasm::WASM_EXTERNAL_TAG
@ WASM_EXTERNAL_TAG
Definition: Wasm.h:270
llvm::wasm::WASM_COMDAT_SECTION
@ WASM_COMDAT_SECTION
Definition: Wasm.h:364
llvm::object::BasicSymbolRef::SF_Global
@ SF_Global
Definition: SymbolicFile.h:109
llvm::object::BasicSymbolRef::SF_Hidden
@ SF_Hidden
Definition: SymbolicFile.h:118
llvm::wasm::WASM_DYLINK_EXPORT_INFO
@ WASM_DYLINK_EXPORT_INFO
Definition: Wasm.h:355
llvm::to_string
std::string to_string(const T &Value)
Definition: ScopedPrinter.h:63
readVaruint64
static uint64_t readVaruint64(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:159
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
llvm::wasm::WASM_SYMBOL_TABLE
@ WASM_SYMBOL_TABLE
Definition: Wasm.h:348
llvm::wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX
@ WASM_DATA_SEGMENT_HAS_MEMINDEX
Definition: Wasm.h:318
llvm::pdb::PDB_DataKind::Global
@ Global
llvm::SmallVectorImpl< char >
llvm::wasm::WasmFeatureEntry::Name
std::string Name
Definition: Wasm.h:68
llvm::object::SymbolRef
This is a value type class that represents a single symbol in the list of symbols in the object file.
Definition: ObjectFile.h:167
llvm::object::Binary::getData
StringRef getData() const
Definition: Binary.cpp:40
llvm::wasm::WASM_FEATURE_PREFIX_REQUIRED
@ WASM_FEATURE_PREFIX_REQUIRED
Definition: Wasm.h:331
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
llvm::wasm::WASM_TYPE_FUNCREF
@ WASM_TYPE_FUNCREF
Definition: Wasm.h:258
llvm::wasm::WasmInitExpr::Opcode
uint8_t Opcode
Definition: Wasm.h:95
ECase
#define ECase(X)
llvm::object::DataRefImpl::b
uint32_t b
Definition: SymbolicFile.h:37
llvm::object::WasmSymbol::dump
LLVM_DUMP_METHOD void dump() const
Definition: WasmObjectFile.cpp:54
llvm::wasm::WasmImport::Kind
uint8_t Kind
Definition: Wasm.h:126
llvm::object::WasmObjectFile::getRelocationType
uint64_t getRelocationType(DataRefImpl Rel) const override
Definition: WasmObjectFile.cpp:1791
llvm::object::RelocationRef
This is a value type class that represents a single relocation in the list of relocations in the obje...
Definition: ObjectFile.h:51
readString
static StringRef readString(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:114
llvm::object::WasmSectionOrderChecker::DisallowedPredecessors
static int DisallowedPredecessors[WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS]
Definition: Wasm.h:347
llvm::object::WasmObjectFile::section_rel_end
relocation_iterator section_rel_end(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1766
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::SmallVectorImpl::reserve
void reserve(size_type N)
Definition: SmallVector.h:624
llvm::wasm::WasmTableType
Definition: Wasm.h:83
Endian.h
llvm::StringRef::begin
iterator begin() const
Definition: StringRef.h:128
llvm::Triple::wasm64
@ wasm64
Definition: Triple.h:100
llvm::wasm::WasmDylinkInfo::TableAlignment
uint32_t TableAlignment
Definition: Wasm.h:54
llvm::wasm::WasmSignature::Params
SmallVector< ValType, 4 > Params
Definition: Wasm.h:422
llvm::object::WasmSection::Relocations
std::vector< wasm::WasmRelocation > Relocations
Definition: Wasm.h:112
llvm::object::WasmObjectFile::getFileFormatName
StringRef getFileFormatName() const override
Definition: WasmObjectFile.cpp:1831
llvm::wasm::WasmExport
Definition: Wasm.h:71
llvm::wasm::WASM_SYMBOL_TYPE_DATA
@ WASM_SYMBOL_TYPE_DATA
Definition: Wasm.h:370
llvm::wasm::WASM_DYLINK_IMPORT_INFO
@ WASM_DYLINK_IMPORT_INFO
Definition: Wasm.h:356
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_RELOC
@ WASM_SEC_ORDER_RELOC
Definition: Wasm.h:332
llvm::wasm::WasmSignature
Definition: Wasm.h:420
llvm::Optional::getValue
constexpr const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:282
llvm::wasm::WASM_NAMES_GLOBAL
@ WASM_NAMES_GLOBAL
Definition: Wasm.h:339
readLimits
static wasm::WasmLimits readLimits(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:208
llvm::wasm::WASM_FEATURE_PREFIX_USED
@ WASM_FEATURE_PREFIX_USED
Definition: Wasm.h:330
llvm::object::WasmSymbol::isBindingLocal
bool isBindingLocal() const
Definition: Wasm.h:81
SmallSet.h
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_DATACOUNT
@ WASM_SEC_ORDER_DATACOUNT
Definition: Wasm.h:322
ScopedPrinter.h