LLVM  15.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/SmallSet.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/ADT/StringSet.h"
14 #include "llvm/ADT/StringSwitch.h"
15 #include "llvm/ADT/Triple.h"
16 #include "llvm/BinaryFormat/Wasm.h"
18 #include "llvm/Object/Binary.h"
19 #include "llvm/Object/Error.h"
20 #include "llvm/Object/ObjectFile.h"
22 #include "llvm/Object/Wasm.h"
23 #include "llvm/Support/Endian.h"
24 #include "llvm/Support/Error.h"
26 #include "llvm/Support/LEB128.h"
28 #include <algorithm>
29 #include <cassert>
30 #include <cstdint>
31 #include <cstring>
32 
33 #define DEBUG_TYPE "wasm-object"
34 
35 using namespace llvm;
36 using namespace object;
37 
38 void WasmSymbol::print(raw_ostream &Out) const {
39  Out << "Name=" << Info.Name
40  << ", Kind=" << toString(wasm::WasmSymbolType(Info.Kind)) << ", Flags=0x"
42  if (!isTypeData()) {
43  Out << ", ElemIndex=" << Info.ElementIndex;
44  } else if (isDefined()) {
45  Out << ", Segment=" << Info.DataRef.Segment;
46  Out << ", Offset=" << Info.DataRef.Offset;
47  Out << ", Size=" << Info.DataRef.Size;
48  }
49 }
50 
51 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
53 #endif
54 
57  Error Err = Error::success();
58  auto ObjectFile = std::make_unique<WasmObjectFile>(Buffer, Err);
59  if (Err)
60  return std::move(Err);
61 
62  return std::move(ObjectFile);
63 }
64 
65 #define VARINT7_MAX ((1 << 7) - 1)
66 #define VARINT7_MIN (-(1 << 7))
67 #define VARUINT7_MAX (1 << 7)
68 #define VARUINT1_MAX (1)
69 
70 static uint8_t readUint8(WasmObjectFile::ReadContext &Ctx) {
71  if (Ctx.Ptr == Ctx.End)
72  report_fatal_error("EOF while reading uint8");
73  return *Ctx.Ptr++;
74 }
75 
76 static uint32_t readUint32(WasmObjectFile::ReadContext &Ctx) {
77  if (Ctx.Ptr + 4 > Ctx.End)
78  report_fatal_error("EOF while reading uint32");
79  uint32_t Result = support::endian::read32le(Ctx.Ptr);
80  Ctx.Ptr += 4;
81  return Result;
82 }
83 
84 static int32_t readFloat32(WasmObjectFile::ReadContext &Ctx) {
85  if (Ctx.Ptr + 4 > Ctx.End)
86  report_fatal_error("EOF while reading float64");
87  int32_t Result = 0;
88  memcpy(&Result, Ctx.Ptr, sizeof(Result));
89  Ctx.Ptr += sizeof(Result);
90  return Result;
91 }
92 
93 static int64_t readFloat64(WasmObjectFile::ReadContext &Ctx) {
94  if (Ctx.Ptr + 8 > Ctx.End)
95  report_fatal_error("EOF while reading float64");
96  int64_t Result = 0;
97  memcpy(&Result, Ctx.Ptr, sizeof(Result));
98  Ctx.Ptr += sizeof(Result);
99  return Result;
100 }
101 
102 static uint64_t readULEB128(WasmObjectFile::ReadContext &Ctx) {
103  unsigned Count;
104  const char *Error = nullptr;
105  uint64_t Result = decodeULEB128(Ctx.Ptr, &Count, Ctx.End, &Error);
106  if (Error)
108  Ctx.Ptr += Count;
109  return Result;
110 }
111 
112 static StringRef readString(WasmObjectFile::ReadContext &Ctx) {
113  uint32_t StringLen = readULEB128(Ctx);
114  if (Ctx.Ptr + StringLen > Ctx.End)
115  report_fatal_error("EOF while reading string");
116  StringRef Return =
117  StringRef(reinterpret_cast<const char *>(Ctx.Ptr), StringLen);
118  Ctx.Ptr += StringLen;
119  return Return;
120 }
121 
122 static int64_t readLEB128(WasmObjectFile::ReadContext &Ctx) {
123  unsigned Count;
124  const char *Error = nullptr;
125  uint64_t Result = decodeSLEB128(Ctx.Ptr, &Count, Ctx.End, &Error);
126  if (Error)
128  Ctx.Ptr += Count;
129  return Result;
130 }
131 
132 static uint8_t readVaruint1(WasmObjectFile::ReadContext &Ctx) {
133  int64_t Result = readLEB128(Ctx);
134  if (Result > VARUINT1_MAX || Result < 0)
135  report_fatal_error("LEB is outside Varuint1 range");
136  return Result;
137 }
138 
139 static int32_t readVarint32(WasmObjectFile::ReadContext &Ctx) {
140  int64_t Result = readLEB128(Ctx);
141  if (Result > INT32_MAX || Result < INT32_MIN)
142  report_fatal_error("LEB is outside Varint32 range");
143  return Result;
144 }
145 
146 static uint32_t readVaruint32(WasmObjectFile::ReadContext &Ctx) {
147  uint64_t Result = readULEB128(Ctx);
148  if (Result > UINT32_MAX)
149  report_fatal_error("LEB is outside Varuint32 range");
150  return Result;
151 }
152 
153 static int64_t readVarint64(WasmObjectFile::ReadContext &Ctx) {
154  return readLEB128(Ctx);
155 }
156 
157 static uint64_t readVaruint64(WasmObjectFile::ReadContext &Ctx) {
158  return readULEB128(Ctx);
159 }
160 
161 static uint8_t readOpcode(WasmObjectFile::ReadContext &Ctx) {
162  return readUint8(Ctx);
163 }
164 
166  WasmObjectFile::ReadContext &Ctx) {
167  auto Start = Ctx.Ptr;
168 
169  Expr.Extended = false;
170  Expr.Inst.Opcode = readOpcode(Ctx);
171  switch (Expr.Inst.Opcode) {
173  Expr.Inst.Value.Int32 = readVarint32(Ctx);
174  break;
176  Expr.Inst.Value.Int64 = readVarint64(Ctx);
177  break;
179  Expr.Inst.Value.Float32 = readFloat32(Ctx);
180  break;
182  Expr.Inst.Value.Float64 = readFloat64(Ctx);
183  break;
185  Expr.Inst.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  Expr.Extended = true;
197  }
198 
199  if (!Expr.Extended) {
200  uint8_t EndOpcode = readOpcode(Ctx);
201  if (EndOpcode != wasm::WASM_OPCODE_END)
202  Expr.Extended = true;
203  }
204 
205  if (Expr.Extended) {
206  Ctx.Ptr = Start;
207  while (1) {
208  uint8_t Opcode = readOpcode(Ctx);
209  switch (Opcode) {
216  readULEB128(Ctx);
217  break;
224  break;
226  Expr.Body = ArrayRef<uint8_t>(Start, Ctx.Ptr - Start);
227  return Error::success();
228  default:
229  return make_error<GenericBinaryError>(
230  Twine("invalid opcode in init_expr: ") + Twine(unsigned(Opcode)),
232  }
233  }
234  }
235 
236  return Error::success();
237 }
238 
239 static wasm::WasmLimits readLimits(WasmObjectFile::ReadContext &Ctx) {
240  wasm::WasmLimits Result;
241  Result.Flags = readVaruint32(Ctx);
242  Result.Minimum = readVaruint64(Ctx);
243  if (Result.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
244  Result.Maximum = readVaruint64(Ctx);
245  return Result;
246 }
247 
248 static wasm::WasmTableType readTableType(WasmObjectFile::ReadContext &Ctx) {
249  wasm::WasmTableType TableType;
250  TableType.ElemType = readUint8(Ctx);
251  TableType.Limits = readLimits(Ctx);
252  return TableType;
253 }
254 
255 static Error readSection(WasmSection &Section, WasmObjectFile::ReadContext &Ctx,
256  WasmSectionOrderChecker &Checker) {
257  Section.Offset = Ctx.Ptr - Ctx.Start;
258  Section.Type = readUint8(Ctx);
259  LLVM_DEBUG(dbgs() << "readSection type=" << Section.Type << "\n");
260  uint32_t Size = readVaruint32(Ctx);
261  if (Size == 0)
262  return make_error<StringError>("zero length section",
264  if (Ctx.Ptr + Size > Ctx.End)
265  return make_error<StringError>("section too large",
267  if (Section.Type == wasm::WASM_SEC_CUSTOM) {
268  WasmObjectFile::ReadContext SectionCtx;
269  SectionCtx.Start = Ctx.Ptr;
270  SectionCtx.Ptr = Ctx.Ptr;
271  SectionCtx.End = Ctx.Ptr + Size;
272 
273  Section.Name = readString(SectionCtx);
274 
275  uint32_t SectionNameSize = SectionCtx.Ptr - SectionCtx.Start;
276  Ctx.Ptr += SectionNameSize;
277  Size -= SectionNameSize;
278  }
279 
280  if (!Checker.isValidSectionOrder(Section.Type, Section.Name)) {
281  return make_error<StringError>("out of order section type: " +
282  llvm::to_string(Section.Type),
284  }
285 
286  Section.Content = ArrayRef<uint8_t>(Ctx.Ptr, Size);
287  Ctx.Ptr += Size;
288  return Error::success();
289 }
290 
292  : ObjectFile(Binary::ID_Wasm, Buffer) {
293  ErrorAsOutParameter ErrAsOutParam(&Err);
294  Header.Magic = getData().substr(0, 4);
295  if (Header.Magic != StringRef("\0asm", 4)) {
296  Err = make_error<StringError>("invalid magic number",
298  return;
299  }
300 
301  ReadContext Ctx;
302  Ctx.Start = getData().bytes_begin();
303  Ctx.Ptr = Ctx.Start + 4;
304  Ctx.End = Ctx.Start + getData().size();
305 
306  if (Ctx.Ptr + 4 > Ctx.End) {
307  Err = make_error<StringError>("missing version number",
309  return;
310  }
311 
312  Header.Version = readUint32(Ctx);
313  if (Header.Version != wasm::WasmVersion) {
314  Err = make_error<StringError>("invalid version number: " +
315  Twine(Header.Version),
317  return;
318  }
319 
320  WasmSectionOrderChecker Checker;
321  while (Ctx.Ptr < Ctx.End) {
322  WasmSection Sec;
323  if ((Err = readSection(Sec, Ctx, Checker)))
324  return;
325  if ((Err = parseSection(Sec)))
326  return;
327 
328  Sections.push_back(Sec);
329  }
330 }
331 
332 Error WasmObjectFile::parseSection(WasmSection &Sec) {
333  ReadContext Ctx;
334  Ctx.Start = Sec.Content.data();
335  Ctx.End = Ctx.Start + Sec.Content.size();
336  Ctx.Ptr = Ctx.Start;
337  switch (Sec.Type) {
339  return parseCustomSection(Sec, Ctx);
340  case wasm::WASM_SEC_TYPE:
341  return parseTypeSection(Ctx);
343  return parseImportSection(Ctx);
345  return parseFunctionSection(Ctx);
347  return parseTableSection(Ctx);
349  return parseMemorySection(Ctx);
350  case wasm::WASM_SEC_TAG:
351  return parseTagSection(Ctx);
353  return parseGlobalSection(Ctx);
355  return parseExportSection(Ctx);
357  return parseStartSection(Ctx);
358  case wasm::WASM_SEC_ELEM:
359  return parseElemSection(Ctx);
360  case wasm::WASM_SEC_CODE:
361  return parseCodeSection(Ctx);
362  case wasm::WASM_SEC_DATA:
363  return parseDataSection(Ctx);
365  return parseDataCountSection(Ctx);
366  default:
367  return make_error<GenericBinaryError>(
368  "invalid section type: " + Twine(Sec.Type), object_error::parse_failed);
369  }
370 }
371 
372 Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) {
373  // Legacy "dylink" section support.
374  // See parseDylink0Section for the current "dylink.0" section parsing.
375  HasDylinkSection = true;
376  DylinkInfo.MemorySize = readVaruint32(Ctx);
377  DylinkInfo.MemoryAlignment = readVaruint32(Ctx);
378  DylinkInfo.TableSize = readVaruint32(Ctx);
379  DylinkInfo.TableAlignment = readVaruint32(Ctx);
380  uint32_t Count = readVaruint32(Ctx);
381  while (Count--) {
382  DylinkInfo.Needed.push_back(readString(Ctx));
383  }
384 
385  if (Ctx.Ptr != Ctx.End)
386  return make_error<GenericBinaryError>("dylink section ended prematurely",
388  return Error::success();
389 }
390 
391 Error WasmObjectFile::parseDylink0Section(ReadContext &Ctx) {
392  // See
393  // https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md
394  HasDylinkSection = true;
395 
396  const uint8_t *OrigEnd = Ctx.End;
397  while (Ctx.Ptr < OrigEnd) {
398  Ctx.End = OrigEnd;
399  uint8_t Type = readUint8(Ctx);
400  uint32_t Size = readVaruint32(Ctx);
401  LLVM_DEBUG(dbgs() << "readSubsection type=" << int(Type) << " size=" << Size
402  << "\n");
403  Ctx.End = Ctx.Ptr + Size;
404  uint32_t Count;
405  switch (Type) {
407  DylinkInfo.MemorySize = readVaruint32(Ctx);
408  DylinkInfo.MemoryAlignment = readVaruint32(Ctx);
409  DylinkInfo.TableSize = readVaruint32(Ctx);
410  DylinkInfo.TableAlignment = readVaruint32(Ctx);
411  break;
413  Count = readVaruint32(Ctx);
414  while (Count--) {
415  DylinkInfo.Needed.push_back(readString(Ctx));
416  }
417  break;
419  uint32_t Count = readVaruint32(Ctx);
420  while (Count--) {
421  DylinkInfo.ExportInfo.push_back({readString(Ctx), readVaruint32(Ctx)});
422  }
423  break;
424  }
426  uint32_t Count = readVaruint32(Ctx);
427  while (Count--) {
428  DylinkInfo.ImportInfo.push_back(
429  {readString(Ctx), readString(Ctx), readVaruint32(Ctx)});
430  }
431  break;
432  }
433  default:
434  LLVM_DEBUG(dbgs() << "unknown dylink.0 sub-section: " << Type << "\n");
435  Ctx.Ptr += Size;
436  break;
437  }
438  if (Ctx.Ptr != Ctx.End) {
439  return make_error<GenericBinaryError>(
440  "dylink.0 sub-section ended prematurely", object_error::parse_failed);
441  }
442  }
443 
444  if (Ctx.Ptr != Ctx.End)
445  return make_error<GenericBinaryError>("dylink.0 section ended prematurely",
447  return Error::success();
448 }
449 
450 Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
451  llvm::DenseSet<uint64_t> SeenFunctions;
452  llvm::DenseSet<uint64_t> SeenGlobals;
453  llvm::DenseSet<uint64_t> SeenSegments;
454  if (Functions.size() && !SeenCodeSection) {
455  return make_error<GenericBinaryError>("names must come after code section",
457  }
458 
459  while (Ctx.Ptr < Ctx.End) {
460  uint8_t Type = readUint8(Ctx);
461  uint32_t Size = readVaruint32(Ctx);
462  const uint8_t *SubSectionEnd = Ctx.Ptr + Size;
463  switch (Type) {
467  uint32_t Count = readVaruint32(Ctx);
468  while (Count--) {
470  StringRef Name = readString(Ctx);
473  if (!SeenFunctions.insert(Index).second)
474  return make_error<GenericBinaryError>(
475  "function named more than once", object_error::parse_failed);
476  if (!isValidFunctionIndex(Index) || Name.empty())
477  return make_error<GenericBinaryError>("invalid name entry",
479 
480  if (isDefinedFunctionIndex(Index))
481  getDefinedFunction(Index).DebugName = Name;
482  } else if (Type == wasm::WASM_NAMES_GLOBAL) {
483  nameType = wasm::NameType::GLOBAL;
484  if (!SeenGlobals.insert(Index).second)
485  return make_error<GenericBinaryError>("global named more than once",
487  if (!isValidGlobalIndex(Index) || Name.empty())
488  return make_error<GenericBinaryError>("invalid name entry",
490  } else {
491  nameType = wasm::NameType::DATA_SEGMENT;
492  if (!SeenSegments.insert(Index).second)
493  return make_error<GenericBinaryError>(
494  "segment named more than once", object_error::parse_failed);
495  if (Index > DataSegments.size())
496  return make_error<GenericBinaryError>("invalid named data segment",
498  }
499  DebugNames.push_back(wasm::WasmDebugName{nameType, Index, Name});
500  }
501  break;
502  }
503  // Ignore local names for now
505  default:
506  Ctx.Ptr += Size;
507  break;
508  }
509  if (Ctx.Ptr != SubSectionEnd)
510  return make_error<GenericBinaryError>(
511  "name sub-section ended prematurely", object_error::parse_failed);
512  }
513 
514  if (Ctx.Ptr != Ctx.End)
515  return make_error<GenericBinaryError>("name section ended prematurely",
517  return Error::success();
518 }
519 
520 Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {
521  HasLinkingSection = true;
522  if (Functions.size() && !SeenCodeSection) {
523  return make_error<GenericBinaryError>(
524  "linking data must come after code section",
526  }
527 
528  LinkingData.Version = readVaruint32(Ctx);
529  if (LinkingData.Version != wasm::WasmMetadataVersion) {
530  return make_error<GenericBinaryError>(
531  "unexpected metadata version: " + Twine(LinkingData.Version) +
532  " (Expected: " + Twine(wasm::WasmMetadataVersion) + ")",
534  }
535 
536  const uint8_t *OrigEnd = Ctx.End;
537  while (Ctx.Ptr < OrigEnd) {
538  Ctx.End = OrigEnd;
539  uint8_t Type = readUint8(Ctx);
540  uint32_t Size = readVaruint32(Ctx);
541  LLVM_DEBUG(dbgs() << "readSubsection type=" << int(Type) << " size=" << Size
542  << "\n");
543  Ctx.End = Ctx.Ptr + Size;
544  switch (Type) {
546  if (Error Err = parseLinkingSectionSymtab(Ctx))
547  return Err;
548  break;
550  uint32_t Count = readVaruint32(Ctx);
551  if (Count > DataSegments.size())
552  return make_error<GenericBinaryError>("too many segment names",
554  for (uint32_t I = 0; I < Count; I++) {
555  DataSegments[I].Data.Name = readString(Ctx);
556  DataSegments[I].Data.Alignment = readVaruint32(Ctx);
557  DataSegments[I].Data.LinkingFlags = readVaruint32(Ctx);
558  }
559  break;
560  }
561  case wasm::WASM_INIT_FUNCS: {
562  uint32_t Count = readVaruint32(Ctx);
563  LinkingData.InitFunctions.reserve(Count);
564  for (uint32_t I = 0; I < Count; I++) {
566  Init.Priority = readVaruint32(Ctx);
567  Init.Symbol = readVaruint32(Ctx);
568  if (!isValidFunctionSymbol(Init.Symbol))
569  return make_error<GenericBinaryError>("invalid function symbol: " +
570  Twine(Init.Symbol),
572  LinkingData.InitFunctions.emplace_back(Init);
573  }
574  break;
575  }
577  if (Error Err = parseLinkingSectionComdat(Ctx))
578  return Err;
579  break;
580  default:
581  Ctx.Ptr += Size;
582  break;
583  }
584  if (Ctx.Ptr != Ctx.End)
585  return make_error<GenericBinaryError>(
586  "linking sub-section ended prematurely", object_error::parse_failed);
587  }
588  if (Ctx.Ptr != OrigEnd)
589  return make_error<GenericBinaryError>("linking section ended prematurely",
591  return Error::success();
592 }
593 
594 Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
595  uint32_t Count = readVaruint32(Ctx);
596  LinkingData.SymbolTable.reserve(Count);
597  Symbols.reserve(Count);
598  StringSet<> SymbolNames;
599 
600  std::vector<wasm::WasmImport *> ImportedGlobals;
601  std::vector<wasm::WasmImport *> ImportedFunctions;
602  std::vector<wasm::WasmImport *> ImportedTags;
603  std::vector<wasm::WasmImport *> ImportedTables;
604  ImportedGlobals.reserve(Imports.size());
605  ImportedFunctions.reserve(Imports.size());
606  ImportedTags.reserve(Imports.size());
607  ImportedTables.reserve(Imports.size());
608  for (auto &I : Imports) {
609  if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
610  ImportedFunctions.emplace_back(&I);
611  else if (I.Kind == wasm::WASM_EXTERNAL_GLOBAL)
612  ImportedGlobals.emplace_back(&I);
613  else if (I.Kind == wasm::WASM_EXTERNAL_TAG)
614  ImportedTags.emplace_back(&I);
615  else if (I.Kind == wasm::WASM_EXTERNAL_TABLE)
616  ImportedTables.emplace_back(&I);
617  }
618 
619  while (Count--) {
621  const wasm::WasmSignature *Signature = nullptr;
622  const wasm::WasmGlobalType *GlobalType = nullptr;
623  const wasm::WasmTableType *TableType = nullptr;
624 
625  Info.Kind = readUint8(Ctx);
626  Info.Flags = readVaruint32(Ctx);
627  bool IsDefined = (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0;
628 
629  switch (Info.Kind) {
631  Info.ElementIndex = readVaruint32(Ctx);
632  if (!isValidFunctionIndex(Info.ElementIndex) ||
633  IsDefined != isDefinedFunctionIndex(Info.ElementIndex))
634  return make_error<GenericBinaryError>("invalid function symbol index",
636  if (IsDefined) {
637  Info.Name = readString(Ctx);
638  unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions;
639  wasm::WasmFunction &Function = Functions[FuncIndex];
640  Signature = &Signatures[Function.SigIndex];
641  if (Function.SymbolName.empty())
642  Function.SymbolName = Info.Name;
643  } else {
644  wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex];
645  if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
646  Info.Name = readString(Ctx);
647  Info.ImportName = Import.Field;
648  } else {
649  Info.Name = Import.Field;
650  }
651  Signature = &Signatures[Import.SigIndex];
652  if (!Import.Module.empty()) {
653  Info.ImportModule = Import.Module;
654  }
655  }
656  break;
657 
659  Info.ElementIndex = readVaruint32(Ctx);
660  if (!isValidGlobalIndex(Info.ElementIndex) ||
661  IsDefined != isDefinedGlobalIndex(Info.ElementIndex))
662  return make_error<GenericBinaryError>("invalid global symbol index",
664  if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
666  return make_error<GenericBinaryError>("undefined weak global symbol",
668  if (IsDefined) {
669  Info.Name = readString(Ctx);
670  unsigned GlobalIndex = Info.ElementIndex - NumImportedGlobals;
671  wasm::WasmGlobal &Global = Globals[GlobalIndex];
672  GlobalType = &Global.Type;
673  if (Global.SymbolName.empty())
674  Global.SymbolName = Info.Name;
675  } else {
676  wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex];
677  if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
678  Info.Name = readString(Ctx);
679  Info.ImportName = Import.Field;
680  } else {
681  Info.Name = Import.Field;
682  }
683  GlobalType = &Import.Global;
684  if (!Import.Module.empty()) {
685  Info.ImportModule = Import.Module;
686  }
687  }
688  break;
689 
691  Info.ElementIndex = readVaruint32(Ctx);
692  if (!isValidTableNumber(Info.ElementIndex) ||
693  IsDefined != isDefinedTableNumber(Info.ElementIndex))
694  return make_error<GenericBinaryError>("invalid table symbol index",
696  if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
698  return make_error<GenericBinaryError>("undefined weak table symbol",
700  if (IsDefined) {
701  Info.Name = readString(Ctx);
702  unsigned TableNumber = Info.ElementIndex - NumImportedTables;
703  wasm::WasmTable &Table = Tables[TableNumber];
704  TableType = &Table.Type;
705  if (Table.SymbolName.empty())
706  Table.SymbolName = Info.Name;
707  } else {
708  wasm::WasmImport &Import = *ImportedTables[Info.ElementIndex];
709  if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
710  Info.Name = readString(Ctx);
711  Info.ImportName = Import.Field;
712  } else {
713  Info.Name = Import.Field;
714  }
715  TableType = &Import.Table;
716  if (!Import.Module.empty()) {
717  Info.ImportModule = Import.Module;
718  }
719  }
720  break;
721 
723  Info.Name = readString(Ctx);
724  if (IsDefined) {
725  auto Index = readVaruint32(Ctx);
726  if (Index >= DataSegments.size())
727  return make_error<GenericBinaryError>("invalid data symbol index",
729  auto Offset = readVaruint64(Ctx);
730  auto Size = readVaruint64(Ctx);
731  size_t SegmentSize = DataSegments[Index].Data.Content.size();
732  if (Offset > SegmentSize)
733  return make_error<GenericBinaryError>(
734  "invalid data symbol offset: `" + Info.Name + "` (offset: " +
735  Twine(Offset) + " segment size: " + Twine(SegmentSize) + ")",
738  }
739  break;
740 
742  if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
744  return make_error<GenericBinaryError>(
745  "section symbols must have local binding",
747  Info.ElementIndex = readVaruint32(Ctx);
748  // Use somewhat unique section name as symbol name.
749  StringRef SectionName = Sections[Info.ElementIndex].Name;
750  Info.Name = SectionName;
751  break;
752  }
753 
755  Info.ElementIndex = readVaruint32(Ctx);
756  if (!isValidTagIndex(Info.ElementIndex) ||
757  IsDefined != isDefinedTagIndex(Info.ElementIndex))
758  return make_error<GenericBinaryError>("invalid tag symbol index",
760  if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
762  return make_error<GenericBinaryError>("undefined weak global symbol",
764  if (IsDefined) {
765  Info.Name = readString(Ctx);
766  unsigned TagIndex = Info.ElementIndex - NumImportedTags;
767  wasm::WasmTag &Tag = Tags[TagIndex];
768  Signature = &Signatures[Tag.SigIndex];
769  if (Tag.SymbolName.empty())
770  Tag.SymbolName = Info.Name;
771 
772  } else {
773  wasm::WasmImport &Import = *ImportedTags[Info.ElementIndex];
774  if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
775  Info.Name = readString(Ctx);
776  Info.ImportName = Import.Field;
777  } else {
778  Info.Name = Import.Field;
779  }
780  Signature = &Signatures[Import.SigIndex];
781  if (!Import.Module.empty()) {
782  Info.ImportModule = Import.Module;
783  }
784  }
785  break;
786  }
787 
788  default:
789  return make_error<GenericBinaryError>("invalid symbol type: " +
790  Twine(unsigned(Info.Kind)),
792  }
793 
794  if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
796  !SymbolNames.insert(Info.Name).second)
797  return make_error<GenericBinaryError>("duplicate symbol name " +
798  Twine(Info.Name),
800  LinkingData.SymbolTable.emplace_back(Info);
801  Symbols.emplace_back(LinkingData.SymbolTable.back(), GlobalType, TableType,
802  Signature);
803  LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");
804  }
805 
806  return Error::success();
807 }
808 
809 Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
810  uint32_t ComdatCount = readVaruint32(Ctx);
811  StringSet<> ComdatSet;
812  for (unsigned ComdatIndex = 0; ComdatIndex < ComdatCount; ++ComdatIndex) {
813  StringRef Name = readString(Ctx);
814  if (Name.empty() || !ComdatSet.insert(Name).second)
815  return make_error<GenericBinaryError>("bad/duplicate COMDAT name " +
816  Twine(Name),
818  LinkingData.Comdats.emplace_back(Name);
819  uint32_t Flags = readVaruint32(Ctx);
820  if (Flags != 0)
821  return make_error<GenericBinaryError>("unsupported COMDAT flags",
823 
824  uint32_t EntryCount = readVaruint32(Ctx);
825  while (EntryCount--) {
826  unsigned Kind = readVaruint32(Ctx);
827  unsigned Index = readVaruint32(Ctx);
828  switch (Kind) {
829  default:
830  return make_error<GenericBinaryError>("invalid COMDAT entry type",
833  if (Index >= DataSegments.size())
834  return make_error<GenericBinaryError>(
835  "COMDAT data index out of range", object_error::parse_failed);
836  if (DataSegments[Index].Data.Comdat != UINT32_MAX)
837  return make_error<GenericBinaryError>("data segment in two COMDATs",
839  DataSegments[Index].Data.Comdat = ComdatIndex;
840  break;
842  if (!isDefinedFunctionIndex(Index))
843  return make_error<GenericBinaryError>(
844  "COMDAT function index out of range", object_error::parse_failed);
845  if (getDefinedFunction(Index).Comdat != UINT32_MAX)
846  return make_error<GenericBinaryError>("function in two COMDATs",
848  getDefinedFunction(Index).Comdat = ComdatIndex;
849  break;
851  if (Index >= Sections.size())
852  return make_error<GenericBinaryError>(
853  "COMDAT section index out of range", object_error::parse_failed);
854  if (Sections[Index].Type != wasm::WASM_SEC_CUSTOM)
855  return make_error<GenericBinaryError>(
856  "non-custom section in a COMDAT", object_error::parse_failed);
857  Sections[Index].Comdat = ComdatIndex;
858  break;
859  }
860  }
861  }
862  return Error::success();
863 }
864 
865 Error WasmObjectFile::parseProducersSection(ReadContext &Ctx) {
866  llvm::SmallSet<StringRef, 3> FieldsSeen;
867  uint32_t Fields = readVaruint32(Ctx);
868  for (size_t I = 0; I < Fields; ++I) {
869  StringRef FieldName = readString(Ctx);
870  if (!FieldsSeen.insert(FieldName).second)
871  return make_error<GenericBinaryError>(
872  "producers section does not have unique fields",
874  std::vector<std::pair<std::string, std::string>> *ProducerVec = nullptr;
875  if (FieldName == "language") {
876  ProducerVec = &ProducerInfo.Languages;
877  } else if (FieldName == "processed-by") {
878  ProducerVec = &ProducerInfo.Tools;
879  } else if (FieldName == "sdk") {
880  ProducerVec = &ProducerInfo.SDKs;
881  } else {
882  return make_error<GenericBinaryError>(
883  "producers section field is not named one of language, processed-by, "
884  "or sdk",
886  }
887  uint32_t ValueCount = readVaruint32(Ctx);
888  llvm::SmallSet<StringRef, 8> ProducersSeen;
889  for (size_t J = 0; J < ValueCount; ++J) {
890  StringRef Name = readString(Ctx);
892  if (!ProducersSeen.insert(Name).second) {
893  return make_error<GenericBinaryError>(
894  "producers section contains repeated producer",
896  }
897  ProducerVec->emplace_back(std::string(Name), std::string(Version));
898  }
899  }
900  if (Ctx.Ptr != Ctx.End)
901  return make_error<GenericBinaryError>("producers section ended prematurely",
903  return Error::success();
904 }
905 
906 Error WasmObjectFile::parseTargetFeaturesSection(ReadContext &Ctx) {
907  llvm::SmallSet<std::string, 8> FeaturesSeen;
908  uint32_t FeatureCount = readVaruint32(Ctx);
909  for (size_t I = 0; I < FeatureCount; ++I) {
910  wasm::WasmFeatureEntry Feature;
911  Feature.Prefix = readUint8(Ctx);
912  switch (Feature.Prefix) {
916  break;
917  default:
918  return make_error<GenericBinaryError>("unknown feature policy prefix",
920  }
921  Feature.Name = std::string(readString(Ctx));
922  if (!FeaturesSeen.insert(Feature.Name).second)
923  return make_error<GenericBinaryError>(
924  "target features section contains repeated feature \"" +
925  Feature.Name + "\"",
927  TargetFeatures.push_back(Feature);
928  }
929  if (Ctx.Ptr != Ctx.End)
930  return make_error<GenericBinaryError>(
931  "target features section ended prematurely",
933  return Error::success();
934 }
935 
936 Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
937  uint32_t SectionIndex = readVaruint32(Ctx);
938  if (SectionIndex >= Sections.size())
939  return make_error<GenericBinaryError>("invalid section index",
941  WasmSection &Section = Sections[SectionIndex];
942  uint32_t RelocCount = readVaruint32(Ctx);
943  uint32_t EndOffset = Section.Content.size();
944  uint32_t PreviousOffset = 0;
945  while (RelocCount--) {
946  wasm::WasmRelocation Reloc = {};
947  uint32_t type = readVaruint32(Ctx);
948  Reloc.Type = type;
949  Reloc.Offset = readVaruint32(Ctx);
950  if (Reloc.Offset < PreviousOffset)
951  return make_error<GenericBinaryError>("relocations not in offset order",
953  PreviousOffset = Reloc.Offset;
954  Reloc.Index = readVaruint32(Ctx);
955  switch (type) {
956  case wasm::R_WASM_FUNCTION_INDEX_LEB:
957  case wasm::R_WASM_TABLE_INDEX_SLEB:
958  case wasm::R_WASM_TABLE_INDEX_SLEB64:
959  case wasm::R_WASM_TABLE_INDEX_I32:
960  case wasm::R_WASM_TABLE_INDEX_I64:
961  case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
962  case wasm::R_WASM_TABLE_INDEX_REL_SLEB64:
963  if (!isValidFunctionSymbol(Reloc.Index))
964  return make_error<GenericBinaryError>(
965  "invalid relocation function index", object_error::parse_failed);
966  break;
967  case wasm::R_WASM_TABLE_NUMBER_LEB:
968  if (!isValidTableSymbol(Reloc.Index))
969  return make_error<GenericBinaryError>("invalid relocation table index",
971  break;
972  case wasm::R_WASM_TYPE_INDEX_LEB:
973  if (Reloc.Index >= Signatures.size())
974  return make_error<GenericBinaryError>("invalid relocation type index",
976  break;
977  case wasm::R_WASM_GLOBAL_INDEX_LEB:
978  // R_WASM_GLOBAL_INDEX_LEB are can be used against function and data
979  // symbols to refer to their GOT entries.
980  if (!isValidGlobalSymbol(Reloc.Index) &&
981  !isValidDataSymbol(Reloc.Index) &&
982  !isValidFunctionSymbol(Reloc.Index))
983  return make_error<GenericBinaryError>("invalid relocation global index",
985  break;
986  case wasm::R_WASM_GLOBAL_INDEX_I32:
987  if (!isValidGlobalSymbol(Reloc.Index))
988  return make_error<GenericBinaryError>("invalid relocation global index",
990  break;
991  case wasm::R_WASM_TAG_INDEX_LEB:
992  if (!isValidTagSymbol(Reloc.Index))
993  return make_error<GenericBinaryError>("invalid relocation tag index",
995  break;
996  case wasm::R_WASM_MEMORY_ADDR_LEB:
997  case wasm::R_WASM_MEMORY_ADDR_SLEB:
998  case wasm::R_WASM_MEMORY_ADDR_I32:
999  case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
1000  case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
1001  case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
1002  if (!isValidDataSymbol(Reloc.Index))
1003  return make_error<GenericBinaryError>("invalid relocation data index",
1005  Reloc.Addend = readVarint32(Ctx);
1006  break;
1007  case wasm::R_WASM_MEMORY_ADDR_LEB64:
1008  case wasm::R_WASM_MEMORY_ADDR_SLEB64:
1009  case wasm::R_WASM_MEMORY_ADDR_I64:
1010  case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
1011  case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64:
1012  if (!isValidDataSymbol(Reloc.Index))
1013  return make_error<GenericBinaryError>("invalid relocation data index",
1015  Reloc.Addend = readVarint64(Ctx);
1016  break;
1017  case wasm::R_WASM_FUNCTION_OFFSET_I32:
1018  if (!isValidFunctionSymbol(Reloc.Index))
1019  return make_error<GenericBinaryError>(
1020  "invalid relocation function index", object_error::parse_failed);
1021  Reloc.Addend = readVarint32(Ctx);
1022  break;
1023  case wasm::R_WASM_FUNCTION_OFFSET_I64:
1024  if (!isValidFunctionSymbol(Reloc.Index))
1025  return make_error<GenericBinaryError>(
1026  "invalid relocation function index", object_error::parse_failed);
1027  Reloc.Addend = readVarint64(Ctx);
1028  break;
1029  case wasm::R_WASM_SECTION_OFFSET_I32:
1030  if (!isValidSectionSymbol(Reloc.Index))
1031  return make_error<GenericBinaryError>(
1032  "invalid relocation section index", object_error::parse_failed);
1033  Reloc.Addend = readVarint32(Ctx);
1034  break;
1035  default:
1036  return make_error<GenericBinaryError>("invalid relocation type: " +
1037  Twine(type),
1039  }
1040 
1041  // Relocations must fit inside the section, and must appear in order. They
1042  // also shouldn't overlap a function/element boundary, but we don't bother
1043  // to check that.
1044  uint64_t Size = 5;
1045  if (Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LEB64 ||
1046  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_SLEB64 ||
1047  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_REL_SLEB64)
1048  Size = 10;
1049  if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I32 ||
1050  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I32 ||
1051  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LOCREL_I32 ||
1052  Reloc.Type == wasm::R_WASM_SECTION_OFFSET_I32 ||
1053  Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||
1054  Reloc.Type == wasm::R_WASM_GLOBAL_INDEX_I32)
1055  Size = 4;
1056  if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I64 ||
1057  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I64 ||
1058  Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I64)
1059  Size = 8;
1060  if (Reloc.Offset + Size > EndOffset)
1061  return make_error<GenericBinaryError>("invalid relocation offset",
1063 
1064  Section.Relocations.push_back(Reloc);
1065  }
1066  if (Ctx.Ptr != Ctx.End)
1067  return make_error<GenericBinaryError>("reloc section ended prematurely",
1069  return Error::success();
1070 }
1071 
1072 Error WasmObjectFile::parseCustomSection(WasmSection &Sec, ReadContext &Ctx) {
1073  if (Sec.Name == "dylink") {
1074  if (Error Err = parseDylinkSection(Ctx))
1075  return Err;
1076  } else if (Sec.Name == "dylink.0") {
1077  if (Error Err = parseDylink0Section(Ctx))
1078  return Err;
1079  } else if (Sec.Name == "name") {
1080  if (Error Err = parseNameSection(Ctx))
1081  return Err;
1082  } else if (Sec.Name == "linking") {
1083  if (Error Err = parseLinkingSection(Ctx))
1084  return Err;
1085  } else if (Sec.Name == "producers") {
1086  if (Error Err = parseProducersSection(Ctx))
1087  return Err;
1088  } else if (Sec.Name == "target_features") {
1089  if (Error Err = parseTargetFeaturesSection(Ctx))
1090  return Err;
1091  } else if (Sec.Name.startswith("reloc.")) {
1092  if (Error Err = parseRelocSection(Sec.Name, Ctx))
1093  return Err;
1094  }
1095  return Error::success();
1096 }
1097 
1098 Error WasmObjectFile::parseTypeSection(ReadContext &Ctx) {
1099  uint32_t Count = readVaruint32(Ctx);
1100  Signatures.reserve(Count);
1101  while (Count--) {
1102  wasm::WasmSignature Sig;
1103  uint8_t Form = readUint8(Ctx);
1104  if (Form != wasm::WASM_TYPE_FUNC) {
1105  return make_error<GenericBinaryError>("invalid signature type",
1107  }
1108  uint32_t ParamCount = readVaruint32(Ctx);
1109  Sig.Params.reserve(ParamCount);
1110  while (ParamCount--) {
1111  uint32_t ParamType = readUint8(Ctx);
1112  Sig.Params.push_back(wasm::ValType(ParamType));
1113  }
1114  uint32_t ReturnCount = readVaruint32(Ctx);
1115  while (ReturnCount--) {
1116  uint32_t ReturnType = readUint8(Ctx);
1117  Sig.Returns.push_back(wasm::ValType(ReturnType));
1118  }
1119  Signatures.push_back(std::move(Sig));
1120  }
1121  if (Ctx.Ptr != Ctx.End)
1122  return make_error<GenericBinaryError>("type section ended prematurely",
1124  return Error::success();
1125 }
1126 
1127 Error WasmObjectFile::parseImportSection(ReadContext &Ctx) {
1128  uint32_t Count = readVaruint32(Ctx);
1129  uint32_t NumTypes = Signatures.size();
1130  Imports.reserve(Count);
1131  for (uint32_t I = 0; I < Count; I++) {
1132  wasm::WasmImport Im;
1133  Im.Module = readString(Ctx);
1134  Im.Field = readString(Ctx);
1135  Im.Kind = readUint8(Ctx);
1136  switch (Im.Kind) {
1138  NumImportedFunctions++;
1139  Im.SigIndex = readVaruint32(Ctx);
1140  if (Im.SigIndex >= NumTypes)
1141  return make_error<GenericBinaryError>("invalid function type",
1143  break;
1145  NumImportedGlobals++;
1146  Im.Global.Type = readUint8(Ctx);
1147  Im.Global.Mutable = readVaruint1(Ctx);
1148  break;
1150  Im.Memory = readLimits(Ctx);
1152  HasMemory64 = true;
1153  break;
1155  Im.Table = readTableType(Ctx);
1156  NumImportedTables++;
1157  auto ElemType = Im.Table.ElemType;
1158  if (ElemType != wasm::WASM_TYPE_FUNCREF &&
1159  ElemType != wasm::WASM_TYPE_EXTERNREF)
1160  return make_error<GenericBinaryError>("invalid table element type",
1162  break;
1163  }
1165  NumImportedTags++;
1166  if (readUint8(Ctx) != 0) // Reserved 'attribute' field
1167  return make_error<GenericBinaryError>("invalid attribute",
1169  Im.SigIndex = readVaruint32(Ctx);
1170  if (Im.SigIndex >= NumTypes)
1171  return make_error<GenericBinaryError>("invalid tag type",
1173  break;
1174  default:
1175  return make_error<GenericBinaryError>("unexpected import kind",
1177  }
1178  Imports.push_back(Im);
1179  }
1180  if (Ctx.Ptr != Ctx.End)
1181  return make_error<GenericBinaryError>("import section ended prematurely",
1183  return Error::success();
1184 }
1185 
1186 Error WasmObjectFile::parseFunctionSection(ReadContext &Ctx) {
1187  uint32_t Count = readVaruint32(Ctx);
1188  Functions.reserve(Count);
1189  uint32_t NumTypes = Signatures.size();
1190  while (Count--) {
1191  uint32_t Type = readVaruint32(Ctx);
1192  if (Type >= NumTypes)
1193  return make_error<GenericBinaryError>("invalid function type",
1196  F.SigIndex = Type;
1197  Functions.push_back(F);
1198  }
1199  if (Ctx.Ptr != Ctx.End)
1200  return make_error<GenericBinaryError>("function section ended prematurely",
1202  return Error::success();
1203 }
1204 
1205 Error WasmObjectFile::parseTableSection(ReadContext &Ctx) {
1206  TableSection = Sections.size();
1207  uint32_t Count = readVaruint32(Ctx);
1208  Tables.reserve(Count);
1209  while (Count--) {
1211  T.Type = readTableType(Ctx);
1212  T.Index = NumImportedTables + Tables.size();
1213  Tables.push_back(T);
1214  auto ElemType = Tables.back().Type.ElemType;
1215  if (ElemType != wasm::WASM_TYPE_FUNCREF &&
1216  ElemType != wasm::WASM_TYPE_EXTERNREF) {
1217  return make_error<GenericBinaryError>("invalid table element type",
1219  }
1220  }
1221  if (Ctx.Ptr != Ctx.End)
1222  return make_error<GenericBinaryError>("table section ended prematurely",
1224  return Error::success();
1225 }
1226 
1227 Error WasmObjectFile::parseMemorySection(ReadContext &Ctx) {
1228  uint32_t Count = readVaruint32(Ctx);
1229  Memories.reserve(Count);
1230  while (Count--) {
1231  auto Limits = readLimits(Ctx);
1232  if (Limits.Flags & wasm::WASM_LIMITS_FLAG_IS_64)
1233  HasMemory64 = true;
1234  Memories.push_back(Limits);
1235  }
1236  if (Ctx.Ptr != Ctx.End)
1237  return make_error<GenericBinaryError>("memory section ended prematurely",
1239  return Error::success();
1240 }
1241 
1242 Error WasmObjectFile::parseTagSection(ReadContext &Ctx) {
1243  TagSection = Sections.size();
1244  uint32_t Count = readVaruint32(Ctx);
1245  Tags.reserve(Count);
1246  uint32_t NumTypes = Signatures.size();
1247  while (Count--) {
1248  if (readUint8(Ctx) != 0) // Reserved 'attribute' field
1249  return make_error<GenericBinaryError>("invalid attribute",
1251  uint32_t Type = readVaruint32(Ctx);
1252  if (Type >= NumTypes)
1253  return make_error<GenericBinaryError>("invalid tag type",
1256  Tag.Index = NumImportedTags + Tags.size();
1257  Tag.SigIndex = Type;
1258  Tags.push_back(Tag);
1259  }
1260 
1261  if (Ctx.Ptr != Ctx.End)
1262  return make_error<GenericBinaryError>("tag section ended prematurely",
1264  return Error::success();
1265 }
1266 
1267 Error WasmObjectFile::parseGlobalSection(ReadContext &Ctx) {
1268  GlobalSection = Sections.size();
1269  uint32_t Count = readVaruint32(Ctx);
1270  Globals.reserve(Count);
1271  while (Count--) {
1273  Global.Index = NumImportedGlobals + Globals.size();
1274  Global.Type.Type = readUint8(Ctx);
1275  Global.Type.Mutable = readVaruint1(Ctx);
1276  if (Error Err = readInitExpr(Global.InitExpr, Ctx))
1277  return Err;
1278  Globals.push_back(Global);
1279  }
1280  if (Ctx.Ptr != Ctx.End)
1281  return make_error<GenericBinaryError>("global section ended prematurely",
1283  return Error::success();
1284 }
1285 
1286 Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
1287  uint32_t Count = readVaruint32(Ctx);
1288  Exports.reserve(Count);
1289  for (uint32_t I = 0; I < Count; I++) {
1290  wasm::WasmExport Ex;
1291  Ex.Name = readString(Ctx);
1292  Ex.Kind = readUint8(Ctx);
1293  Ex.Index = readVaruint32(Ctx);
1294  switch (Ex.Kind) {
1296 
1297  if (!isDefinedFunctionIndex(Ex.Index))
1298  return make_error<GenericBinaryError>("invalid function export",
1300  getDefinedFunction(Ex.Index).ExportName = Ex.Name;
1301  break;
1303  if (!isValidGlobalIndex(Ex.Index))
1304  return make_error<GenericBinaryError>("invalid global export",
1306  break;
1308  if (!isValidTagIndex(Ex.Index))
1309  return make_error<GenericBinaryError>("invalid tag export",
1311  break;
1314  break;
1315  default:
1316  return make_error<GenericBinaryError>("unexpected export kind",
1318  }
1319  Exports.push_back(Ex);
1320  }
1321  if (Ctx.Ptr != Ctx.End)
1322  return make_error<GenericBinaryError>("export section ended prematurely",
1324  return Error::success();
1325 }
1326 
1327 bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const {
1328  return Index < NumImportedFunctions + Functions.size();
1329 }
1330 
1331 bool WasmObjectFile::isDefinedFunctionIndex(uint32_t Index) const {
1332  return Index >= NumImportedFunctions && isValidFunctionIndex(Index);
1333 }
1334 
1335 bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const {
1336  return Index < NumImportedGlobals + Globals.size();
1337 }
1338 
1339 bool WasmObjectFile::isValidTableNumber(uint32_t Index) const {
1340  return Index < NumImportedTables + Tables.size();
1341 }
1342 
1343 bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const {
1344  return Index >= NumImportedGlobals && isValidGlobalIndex(Index);
1345 }
1346 
1347 bool WasmObjectFile::isDefinedTableNumber(uint32_t Index) const {
1348  return Index >= NumImportedTables && isValidTableNumber(Index);
1349 }
1350 
1351 bool WasmObjectFile::isValidTagIndex(uint32_t Index) const {
1352  return Index < NumImportedTags + Tags.size();
1353 }
1354 
1355 bool WasmObjectFile::isDefinedTagIndex(uint32_t Index) const {
1356  return Index >= NumImportedTags && isValidTagIndex(Index);
1357 }
1358 
1359 bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
1360  return Index < Symbols.size() && Symbols[Index].isTypeFunction();
1361 }
1362 
1363 bool WasmObjectFile::isValidTableSymbol(uint32_t Index) const {
1364  return Index < Symbols.size() && Symbols[Index].isTypeTable();
1365 }
1366 
1367 bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const {
1368  return Index < Symbols.size() && Symbols[Index].isTypeGlobal();
1369 }
1370 
1371 bool WasmObjectFile::isValidTagSymbol(uint32_t Index) const {
1372  return Index < Symbols.size() && Symbols[Index].isTypeTag();
1373 }
1374 
1375 bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
1376  return Index < Symbols.size() && Symbols[Index].isTypeData();
1377 }
1378 
1379 bool WasmObjectFile::isValidSectionSymbol(uint32_t Index) const {
1380  return Index < Symbols.size() && Symbols[Index].isTypeSection();
1381 }
1382 
1383 wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) {
1384  assert(isDefinedFunctionIndex(Index));
1385  return Functions[Index - NumImportedFunctions];
1386 }
1387 
1388 const wasm::WasmFunction &
1389 WasmObjectFile::getDefinedFunction(uint32_t Index) const {
1390  assert(isDefinedFunctionIndex(Index));
1391  return Functions[Index - NumImportedFunctions];
1392 }
1393 
1394 wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) {
1395  assert(isDefinedGlobalIndex(Index));
1396  return Globals[Index - NumImportedGlobals];
1397 }
1398 
1399 wasm::WasmTag &WasmObjectFile::getDefinedTag(uint32_t Index) {
1400  assert(isDefinedTagIndex(Index));
1401  return Tags[Index - NumImportedTags];
1402 }
1403 
1404 Error WasmObjectFile::parseStartSection(ReadContext &Ctx) {
1405  StartFunction = readVaruint32(Ctx);
1406  if (!isValidFunctionIndex(StartFunction))
1407  return make_error<GenericBinaryError>("invalid start function",
1409  return Error::success();
1410 }
1411 
1412 Error WasmObjectFile::parseCodeSection(ReadContext &Ctx) {
1413  SeenCodeSection = true;
1414  CodeSection = Sections.size();
1415  uint32_t FunctionCount = readVaruint32(Ctx);
1416  if (FunctionCount != Functions.size()) {
1417  return make_error<GenericBinaryError>("invalid function count",
1419  }
1420 
1421  for (uint32_t i = 0; i < FunctionCount; i++) {
1422  wasm::WasmFunction& Function = Functions[i];
1423  const uint8_t *FunctionStart = Ctx.Ptr;
1424  uint32_t Size = readVaruint32(Ctx);
1425  const uint8_t *FunctionEnd = Ctx.Ptr + Size;
1426 
1427  Function.CodeOffset = Ctx.Ptr - FunctionStart;
1428  Function.Index = NumImportedFunctions + i;
1429  Function.CodeSectionOffset = FunctionStart - Ctx.Start;
1430  Function.Size = FunctionEnd - FunctionStart;
1431 
1432  uint32_t NumLocalDecls = readVaruint32(Ctx);
1433  Function.Locals.reserve(NumLocalDecls);
1434  while (NumLocalDecls--) {
1435  wasm::WasmLocalDecl Decl;
1436  Decl.Count = readVaruint32(Ctx);
1437  Decl.Type = readUint8(Ctx);
1438  Function.Locals.push_back(Decl);
1439  }
1440 
1441  uint32_t BodySize = FunctionEnd - Ctx.Ptr;
1442  Function.Body = ArrayRef<uint8_t>(Ctx.Ptr, BodySize);
1443  // This will be set later when reading in the linking metadata section.
1444  Function.Comdat = UINT32_MAX;
1445  Ctx.Ptr += BodySize;
1446  assert(Ctx.Ptr == FunctionEnd);
1447  }
1448  if (Ctx.Ptr != Ctx.End)
1449  return make_error<GenericBinaryError>("code section ended prematurely",
1451  return Error::success();
1452 }
1453 
1454 Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
1455  uint32_t Count = readVaruint32(Ctx);
1456  ElemSegments.reserve(Count);
1457  while (Count--) {
1458  wasm::WasmElemSegment Segment;
1459  Segment.Flags = readVaruint32(Ctx);
1460 
1464  if (Segment.Flags & ~SupportedFlags)
1465  return make_error<GenericBinaryError>(
1466  "Unsupported flags for element segment", object_error::parse_failed);
1467 
1469  Segment.TableNumber = readVaruint32(Ctx);
1470  else
1471  Segment.TableNumber = 0;
1472  if (!isValidTableNumber(Segment.TableNumber))
1473  return make_error<GenericBinaryError>("invalid TableNumber",
1475 
1476  if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_IS_PASSIVE) {
1477  Segment.Offset.Extended = false;
1479  Segment.Offset.Inst.Value.Int32 = 0;
1480  } else {
1481  if (Error Err = readInitExpr(Segment.Offset, Ctx))
1482  return Err;
1483  }
1484 
1486  Segment.ElemKind = readUint8(Ctx);
1488  if (Segment.ElemKind != uint8_t(wasm::ValType::FUNCREF) &&
1489  Segment.ElemKind != uint8_t(wasm::ValType::EXTERNREF)) {
1490  return make_error<GenericBinaryError>("invalid reference type",
1492  }
1493  } else {
1494  if (Segment.ElemKind != 0)
1495  return make_error<GenericBinaryError>("invalid elemtype",
1497  Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF);
1498  }
1499  } else {
1500  Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF);
1501  }
1502 
1504  return make_error<GenericBinaryError>(
1505  "elem segment init expressions not yet implemented",
1507 
1508  uint32_t NumElems = readVaruint32(Ctx);
1509  while (NumElems--) {
1510  Segment.Functions.push_back(readVaruint32(Ctx));
1511  }
1512  ElemSegments.push_back(Segment);
1513  }
1514  if (Ctx.Ptr != Ctx.End)
1515  return make_error<GenericBinaryError>("elem section ended prematurely",
1517  return Error::success();
1518 }
1519 
1520 Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
1521  DataSection = Sections.size();
1522  uint32_t Count = readVaruint32(Ctx);
1523  if (DataCount && Count != DataCount.getValue())
1524  return make_error<GenericBinaryError>(
1525  "number of data segments does not match DataCount section");
1526  DataSegments.reserve(Count);
1527  while (Count--) {
1528  WasmSegment Segment;
1529  Segment.Data.InitFlags = readVaruint32(Ctx);
1530  Segment.Data.MemoryIndex =
1531  (Segment.Data.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX)
1532  ? readVaruint32(Ctx)
1533  : 0;
1534  if ((Segment.Data.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) {
1535  if (Error Err = readInitExpr(Segment.Data.Offset, Ctx))
1536  return Err;
1537  } else {
1538  Segment.Data.Offset.Extended = false;
1539  Segment.Data.Offset.Inst.Opcode = wasm::WASM_OPCODE_I32_CONST;
1540  Segment.Data.Offset.Inst.Value.Int32 = 0;
1541  }
1542  uint32_t Size = readVaruint32(Ctx);
1543  if (Size > (size_t)(Ctx.End - Ctx.Ptr))
1544  return make_error<GenericBinaryError>("invalid segment size",
1546  Segment.Data.Content = ArrayRef<uint8_t>(Ctx.Ptr, Size);
1547  // The rest of these Data fields are set later, when reading in the linking
1548  // metadata section.
1549  Segment.Data.Alignment = 0;
1550  Segment.Data.LinkingFlags = 0;
1551  Segment.Data.Comdat = UINT32_MAX;
1552  Segment.SectionOffset = Ctx.Ptr - Ctx.Start;
1553  Ctx.Ptr += Size;
1554  DataSegments.push_back(Segment);
1555  }
1556  if (Ctx.Ptr != Ctx.End)
1557  return make_error<GenericBinaryError>("data section ended prematurely",
1559  return Error::success();
1560 }
1561 
1562 Error WasmObjectFile::parseDataCountSection(ReadContext &Ctx) {
1563  DataCount = readVaruint32(Ctx);
1564  return Error::success();
1565 }
1566 
1568  return Header;
1569 }
1570 
1571 void WasmObjectFile::moveSymbolNext(DataRefImpl &Symb) const { Symb.d.b++; }
1572 
1574  uint32_t Result = SymbolRef::SF_None;
1575  const WasmSymbol &Sym = getWasmSymbol(Symb);
1576 
1577  LLVM_DEBUG(dbgs() << "getSymbolFlags: ptr=" << &Sym << " " << Sym << "\n");
1578  if (Sym.isBindingWeak())
1579  Result |= SymbolRef::SF_Weak;
1580  if (!Sym.isBindingLocal())
1581  Result |= SymbolRef::SF_Global;
1582  if (Sym.isHidden())
1583  Result |= SymbolRef::SF_Hidden;
1584  if (!Sym.isDefined())
1585  Result |= SymbolRef::SF_Undefined;
1586  if (Sym.isTypeFunction())
1587  Result |= SymbolRef::SF_Executable;
1588  return Result;
1589 }
1590 
1592  DataRefImpl Ref;
1593  Ref.d.a = 1; // Arbitrary non-zero value so that Ref.p is non-null
1594  Ref.d.b = 0; // Symbol index
1595  return BasicSymbolRef(Ref, this);
1596 }
1597 
1599  DataRefImpl Ref;
1600  Ref.d.a = 1; // Arbitrary non-zero value so that Ref.p is non-null
1601  Ref.d.b = Symbols.size(); // Symbol index
1602  return BasicSymbolRef(Ref, this);
1603 }
1604 
1606  return Symbols[Symb.d.b];
1607 }
1608 
1609 const WasmSymbol &WasmObjectFile::getWasmSymbol(const SymbolRef &Symb) const {
1610  return getWasmSymbol(Symb.getRawDataRefImpl());
1611 }
1612 
1614  return getWasmSymbol(Symb).Info.Name;
1615 }
1616 
1618  auto &Sym = getWasmSymbol(Symb);
1619  if (Sym.Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION &&
1620  isDefinedFunctionIndex(Sym.Info.ElementIndex))
1621  return getDefinedFunction(Sym.Info.ElementIndex).CodeSectionOffset;
1622  else
1623  return getSymbolValue(Symb);
1624 }
1625 
1627  switch (Sym.Info.Kind) {
1632  return Sym.Info.ElementIndex;
1634  // The value of a data symbol is the segment offset, plus the symbol
1635  // offset within the segment.
1636  uint32_t SegmentIndex = Sym.Info.DataRef.Segment;
1637  const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data;
1638  if (Segment.Offset.Extended) {
1639  llvm_unreachable("extended init exprs not supported");
1640  } else if (Segment.Offset.Inst.Opcode == wasm::WASM_OPCODE_I32_CONST) {
1641  return Segment.Offset.Inst.Value.Int32 + Sym.Info.DataRef.Offset;
1642  } else if (Segment.Offset.Inst.Opcode == wasm::WASM_OPCODE_I64_CONST) {
1643  return Segment.Offset.Inst.Value.Int64 + Sym.Info.DataRef.Offset;
1644  } else {
1645  llvm_unreachable("unknown init expr opcode");
1646  }
1647  }
1649  return 0;
1650  }
1651  llvm_unreachable("invalid symbol type");
1652 }
1653 
1655  return getWasmSymbolValue(getWasmSymbol(Symb));
1656 }
1657 
1659  llvm_unreachable("not yet implemented");
1660  return 0;
1661 }
1662 
1664  llvm_unreachable("not yet implemented");
1665  return 0;
1666 }
1667 
1670  const WasmSymbol &Sym = getWasmSymbol(Symb);
1671 
1672  switch (Sym.Info.Kind) {
1674  return SymbolRef::ST_Function;
1676  return SymbolRef::ST_Other;
1678  return SymbolRef::ST_Data;
1680  return SymbolRef::ST_Debug;
1682  return SymbolRef::ST_Other;
1684  return SymbolRef::ST_Other;
1685  }
1686 
1687  llvm_unreachable("unknown WasmSymbol::SymbolType");
1688  return SymbolRef::ST_Other;
1689 }
1690 
1693  const WasmSymbol &Sym = getWasmSymbol(Symb);
1694  if (Sym.isUndefined())
1695  return section_end();
1696 
1697  DataRefImpl Ref;
1698  Ref.d.a = getSymbolSectionIdImpl(Sym);
1699  return section_iterator(SectionRef(Ref, this));
1700 }
1701 
1703  const WasmSymbol &Sym = getWasmSymbol(Symb);
1704  return getSymbolSectionIdImpl(Sym);
1705 }
1706 
1707 uint32_t WasmObjectFile::getSymbolSectionIdImpl(const WasmSymbol &Sym) const {
1708  switch (Sym.Info.Kind) {
1710  return CodeSection;
1712  return GlobalSection;
1714  return DataSection;
1716  return Sym.Info.ElementIndex;
1718  return TagSection;
1720  return TableSection;
1721  default:
1722  llvm_unreachable("unknown WasmSymbol::SymbolType");
1723  }
1724 }
1725 
1726 void WasmObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; }
1727 
1729  const WasmSection &S = Sections[Sec.d.a];
1730 #define ECase(X) \
1731  case wasm::WASM_SEC_##X: \
1732  return #X;
1733  switch (S.Type) {
1734  ECase(TYPE);
1735  ECase(IMPORT);
1736  ECase(FUNCTION);
1737  ECase(TABLE);
1738  ECase(MEMORY);
1739  ECase(GLOBAL);
1740  ECase(TAG);
1741  ECase(EXPORT);
1742  ECase(START);
1743  ECase(ELEM);
1744  ECase(CODE);
1745  ECase(DATA);
1746  ECase(DATACOUNT);
1747  case wasm::WASM_SEC_CUSTOM:
1748  return S.Name;
1749  default:
1751  }
1752 #undef ECase
1753 }
1754 
1756 
1758  return Sec.d.a;
1759 }
1760 
1762  const WasmSection &S = Sections[Sec.d.a];
1763  return S.Content.size();
1764 }
1765 
1768  const WasmSection &S = Sections[Sec.d.a];
1769  // This will never fail since wasm sections can never be empty (user-sections
1770  // must have a name and non-user sections each have a defined structure).
1771  return S.Content;
1772 }
1773 
1775  return 1;
1776 }
1777 
1779  return false;
1780 }
1781 
1783  return getWasmSection(Sec).Type == wasm::WASM_SEC_CODE;
1784 }
1785 
1787  return getWasmSection(Sec).Type == wasm::WASM_SEC_DATA;
1788 }
1789 
1790 bool WasmObjectFile::isSectionBSS(DataRefImpl Sec) const { return false; }
1791 
1792 bool WasmObjectFile::isSectionVirtual(DataRefImpl Sec) const { return false; }
1793 
1795  DataRefImpl RelocRef;
1796  RelocRef.d.a = Ref.d.a;
1797  RelocRef.d.b = 0;
1798  return relocation_iterator(RelocationRef(RelocRef, this));
1799 }
1800 
1802  const WasmSection &Sec = getWasmSection(Ref);
1803  DataRefImpl RelocRef;
1804  RelocRef.d.a = Ref.d.a;
1805  RelocRef.d.b = Sec.Relocations.size();
1806  return relocation_iterator(RelocationRef(RelocRef, this));
1807 }
1808 
1810 
1813  return Rel.Offset;
1814 }
1815 
1818  if (Rel.Type == wasm::R_WASM_TYPE_INDEX_LEB)
1819  return symbol_end();
1820  DataRefImpl Sym;
1821  Sym.d.a = 1;
1822  Sym.d.b = Rel.Index;
1823  return symbol_iterator(SymbolRef(Sym, this));
1824 }
1825 
1828  return Rel.Type;
1829 }
1830 
1832  DataRefImpl Ref, SmallVectorImpl<char> &Result) const {
1834  StringRef Res = "Unknown";
1835 
1836 #define WASM_RELOC(name, value) \
1837  case wasm::name: \
1838  Res = #name; \
1839  break;
1840 
1841  switch (Rel.Type) {
1842 #include "llvm/BinaryFormat/WasmRelocs.def"
1843  }
1844 
1845 #undef WASM_RELOC
1846 
1847  Result.append(Res.begin(), Res.end());
1848 }
1849 
1851  DataRefImpl Ref;
1852  Ref.d.a = 0;
1853  return section_iterator(SectionRef(Ref, this));
1854 }
1855 
1857  DataRefImpl Ref;
1858  Ref.d.a = Sections.size();
1859  return section_iterator(SectionRef(Ref, this));
1860 }
1861 
1863  return HasMemory64 ? 8 : 4;
1864 }
1865 
1867 
1869  return HasMemory64 ? Triple::wasm64 : Triple::wasm32;
1870 }
1871 
1873  return SubtargetFeatures();
1874 }
1875 
1876 bool WasmObjectFile::isRelocatableObject() const { return HasLinkingSection; }
1877 
1878 bool WasmObjectFile::isSharedObject() const { return HasDylinkSection; }
1879 
1881  assert(Ref.d.a < Sections.size());
1882  return Sections[Ref.d.a];
1883 }
1884 
1885 const WasmSection &
1887  return getWasmSection(Section.getRawDataRefImpl());
1888 }
1889 
1890 const wasm::WasmRelocation &
1892  return getWasmRelocation(Ref.getRawDataRefImpl());
1893 }
1894 
1895 const wasm::WasmRelocation &
1897  assert(Ref.d.a < Sections.size());
1898  const WasmSection &Sec = Sections[Ref.d.a];
1899  assert(Ref.d.b < Sec.Relocations.size());
1900  return Sec.Relocations[Ref.d.b];
1901 }
1902 
1903 int WasmSectionOrderChecker::getSectionOrder(unsigned ID,
1904  StringRef CustomSectionName) {
1905  switch (ID) {
1906  case wasm::WASM_SEC_CUSTOM:
1907  return StringSwitch<unsigned>(CustomSectionName)
1908  .Case("dylink", WASM_SEC_ORDER_DYLINK)
1909  .Case("dylink.0", WASM_SEC_ORDER_DYLINK)
1910  .Case("linking", WASM_SEC_ORDER_LINKING)
1911  .StartsWith("reloc.", WASM_SEC_ORDER_RELOC)
1912  .Case("name", WASM_SEC_ORDER_NAME)
1913  .Case("producers", WASM_SEC_ORDER_PRODUCERS)
1914  .Case("target_features", WASM_SEC_ORDER_TARGET_FEATURES)
1916  case wasm::WASM_SEC_TYPE:
1917  return WASM_SEC_ORDER_TYPE;
1918  case wasm::WASM_SEC_IMPORT:
1919  return WASM_SEC_ORDER_IMPORT;
1921  return WASM_SEC_ORDER_FUNCTION;
1922  case wasm::WASM_SEC_TABLE:
1923  return WASM_SEC_ORDER_TABLE;
1924  case wasm::WASM_SEC_MEMORY:
1925  return WASM_SEC_ORDER_MEMORY;
1926  case wasm::WASM_SEC_GLOBAL:
1927  return WASM_SEC_ORDER_GLOBAL;
1928  case wasm::WASM_SEC_EXPORT:
1929  return WASM_SEC_ORDER_EXPORT;
1930  case wasm::WASM_SEC_START:
1931  return WASM_SEC_ORDER_START;
1932  case wasm::WASM_SEC_ELEM:
1933  return WASM_SEC_ORDER_ELEM;
1934  case wasm::WASM_SEC_CODE:
1935  return WASM_SEC_ORDER_CODE;
1936  case wasm::WASM_SEC_DATA:
1937  return WASM_SEC_ORDER_DATA;
1939  return WASM_SEC_ORDER_DATACOUNT;
1940  case wasm::WASM_SEC_TAG:
1941  return WASM_SEC_ORDER_TAG;
1942  default:
1943  return WASM_SEC_ORDER_NONE;
1944  }
1945 }
1946 
1947 // Represents the edges in a directed graph where any node B reachable from node
1948 // A is not allowed to appear before A in the section ordering, but may appear
1949 // afterward.
1951  [WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS] = {
1952  // WASM_SEC_ORDER_NONE
1953  {},
1954  // WASM_SEC_ORDER_TYPE
1955  {WASM_SEC_ORDER_TYPE, WASM_SEC_ORDER_IMPORT},
1956  // WASM_SEC_ORDER_IMPORT
1957  {WASM_SEC_ORDER_IMPORT, WASM_SEC_ORDER_FUNCTION},
1958  // WASM_SEC_ORDER_FUNCTION
1959  {WASM_SEC_ORDER_FUNCTION, WASM_SEC_ORDER_TABLE},
1960  // WASM_SEC_ORDER_TABLE
1961  {WASM_SEC_ORDER_TABLE, WASM_SEC_ORDER_MEMORY},
1962  // WASM_SEC_ORDER_MEMORY
1963  {WASM_SEC_ORDER_MEMORY, WASM_SEC_ORDER_TAG},
1964  // WASM_SEC_ORDER_TAG
1965  {WASM_SEC_ORDER_TAG, WASM_SEC_ORDER_GLOBAL},
1966  // WASM_SEC_ORDER_GLOBAL
1967  {WASM_SEC_ORDER_GLOBAL, WASM_SEC_ORDER_EXPORT},
1968  // WASM_SEC_ORDER_EXPORT
1969  {WASM_SEC_ORDER_EXPORT, WASM_SEC_ORDER_START},
1970  // WASM_SEC_ORDER_START
1971  {WASM_SEC_ORDER_START, WASM_SEC_ORDER_ELEM},
1972  // WASM_SEC_ORDER_ELEM
1973  {WASM_SEC_ORDER_ELEM, WASM_SEC_ORDER_DATACOUNT},
1974  // WASM_SEC_ORDER_DATACOUNT
1975  {WASM_SEC_ORDER_DATACOUNT, WASM_SEC_ORDER_CODE},
1976  // WASM_SEC_ORDER_CODE
1977  {WASM_SEC_ORDER_CODE, WASM_SEC_ORDER_DATA},
1978  // WASM_SEC_ORDER_DATA
1979  {WASM_SEC_ORDER_DATA, WASM_SEC_ORDER_LINKING},
1980 
1981  // Custom Sections
1982  // WASM_SEC_ORDER_DYLINK
1983  {WASM_SEC_ORDER_DYLINK, WASM_SEC_ORDER_TYPE},
1984  // WASM_SEC_ORDER_LINKING
1985  {WASM_SEC_ORDER_LINKING, WASM_SEC_ORDER_RELOC, WASM_SEC_ORDER_NAME},
1986  // WASM_SEC_ORDER_RELOC (can be repeated)
1987  {},
1988  // WASM_SEC_ORDER_NAME
1989  {WASM_SEC_ORDER_NAME, WASM_SEC_ORDER_PRODUCERS},
1990  // WASM_SEC_ORDER_PRODUCERS
1991  {WASM_SEC_ORDER_PRODUCERS, WASM_SEC_ORDER_TARGET_FEATURES},
1992  // WASM_SEC_ORDER_TARGET_FEATURES
1993  {WASM_SEC_ORDER_TARGET_FEATURES}};
1994 
1996  StringRef CustomSectionName) {
1997  int Order = getSectionOrder(ID, CustomSectionName);
1998  if (Order == WASM_SEC_ORDER_NONE)
1999  return true;
2000 
2001  // Disallowed predecessors we need to check for
2003 
2004  // Keep track of completed checks to avoid repeating work
2005  bool Checked[WASM_NUM_SEC_ORDERS] = {};
2006 
2007  int Curr = Order;
2008  while (true) {
2009  // Add new disallowed predecessors to work list
2010  for (size_t I = 0;; ++I) {
2011  int Next = DisallowedPredecessors[Curr][I];
2012  if (Next == WASM_SEC_ORDER_NONE)
2013  break;
2014  if (Checked[Next])
2015  continue;
2016  WorkList.push_back(Next);
2017  Checked[Next] = true;
2018  }
2019 
2020  if (WorkList.empty())
2021  break;
2022 
2023  // Consider next disallowed predecessor
2024  Curr = WorkList.pop_back_val();
2025  if (Seen[Curr])
2026  return false;
2027  }
2028 
2029  // Have not seen any disallowed predecessors
2030  Seen[Order] = true;
2031  return true;
2032 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:76
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
i
i
Definition: README.txt:29
llvm::object::WasmSectionOrderChecker
Definition: Wasm.h:304
llvm::wasm::WASM_FEATURE_PREFIX_USED
@ WASM_FEATURE_PREFIX_USED
Definition: Wasm.h:342
llvm::wasm::WasmImport::Memory
WasmLimits Memory
Definition: Wasm.h:138
llvm::wasm::WASM_SYMBOL_TYPE_SECTION
@ WASM_SYMBOL_TYPE_SECTION
Definition: Wasm.h:384
llvm::wasm::WasmInitExprMVP::Float64
uint64_t Float64
Definition: Wasm.h:100
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_PRODUCERS
@ WASM_SEC_ORDER_PRODUCERS
Definition: Wasm.h:337
llvm::wasm::WASM_FEATURE_PREFIX_DISALLOWED
@ WASM_FEATURE_PREFIX_DISALLOWED
Definition: Wasm.h:344
llvm::wasm::WASM_DYLINK_MEM_INFO
@ WASM_DYLINK_MEM_INFO
Definition: Wasm.h:365
llvm::wasm::WasmTag
Definition: Wasm.h:124
llvm::wasm::WasmDataSegment::Offset
WasmInitExpr Offset
Definition: Wasm.h:166
llvm::StringSwitch::StartsWith
StringSwitch & StartsWith(StringLiteral S, T Value)
Definition: StringSwitch.h:83
llvm::wasm::WASM_COMDAT_SECTION
@ WASM_COMDAT_SECTION
Definition: Wasm.h:376
llvm::wasm::WASM_EXTERNAL_TAG
@ WASM_EXTERNAL_TAG
Definition: Wasm.h:277
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:494
llvm::object::Kind
Kind
Definition: COFFModuleDefinition.cpp:31
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::wasm::WasmElemSegment::Offset
WasmInitExpr Offset
Definition: Wasm.h:179
llvm::object::WasmObjectFile::WasmObjectFile
WasmObjectFile(MemoryBufferRef Object, Error &Err)
Definition: WasmObjectFile.cpp:291
llvm::wasm::NameType
NameType
Definition: Wasm.h:222
llvm::object::DataRefImpl::a
uint32_t a
Definition: SymbolicFile.h:39
llvm::object::WasmObjectFile::symbol_begin
basic_symbol_iterator symbol_begin() const override
Definition: WasmObjectFile.cpp:1591
type
llvm::wasm::WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND
const unsigned WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND
Definition: Wasm.h:338
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_EXPORT
@ WASM_SEC_ORDER_EXPORT
Definition: Wasm.h:319
llvm::object::WasmObjectFile::getFeatures
SubtargetFeatures getFeatures() const override
Definition: WasmObjectFile.cpp:1872
llvm::wasm::WASM_NAMES_GLOBAL
@ WASM_NAMES_GLOBAL
Definition: Wasm.h:351
llvm::wasm::WasmInitExpr::Inst
WasmInitExprMVP Inst
Definition: Wasm.h:108
llvm::object::WasmObjectFile::ReadContext::Start
const uint8_t * Start
Definition: Wasm.h:211
llvm::wasm::WASM_OPCODE_I64_MUL
@ WASM_OPCODE_I64_MUL
Definition: Wasm.h:299
llvm::Triple::wasm32
@ wasm32
Definition: Triple.h:103
llvm::Function::empty
bool empty() const
Definition: Function.h:731
llvm::object::WasmSection::Content
ArrayRef< uint8_t > Content
Definition: Wasm.h:111
llvm::Function
Definition: Function.h:60
StringRef.h
llvm::wasm::WASM_TYPE_EXTERNREF
@ WASM_TYPE_EXTERNREF
Definition: Wasm.h:266
llvm::StringSwitch::Default
LLVM_NODISCARD R Default(T Value)
Definition: StringSwitch.h:183
llvm::wasm::WasmVersion
const uint32_t WasmVersion
Definition: Wasm.h:28
TAG
static constexpr auto TAG
Definition: OpenMPOpt.cpp:173
llvm::object::ObjectFile::RelocationRef
friend class RelocationRef
Definition: ObjectFile.h:286
llvm::wasm::WASM_OPCODE_REF_NULL
@ WASM_OPCODE_REF_NULL
Definition: Wasm.h:300
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:1862
llvm::wasm::WasmFeatureEntry
Definition: Wasm.h:66
llvm::object::WasmSectionOrderChecker::isValidSectionOrder
bool isValidSectionOrder(unsigned ID, StringRef CustomSectionName="")
Definition: WasmObjectFile.cpp:1995
llvm::object::ObjectFile::createWasmObjectFile
static Expected< std::unique_ptr< WasmObjectFile > > createWasmObjectFile(MemoryBufferRef Object)
Definition: WasmObjectFile.cpp:56
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
llvm::wasm::WasmObjectHeader::Version
uint32_t Version
Definition: Wasm.h:36
llvm::object::WasmSymbol::Info
const wasm::WasmSymbolInfo & Info
Definition: Wasm.h:44
llvm::dwarf::Form
Form
Definition: Dwarf.h:132
ErrorHandling.h
llvm::wasm::WasmLinkingData::SymbolTable
std::vector< WasmSymbolInfo > SymbolTable
Definition: Wasm.h:238
llvm::object::WasmSymbol::isDefined
bool isDefined() const
Definition: Wasm.h:67
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
readVaruint32
static uint32_t readVaruint32(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:146
llvm::wasm::WasmFunction::Comdat
uint32_t Comdat
Definition: Wasm.h:158
llvm::wasm::WASM_SYMBOL_BINDING_LOCAL
const unsigned WASM_SYMBOL_BINDING_LOCAL
Definition: Wasm.h:404
llvm::wasm::WASM_SYMBOL_TYPE_TABLE
@ WASM_SYMBOL_TYPE_TABLE
Definition: Wasm.h:386
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_GLOBAL
@ WASM_SEC_ORDER_GLOBAL
Definition: Wasm.h:318
llvm::wasm::WASM_SYMBOL_TYPE_GLOBAL
@ WASM_SYMBOL_TYPE_GLOBAL
Definition: Wasm.h:383
llvm::object::WasmSection
Definition: Wasm.h:104
Error.h
llvm::wasm::WasmRelocation
Definition: Wasm.h:191
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_RELOC
@ WASM_SEC_ORDER_RELOC
Definition: Wasm.h:332
llvm::wasm::WasmImport::Table
WasmTableType Table
Definition: Wasm.h:137
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:56
llvm::object::relocation_iterator
content_iterator< RelocationRef > relocation_iterator
Definition: ObjectFile.h:76
llvm::wasm::WASM_TYPE_FUNC
@ WASM_TYPE_FUNC
Definition: Wasm.h:267
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_LINKING
@ WASM_SEC_ORDER_LINKING
Definition: Wasm.h:330
llvm::wasm::WasmDylinkInfo::ImportInfo
std::vector< WasmDylinkImportInfo > ImportInfo
Definition: Wasm.h:56
llvm::wasm::WASM_COMDAT_DATA
@ WASM_COMDAT_DATA
Definition: Wasm.h:373
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:1778
llvm::wasm::WASM_SEC_EXPORT
@ WASM_SEC_EXPORT
Definition: Wasm.h:249
llvm::wasm::WasmImport::SigIndex
uint32_t SigIndex
Definition: Wasm.h:135
llvm::object::Binary::Data
MemoryBufferRef Data
Definition: Binary.h:37
llvm::wasm::WASM_INIT_FUNCS
@ WASM_INIT_FUNCS
Definition: Wasm.h:358
readVaruint1
static uint8_t readVaruint1(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:132
llvm::SmallSet
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:136
llvm::wasm::WasmElemSegment::ElemKind
uint8_t ElemKind
Definition: Wasm.h:178
FUNCTION
#define FUNCTION(NAME, NARG, ROUND_MODE, INTRINSIC)
llvm::object::WasmObjectFile::getSectionName
Expected< StringRef > getSectionName(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1728
llvm::wasm::WASM_SYMBOL_UNDEFINED
const unsigned WASM_SYMBOL_UNDEFINED
Definition: Wasm.h:407
T
#define T
Definition: Mips16ISelLowering.cpp:341
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:79
llvm::wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER
@ WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER
Definition: Wasm.h:335
llvm::object::WasmObjectFile::getSymbolValueImpl
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1654
llvm::wasm::WASM_OPCODE_I64_CONST
@ WASM_OPCODE_I64_CONST
Definition: Wasm.h:291
llvm::object::WasmObjectFile::getRelocationTypeName
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
Definition: WasmObjectFile.cpp:1831
llvm::object::WasmObjectFile::isSectionBSS
bool isSectionBSS(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1790
llvm::wasm::WasmSymbolInfo::Kind
uint8_t Kind
Definition: Wasm.h:205
llvm::StringSet::insert
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition: StringSet.h:34
llvm::wasm::WASM_OPCODE_END
@ WASM_OPCODE_END
Definition: Wasm.h:282
llvm::object::SymbolRef::ST_Data
@ ST_Data
Definition: ObjectFile.h:174
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::wasm::WASM_NAMES_DATA_SEGMENT
@ WASM_NAMES_DATA_SEGMENT
Definition: Wasm.h:352
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:654
llvm::wasm::WasmFunction
Definition: Wasm.h:147
llvm::wasm::WASM_OPCODE_F32_CONST
@ WASM_OPCODE_F32_CONST
Definition: Wasm.h:292
llvm::object::BasicSymbolRef::SF_Weak
@ SF_Weak
Definition: SymbolicFile.h:112
llvm::wasm::WasmExport::Kind
uint8_t Kind
Definition: Wasm.h:73
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:105
SymbolicFile.h
llvm::object::WasmObjectFile::isRelocatableObject
bool isRelocatableObject() const override
True if this is a relocatable object (.o/.obj).
Definition: WasmObjectFile.cpp:1876
llvm::object::WasmObjectFile::getArch
Triple::ArchType getArch() const override
Definition: WasmObjectFile.cpp:1868
llvm::wasm::WasmDataReference::Offset
uint64_t Offset
Definition: Wasm.h:187
llvm::wasm::WASM_SEC_TABLE
@ WASM_SEC_TABLE
Definition: Wasm.h:246
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:185
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_NAME
@ WASM_SEC_ORDER_NAME
Definition: Wasm.h:335
readInitExpr
static Error readInitExpr(wasm::WasmInitExpr &Expr, WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:165
llvm::wasm::WasmExport::Index
uint32_t Index
Definition: Wasm.h:74
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::object::BasicSymbolRef::SF_Executable
@ SF_Executable
Definition: SymbolicFile.h:122
llvm::wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX
@ WASM_DATA_SEGMENT_HAS_MEMINDEX
Definition: Wasm.h:330
llvm::ArrayRef::data
const T * data() const
Definition: ArrayRef.h:161
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::wasm::WASM_DYLINK_NEEDED
@ WASM_DYLINK_NEEDED
Definition: Wasm.h:366
llvm::object::WasmObjectFile::moveSectionNext
void moveSectionNext(DataRefImpl &Sec) const override
Definition: WasmObjectFile.cpp:1726
llvm::wasm::WasmRelocation::Offset
uint64_t Offset
Definition: Wasm.h:194
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::ARMBuildAttrs::Section
@ Section
Legacy Tags.
Definition: ARMBuildAttributes.h:82
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
readULEB128
static uint64_t readULEB128(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:102
llvm::wasm::WASM_SEC_MEMORY
@ WASM_SEC_MEMORY
Definition: Wasm.h:247
readVarint32
static int32_t readVarint32(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:139
llvm::wasm::WasmElemSegment::TableNumber
uint32_t TableNumber
Definition: Wasm.h:177
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:403
llvm::wasm::WASM_LIMITS_FLAG_HAS_MAX
@ WASM_LIMITS_FLAG_HAS_MAX
Definition: Wasm.h:323
llvm::wasm::WasmFunction::DebugName
StringRef DebugName
Definition: Wasm.h:157
llvm::wasm::WASM_OPCODE_I32_ADD
@ WASM_OPCODE_I32_ADD
Definition: Wasm.h:294
llvm::object::WasmSection::Type
uint32_t Type
Definition: Wasm.h:107
Error.h
SubtargetFeature.h
llvm::Triple::ArchType
ArchType
Definition: Triple.h:46
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::object::WasmSectionOrderChecker::WASM_NUM_SEC_ORDERS
@ WASM_NUM_SEC_ORDERS
Definition: Wasm.h:342
llvm::wasm::WasmGlobalType::Mutable
bool Mutable
Definition: Wasm.h:114
llvm::wasm::WasmLimits
Definition: Wasm.h:77
llvm::object::BasicSymbolRef::getRawDataRefImpl
DataRefImpl getRawDataRefImpl() const
Definition: SymbolicFile.h:208
llvm::wasm::WasmRelocation::Addend
int64_t Addend
Definition: Wasm.h:195
llvm::wasm::WASM_EXTERNAL_GLOBAL
@ WASM_EXTERNAL_GLOBAL
Definition: Wasm.h:276
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:1891
llvm::wasm::WASM_SYMBOL_TABLE
@ WASM_SYMBOL_TABLE
Definition: Wasm.h:360
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_DATACOUNT
@ WASM_SEC_ORDER_DATACOUNT
Definition: Wasm.h:322
llvm::wasm::WASM_SEGMENT_INFO
@ WASM_SEGMENT_INFO
Definition: Wasm.h:357
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:103
llvm::object::WasmSymbol
Definition: Wasm.h:35
llvm::wasm::WasmFeatureEntry::Prefix
uint8_t Prefix
Definition: Wasm.h:67
llvm::object::WasmObjectFile::isSectionText
bool isSectionText(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1782
llvm::object::WasmObjectFile::getSymbolAlignment
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1658
llvm::SubtargetFeatures
Manages the enabling and disabling of subtarget specific features.
Definition: SubtargetFeature.h:183
llvm::object::WasmObjectFile::getSymbolSectionId
uint32_t getSymbolSectionId(SymbolRef Sym) const
Definition: WasmObjectFile.cpp:1702
readUint8
static uint8_t readUint8(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:70
llvm::wasm::WasmGlobalType
Definition: Wasm.h:112
DenseSet.h
llvm::wasm::WASM_OPCODE_I64_ADD
@ WASM_OPCODE_I64_ADD
Definition: Wasm.h:297
llvm::MCID::Return
@ Return
Definition: MCInstrDesc.h:153
llvm::wasm::WasmFunction::CodeSectionOffset
uint32_t CodeSectionOffset
Definition: Wasm.h:152
llvm::wasm::WasmProducerInfo::Languages
std::vector< std::pair< std::string, std::string > > Languages
Definition: Wasm.h:61
llvm::wasm::WASM_COMDAT_FUNCTION
@ WASM_COMDAT_FUNCTION
Definition: Wasm.h:374
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:1692
llvm::wasm::WasmInitExprMVP::Int64
int64_t Int64
Definition: Wasm.h:98
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_FUNCTION
@ WASM_SEC_ORDER_FUNCTION
Definition: Wasm.h:314
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:143
llvm::wasm::WasmDylinkInfo::MemoryAlignment
uint32_t MemoryAlignment
Definition: Wasm.h:52
llvm::wasm::WasmDataReference::Size
uint64_t Size
Definition: Wasm.h:188
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:54
llvm::AMDGPU::ElfNote::SectionName
const char SectionName[]
Definition: AMDGPUPTNote.h:24
llvm::ErrorAsOutParameter
Helper for Errors used as out-parameters.
Definition: Error.h:1097
llvm::object::object_error::parse_failed
@ parse_failed
llvm::wasm::WASM_SYMBOL_TYPE_FUNCTION
@ WASM_SYMBOL_TYPE_FUNCTION
Definition: Wasm.h:381
llvm::object::WasmObjectFile::moveRelocationNext
void moveRelocationNext(DataRefImpl &Rel) const override
Definition: WasmObjectFile.cpp:1809
llvm::wasm::WasmMetadataVersion
const uint32_t WasmMetadataVersion
Definition: Wasm.h:30
llvm::wasm::NameType::FUNCTION
@ FUNCTION
llvm::wasm::ValType
ValType
Definition: Wasm.h:422
llvm::wasm::WasmLocalDecl::Type
uint8_t Type
Definition: Wasm.h:143
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_IMPORT
@ WASM_SEC_ORDER_IMPORT
Definition: Wasm.h:313
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_MEMORY
@ WASM_SEC_ORDER_MEMORY
Definition: Wasm.h:316
llvm::wasm::WasmTable::Type
WasmTableType Type
Definition: Wasm.h:90
llvm::Comdat
Definition: Comdat.h:33
llvm::object::WasmSymbol::isUndefined
bool isUndefined() const
Definition: Wasm.h:69
llvm::wasm::WasmInitExpr::Body
ArrayRef< uint8_t > Body
Definition: Wasm.h:109
llvm::wasm::WasmSymbolInfo::Name
StringRef Name
Definition: Wasm.h:204
llvm::object::WasmObjectFile::getHeader
const wasm::WasmObjectHeader & getHeader() const
Definition: WasmObjectFile.cpp:1567
Wasm.h
llvm::wasm::WasmImport::Field
StringRef Field
Definition: Wasm.h:132
llvm::wasm::WasmSymbolInfo::ElementIndex
uint32_t ElementIndex
Definition: Wasm.h:216
llvm::object::WasmSymbol::print
void print(raw_ostream &Out) const
Definition: WasmObjectFile.cpp:38
llvm::PassSummaryAction::Import
@ Import
Import information from summary.
llvm::wasm::WASM_SEC_FUNCTION
@ WASM_SEC_FUNCTION
Definition: Wasm.h:245
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::object::WasmObjectFile::getSectionIndex
uint64_t getSectionIndex(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1757
llvm::wasm::WASM_OPCODE_I32_CONST
@ WASM_OPCODE_I32_CONST
Definition: Wasm.h:290
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_TABLE
@ WASM_SEC_ORDER_TABLE
Definition: Wasm.h:315
llvm::wasm::WasmObjectHeader::Magic
StringRef Magic
Definition: Wasm.h:35
readLEB128
static int64_t readLEB128(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:122
llvm::wasm::WASM_DYLINK_IMPORT_INFO
@ WASM_DYLINK_IMPORT_INFO
Definition: Wasm.h:368
llvm::wasm::NameType::GLOBAL
@ GLOBAL
llvm::wasm::WasmLinkingData::Comdats
std::vector< StringRef > Comdats
Definition: Wasm.h:237
llvm::wasm::WasmLimits::Flags
uint8_t Flags
Definition: Wasm.h:78
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:192
llvm::wasm::WASM_OPCODE_GLOBAL_GET
@ WASM_OPCODE_GLOBAL_GET
Definition: Wasm.h:286
llvm::DenseSet< uint64_t >
llvm::object::ObjectFile::SymbolRef
friend class SymbolRef
Definition: ObjectFile.h:246
llvm::wasm::WASM_OPCODE_I32_MUL
@ WASM_OPCODE_I32_MUL
Definition: Wasm.h:296
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::StringRef::empty
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
Index
uint32_t Index
Definition: ELFObjHandler.cpp:82
uint64_t
llvm::object::WasmObjectFile::getSymbolType
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1669
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_START
@ WASM_SEC_ORDER_START
Definition: Wasm.h:320
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:180
llvm::object::SymbolRef::ST_Function
@ ST_Function
Definition: ObjectFile.h:177
llvm::wasm::WASM_LIMITS_FLAG_IS_64
@ WASM_LIMITS_FLAG_IS_64
Definition: Wasm.h:325
llvm::wasm::ValType::EXTERNREF
@ EXTERNREF
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_DYLINK
@ WASM_SEC_ORDER_DYLINK
Definition: Wasm.h:328
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_NONE
@ WASM_SEC_ORDER_NONE
Definition: Wasm.h:309
llvm::wasm::WasmExport::Name
StringRef Name
Definition: Wasm.h:72
llvm::object::WasmObjectFile::section_begin
section_iterator section_begin() const override
Definition: WasmObjectFile.cpp:1850
llvm::wasm::WASM_SYMBOL_EXPLICIT_NAME
const unsigned WASM_SYMBOL_EXPLICIT_NAME
Definition: Wasm.h:409
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_TARGET_FEATURES
@ WASM_SEC_ORDER_TARGET_FEATURES
Definition: Wasm.h:339
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:109
llvm::wasm::WasmLocalDecl
Definition: Wasm.h:142
llvm::wasm::ValType::FUNCREF
@ FUNCREF
llvm::object::ObjectFile::SectionRef
friend class SectionRef
Definition: ObjectFile.h:260
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_ELEM
@ WASM_SEC_ORDER_ELEM
Definition: Wasm.h:321
readUint32
static uint32_t readUint32(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:76
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:1573
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::object::BasicSymbolRef::SF_Undefined
@ SF_Undefined
Definition: SymbolicFile.h:110
llvm::wasm::WasmSignature::Returns
SmallVector< ValType, 1 > Returns
Definition: Wasm.h:433
llvm::wasm::WASM_SEC_DATACOUNT
@ WASM_SEC_DATACOUNT
Definition: Wasm.h:254
llvm::wasm::WasmDylinkInfo::TableSize
uint32_t TableSize
Definition: Wasm.h:53
llvm::wasm::WasmImport
Definition: Wasm.h:130
llvm::wasm::WASM_SEC_IMPORT
@ WASM_SEC_IMPORT
Definition: Wasm.h:244
llvm::wasm::WASM_FEATURE_PREFIX_REQUIRED
@ WASM_FEATURE_PREFIX_REQUIRED
Definition: Wasm.h:343
ArrayRef.h
llvm::wasm::WASM_SEC_GLOBAL
@ WASM_SEC_GLOBAL
Definition: Wasm.h:248
llvm::wasm::WASM_SYMBOL_TYPE_TAG
@ WASM_SYMBOL_TYPE_TAG
Definition: Wasm.h:385
TemplateParamKind::Type
@ Type
llvm::wasm::WASM_ELEM_SEGMENT_IS_PASSIVE
@ WASM_ELEM_SEGMENT_IS_PASSIVE
Definition: Wasm.h:334
llvm::wasm::WASM_DATA_SEGMENT_IS_PASSIVE
@ WASM_DATA_SEGMENT_IS_PASSIVE
Definition: Wasm.h:329
llvm::wasm::WASM_EXTERNAL_FUNCTION
@ WASM_EXTERNAL_FUNCTION
Definition: Wasm.h:273
llvm::object::SymbolRef::ST_Debug
@ ST_Debug
Definition: ObjectFile.h:175
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::wasm::WasmDebugName
Definition: Wasm.h:228
llvm::Optional::getValue
constexpr const T & getValue() const &
Definition: Optional.h:279
ObjectFile.h
llvm::object::WasmObjectFile::getSectionAddress
uint64_t getSectionAddress(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1755
readFloat64
static int64_t readFloat64(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:93
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::wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS
@ WASM_ELEM_SEGMENT_HAS_INIT_EXPRS
Definition: Wasm.h:336
llvm::object::content_iterator
Definition: SymbolicFile.h:69
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_CODE
@ WASM_SEC_ORDER_CODE
Definition: Wasm.h:323
llvm::wasm::WASM_NAMES_LOCAL
@ WASM_NAMES_LOCAL
Definition: Wasm.h:350
llvm::wasm::WASM_SEC_START
@ WASM_SEC_START
Definition: Wasm.h:250
llvm::object::WasmObjectFile::getWasmSymbolValue
uint64_t getWasmSymbolValue(const WasmSymbol &Sym) const
Definition: WasmObjectFile.cpp:1626
llvm::wasm::WASM_DYLINK_EXPORT_INFO
@ WASM_DYLINK_EXPORT_INFO
Definition: Wasm.h:367
llvm::object::WasmObjectFile::isSharedObject
bool isSharedObject() const
Definition: WasmObjectFile.cpp:1878
llvm::wasm::WasmInitExprMVP::Global
uint32_t Global
Definition: Wasm.h:101
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::WasmInitExprMVP::Value
union llvm::wasm::WasmInitExprMVP::@171 Value
llvm::object::WasmObjectFile::getSymbolName
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1613
Triple.h
llvm::wasm::WASM_EXTERNAL_TABLE
@ WASM_EXTERNAL_TABLE
Definition: Wasm.h:274
llvm::StringSet
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition: StringSet.h:23
llvm::wasm::WASM_SEC_TYPE
@ WASM_SEC_TYPE
Definition: Wasm.h:243
llvm::wasm::WasmElemSegment::Flags
uint32_t Flags
Definition: Wasm.h:176
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_DATA
@ WASM_SEC_ORDER_DATA
Definition: Wasm.h:324
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
readVarint64
static int64_t readVarint64(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:153
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::wasm::WASM_SEC_CUSTOM
@ WASM_SEC_CUSTOM
Definition: Wasm.h:242
llvm::wasm::WASM_OPCODE_I32_SUB
@ WASM_OPCODE_I32_SUB
Definition: Wasm.h:295
llvm::object::Binary
Definition: Binary.h:32
llvm::object::WasmObjectFile::getSectionContents
Expected< ArrayRef< uint8_t > > getSectionContents(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1767
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::wasm::WasmObjectHeader
Definition: Wasm.h:34
llvm::wasm::WasmGlobal
Definition: Wasm.h:117
llvm::wasm::WasmInitExprMVP::Int32
int32_t Int32
Definition: Wasm.h:97
uint32_t
llvm::wasm::WASM_SYMBOL_BINDING_MASK
const unsigned WASM_SYMBOL_BINDING_MASK
Definition: Wasm.h:399
llvm::wasm::WasmSymbolType
WasmSymbolType
Definition: Wasm.h:380
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:35
llvm::object::WasmObjectFile::isSectionVirtual
bool isSectionVirtual(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1792
llvm::wasm::WasmTableType::Limits
WasmLimits Limits
Definition: Wasm.h:85
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_TAG
@ WASM_SEC_ORDER_TAG
Definition: Wasm.h:317
llvm::wasm::WasmSymbolInfo
Definition: Wasm.h:203
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:182
llvm::wasm::WasmDylinkInfo::Needed
std::vector< StringRef > Needed
Definition: Wasm.h:55
llvm::wasm::WasmImport::Global
WasmGlobalType Global
Definition: Wasm.h:136
llvm::wasm::WasmGlobalType::Type
uint8_t Type
Definition: Wasm.h:113
llvm::object::object_error::invalid_section_index
@ invalid_section_index
llvm::Init
Definition: Record.h:281
readSection
static Error readSection(WasmSection &Section, WasmObjectFile::ReadContext &Ctx, WasmSectionOrderChecker &Checker)
Definition: WasmObjectFile.cpp:255
llvm::wasm::WasmSymbolInfo::DataRef
WasmDataReference DataRef
Definition: Wasm.h:218
llvm::object::WasmObjectFile::isSectionData
bool isSectionData(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1786
llvm::wasm::WASM_SEC_CODE
@ WASM_SEC_CODE
Definition: Wasm.h:252
llvm::object::WasmObjectFile::getSectionSize
uint64_t getSectionSize(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1761
llvm::wasm::WASM_SEC_TAG
@ WASM_SEC_TAG
Definition: Wasm.h:255
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:1886
StringSet.h
llvm::StringRef::size
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::object::WasmObjectFile::ReadContext
Definition: Wasm.h:210
llvm::object::WasmObjectFile::getSectionAlignment
uint64_t getSectionAlignment(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1774
llvm::wasm::WasmDataReference::Segment
uint32_t Segment
Definition: Wasm.h:186
llvm::object::WasmObjectFile::moveSymbolNext
void moveSymbolNext(DataRefImpl &Symb) const override
Definition: WasmObjectFile.cpp:1571
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:84
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1239
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::wasm::WASM_OPCODE_F64_CONST
@ WASM_OPCODE_F64_CONST
Definition: Wasm.h:293
llvm::object::WasmObjectFile::getRelocationSymbol
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
Definition: WasmObjectFile.cpp:1816
llvm::object::DataRefImpl::d
struct llvm::object::DataRefImpl::@331 d
llvm::toString
const char * toString(DWARFSectionKind Kind)
Definition: DWARFUnitIndex.h:67
VARUINT1_MAX
#define VARUINT1_MAX
Definition: WasmObjectFile.cpp:68
llvm::wasm::WasmLinkingData::InitFunctions
std::vector< WasmInitFunc > InitFunctions
Definition: Wasm.h:236
llvm::SectionName
Definition: DWARFSection.h:21
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
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:1605
llvm::wasm::WasmInitFunc
Definition: Wasm.h:198
llvm::wasm::WasmSymbolInfo::Flags
uint32_t Flags
Definition: Wasm.h:206
llvm::wasm::WasmLocalDecl::Count
uint32_t Count
Definition: Wasm.h:144
readOpcode
static uint8_t readOpcode(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:161
readTableType
static wasm::WasmTableType readTableType(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:248
llvm::object::WasmObjectFile::section_end
section_iterator section_end() const override
Definition: WasmObjectFile.cpp:1856
llvm::wasm::WASM_SEC_ELEM
@ WASM_SEC_ELEM
Definition: Wasm.h:251
llvm::wasm::WasmDataSegment
Definition: Wasm.h:161
llvm::object::WasmObjectFile::getSymbolAddress
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1617
llvm::object::WasmObjectFile::getRelocationOffset
uint64_t getRelocationOffset(DataRefImpl Rel) const override
Definition: WasmObjectFile.cpp:1811
llvm::object::WasmObjectFile::symbol_end
basic_symbol_iterator symbol_end() const override
Definition: WasmObjectFile.cpp:1598
llvm::wasm::WasmInitExpr
Definition: Wasm.h:105
StringSwitch.h
llvm::wasm::WasmFunction::ExportName
Optional< StringRef > ExportName
Definition: Wasm.h:155
llvm::object::WasmObjectFile::section_rel_begin
relocation_iterator section_rel_begin(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1794
llvm::wasm::WasmLinkingData::Version
uint32_t Version
Definition: Wasm.h:235
Wasm.h
llvm::object::SymbolRef::ST_Other
@ ST_Other
Definition: ObjectFile.h:173
llvm::wasm::WasmTable
Definition: Wasm.h:88
llvm::wasm::NameType::DATA_SEGMENT
@ DATA_SEGMENT
llvm::NVPTX::PTXLdStInstCode::GLOBAL
@ GLOBAL
Definition: NVPTX.h:109
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:131
llvm::wasm::WasmRelocation::Index
uint32_t Index
Definition: Wasm.h:193
Version
uint64_t Version
Definition: RawMemProfReader.cpp:40
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:1663
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_TYPE
@ WASM_SEC_ORDER_TYPE
Definition: Wasm.h:312
llvm::wasm::WasmElemSegment
Definition: Wasm.h:175
llvm::object::BasicSymbolRef::SF_Global
@ SF_Global
Definition: SymbolicFile.h:111
llvm::object::BasicSymbolRef::SF_Hidden
@ SF_Hidden
Definition: SymbolicFile.h:120
llvm::to_string
std::string to_string(const T &Value)
Definition: ScopedPrinter.h:86
readVaruint64
static uint64_t readVaruint64(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:157
llvm::wasm::WASM_NAMES_FUNCTION
@ WASM_NAMES_FUNCTION
Definition: Wasm.h:349
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:164
llvm::wasm::WASM_COMDAT_INFO
@ WASM_COMDAT_INFO
Definition: Wasm.h:359
llvm::pdb::PDB_DataKind::Global
@ Global
llvm::SmallVectorImpl< char >
llvm::wasm::WasmFeatureEntry::Name
std::string Name
Definition: Wasm.h:68
llvm::wasm::WASM_SEC_DATA
@ WASM_SEC_DATA
Definition: Wasm.h:253
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:38
llvm::wasm::WASM_OPCODE_I64_SUB
@ WASM_OPCODE_I64_SUB
Definition: Wasm.h:298
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
llvm::wasm::WASM_TYPE_FUNCREF
@ WASM_TYPE_FUNCREF
Definition: Wasm.h:265
ECase
#define ECase(X)
llvm::object::DataRefImpl::b
uint32_t b
Definition: SymbolicFile.h:39
llvm::object::WasmSymbol::dump
LLVM_DUMP_METHOD void dump() const
Definition: WasmObjectFile.cpp:52
llvm::wasm::WasmImport::Kind
uint8_t Kind
Definition: Wasm.h:133
llvm::object::WasmObjectFile::getRelocationType
uint64_t getRelocationType(DataRefImpl Rel) const override
Definition: WasmObjectFile.cpp:1826
llvm::wasm::WasmInitExprMVP::Opcode
uint8_t Opcode
Definition: Wasm.h:95
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:112
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:1801
llvm::wasm::WASM_EXTERNAL_MEMORY
@ WASM_EXTERNAL_MEMORY
Definition: Wasm.h:275
llvm::SmallVectorImpl::reserve
void reserve(size_type N)
Definition: SmallVector.h:644
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:104
llvm::wasm::WasmDylinkInfo::TableAlignment
uint32_t TableAlignment
Definition: Wasm.h:54
llvm::wasm::WasmInitExprMVP::Float32
uint32_t Float32
Definition: Wasm.h:99
llvm::wasm::WasmInitExpr::Extended
uint8_t Extended
Definition: Wasm.h:106
llvm::wasm::WasmSignature::Params
SmallVector< ValType, 4 > Params
Definition: Wasm.h:434
llvm::object::WasmSection::Relocations
std::vector< wasm::WasmRelocation > Relocations
Definition: Wasm.h:112
llvm::object::WasmObjectFile::getFileFormatName
StringRef getFileFormatName() const override
Definition: WasmObjectFile.cpp:1866
llvm::wasm::WasmExport
Definition: Wasm.h:71
llvm::wasm::WASM_SYMBOL_TYPE_DATA
@ WASM_SYMBOL_TYPE_DATA
Definition: Wasm.h:382
llvm::wasm::WasmSignature
Definition: Wasm.h:432
readLimits
static wasm::WasmLimits readLimits(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:239
llvm::object::WasmSymbol::isBindingLocal
bool isBindingLocal() const
Definition: Wasm.h:81
SmallSet.h
ScopedPrinter.h