LLVM  16.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 (true) {
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 
455  while (Ctx.Ptr < Ctx.End) {
456  uint8_t Type = readUint8(Ctx);
457  uint32_t Size = readVaruint32(Ctx);
458  const uint8_t *SubSectionEnd = Ctx.Ptr + Size;
459  switch (Type) {
463  uint32_t Count = readVaruint32(Ctx);
464  while (Count--) {
466  StringRef Name = readString(Ctx);
469  if (!SeenFunctions.insert(Index).second)
470  return make_error<GenericBinaryError>(
471  "function named more than once", object_error::parse_failed);
472  if (!isValidFunctionIndex(Index) || Name.empty())
473  return make_error<GenericBinaryError>("invalid function name entry",
475 
476  if (isDefinedFunctionIndex(Index))
477  getDefinedFunction(Index).DebugName = Name;
478  } else if (Type == wasm::WASM_NAMES_GLOBAL) {
479  nameType = wasm::NameType::GLOBAL;
480  if (!SeenGlobals.insert(Index).second)
481  return make_error<GenericBinaryError>("global named more than once",
483  if (!isValidGlobalIndex(Index) || Name.empty())
484  return make_error<GenericBinaryError>("invalid global name entry",
486  } else {
487  nameType = wasm::NameType::DATA_SEGMENT;
488  if (!SeenSegments.insert(Index).second)
489  return make_error<GenericBinaryError>(
490  "segment named more than once", object_error::parse_failed);
491  if (Index > DataSegments.size())
492  return make_error<GenericBinaryError>("invalid data segment name entry",
494  }
495  DebugNames.push_back(wasm::WasmDebugName{nameType, Index, Name});
496  }
497  break;
498  }
499  // Ignore local names for now
501  default:
502  Ctx.Ptr += Size;
503  break;
504  }
505  if (Ctx.Ptr != SubSectionEnd)
506  return make_error<GenericBinaryError>(
507  "name sub-section ended prematurely", object_error::parse_failed);
508  }
509 
510  if (Ctx.Ptr != Ctx.End)
511  return make_error<GenericBinaryError>("name section ended prematurely",
513  return Error::success();
514 }
515 
516 Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {
517  HasLinkingSection = true;
518 
519  LinkingData.Version = readVaruint32(Ctx);
520  if (LinkingData.Version != wasm::WasmMetadataVersion) {
521  return make_error<GenericBinaryError>(
522  "unexpected metadata version: " + Twine(LinkingData.Version) +
523  " (Expected: " + Twine(wasm::WasmMetadataVersion) + ")",
525  }
526 
527  const uint8_t *OrigEnd = Ctx.End;
528  while (Ctx.Ptr < OrigEnd) {
529  Ctx.End = OrigEnd;
530  uint8_t Type = readUint8(Ctx);
531  uint32_t Size = readVaruint32(Ctx);
532  LLVM_DEBUG(dbgs() << "readSubsection type=" << int(Type) << " size=" << Size
533  << "\n");
534  Ctx.End = Ctx.Ptr + Size;
535  switch (Type) {
537  if (Error Err = parseLinkingSectionSymtab(Ctx))
538  return Err;
539  break;
541  uint32_t Count = readVaruint32(Ctx);
542  if (Count > DataSegments.size())
543  return make_error<GenericBinaryError>("too many segment names",
545  for (uint32_t I = 0; I < Count; I++) {
546  DataSegments[I].Data.Name = readString(Ctx);
547  DataSegments[I].Data.Alignment = readVaruint32(Ctx);
548  DataSegments[I].Data.LinkingFlags = readVaruint32(Ctx);
549  }
550  break;
551  }
552  case wasm::WASM_INIT_FUNCS: {
553  uint32_t Count = readVaruint32(Ctx);
554  LinkingData.InitFunctions.reserve(Count);
555  for (uint32_t I = 0; I < Count; I++) {
557  Init.Priority = readVaruint32(Ctx);
558  Init.Symbol = readVaruint32(Ctx);
559  if (!isValidFunctionSymbol(Init.Symbol))
560  return make_error<GenericBinaryError>("invalid function symbol: " +
561  Twine(Init.Symbol),
563  LinkingData.InitFunctions.emplace_back(Init);
564  }
565  break;
566  }
568  if (Error Err = parseLinkingSectionComdat(Ctx))
569  return Err;
570  break;
571  default:
572  Ctx.Ptr += Size;
573  break;
574  }
575  if (Ctx.Ptr != Ctx.End)
576  return make_error<GenericBinaryError>(
577  "linking sub-section ended prematurely", object_error::parse_failed);
578  }
579  if (Ctx.Ptr != OrigEnd)
580  return make_error<GenericBinaryError>("linking section ended prematurely",
582  return Error::success();
583 }
584 
585 Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
586  uint32_t Count = readVaruint32(Ctx);
587  LinkingData.SymbolTable.reserve(Count);
588  Symbols.reserve(Count);
589  StringSet<> SymbolNames;
590 
591  std::vector<wasm::WasmImport *> ImportedGlobals;
592  std::vector<wasm::WasmImport *> ImportedFunctions;
593  std::vector<wasm::WasmImport *> ImportedTags;
594  std::vector<wasm::WasmImport *> ImportedTables;
595  ImportedGlobals.reserve(Imports.size());
596  ImportedFunctions.reserve(Imports.size());
597  ImportedTags.reserve(Imports.size());
598  ImportedTables.reserve(Imports.size());
599  for (auto &I : Imports) {
600  if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
601  ImportedFunctions.emplace_back(&I);
602  else if (I.Kind == wasm::WASM_EXTERNAL_GLOBAL)
603  ImportedGlobals.emplace_back(&I);
604  else if (I.Kind == wasm::WASM_EXTERNAL_TAG)
605  ImportedTags.emplace_back(&I);
606  else if (I.Kind == wasm::WASM_EXTERNAL_TABLE)
607  ImportedTables.emplace_back(&I);
608  }
609 
610  while (Count--) {
612  const wasm::WasmSignature *Signature = nullptr;
613  const wasm::WasmGlobalType *GlobalType = nullptr;
614  const wasm::WasmTableType *TableType = nullptr;
615 
616  Info.Kind = readUint8(Ctx);
617  Info.Flags = readVaruint32(Ctx);
618  bool IsDefined = (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0;
619 
620  switch (Info.Kind) {
622  Info.ElementIndex = readVaruint32(Ctx);
623  if (!isValidFunctionIndex(Info.ElementIndex) ||
624  IsDefined != isDefinedFunctionIndex(Info.ElementIndex))
625  return make_error<GenericBinaryError>("invalid function symbol index",
627  if (IsDefined) {
628  Info.Name = readString(Ctx);
629  unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions;
630  wasm::WasmFunction &Function = Functions[FuncIndex];
631  Signature = &Signatures[Function.SigIndex];
632  if (Function.SymbolName.empty())
633  Function.SymbolName = Info.Name;
634  } else {
635  wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex];
636  if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
637  Info.Name = readString(Ctx);
638  Info.ImportName = Import.Field;
639  } else {
640  Info.Name = Import.Field;
641  }
642  Signature = &Signatures[Import.SigIndex];
643  Info.ImportModule = Import.Module;
644  }
645  break;
646 
648  Info.ElementIndex = readVaruint32(Ctx);
649  if (!isValidGlobalIndex(Info.ElementIndex) ||
650  IsDefined != isDefinedGlobalIndex(Info.ElementIndex))
651  return make_error<GenericBinaryError>("invalid global symbol index",
653  if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
655  return make_error<GenericBinaryError>("undefined weak global symbol",
657  if (IsDefined) {
658  Info.Name = readString(Ctx);
659  unsigned GlobalIndex = Info.ElementIndex - NumImportedGlobals;
660  wasm::WasmGlobal &Global = Globals[GlobalIndex];
661  GlobalType = &Global.Type;
662  if (Global.SymbolName.empty())
663  Global.SymbolName = Info.Name;
664  } else {
665  wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex];
666  if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
667  Info.Name = readString(Ctx);
668  Info.ImportName = Import.Field;
669  } else {
670  Info.Name = Import.Field;
671  }
672  GlobalType = &Import.Global;
673  Info.ImportModule = Import.Module;
674  }
675  break;
676 
678  Info.ElementIndex = readVaruint32(Ctx);
679  if (!isValidTableNumber(Info.ElementIndex) ||
680  IsDefined != isDefinedTableNumber(Info.ElementIndex))
681  return make_error<GenericBinaryError>("invalid table symbol index",
683  if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
685  return make_error<GenericBinaryError>("undefined weak table symbol",
687  if (IsDefined) {
688  Info.Name = readString(Ctx);
689  unsigned TableNumber = Info.ElementIndex - NumImportedTables;
690  wasm::WasmTable &Table = Tables[TableNumber];
691  TableType = &Table.Type;
692  if (Table.SymbolName.empty())
693  Table.SymbolName = Info.Name;
694  } else {
695  wasm::WasmImport &Import = *ImportedTables[Info.ElementIndex];
696  if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
697  Info.Name = readString(Ctx);
698  Info.ImportName = Import.Field;
699  } else {
700  Info.Name = Import.Field;
701  }
702  TableType = &Import.Table;
703  Info.ImportModule = Import.Module;
704  }
705  break;
706 
708  Info.Name = readString(Ctx);
709  if (IsDefined) {
710  auto Index = readVaruint32(Ctx);
711  if (Index >= DataSegments.size())
712  return make_error<GenericBinaryError>("invalid data symbol index",
714  auto Offset = readVaruint64(Ctx);
715  auto Size = readVaruint64(Ctx);
716  size_t SegmentSize = DataSegments[Index].Data.Content.size();
717  if (Offset > SegmentSize)
718  return make_error<GenericBinaryError>(
719  "invalid data symbol offset: `" + Info.Name + "` (offset: " +
720  Twine(Offset) + " segment size: " + Twine(SegmentSize) + ")",
723  }
724  break;
725 
727  if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
729  return make_error<GenericBinaryError>(
730  "section symbols must have local binding",
732  Info.ElementIndex = readVaruint32(Ctx);
733  // Use somewhat unique section name as symbol name.
734  StringRef SectionName = Sections[Info.ElementIndex].Name;
735  Info.Name = SectionName;
736  break;
737  }
738 
740  Info.ElementIndex = readVaruint32(Ctx);
741  if (!isValidTagIndex(Info.ElementIndex) ||
742  IsDefined != isDefinedTagIndex(Info.ElementIndex))
743  return make_error<GenericBinaryError>("invalid tag symbol index",
745  if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
747  return make_error<GenericBinaryError>("undefined weak global symbol",
749  if (IsDefined) {
750  Info.Name = readString(Ctx);
751  unsigned TagIndex = Info.ElementIndex - NumImportedTags;
752  wasm::WasmTag &Tag = Tags[TagIndex];
753  Signature = &Signatures[Tag.SigIndex];
754  if (Tag.SymbolName.empty())
755  Tag.SymbolName = Info.Name;
756 
757  } else {
758  wasm::WasmImport &Import = *ImportedTags[Info.ElementIndex];
759  if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
760  Info.Name = readString(Ctx);
761  Info.ImportName = Import.Field;
762  } else {
763  Info.Name = Import.Field;
764  }
765  Signature = &Signatures[Import.SigIndex];
766  Info.ImportModule = Import.Module;
767  }
768  break;
769  }
770 
771  default:
772  return make_error<GenericBinaryError>("invalid symbol type: " +
773  Twine(unsigned(Info.Kind)),
775  }
776 
777  if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
779  !SymbolNames.insert(Info.Name).second)
780  return make_error<GenericBinaryError>("duplicate symbol name " +
781  Twine(Info.Name),
783  LinkingData.SymbolTable.emplace_back(Info);
784  Symbols.emplace_back(LinkingData.SymbolTable.back(), GlobalType, TableType,
785  Signature);
786  LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");
787  }
788 
789  return Error::success();
790 }
791 
792 Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
793  uint32_t ComdatCount = readVaruint32(Ctx);
794  StringSet<> ComdatSet;
795  for (unsigned ComdatIndex = 0; ComdatIndex < ComdatCount; ++ComdatIndex) {
796  StringRef Name = readString(Ctx);
797  if (Name.empty() || !ComdatSet.insert(Name).second)
798  return make_error<GenericBinaryError>("bad/duplicate COMDAT name " +
799  Twine(Name),
801  LinkingData.Comdats.emplace_back(Name);
802  uint32_t Flags = readVaruint32(Ctx);
803  if (Flags != 0)
804  return make_error<GenericBinaryError>("unsupported COMDAT flags",
806 
807  uint32_t EntryCount = readVaruint32(Ctx);
808  while (EntryCount--) {
809  unsigned Kind = readVaruint32(Ctx);
810  unsigned Index = readVaruint32(Ctx);
811  switch (Kind) {
812  default:
813  return make_error<GenericBinaryError>("invalid COMDAT entry type",
816  if (Index >= DataSegments.size())
817  return make_error<GenericBinaryError>(
818  "COMDAT data index out of range", object_error::parse_failed);
819  if (DataSegments[Index].Data.Comdat != UINT32_MAX)
820  return make_error<GenericBinaryError>("data segment in two COMDATs",
822  DataSegments[Index].Data.Comdat = ComdatIndex;
823  break;
825  if (!isDefinedFunctionIndex(Index))
826  return make_error<GenericBinaryError>(
827  "COMDAT function index out of range", object_error::parse_failed);
828  if (getDefinedFunction(Index).Comdat != UINT32_MAX)
829  return make_error<GenericBinaryError>("function in two COMDATs",
831  getDefinedFunction(Index).Comdat = ComdatIndex;
832  break;
834  if (Index >= Sections.size())
835  return make_error<GenericBinaryError>(
836  "COMDAT section index out of range", object_error::parse_failed);
837  if (Sections[Index].Type != wasm::WASM_SEC_CUSTOM)
838  return make_error<GenericBinaryError>(
839  "non-custom section in a COMDAT", object_error::parse_failed);
840  Sections[Index].Comdat = ComdatIndex;
841  break;
842  }
843  }
844  }
845  return Error::success();
846 }
847 
848 Error WasmObjectFile::parseProducersSection(ReadContext &Ctx) {
849  llvm::SmallSet<StringRef, 3> FieldsSeen;
850  uint32_t Fields = readVaruint32(Ctx);
851  for (size_t I = 0; I < Fields; ++I) {
852  StringRef FieldName = readString(Ctx);
853  if (!FieldsSeen.insert(FieldName).second)
854  return make_error<GenericBinaryError>(
855  "producers section does not have unique fields",
857  std::vector<std::pair<std::string, std::string>> *ProducerVec = nullptr;
858  if (FieldName == "language") {
859  ProducerVec = &ProducerInfo.Languages;
860  } else if (FieldName == "processed-by") {
861  ProducerVec = &ProducerInfo.Tools;
862  } else if (FieldName == "sdk") {
863  ProducerVec = &ProducerInfo.SDKs;
864  } else {
865  return make_error<GenericBinaryError>(
866  "producers section field is not named one of language, processed-by, "
867  "or sdk",
869  }
870  uint32_t ValueCount = readVaruint32(Ctx);
871  llvm::SmallSet<StringRef, 8> ProducersSeen;
872  for (size_t J = 0; J < ValueCount; ++J) {
873  StringRef Name = readString(Ctx);
875  if (!ProducersSeen.insert(Name).second) {
876  return make_error<GenericBinaryError>(
877  "producers section contains repeated producer",
879  }
880  ProducerVec->emplace_back(std::string(Name), std::string(Version));
881  }
882  }
883  if (Ctx.Ptr != Ctx.End)
884  return make_error<GenericBinaryError>("producers section ended prematurely",
886  return Error::success();
887 }
888 
889 Error WasmObjectFile::parseTargetFeaturesSection(ReadContext &Ctx) {
890  llvm::SmallSet<std::string, 8> FeaturesSeen;
891  uint32_t FeatureCount = readVaruint32(Ctx);
892  for (size_t I = 0; I < FeatureCount; ++I) {
893  wasm::WasmFeatureEntry Feature;
894  Feature.Prefix = readUint8(Ctx);
895  switch (Feature.Prefix) {
899  break;
900  default:
901  return make_error<GenericBinaryError>("unknown feature policy prefix",
903  }
904  Feature.Name = std::string(readString(Ctx));
905  if (!FeaturesSeen.insert(Feature.Name).second)
906  return make_error<GenericBinaryError>(
907  "target features section contains repeated feature \"" +
908  Feature.Name + "\"",
910  TargetFeatures.push_back(Feature);
911  }
912  if (Ctx.Ptr != Ctx.End)
913  return make_error<GenericBinaryError>(
914  "target features section ended prematurely",
916  return Error::success();
917 }
918 
919 Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
920  uint32_t SectionIndex = readVaruint32(Ctx);
921  if (SectionIndex >= Sections.size())
922  return make_error<GenericBinaryError>("invalid section index",
924  WasmSection &Section = Sections[SectionIndex];
925  uint32_t RelocCount = readVaruint32(Ctx);
926  uint32_t EndOffset = Section.Content.size();
927  uint32_t PreviousOffset = 0;
928  while (RelocCount--) {
929  wasm::WasmRelocation Reloc = {};
930  uint32_t type = readVaruint32(Ctx);
931  Reloc.Type = type;
932  Reloc.Offset = readVaruint32(Ctx);
933  if (Reloc.Offset < PreviousOffset)
934  return make_error<GenericBinaryError>("relocations not in offset order",
936  PreviousOffset = Reloc.Offset;
937  Reloc.Index = readVaruint32(Ctx);
938  switch (type) {
939  case wasm::R_WASM_FUNCTION_INDEX_LEB:
940  case wasm::R_WASM_TABLE_INDEX_SLEB:
941  case wasm::R_WASM_TABLE_INDEX_SLEB64:
942  case wasm::R_WASM_TABLE_INDEX_I32:
943  case wasm::R_WASM_TABLE_INDEX_I64:
944  case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
945  case wasm::R_WASM_TABLE_INDEX_REL_SLEB64:
946  if (!isValidFunctionSymbol(Reloc.Index))
947  return make_error<GenericBinaryError>(
948  "invalid relocation function index", object_error::parse_failed);
949  break;
950  case wasm::R_WASM_TABLE_NUMBER_LEB:
951  if (!isValidTableSymbol(Reloc.Index))
952  return make_error<GenericBinaryError>("invalid relocation table index",
954  break;
955  case wasm::R_WASM_TYPE_INDEX_LEB:
956  if (Reloc.Index >= Signatures.size())
957  return make_error<GenericBinaryError>("invalid relocation type index",
959  break;
960  case wasm::R_WASM_GLOBAL_INDEX_LEB:
961  // R_WASM_GLOBAL_INDEX_LEB are can be used against function and data
962  // symbols to refer to their GOT entries.
963  if (!isValidGlobalSymbol(Reloc.Index) &&
964  !isValidDataSymbol(Reloc.Index) &&
965  !isValidFunctionSymbol(Reloc.Index))
966  return make_error<GenericBinaryError>("invalid relocation global index",
968  break;
969  case wasm::R_WASM_GLOBAL_INDEX_I32:
970  if (!isValidGlobalSymbol(Reloc.Index))
971  return make_error<GenericBinaryError>("invalid relocation global index",
973  break;
974  case wasm::R_WASM_TAG_INDEX_LEB:
975  if (!isValidTagSymbol(Reloc.Index))
976  return make_error<GenericBinaryError>("invalid relocation tag index",
978  break;
979  case wasm::R_WASM_MEMORY_ADDR_LEB:
980  case wasm::R_WASM_MEMORY_ADDR_SLEB:
981  case wasm::R_WASM_MEMORY_ADDR_I32:
982  case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
983  case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
984  case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
985  if (!isValidDataSymbol(Reloc.Index))
986  return make_error<GenericBinaryError>("invalid relocation data index",
988  Reloc.Addend = readVarint32(Ctx);
989  break;
990  case wasm::R_WASM_MEMORY_ADDR_LEB64:
991  case wasm::R_WASM_MEMORY_ADDR_SLEB64:
992  case wasm::R_WASM_MEMORY_ADDR_I64:
993  case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
994  case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64:
995  if (!isValidDataSymbol(Reloc.Index))
996  return make_error<GenericBinaryError>("invalid relocation data index",
998  Reloc.Addend = readVarint64(Ctx);
999  break;
1000  case wasm::R_WASM_FUNCTION_OFFSET_I32:
1001  if (!isValidFunctionSymbol(Reloc.Index))
1002  return make_error<GenericBinaryError>(
1003  "invalid relocation function index", object_error::parse_failed);
1004  Reloc.Addend = readVarint32(Ctx);
1005  break;
1006  case wasm::R_WASM_FUNCTION_OFFSET_I64:
1007  if (!isValidFunctionSymbol(Reloc.Index))
1008  return make_error<GenericBinaryError>(
1009  "invalid relocation function index", object_error::parse_failed);
1010  Reloc.Addend = readVarint64(Ctx);
1011  break;
1012  case wasm::R_WASM_SECTION_OFFSET_I32:
1013  if (!isValidSectionSymbol(Reloc.Index))
1014  return make_error<GenericBinaryError>(
1015  "invalid relocation section index", object_error::parse_failed);
1016  Reloc.Addend = readVarint32(Ctx);
1017  break;
1018  default:
1019  return make_error<GenericBinaryError>("invalid relocation type: " +
1020  Twine(type),
1022  }
1023 
1024  // Relocations must fit inside the section, and must appear in order. They
1025  // also shouldn't overlap a function/element boundary, but we don't bother
1026  // to check that.
1027  uint64_t Size = 5;
1028  if (Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LEB64 ||
1029  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_SLEB64 ||
1030  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_REL_SLEB64)
1031  Size = 10;
1032  if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I32 ||
1033  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I32 ||
1034  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LOCREL_I32 ||
1035  Reloc.Type == wasm::R_WASM_SECTION_OFFSET_I32 ||
1036  Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||
1037  Reloc.Type == wasm::R_WASM_GLOBAL_INDEX_I32)
1038  Size = 4;
1039  if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I64 ||
1040  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I64 ||
1041  Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I64)
1042  Size = 8;
1043  if (Reloc.Offset + Size > EndOffset)
1044  return make_error<GenericBinaryError>("invalid relocation offset",
1046 
1047  Section.Relocations.push_back(Reloc);
1048  }
1049  if (Ctx.Ptr != Ctx.End)
1050  return make_error<GenericBinaryError>("reloc section ended prematurely",
1052  return Error::success();
1053 }
1054 
1055 Error WasmObjectFile::parseCustomSection(WasmSection &Sec, ReadContext &Ctx) {
1056  if (Sec.Name == "dylink") {
1057  if (Error Err = parseDylinkSection(Ctx))
1058  return Err;
1059  } else if (Sec.Name == "dylink.0") {
1060  if (Error Err = parseDylink0Section(Ctx))
1061  return Err;
1062  } else if (Sec.Name == "name") {
1063  if (Error Err = parseNameSection(Ctx))
1064  return Err;
1065  } else if (Sec.Name == "linking") {
1066  if (Error Err = parseLinkingSection(Ctx))
1067  return Err;
1068  } else if (Sec.Name == "producers") {
1069  if (Error Err = parseProducersSection(Ctx))
1070  return Err;
1071  } else if (Sec.Name == "target_features") {
1072  if (Error Err = parseTargetFeaturesSection(Ctx))
1073  return Err;
1074  } else if (Sec.Name.startswith("reloc.")) {
1075  if (Error Err = parseRelocSection(Sec.Name, Ctx))
1076  return Err;
1077  }
1078  return Error::success();
1079 }
1080 
1081 Error WasmObjectFile::parseTypeSection(ReadContext &Ctx) {
1082  uint32_t Count = readVaruint32(Ctx);
1083  Signatures.reserve(Count);
1084  while (Count--) {
1085  wasm::WasmSignature Sig;
1086  uint8_t Form = readUint8(Ctx);
1087  if (Form != wasm::WASM_TYPE_FUNC) {
1088  return make_error<GenericBinaryError>("invalid signature type",
1090  }
1091  uint32_t ParamCount = readVaruint32(Ctx);
1092  Sig.Params.reserve(ParamCount);
1093  while (ParamCount--) {
1094  uint32_t ParamType = readUint8(Ctx);
1095  Sig.Params.push_back(wasm::ValType(ParamType));
1096  }
1097  uint32_t ReturnCount = readVaruint32(Ctx);
1098  while (ReturnCount--) {
1099  uint32_t ReturnType = readUint8(Ctx);
1100  Sig.Returns.push_back(wasm::ValType(ReturnType));
1101  }
1102  Signatures.push_back(std::move(Sig));
1103  }
1104  if (Ctx.Ptr != Ctx.End)
1105  return make_error<GenericBinaryError>("type section ended prematurely",
1107  return Error::success();
1108 }
1109 
1110 Error WasmObjectFile::parseImportSection(ReadContext &Ctx) {
1111  uint32_t Count = readVaruint32(Ctx);
1112  uint32_t NumTypes = Signatures.size();
1113  Imports.reserve(Count);
1114  for (uint32_t I = 0; I < Count; I++) {
1115  wasm::WasmImport Im;
1116  Im.Module = readString(Ctx);
1117  Im.Field = readString(Ctx);
1118  Im.Kind = readUint8(Ctx);
1119  switch (Im.Kind) {
1121  NumImportedFunctions++;
1122  Im.SigIndex = readVaruint32(Ctx);
1123  if (Im.SigIndex >= NumTypes)
1124  return make_error<GenericBinaryError>("invalid function type",
1126  break;
1128  NumImportedGlobals++;
1129  Im.Global.Type = readUint8(Ctx);
1130  Im.Global.Mutable = readVaruint1(Ctx);
1131  break;
1133  Im.Memory = readLimits(Ctx);
1135  HasMemory64 = true;
1136  break;
1138  Im.Table = readTableType(Ctx);
1139  NumImportedTables++;
1140  auto ElemType = Im.Table.ElemType;
1141  if (ElemType != wasm::WASM_TYPE_FUNCREF &&
1142  ElemType != wasm::WASM_TYPE_EXTERNREF)
1143  return make_error<GenericBinaryError>("invalid table element type",
1145  break;
1146  }
1148  NumImportedTags++;
1149  if (readUint8(Ctx) != 0) // Reserved 'attribute' field
1150  return make_error<GenericBinaryError>("invalid attribute",
1152  Im.SigIndex = readVaruint32(Ctx);
1153  if (Im.SigIndex >= NumTypes)
1154  return make_error<GenericBinaryError>("invalid tag type",
1156  break;
1157  default:
1158  return make_error<GenericBinaryError>("unexpected import kind",
1160  }
1161  Imports.push_back(Im);
1162  }
1163  if (Ctx.Ptr != Ctx.End)
1164  return make_error<GenericBinaryError>("import section ended prematurely",
1166  return Error::success();
1167 }
1168 
1169 Error WasmObjectFile::parseFunctionSection(ReadContext &Ctx) {
1170  uint32_t Count = readVaruint32(Ctx);
1171  Functions.reserve(Count);
1172  uint32_t NumTypes = Signatures.size();
1173  while (Count--) {
1174  uint32_t Type = readVaruint32(Ctx);
1175  if (Type >= NumTypes)
1176  return make_error<GenericBinaryError>("invalid function type",
1179  F.SigIndex = Type;
1180  Functions.push_back(F);
1181  }
1182  if (Ctx.Ptr != Ctx.End)
1183  return make_error<GenericBinaryError>("function section ended prematurely",
1185  return Error::success();
1186 }
1187 
1188 Error WasmObjectFile::parseTableSection(ReadContext &Ctx) {
1189  TableSection = Sections.size();
1190  uint32_t Count = readVaruint32(Ctx);
1191  Tables.reserve(Count);
1192  while (Count--) {
1194  T.Type = readTableType(Ctx);
1195  T.Index = NumImportedTables + Tables.size();
1196  Tables.push_back(T);
1197  auto ElemType = Tables.back().Type.ElemType;
1198  if (ElemType != wasm::WASM_TYPE_FUNCREF &&
1199  ElemType != wasm::WASM_TYPE_EXTERNREF) {
1200  return make_error<GenericBinaryError>("invalid table element type",
1202  }
1203  }
1204  if (Ctx.Ptr != Ctx.End)
1205  return make_error<GenericBinaryError>("table section ended prematurely",
1207  return Error::success();
1208 }
1209 
1210 Error WasmObjectFile::parseMemorySection(ReadContext &Ctx) {
1211  uint32_t Count = readVaruint32(Ctx);
1212  Memories.reserve(Count);
1213  while (Count--) {
1214  auto Limits = readLimits(Ctx);
1215  if (Limits.Flags & wasm::WASM_LIMITS_FLAG_IS_64)
1216  HasMemory64 = true;
1217  Memories.push_back(Limits);
1218  }
1219  if (Ctx.Ptr != Ctx.End)
1220  return make_error<GenericBinaryError>("memory section ended prematurely",
1222  return Error::success();
1223 }
1224 
1225 Error WasmObjectFile::parseTagSection(ReadContext &Ctx) {
1226  TagSection = Sections.size();
1227  uint32_t Count = readVaruint32(Ctx);
1228  Tags.reserve(Count);
1229  uint32_t NumTypes = Signatures.size();
1230  while (Count--) {
1231  if (readUint8(Ctx) != 0) // Reserved 'attribute' field
1232  return make_error<GenericBinaryError>("invalid attribute",
1234  uint32_t Type = readVaruint32(Ctx);
1235  if (Type >= NumTypes)
1236  return make_error<GenericBinaryError>("invalid tag type",
1239  Tag.Index = NumImportedTags + Tags.size();
1240  Tag.SigIndex = Type;
1241  Tags.push_back(Tag);
1242  }
1243 
1244  if (Ctx.Ptr != Ctx.End)
1245  return make_error<GenericBinaryError>("tag section ended prematurely",
1247  return Error::success();
1248 }
1249 
1250 Error WasmObjectFile::parseGlobalSection(ReadContext &Ctx) {
1251  GlobalSection = Sections.size();
1252  uint32_t Count = readVaruint32(Ctx);
1253  Globals.reserve(Count);
1254  while (Count--) {
1256  Global.Index = NumImportedGlobals + Globals.size();
1257  Global.Type.Type = readUint8(Ctx);
1258  Global.Type.Mutable = readVaruint1(Ctx);
1259  if (Error Err = readInitExpr(Global.InitExpr, Ctx))
1260  return Err;
1261  Globals.push_back(Global);
1262  }
1263  if (Ctx.Ptr != Ctx.End)
1264  return make_error<GenericBinaryError>("global section ended prematurely",
1266  return Error::success();
1267 }
1268 
1269 Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
1270  uint32_t Count = readVaruint32(Ctx);
1271  Exports.reserve(Count);
1272  for (uint32_t I = 0; I < Count; I++) {
1273  wasm::WasmExport Ex;
1274  Ex.Name = readString(Ctx);
1275  Ex.Kind = readUint8(Ctx);
1276  Ex.Index = readVaruint32(Ctx);
1277  switch (Ex.Kind) {
1279 
1280  if (!isDefinedFunctionIndex(Ex.Index))
1281  return make_error<GenericBinaryError>("invalid function export",
1283  getDefinedFunction(Ex.Index).ExportName = Ex.Name;
1284  break;
1286  if (!isValidGlobalIndex(Ex.Index))
1287  return make_error<GenericBinaryError>("invalid global export",
1289  break;
1291  if (!isValidTagIndex(Ex.Index))
1292  return make_error<GenericBinaryError>("invalid tag export",
1294  break;
1297  break;
1298  default:
1299  return make_error<GenericBinaryError>("unexpected export kind",
1301  }
1302  Exports.push_back(Ex);
1303  }
1304  if (Ctx.Ptr != Ctx.End)
1305  return make_error<GenericBinaryError>("export section ended prematurely",
1307  return Error::success();
1308 }
1309 
1310 bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const {
1311  return Index < NumImportedFunctions + Functions.size();
1312 }
1313 
1314 bool WasmObjectFile::isDefinedFunctionIndex(uint32_t Index) const {
1315  return Index >= NumImportedFunctions && isValidFunctionIndex(Index);
1316 }
1317 
1318 bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const {
1319  return Index < NumImportedGlobals + Globals.size();
1320 }
1321 
1322 bool WasmObjectFile::isValidTableNumber(uint32_t Index) const {
1323  return Index < NumImportedTables + Tables.size();
1324 }
1325 
1326 bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const {
1327  return Index >= NumImportedGlobals && isValidGlobalIndex(Index);
1328 }
1329 
1330 bool WasmObjectFile::isDefinedTableNumber(uint32_t Index) const {
1331  return Index >= NumImportedTables && isValidTableNumber(Index);
1332 }
1333 
1334 bool WasmObjectFile::isValidTagIndex(uint32_t Index) const {
1335  return Index < NumImportedTags + Tags.size();
1336 }
1337 
1338 bool WasmObjectFile::isDefinedTagIndex(uint32_t Index) const {
1339  return Index >= NumImportedTags && isValidTagIndex(Index);
1340 }
1341 
1342 bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
1343  return Index < Symbols.size() && Symbols[Index].isTypeFunction();
1344 }
1345 
1346 bool WasmObjectFile::isValidTableSymbol(uint32_t Index) const {
1347  return Index < Symbols.size() && Symbols[Index].isTypeTable();
1348 }
1349 
1350 bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const {
1351  return Index < Symbols.size() && Symbols[Index].isTypeGlobal();
1352 }
1353 
1354 bool WasmObjectFile::isValidTagSymbol(uint32_t Index) const {
1355  return Index < Symbols.size() && Symbols[Index].isTypeTag();
1356 }
1357 
1358 bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
1359  return Index < Symbols.size() && Symbols[Index].isTypeData();
1360 }
1361 
1362 bool WasmObjectFile::isValidSectionSymbol(uint32_t Index) const {
1363  return Index < Symbols.size() && Symbols[Index].isTypeSection();
1364 }
1365 
1366 wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) {
1367  assert(isDefinedFunctionIndex(Index));
1368  return Functions[Index - NumImportedFunctions];
1369 }
1370 
1371 const wasm::WasmFunction &
1372 WasmObjectFile::getDefinedFunction(uint32_t Index) const {
1373  assert(isDefinedFunctionIndex(Index));
1374  return Functions[Index - NumImportedFunctions];
1375 }
1376 
1377 wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) {
1378  assert(isDefinedGlobalIndex(Index));
1379  return Globals[Index - NumImportedGlobals];
1380 }
1381 
1382 wasm::WasmTag &WasmObjectFile::getDefinedTag(uint32_t Index) {
1383  assert(isDefinedTagIndex(Index));
1384  return Tags[Index - NumImportedTags];
1385 }
1386 
1387 Error WasmObjectFile::parseStartSection(ReadContext &Ctx) {
1388  StartFunction = readVaruint32(Ctx);
1389  if (!isValidFunctionIndex(StartFunction))
1390  return make_error<GenericBinaryError>("invalid start function",
1392  return Error::success();
1393 }
1394 
1395 Error WasmObjectFile::parseCodeSection(ReadContext &Ctx) {
1396  CodeSection = Sections.size();
1397  uint32_t FunctionCount = readVaruint32(Ctx);
1398  if (FunctionCount != Functions.size()) {
1399  return make_error<GenericBinaryError>("invalid function count",
1401  }
1402 
1403  for (uint32_t i = 0; i < FunctionCount; i++) {
1404  wasm::WasmFunction& Function = Functions[i];
1405  const uint8_t *FunctionStart = Ctx.Ptr;
1406  uint32_t Size = readVaruint32(Ctx);
1407  const uint8_t *FunctionEnd = Ctx.Ptr + Size;
1408 
1409  Function.CodeOffset = Ctx.Ptr - FunctionStart;
1410  Function.Index = NumImportedFunctions + i;
1411  Function.CodeSectionOffset = FunctionStart - Ctx.Start;
1412  Function.Size = FunctionEnd - FunctionStart;
1413 
1414  uint32_t NumLocalDecls = readVaruint32(Ctx);
1415  Function.Locals.reserve(NumLocalDecls);
1416  while (NumLocalDecls--) {
1417  wasm::WasmLocalDecl Decl;
1418  Decl.Count = readVaruint32(Ctx);
1419  Decl.Type = readUint8(Ctx);
1420  Function.Locals.push_back(Decl);
1421  }
1422 
1423  uint32_t BodySize = FunctionEnd - Ctx.Ptr;
1424  Function.Body = ArrayRef<uint8_t>(Ctx.Ptr, BodySize);
1425  // This will be set later when reading in the linking metadata section.
1426  Function.Comdat = UINT32_MAX;
1427  Ctx.Ptr += BodySize;
1428  assert(Ctx.Ptr == FunctionEnd);
1429  }
1430  if (Ctx.Ptr != Ctx.End)
1431  return make_error<GenericBinaryError>("code section ended prematurely",
1433  return Error::success();
1434 }
1435 
1436 Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
1437  uint32_t Count = readVaruint32(Ctx);
1438  ElemSegments.reserve(Count);
1439  while (Count--) {
1440  wasm::WasmElemSegment Segment;
1441  Segment.Flags = readVaruint32(Ctx);
1442 
1446  if (Segment.Flags & ~SupportedFlags)
1447  return make_error<GenericBinaryError>(
1448  "Unsupported flags for element segment", object_error::parse_failed);
1449 
1451  Segment.TableNumber = readVaruint32(Ctx);
1452  else
1453  Segment.TableNumber = 0;
1454  if (!isValidTableNumber(Segment.TableNumber))
1455  return make_error<GenericBinaryError>("invalid TableNumber",
1457 
1458  if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_IS_PASSIVE) {
1459  Segment.Offset.Extended = false;
1461  Segment.Offset.Inst.Value.Int32 = 0;
1462  } else {
1463  if (Error Err = readInitExpr(Segment.Offset, Ctx))
1464  return Err;
1465  }
1466 
1468  Segment.ElemKind = readUint8(Ctx);
1470  if (Segment.ElemKind != uint8_t(wasm::ValType::FUNCREF) &&
1471  Segment.ElemKind != uint8_t(wasm::ValType::EXTERNREF)) {
1472  return make_error<GenericBinaryError>("invalid reference type",
1474  }
1475  } else {
1476  if (Segment.ElemKind != 0)
1477  return make_error<GenericBinaryError>("invalid elemtype",
1479  Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF);
1480  }
1481  } else {
1482  Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF);
1483  }
1484 
1486  return make_error<GenericBinaryError>(
1487  "elem segment init expressions not yet implemented",
1489 
1490  uint32_t NumElems = readVaruint32(Ctx);
1491  while (NumElems--) {
1492  Segment.Functions.push_back(readVaruint32(Ctx));
1493  }
1494  ElemSegments.push_back(Segment);
1495  }
1496  if (Ctx.Ptr != Ctx.End)
1497  return make_error<GenericBinaryError>("elem section ended prematurely",
1499  return Error::success();
1500 }
1501 
1502 Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
1503  DataSection = Sections.size();
1504  uint32_t Count = readVaruint32(Ctx);
1505  if (DataCount && Count != *DataCount)
1506  return make_error<GenericBinaryError>(
1507  "number of data segments does not match DataCount section");
1508  DataSegments.reserve(Count);
1509  while (Count--) {
1510  WasmSegment Segment;
1511  Segment.Data.InitFlags = readVaruint32(Ctx);
1512  Segment.Data.MemoryIndex =
1513  (Segment.Data.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX)
1514  ? readVaruint32(Ctx)
1515  : 0;
1516  if ((Segment.Data.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) {
1517  if (Error Err = readInitExpr(Segment.Data.Offset, Ctx))
1518  return Err;
1519  } else {
1520  Segment.Data.Offset.Extended = false;
1521  Segment.Data.Offset.Inst.Opcode = wasm::WASM_OPCODE_I32_CONST;
1522  Segment.Data.Offset.Inst.Value.Int32 = 0;
1523  }
1524  uint32_t Size = readVaruint32(Ctx);
1525  if (Size > (size_t)(Ctx.End - Ctx.Ptr))
1526  return make_error<GenericBinaryError>("invalid segment size",
1528  Segment.Data.Content = ArrayRef<uint8_t>(Ctx.Ptr, Size);
1529  // The rest of these Data fields are set later, when reading in the linking
1530  // metadata section.
1531  Segment.Data.Alignment = 0;
1532  Segment.Data.LinkingFlags = 0;
1533  Segment.Data.Comdat = UINT32_MAX;
1534  Segment.SectionOffset = Ctx.Ptr - Ctx.Start;
1535  Ctx.Ptr += Size;
1536  DataSegments.push_back(Segment);
1537  }
1538  if (Ctx.Ptr != Ctx.End)
1539  return make_error<GenericBinaryError>("data section ended prematurely",
1541  return Error::success();
1542 }
1543 
1544 Error WasmObjectFile::parseDataCountSection(ReadContext &Ctx) {
1545  DataCount = readVaruint32(Ctx);
1546  return Error::success();
1547 }
1548 
1550  return Header;
1551 }
1552 
1553 void WasmObjectFile::moveSymbolNext(DataRefImpl &Symb) const { Symb.d.b++; }
1554 
1556  uint32_t Result = SymbolRef::SF_None;
1557  const WasmSymbol &Sym = getWasmSymbol(Symb);
1558 
1559  LLVM_DEBUG(dbgs() << "getSymbolFlags: ptr=" << &Sym << " " << Sym << "\n");
1560  if (Sym.isBindingWeak())
1561  Result |= SymbolRef::SF_Weak;
1562  if (!Sym.isBindingLocal())
1563  Result |= SymbolRef::SF_Global;
1564  if (Sym.isHidden())
1565  Result |= SymbolRef::SF_Hidden;
1566  if (!Sym.isDefined())
1567  Result |= SymbolRef::SF_Undefined;
1568  if (Sym.isTypeFunction())
1569  Result |= SymbolRef::SF_Executable;
1570  return Result;
1571 }
1572 
1574  DataRefImpl Ref;
1575  Ref.d.a = 1; // Arbitrary non-zero value so that Ref.p is non-null
1576  Ref.d.b = 0; // Symbol index
1577  return BasicSymbolRef(Ref, this);
1578 }
1579 
1581  DataRefImpl Ref;
1582  Ref.d.a = 1; // Arbitrary non-zero value so that Ref.p is non-null
1583  Ref.d.b = Symbols.size(); // Symbol index
1584  return BasicSymbolRef(Ref, this);
1585 }
1586 
1588  return Symbols[Symb.d.b];
1589 }
1590 
1591 const WasmSymbol &WasmObjectFile::getWasmSymbol(const SymbolRef &Symb) const {
1592  return getWasmSymbol(Symb.getRawDataRefImpl());
1593 }
1594 
1596  return getWasmSymbol(Symb).Info.Name;
1597 }
1598 
1600  auto &Sym = getWasmSymbol(Symb);
1601  if (Sym.Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION &&
1602  isDefinedFunctionIndex(Sym.Info.ElementIndex))
1603  return getDefinedFunction(Sym.Info.ElementIndex).CodeSectionOffset;
1604  else
1605  return getSymbolValue(Symb);
1606 }
1607 
1609  switch (Sym.Info.Kind) {
1614  return Sym.Info.ElementIndex;
1616  // The value of a data symbol is the segment offset, plus the symbol
1617  // offset within the segment.
1618  uint32_t SegmentIndex = Sym.Info.DataRef.Segment;
1619  const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data;
1620  if (Segment.Offset.Extended) {
1621  llvm_unreachable("extended init exprs not supported");
1622  } else if (Segment.Offset.Inst.Opcode == wasm::WASM_OPCODE_I32_CONST) {
1623  return Segment.Offset.Inst.Value.Int32 + Sym.Info.DataRef.Offset;
1624  } else if (Segment.Offset.Inst.Opcode == wasm::WASM_OPCODE_I64_CONST) {
1625  return Segment.Offset.Inst.Value.Int64 + Sym.Info.DataRef.Offset;
1626  } else {
1627  llvm_unreachable("unknown init expr opcode");
1628  }
1629  }
1631  return 0;
1632  }
1633  llvm_unreachable("invalid symbol type");
1634 }
1635 
1637  return getWasmSymbolValue(getWasmSymbol(Symb));
1638 }
1639 
1641  llvm_unreachable("not yet implemented");
1642  return 0;
1643 }
1644 
1646  llvm_unreachable("not yet implemented");
1647  return 0;
1648 }
1649 
1652  const WasmSymbol &Sym = getWasmSymbol(Symb);
1653 
1654  switch (Sym.Info.Kind) {
1656  return SymbolRef::ST_Function;
1658  return SymbolRef::ST_Other;
1660  return SymbolRef::ST_Data;
1662  return SymbolRef::ST_Debug;
1664  return SymbolRef::ST_Other;
1666  return SymbolRef::ST_Other;
1667  }
1668 
1669  llvm_unreachable("unknown WasmSymbol::SymbolType");
1670  return SymbolRef::ST_Other;
1671 }
1672 
1675  const WasmSymbol &Sym = getWasmSymbol(Symb);
1676  if (Sym.isUndefined())
1677  return section_end();
1678 
1679  DataRefImpl Ref;
1680  Ref.d.a = getSymbolSectionIdImpl(Sym);
1681  return section_iterator(SectionRef(Ref, this));
1682 }
1683 
1685  const WasmSymbol &Sym = getWasmSymbol(Symb);
1686  return getSymbolSectionIdImpl(Sym);
1687 }
1688 
1689 uint32_t WasmObjectFile::getSymbolSectionIdImpl(const WasmSymbol &Sym) const {
1690  switch (Sym.Info.Kind) {
1692  return CodeSection;
1694  return GlobalSection;
1696  return DataSection;
1698  return Sym.Info.ElementIndex;
1700  return TagSection;
1702  return TableSection;
1703  default:
1704  llvm_unreachable("unknown WasmSymbol::SymbolType");
1705  }
1706 }
1707 
1708 void WasmObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; }
1709 
1711  const WasmSection &S = Sections[Sec.d.a];
1712  if (S.Type == wasm::WASM_SEC_CUSTOM)
1713  return S.Name;
1714  if (S.Type > wasm::WASM_SEC_LAST_KNOWN)
1716  return wasm::sectionTypeToString(S.Type);
1717 }
1718 
1720 
1722  return Sec.d.a;
1723 }
1724 
1726  const WasmSection &S = Sections[Sec.d.a];
1727  return S.Content.size();
1728 }
1729 
1732  const WasmSection &S = Sections[Sec.d.a];
1733  // This will never fail since wasm sections can never be empty (user-sections
1734  // must have a name and non-user sections each have a defined structure).
1735  return S.Content;
1736 }
1737 
1739  return 1;
1740 }
1741 
1743  return false;
1744 }
1745 
1747  return getWasmSection(Sec).Type == wasm::WASM_SEC_CODE;
1748 }
1749 
1751  return getWasmSection(Sec).Type == wasm::WASM_SEC_DATA;
1752 }
1753 
1754 bool WasmObjectFile::isSectionBSS(DataRefImpl Sec) const { return false; }
1755 
1756 bool WasmObjectFile::isSectionVirtual(DataRefImpl Sec) const { return false; }
1757 
1759  DataRefImpl RelocRef;
1760  RelocRef.d.a = Ref.d.a;
1761  RelocRef.d.b = 0;
1762  return relocation_iterator(RelocationRef(RelocRef, this));
1763 }
1764 
1766  const WasmSection &Sec = getWasmSection(Ref);
1767  DataRefImpl RelocRef;
1768  RelocRef.d.a = Ref.d.a;
1769  RelocRef.d.b = Sec.Relocations.size();
1770  return relocation_iterator(RelocationRef(RelocRef, this));
1771 }
1772 
1774 
1777  return Rel.Offset;
1778 }
1779 
1782  if (Rel.Type == wasm::R_WASM_TYPE_INDEX_LEB)
1783  return symbol_end();
1784  DataRefImpl Sym;
1785  Sym.d.a = 1;
1786  Sym.d.b = Rel.Index;
1787  return symbol_iterator(SymbolRef(Sym, this));
1788 }
1789 
1792  return Rel.Type;
1793 }
1794 
1796  DataRefImpl Ref, SmallVectorImpl<char> &Result) const {
1798  StringRef Res = "Unknown";
1799 
1800 #define WASM_RELOC(name, value) \
1801  case wasm::name: \
1802  Res = #name; \
1803  break;
1804 
1805  switch (Rel.Type) {
1806 #include "llvm/BinaryFormat/WasmRelocs.def"
1807  }
1808 
1809 #undef WASM_RELOC
1810 
1811  Result.append(Res.begin(), Res.end());
1812 }
1813 
1815  DataRefImpl Ref;
1816  Ref.d.a = 0;
1817  return section_iterator(SectionRef(Ref, this));
1818 }
1819 
1821  DataRefImpl Ref;
1822  Ref.d.a = Sections.size();
1823  return section_iterator(SectionRef(Ref, this));
1824 }
1825 
1827  return HasMemory64 ? 8 : 4;
1828 }
1829 
1831 
1833  return HasMemory64 ? Triple::wasm64 : Triple::wasm32;
1834 }
1835 
1837  return SubtargetFeatures();
1838 }
1839 
1840 bool WasmObjectFile::isRelocatableObject() const { return HasLinkingSection; }
1841 
1842 bool WasmObjectFile::isSharedObject() const { return HasDylinkSection; }
1843 
1845  assert(Ref.d.a < Sections.size());
1846  return Sections[Ref.d.a];
1847 }
1848 
1849 const WasmSection &
1851  return getWasmSection(Section.getRawDataRefImpl());
1852 }
1853 
1854 const wasm::WasmRelocation &
1856  return getWasmRelocation(Ref.getRawDataRefImpl());
1857 }
1858 
1859 const wasm::WasmRelocation &
1861  assert(Ref.d.a < Sections.size());
1862  const WasmSection &Sec = Sections[Ref.d.a];
1863  assert(Ref.d.b < Sec.Relocations.size());
1864  return Sec.Relocations[Ref.d.b];
1865 }
1866 
1867 int WasmSectionOrderChecker::getSectionOrder(unsigned ID,
1868  StringRef CustomSectionName) {
1869  switch (ID) {
1870  case wasm::WASM_SEC_CUSTOM:
1871  return StringSwitch<unsigned>(CustomSectionName)
1872  .Case("dylink", WASM_SEC_ORDER_DYLINK)
1873  .Case("dylink.0", WASM_SEC_ORDER_DYLINK)
1874  .Case("linking", WASM_SEC_ORDER_LINKING)
1875  .StartsWith("reloc.", WASM_SEC_ORDER_RELOC)
1876  .Case("name", WASM_SEC_ORDER_NAME)
1877  .Case("producers", WASM_SEC_ORDER_PRODUCERS)
1878  .Case("target_features", WASM_SEC_ORDER_TARGET_FEATURES)
1880  case wasm::WASM_SEC_TYPE:
1881  return WASM_SEC_ORDER_TYPE;
1882  case wasm::WASM_SEC_IMPORT:
1883  return WASM_SEC_ORDER_IMPORT;
1885  return WASM_SEC_ORDER_FUNCTION;
1886  case wasm::WASM_SEC_TABLE:
1887  return WASM_SEC_ORDER_TABLE;
1888  case wasm::WASM_SEC_MEMORY:
1889  return WASM_SEC_ORDER_MEMORY;
1890  case wasm::WASM_SEC_GLOBAL:
1891  return WASM_SEC_ORDER_GLOBAL;
1892  case wasm::WASM_SEC_EXPORT:
1893  return WASM_SEC_ORDER_EXPORT;
1894  case wasm::WASM_SEC_START:
1895  return WASM_SEC_ORDER_START;
1896  case wasm::WASM_SEC_ELEM:
1897  return WASM_SEC_ORDER_ELEM;
1898  case wasm::WASM_SEC_CODE:
1899  return WASM_SEC_ORDER_CODE;
1900  case wasm::WASM_SEC_DATA:
1901  return WASM_SEC_ORDER_DATA;
1903  return WASM_SEC_ORDER_DATACOUNT;
1904  case wasm::WASM_SEC_TAG:
1905  return WASM_SEC_ORDER_TAG;
1906  default:
1907  return WASM_SEC_ORDER_NONE;
1908  }
1909 }
1910 
1911 // Represents the edges in a directed graph where any node B reachable from node
1912 // A is not allowed to appear before A in the section ordering, but may appear
1913 // afterward.
1915  [WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS] = {
1916  // WASM_SEC_ORDER_NONE
1917  {},
1918  // WASM_SEC_ORDER_TYPE
1919  {WASM_SEC_ORDER_TYPE, WASM_SEC_ORDER_IMPORT},
1920  // WASM_SEC_ORDER_IMPORT
1921  {WASM_SEC_ORDER_IMPORT, WASM_SEC_ORDER_FUNCTION},
1922  // WASM_SEC_ORDER_FUNCTION
1923  {WASM_SEC_ORDER_FUNCTION, WASM_SEC_ORDER_TABLE},
1924  // WASM_SEC_ORDER_TABLE
1925  {WASM_SEC_ORDER_TABLE, WASM_SEC_ORDER_MEMORY},
1926  // WASM_SEC_ORDER_MEMORY
1927  {WASM_SEC_ORDER_MEMORY, WASM_SEC_ORDER_TAG},
1928  // WASM_SEC_ORDER_TAG
1929  {WASM_SEC_ORDER_TAG, WASM_SEC_ORDER_GLOBAL},
1930  // WASM_SEC_ORDER_GLOBAL
1931  {WASM_SEC_ORDER_GLOBAL, WASM_SEC_ORDER_EXPORT},
1932  // WASM_SEC_ORDER_EXPORT
1933  {WASM_SEC_ORDER_EXPORT, WASM_SEC_ORDER_START},
1934  // WASM_SEC_ORDER_START
1935  {WASM_SEC_ORDER_START, WASM_SEC_ORDER_ELEM},
1936  // WASM_SEC_ORDER_ELEM
1937  {WASM_SEC_ORDER_ELEM, WASM_SEC_ORDER_DATACOUNT},
1938  // WASM_SEC_ORDER_DATACOUNT
1939  {WASM_SEC_ORDER_DATACOUNT, WASM_SEC_ORDER_CODE},
1940  // WASM_SEC_ORDER_CODE
1941  {WASM_SEC_ORDER_CODE, WASM_SEC_ORDER_DATA},
1942  // WASM_SEC_ORDER_DATA
1943  {WASM_SEC_ORDER_DATA, WASM_SEC_ORDER_LINKING},
1944 
1945  // Custom Sections
1946  // WASM_SEC_ORDER_DYLINK
1947  {WASM_SEC_ORDER_DYLINK, WASM_SEC_ORDER_TYPE},
1948  // WASM_SEC_ORDER_LINKING
1949  {WASM_SEC_ORDER_LINKING, WASM_SEC_ORDER_RELOC, WASM_SEC_ORDER_NAME},
1950  // WASM_SEC_ORDER_RELOC (can be repeated)
1951  {},
1952  // WASM_SEC_ORDER_NAME
1953  {WASM_SEC_ORDER_NAME, WASM_SEC_ORDER_PRODUCERS},
1954  // WASM_SEC_ORDER_PRODUCERS
1955  {WASM_SEC_ORDER_PRODUCERS, WASM_SEC_ORDER_TARGET_FEATURES},
1956  // WASM_SEC_ORDER_TARGET_FEATURES
1957  {WASM_SEC_ORDER_TARGET_FEATURES}};
1958 
1960  StringRef CustomSectionName) {
1961  int Order = getSectionOrder(ID, CustomSectionName);
1962  if (Order == WASM_SEC_ORDER_NONE)
1963  return true;
1964 
1965  // Disallowed predecessors we need to check for
1967 
1968  // Keep track of completed checks to avoid repeating work
1969  bool Checked[WASM_NUM_SEC_ORDERS] = {};
1970 
1971  int Curr = Order;
1972  while (true) {
1973  // Add new disallowed predecessors to work list
1974  for (size_t I = 0;; ++I) {
1975  int Next = DisallowedPredecessors[Curr][I];
1976  if (Next == WASM_SEC_ORDER_NONE)
1977  break;
1978  if (Checked[Next])
1979  continue;
1980  WorkList.push_back(Next);
1981  Checked[Next] = true;
1982  }
1983 
1984  if (WorkList.empty())
1985  break;
1986 
1987  // Consider next disallowed predecessor
1988  Curr = WorkList.pop_back_val();
1989  if (Seen[Curr])
1990  return false;
1991  }
1992 
1993  // Have not seen any disallowed predecessors
1994  Seen[Order] = true;
1995  return true;
1996 }
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:303
llvm::wasm::WasmImport::Memory
WasmLimits Memory
Definition: Wasm.h:138
llvm::wasm::WASM_SYMBOL_TYPE_SECTION
@ WASM_SYMBOL_TYPE_SECTION
Definition: Wasm.h:386
llvm::wasm::WasmInitExprMVP::Float64
uint64_t Float64
Definition: Wasm.h:100
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_DUMP_METHOD
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:492
llvm::object::Kind
Kind
Definition: COFFModuleDefinition.cpp:31
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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::WASM_TYPE_FUNC
@ WASM_TYPE_FUNC
Definition: Wasm.h:268
llvm::wasm::WASM_SEC_TABLE
@ WASM_SEC_TABLE
Definition: Wasm.h:246
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_RELOC
@ WASM_SEC_ORDER_RELOC
Definition: Wasm.h:331
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_TYPE
@ WASM_SEC_ORDER_TYPE
Definition: Wasm.h:311
llvm::wasm::WASM_OPCODE_GLOBAL_GET
@ WASM_OPCODE_GLOBAL_GET
Definition: Wasm.h:288
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:1573
llvm::wasm::WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND
const unsigned WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND
Definition: Wasm.h:340
llvm::object::WasmObjectFile::getFeatures
SubtargetFeatures getFeatures() const override
Definition: WasmObjectFile.cpp:1836
llvm::wasm::WasmInitExpr::Inst
WasmInitExprMVP Inst
Definition: Wasm.h:108
llvm::object::WasmObjectFile::ReadContext::Start
const uint8_t * Start
Definition: Wasm.h:211
llvm::Triple::wasm32
@ wasm32
Definition: Triple.h:103
llvm::Function::empty
bool empty() const
Definition: Function.h:732
T
llvm::object::WasmSection::Content
ArrayRef< uint8_t > Content
Definition: Wasm.h:111
llvm::Function
Definition: Function.h:60
StringRef.h
llvm::wasm::WasmVersion
const uint32_t WasmVersion
Definition: Wasm.h:28
llvm::object::ObjectFile::RelocationRef
friend class RelocationRef
Definition: ObjectFile.h:286
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:1826
llvm::wasm::WasmFeatureEntry
Definition: Wasm.h:66
llvm::wasm::WASM_SEGMENT_INFO
@ WASM_SEGMENT_INFO
Definition: Wasm.h:359
llvm::object::WasmSectionOrderChecker::isValidSectionOrder
bool isValidSectionOrder(unsigned ID, StringRef CustomSectionName="")
Definition: WasmObjectFile.cpp:1959
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:1181
llvm::wasm::WasmObjectHeader::Version
uint32_t Version
Definition: Wasm.h:36
llvm::wasm::WASM_SEC_CODE
@ WASM_SEC_CODE
Definition: Wasm.h:252
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
llvm::wasm::WASM_FEATURE_PREFIX_USED
@ WASM_FEATURE_PREFIX_USED
Definition: Wasm.h:344
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_EXTERNAL_MEMORY
@ WASM_EXTERNAL_MEMORY
Definition: Wasm.h:276
llvm::wasm::WASM_SYMBOL_BINDING_LOCAL
const unsigned WASM_SYMBOL_BINDING_LOCAL
Definition: Wasm.h:406
llvm::wasm::WASM_SYMBOL_TYPE_TABLE
@ WASM_SYMBOL_TYPE_TABLE
Definition: Wasm.h:388
llvm::wasm::WASM_SYMBOL_TYPE_GLOBAL
@ WASM_SYMBOL_TYPE_GLOBAL
Definition: Wasm.h:385
llvm::object::WasmSection
Definition: Wasm.h:104
Error.h
llvm::wasm::WasmRelocation
Definition: Wasm.h:191
llvm::wasm::WASM_NAMES_LOCAL
@ WASM_NAMES_LOCAL
Definition: Wasm.h:352
llvm::wasm::WasmImport::Table
WasmTableType Table
Definition: Wasm.h:137
llvm::wasm::WASM_SYMBOL_TABLE
@ WASM_SYMBOL_TABLE
Definition: Wasm.h:362
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::WasmDylinkInfo::ImportInfo
std::vector< WasmDylinkImportInfo > ImportInfo
Definition: Wasm.h:56
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:1742
llvm::wasm::WasmImport::SigIndex
uint32_t SigIndex
Definition: Wasm.h:135
llvm::object::Binary::Data
MemoryBufferRef Data
Definition: Binary.h:37
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
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_TAG
@ WASM_SEC_ORDER_TAG
Definition: Wasm.h:316
llvm::object::WasmObjectFile::getSectionName
Expected< StringRef > getSectionName(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1710
llvm::wasm::WASM_SYMBOL_UNDEFINED
const unsigned WASM_SYMBOL_UNDEFINED
Definition: Wasm.h:409
llvm::StringRef::substr
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:561
llvm::wasm::WASM_DYLINK_IMPORT_INFO
@ WASM_DYLINK_IMPORT_INFO
Definition: Wasm.h:370
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::wasm::WASM_OPCODE_F64_CONST
@ WASM_OPCODE_F64_CONST
Definition: Wasm.h:295
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:79
llvm::wasm::WASM_TYPE_EXTERNREF
@ WASM_TYPE_EXTERNREF
Definition: Wasm.h:267
llvm::wasm::WASM_NAMES_GLOBAL
@ WASM_NAMES_GLOBAL
Definition: Wasm.h:353
llvm::object::WasmObjectFile::getSymbolValueImpl
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1636
llvm::wasm::WASM_OPCODE_I32_MUL
@ WASM_OPCODE_I32_MUL
Definition: Wasm.h:298
llvm::wasm::WASM_LIMITS_FLAG_HAS_MAX
@ WASM_LIMITS_FLAG_HAS_MAX
Definition: Wasm.h:325
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_FUNCTION
@ WASM_SEC_ORDER_FUNCTION
Definition: Wasm.h:313
llvm::object::WasmObjectFile::getRelocationTypeName
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
Definition: WasmObjectFile.cpp:1795
llvm::wasm::WASM_OPCODE_I64_SUB
@ WASM_OPCODE_I64_SUB
Definition: Wasm.h:300
llvm::object::WasmObjectFile::isSectionBSS
bool isSectionBSS(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1754
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::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_INIT_FUNCS
@ WASM_INIT_FUNCS
Definition: Wasm.h:360
llvm::wasm::WasmFunction
Definition: Wasm.h:147
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:1840
llvm::object::WasmObjectFile::getArch
Triple::ArchType getArch() const override
Definition: WasmObjectFile.cpp:1832
llvm::wasm::WasmDataReference::Offset
uint64_t Offset
Definition: Wasm.h:187
llvm::detail::DenseSetImpl::insert
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
llvm::wasm::WASM_OPCODE_I32_ADD
@ WASM_OPCODE_I32_ADD
Definition: Wasm.h:296
llvm::wasm::WASM_SEC_DATACOUNT
@ WASM_SEC_DATACOUNT
Definition: Wasm.h:254
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
llvm::wasm::WasmDataReference
Definition: Wasm.h:185
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::ArrayRef::data
const T * data() const
Definition: ArrayRef.h:161
llvm::wasm::WASM_SEC_DATA
@ WASM_SEC_DATA
Definition: Wasm.h:253
llvm::wasm::WASM_EXTERNAL_TABLE
@ WASM_EXTERNAL_TABLE
Definition: Wasm.h:275
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::wasm::WASM_SEC_FUNCTION
@ WASM_SEC_FUNCTION
Definition: Wasm.h:245
llvm::object::WasmObjectFile::moveSectionNext
void moveSectionNext(DataRefImpl &Sec) const override
Definition: WasmObjectFile.cpp:1708
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
readULEB128
static uint64_t readULEB128(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:102
readVarint32
static int32_t readVarint32(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:139
llvm::object::DataRefImpl::d
struct llvm::object::DataRefImpl::@339 d
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:405
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_GLOBAL
@ WASM_SEC_ORDER_GLOBAL
Definition: Wasm.h:317
llvm::wasm::WasmFunction::DebugName
StringRef DebugName
Definition: Wasm.h:157
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::wasm::WASM_OPCODE_I64_MUL
@ WASM_OPCODE_I64_MUL
Definition: Wasm.h:301
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::object::WasmSectionOrderChecker::WASM_SEC_ORDER_LINKING
@ WASM_SEC_ORDER_LINKING
Definition: Wasm.h:329
llvm::wasm::WasmRelocation::Addend
int64_t Addend
Definition: Wasm.h:195
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:1855
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::wasm::WASM_OPCODE_I32_SUB
@ WASM_OPCODE_I32_SUB
Definition: Wasm.h:297
llvm::object::WasmObjectFile::isSectionText
bool isSectionText(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1746
llvm::object::WasmObjectFile::getSymbolAlignment
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1640
llvm::SubtargetFeatures
Manages the enabling and disabling of subtarget specific features.
Definition: SubtargetFeature.h:180
llvm::object::WasmObjectFile::getSymbolSectionId
uint32_t getSymbolSectionId(SymbolRef Sym) const
Definition: WasmObjectFile.cpp:1684
llvm::wasm::WASM_COMDAT_SECTION
@ WASM_COMDAT_SECTION
Definition: Wasm.h:378
readUint8
static uint8_t readUint8(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:70
llvm::wasm::WasmGlobalType
Definition: Wasm.h:112
DenseSet.h
llvm::dwarf::Index
Index
Definition: Dwarf.h:472
llvm::MCID::Return
@ Return
Definition: MCInstrDesc.h:153
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_CODE
@ WASM_SEC_ORDER_CODE
Definition: Wasm.h:322
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::object::WasmSectionOrderChecker::WASM_NUM_SEC_ORDERS
@ WASM_NUM_SEC_ORDERS
Definition: Wasm.h:341
llvm::wasm::WASM_SEC_TYPE
@ WASM_SEC_TYPE
Definition: Wasm.h:243
llvm::wasm::WasmTable::SymbolName
StringRef SymbolName
Definition: Wasm.h:91
llvm::wasm::WASM_EXTERNAL_TAG
@ WASM_EXTERNAL_TAG
Definition: Wasm.h:278
llvm::object::WasmObjectFile::getSymbolSection
Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1674
llvm::wasm::WasmInitExprMVP::Int64
int64_t Int64
Definition: Wasm.h:98
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:145
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:52
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::wasm::WASM_OPCODE_REF_NULL
@ WASM_OPCODE_REF_NULL
Definition: Wasm.h:302
llvm::object::object_error::parse_failed
@ parse_failed
llvm::wasm::WASM_SYMBOL_TYPE_FUNCTION
@ WASM_SYMBOL_TYPE_FUNCTION
Definition: Wasm.h:383
llvm::object::WasmObjectFile::moveRelocationNext
void moveRelocationNext(DataRefImpl &Rel) const override
Definition: WasmObjectFile.cpp:1773
llvm::wasm::WasmMetadataVersion
const uint32_t WasmMetadataVersion
Definition: Wasm.h:30
llvm::wasm::WASM_FEATURE_PREFIX_DISALLOWED
@ WASM_FEATURE_PREFIX_DISALLOWED
Definition: Wasm.h:346
llvm::wasm::NameType::FUNCTION
@ FUNCTION
llvm::wasm::ValType
ValType
Definition: Wasm.h:424
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:1056
llvm::wasm::WasmLocalDecl::Type
uint8_t Type
Definition: Wasm.h:143
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
Signatures
static const FuncProtoTy Signatures[]
Definition: TargetLibraryInfo.cpp:68
llvm::wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER
@ WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER
Definition: Wasm.h:337
llvm::wasm::WASM_NAMES_DATA_SEGMENT
@ WASM_NAMES_DATA_SEGMENT
Definition: Wasm.h:354
llvm::wasm::WASM_SEC_TAG
@ WASM_SEC_TAG
Definition: Wasm.h:255
llvm::wasm::WasmTable::Type
WasmTableType Type
Definition: Wasm.h:90
llvm::Comdat
Definition: Comdat.h:33
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_TABLE
@ WASM_SEC_ORDER_TABLE
Definition: Wasm.h:314
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:1549
llvm::wasm::WASM_SEC_LAST_KNOWN
@ WASM_SEC_LAST_KNOWN
Definition: Wasm.h:256
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::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:1721
llvm::wasm::WasmObjectHeader::Magic
StringRef Magic
Definition: Wasm.h:35
llvm::wasm::WASM_DATA_SEGMENT_IS_PASSIVE
@ WASM_DATA_SEGMENT_IS_PASSIVE
Definition: Wasm.h:331
readLEB128
static int64_t readLEB128(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:122
llvm::wasm::WASM_DYLINK_MEM_INFO
@ WASM_DYLINK_MEM_INFO
Definition: Wasm.h:367
llvm::wasm::NameType::GLOBAL
@ GLOBAL
llvm::wasm::WASM_EXTERNAL_FUNCTION
@ WASM_EXTERNAL_FUNCTION
Definition: Wasm.h:274
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::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
llvm::DenseSet< uint64_t >
llvm::wasm::WASM_DYLINK_EXPORT_INFO
@ WASM_DYLINK_EXPORT_INFO
Definition: Wasm.h:369
llvm::object::ObjectFile::SymbolRef
friend class SymbolRef
Definition: ObjectFile.h:246
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_DATACOUNT
@ WASM_SEC_ORDER_DATACOUNT
Definition: Wasm.h:321
llvm::wasm::WASM_OPCODE_END
@ WASM_OPCODE_END
Definition: Wasm.h:283
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
llvm::wasm::WASM_OPCODE_I32_CONST
@ WASM_OPCODE_I32_CONST
Definition: Wasm.h:292
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:404
llvm::object::WasmSymbol::isBindingWeak
bool isBindingWeak() const
Definition: Wasm.h:73
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:1651
llvm::object::symbol_iterator
Definition: ObjectFile.h:207
llvm::StringRef::end
iterator end() const
Definition: StringRef.h:113
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::ValType::EXTERNREF
@ EXTERNREF
llvm::wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS
@ WASM_ELEM_SEGMENT_HAS_INIT_EXPRS
Definition: Wasm.h:338
llvm::wasm::WasmExport::Name
StringRef Name
Definition: Wasm.h:72
llvm::object::WasmObjectFile::section_begin
section_iterator section_begin() const override
Definition: WasmObjectFile.cpp:1814
llvm::wasm::WASM_SYMBOL_EXPLICIT_NAME
const unsigned WASM_SYMBOL_EXPLICIT_NAME
Definition: Wasm.h:411
LEB128.h
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_NAME
@ WASM_SEC_ORDER_NAME
Definition: Wasm.h:334
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
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:1555
llvm::wasm::WASM_NAMES_FUNCTION
@ WASM_NAMES_FUNCTION
Definition: Wasm.h:351
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::wasm::WASM_FEATURE_PREFIX_REQUIRED
@ WASM_FEATURE_PREFIX_REQUIRED
Definition: Wasm.h:345
llvm::object::BasicSymbolRef::SF_Undefined
@ SF_Undefined
Definition: SymbolicFile.h:110
llvm::wasm::WasmSignature::Returns
SmallVector< ValType, 1 > Returns
Definition: Wasm.h:435
llvm::wasm::WASM_COMDAT_FUNCTION
@ WASM_COMDAT_FUNCTION
Definition: Wasm.h:376
llvm::wasm::WasmDylinkInfo::TableSize
uint32_t TableSize
Definition: Wasm.h:53
llvm::wasm::WasmImport
Definition: Wasm.h:130
ArrayRef.h
llvm::wasm::WASM_SYMBOL_TYPE_TAG
@ WASM_SYMBOL_TYPE_TAG
Definition: Wasm.h:387
llvm::wasm::WASM_SEC_ELEM
@ WASM_SEC_ELEM
Definition: Wasm.h:251
TemplateParamKind::Type
@ Type
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_TARGET_FEATURES
@ WASM_SEC_ORDER_TARGET_FEATURES
Definition: Wasm.h:338
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
ObjectFile.h
llvm::object::WasmObjectFile::getSectionAddress
uint64_t getSectionAddress(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1719
llvm::wasm::WASM_COMDAT_DATA
@ WASM_COMDAT_DATA
Definition: Wasm.h:375
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::object::WasmSectionOrderChecker::WASM_SEC_ORDER_PRODUCERS
@ WASM_SEC_ORDER_PRODUCERS
Definition: Wasm.h:336
llvm::object::content_iterator
Definition: SymbolicFile.h:69
llvm::wasm::WASM_OPCODE_F32_CONST
@ WASM_OPCODE_F32_CONST
Definition: Wasm.h:294
llvm::wasm::WASM_EXTERNAL_GLOBAL
@ WASM_EXTERNAL_GLOBAL
Definition: Wasm.h:277
llvm::object::WasmObjectFile::getWasmSymbolValue
uint64_t getWasmSymbolValue(const WasmSymbol &Sym) const
Definition: WasmObjectFile.cpp:1608
llvm::object::WasmObjectFile::isSharedObject
bool isSharedObject() const
Definition: WasmObjectFile.cpp:1842
llvm::wasm::WasmInitExprMVP::Global
uint32_t Global
Definition: Wasm.h:101
llvm::StringRef::bytes_begin
const unsigned char * bytes_begin() const
Definition: StringRef.h:115
llvm::ARM::WinEH::ReturnType
ReturnType
Definition: ARMWinEH.h:25
llvm::wasm::WASM_ELEM_SEGMENT_IS_PASSIVE
@ WASM_ELEM_SEGMENT_IS_PASSIVE
Definition: Wasm.h:336
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_DATA
@ WASM_SEC_ORDER_DATA
Definition: Wasm.h:323
llvm::object::WasmObjectFile::getSymbolName
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1595
Triple.h
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_NONE
@ WASM_SEC_ORDER_NONE
Definition: Wasm.h:308
llvm::StringSet
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition: StringSet.h:23
llvm::wasm::WasmElemSegment::Flags
uint32_t Flags
Definition: Wasm.h:176
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:50
llvm::object::ObjectFile
This class is the base class for all object file types.
Definition: ObjectFile.h:228
llvm::object::Binary
Definition: Binary.h:32
llvm::object::WasmObjectFile::getSectionContents
Expected< ArrayRef< uint8_t > > getSectionContents(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1731
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:401
llvm::wasm::WasmSymbolType
WasmSymbolType
Definition: Wasm.h:382
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::wasm::WASM_OPCODE_I64_CONST
@ WASM_OPCODE_I64_CONST
Definition: Wasm.h:293
llvm::object::WasmObjectFile::isSectionVirtual
bool isSectionVirtual(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1756
llvm::wasm::WasmTableType::Limits
WasmLimits Limits
Definition: Wasm.h:85
llvm::wasm::WasmSymbolInfo
Definition: Wasm.h:203
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_MEMORY
@ WASM_SEC_ORDER_MEMORY
Definition: Wasm.h:315
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
llvm::wasm::WASM_SEC_START
@ WASM_SEC_START
Definition: Wasm.h:250
readSection
static Error readSection(WasmSection &Section, WasmObjectFile::ReadContext &Ctx, WasmSectionOrderChecker &Checker)
Definition: WasmObjectFile.cpp:255
llvm::wasm::WASM_COMDAT_INFO
@ WASM_COMDAT_INFO
Definition: Wasm.h:361
llvm::wasm::WasmSymbolInfo::DataRef
WasmDataReference DataRef
Definition: Wasm.h:218
llvm::object::WasmObjectFile::isSectionData
bool isSectionData(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1750
llvm::object::WasmObjectFile::getSectionSize
uint64_t getSectionSize(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1725
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:1850
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
StringSet.h
llvm::object::WasmObjectFile::ReadContext
Definition: Wasm.h:210
llvm::object::WasmObjectFile::getSectionAlignment
uint64_t getSectionAlignment(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1738
llvm::wasm::WasmDataReference::Segment
uint32_t Segment
Definition: Wasm.h:186
llvm::wasm::WASM_OPCODE_I64_ADD
@ WASM_OPCODE_I64_ADD
Definition: Wasm.h:299
llvm::object::WasmObjectFile::moveSymbolNext
void moveSymbolNext(DataRefImpl &Symb) const override
Definition: WasmObjectFile.cpp:1553
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
readFloat32
static int32_t readFloat32(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:84
llvm::wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX
@ WASM_DATA_SEGMENT_HAS_MEMINDEX
Definition: Wasm.h:332
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::object::WasmObjectFile::getRelocationSymbol
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override
Definition: WasmObjectFile.cpp:1780
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::WASM_SEC_EXPORT
@ WASM_SEC_EXPORT
Definition: Wasm.h:249
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_ELEM
@ WASM_SEC_ORDER_ELEM
Definition: Wasm.h:320
llvm::wasm::WASM_SEC_CUSTOM
@ WASM_SEC_CUSTOM
Definition: Wasm.h:242
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:1587
llvm::wasm::WasmInitFunc
Definition: Wasm.h:198
llvm::wasm::WasmSymbolInfo::Flags
uint32_t Flags
Definition: Wasm.h:206
llvm::wasm::WASM_SEC_MEMORY
@ WASM_SEC_MEMORY
Definition: Wasm.h:247
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:1820
llvm::wasm::WasmDataSegment
Definition: Wasm.h:161
llvm::object::WasmObjectFile::getSymbolAddress
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1599
llvm::object::WasmObjectFile::getRelocationOffset
uint64_t getRelocationOffset(DataRefImpl Rel) const override
Definition: WasmObjectFile.cpp:1775
llvm::object::WasmObjectFile::symbol_end
basic_symbol_iterator symbol_end() const override
Definition: WasmObjectFile.cpp:1580
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:1758
llvm::wasm::WasmLinkingData::Version
uint32_t Version
Definition: Wasm.h:235
Wasm.h
llvm::SmallSet::insert
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:178
llvm::object::SymbolRef::ST_Other
@ ST_Other
Definition: ObjectFile.h:173
llvm::wasm::WASM_LIMITS_FLAG_IS_64
@ WASM_LIMITS_FLAG_IS_64
Definition: Wasm.h:327
llvm::wasm::WasmTable
Definition: Wasm.h:88
llvm::wasm::NameType::DATA_SEGMENT
@ DATA_SEGMENT
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
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_EXPORT
@ WASM_SEC_ORDER_EXPORT
Definition: Wasm.h:318
llvm::support::endian::read32le
uint32_t read32le(const void *P)
Definition: Endian.h:381
llvm::wasm::sectionTypeToString
llvm::StringRef sectionTypeToString(uint32_t type)
Definition: Wasm.cpp:41
llvm::object::WasmObjectFile::getCommonSymbolSizeImpl
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1645
llvm::wasm::WasmElemSegment
Definition: Wasm.h:175
llvm::wasm::WASM_DYLINK_NEEDED
@ WASM_DYLINK_NEEDED
Definition: Wasm.h:368
llvm::object::BasicSymbolRef::SF_Global
@ SF_Global
Definition: SymbolicFile.h:111
llvm::object::BasicSymbolRef::SF_Hidden
@ SF_Hidden
Definition: SymbolicFile.h:120
llvm::wasm::WasmInitExprMVP::Value
union llvm::wasm::WasmInitExprMVP::@177 Value
llvm::SmallVectorImpl::pop_back_val
T pop_back_val()
Definition: SmallVector.h:659
llvm::to_string
std::string to_string(const T &Value)
Definition: ScopedPrinter.h:85
readVaruint64
static uint64_t readVaruint64(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:157
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:164
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_IMPORT
@ WASM_SEC_ORDER_IMPORT
Definition: Wasm.h:312
llvm::pdb::PDB_DataKind::Global
@ Global
llvm::SmallVectorImpl< char >
llvm::wasm::WasmFeatureEntry::Name
std::string Name
Definition: Wasm.h:68
llvm::object::SymbolRef
This is a value type class that represents a single symbol in the list of symbols in the object file.
Definition: ObjectFile.h:167
llvm::object::Binary::getData
StringRef getData() const
Definition: Binary.cpp:39
llvm::StringSwitch::Default
R Default(T Value)
Definition: StringSwitch.h:182
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
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:1790
llvm::wasm::WasmInitExprMVP::Opcode
uint8_t Opcode
Definition: Wasm.h:95
InlinePriorityMode::Size
@ Size
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_START
@ WASM_SEC_ORDER_START
Definition: Wasm.h:319
llvm::wasm::WASM_SEC_GLOBAL
@ WASM_SEC_GLOBAL
Definition: Wasm.h:248
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:346
llvm::object::WasmObjectFile::section_rel_end
relocation_iterator section_rel_end(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1765
llvm::SmallVectorImpl::reserve
void reserve(size_type N)
Definition: SmallVector.h:649
llvm::wasm::WasmTableType
Definition: Wasm.h:83
Endian.h
llvm::StringRef::begin
iterator begin() const
Definition: StringRef.h:111
llvm::wasm::WASM_SEC_IMPORT
@ WASM_SEC_IMPORT
Definition: Wasm.h:244
llvm::Triple::wasm64
@ wasm64
Definition: Triple.h:104
llvm::wasm::WASM_TYPE_FUNCREF
@ WASM_TYPE_FUNCREF
Definition: Wasm.h:266
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:436
llvm::object::WasmSection::Relocations
std::vector< wasm::WasmRelocation > Relocations
Definition: Wasm.h:112
llvm::object::WasmObjectFile::getFileFormatName
StringRef getFileFormatName() const override
Definition: WasmObjectFile.cpp:1830
llvm::wasm::WasmExport
Definition: Wasm.h:71
llvm::wasm::WASM_SYMBOL_TYPE_DATA
@ WASM_SYMBOL_TYPE_DATA
Definition: Wasm.h:384
llvm::wasm::WasmSignature
Definition: Wasm.h:434
readLimits
static wasm::WasmLimits readLimits(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:239
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_DYLINK
@ WASM_SEC_ORDER_DYLINK
Definition: Wasm.h:327
llvm::object::WasmSymbol::isBindingLocal
bool isBindingLocal() const
Definition: Wasm.h:81
SmallSet.h
ScopedPrinter.h