LLVM  15.0.0git
WasmObjectFile.cpp
Go to the documentation of this file.
1 //===- WasmObjectFile.cpp - Wasm object file implementation ---------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/ADT/ArrayRef.h"
10 #include "llvm/ADT/DenseSet.h"
11 #include "llvm/ADT/SmallSet.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/ADT/StringSet.h"
14 #include "llvm/ADT/StringSwitch.h"
15 #include "llvm/ADT/Triple.h"
16 #include "llvm/BinaryFormat/Wasm.h"
18 #include "llvm/Object/Binary.h"
19 #include "llvm/Object/Error.h"
20 #include "llvm/Object/ObjectFile.h"
22 #include "llvm/Object/Wasm.h"
23 #include "llvm/Support/Endian.h"
24 #include "llvm/Support/Error.h"
26 #include "llvm/Support/LEB128.h"
28 #include <algorithm>
29 #include <cassert>
30 #include <cstdint>
31 #include <cstring>
32 
33 #define DEBUG_TYPE "wasm-object"
34 
35 using namespace llvm;
36 using namespace object;
37 
38 void WasmSymbol::print(raw_ostream &Out) const {
39  Out << "Name=" << Info.Name
40  << ", Kind=" << toString(wasm::WasmSymbolType(Info.Kind)) << ", Flags=0x"
42  if (!isTypeData()) {
43  Out << ", ElemIndex=" << Info.ElementIndex;
44  } else if (isDefined()) {
45  Out << ", Segment=" << Info.DataRef.Segment;
46  Out << ", Offset=" << Info.DataRef.Offset;
47  Out << ", Size=" << Info.DataRef.Size;
48  }
49 }
50 
51 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
53 #endif
54 
57  Error Err = Error::success();
58  auto ObjectFile = std::make_unique<WasmObjectFile>(Buffer, Err);
59  if (Err)
60  return std::move(Err);
61 
62  return std::move(ObjectFile);
63 }
64 
65 #define VARINT7_MAX ((1 << 7) - 1)
66 #define VARINT7_MIN (-(1 << 7))
67 #define VARUINT7_MAX (1 << 7)
68 #define VARUINT1_MAX (1)
69 
70 static uint8_t readUint8(WasmObjectFile::ReadContext &Ctx) {
71  if (Ctx.Ptr == Ctx.End)
72  report_fatal_error("EOF while reading uint8");
73  return *Ctx.Ptr++;
74 }
75 
76 static uint32_t readUint32(WasmObjectFile::ReadContext &Ctx) {
77  if (Ctx.Ptr + 4 > Ctx.End)
78  report_fatal_error("EOF while reading uint32");
79  uint32_t Result = support::endian::read32le(Ctx.Ptr);
80  Ctx.Ptr += 4;
81  return Result;
82 }
83 
84 static int32_t readFloat32(WasmObjectFile::ReadContext &Ctx) {
85  if (Ctx.Ptr + 4 > Ctx.End)
86  report_fatal_error("EOF while reading float64");
87  int32_t Result = 0;
88  memcpy(&Result, Ctx.Ptr, sizeof(Result));
89  Ctx.Ptr += sizeof(Result);
90  return Result;
91 }
92 
93 static int64_t readFloat64(WasmObjectFile::ReadContext &Ctx) {
94  if (Ctx.Ptr + 8 > Ctx.End)
95  report_fatal_error("EOF while reading float64");
96  int64_t Result = 0;
97  memcpy(&Result, Ctx.Ptr, sizeof(Result));
98  Ctx.Ptr += sizeof(Result);
99  return Result;
100 }
101 
102 static uint64_t readULEB128(WasmObjectFile::ReadContext &Ctx) {
103  unsigned Count;
104  const char *Error = nullptr;
105  uint64_t Result = decodeULEB128(Ctx.Ptr, &Count, Ctx.End, &Error);
106  if (Error)
108  Ctx.Ptr += Count;
109  return Result;
110 }
111 
112 static StringRef readString(WasmObjectFile::ReadContext &Ctx) {
113  uint32_t StringLen = readULEB128(Ctx);
114  if (Ctx.Ptr + StringLen > Ctx.End)
115  report_fatal_error("EOF while reading string");
116  StringRef Return =
117  StringRef(reinterpret_cast<const char *>(Ctx.Ptr), StringLen);
118  Ctx.Ptr += StringLen;
119  return Return;
120 }
121 
122 static int64_t readLEB128(WasmObjectFile::ReadContext &Ctx) {
123  unsigned Count;
124  const char *Error = nullptr;
125  uint64_t Result = decodeSLEB128(Ctx.Ptr, &Count, Ctx.End, &Error);
126  if (Error)
128  Ctx.Ptr += Count;
129  return Result;
130 }
131 
132 static uint8_t readVaruint1(WasmObjectFile::ReadContext &Ctx) {
133  int64_t Result = readLEB128(Ctx);
134  if (Result > VARUINT1_MAX || Result < 0)
135  report_fatal_error("LEB is outside Varuint1 range");
136  return Result;
137 }
138 
139 static int32_t readVarint32(WasmObjectFile::ReadContext &Ctx) {
140  int64_t Result = readLEB128(Ctx);
141  if (Result > INT32_MAX || Result < INT32_MIN)
142  report_fatal_error("LEB is outside Varint32 range");
143  return Result;
144 }
145 
146 static uint32_t readVaruint32(WasmObjectFile::ReadContext &Ctx) {
147  uint64_t Result = readULEB128(Ctx);
148  if (Result > UINT32_MAX)
149  report_fatal_error("LEB is outside Varuint32 range");
150  return Result;
151 }
152 
153 static int64_t readVarint64(WasmObjectFile::ReadContext &Ctx) {
154  return readLEB128(Ctx);
155 }
156 
157 static uint64_t readVaruint64(WasmObjectFile::ReadContext &Ctx) {
158  return readULEB128(Ctx);
159 }
160 
161 static uint8_t readOpcode(WasmObjectFile::ReadContext &Ctx) {
162  return readUint8(Ctx);
163 }
164 
166  WasmObjectFile::ReadContext &Ctx) {
167  auto Start = Ctx.Ptr;
168 
169  Expr.Extended = false;
170  Expr.Inst.Opcode = readOpcode(Ctx);
171  switch (Expr.Inst.Opcode) {
173  Expr.Inst.Value.Int32 = readVarint32(Ctx);
174  break;
176  Expr.Inst.Value.Int64 = readVarint64(Ctx);
177  break;
179  Expr.Inst.Value.Float32 = readFloat32(Ctx);
180  break;
182  Expr.Inst.Value.Float64 = readFloat64(Ctx);
183  break;
185  Expr.Inst.Value.Global = readULEB128(Ctx);
186  break;
188  wasm::ValType Ty = static_cast<wasm::ValType>(readULEB128(Ctx));
189  if (Ty != wasm::ValType::EXTERNREF) {
190  return make_error<GenericBinaryError>("invalid type for ref.null",
192  }
193  break;
194  }
195  default:
196  Expr.Extended = true;
197  }
198 
199  if (!Expr.Extended) {
200  uint8_t EndOpcode = readOpcode(Ctx);
201  if (EndOpcode != wasm::WASM_OPCODE_END)
202  Expr.Extended = true;
203  }
204 
205  if (Expr.Extended) {
206  Ctx.Ptr = Start;
207  while (1) {
208  uint8_t Opcode = readOpcode(Ctx);
209  switch (Opcode) {
216  readULEB128(Ctx);
217  break;
224  break;
226  Expr.Body = ArrayRef<uint8_t>(Start, Ctx.Ptr - Start);
227  return Error::success();
228  default:
229  return make_error<GenericBinaryError>(
230  Twine("invalid opcode in init_expr: ") + Twine(unsigned(Opcode)),
232  }
233  }
234  }
235 
236  return Error::success();
237 }
238 
239 static wasm::WasmLimits readLimits(WasmObjectFile::ReadContext &Ctx) {
240  wasm::WasmLimits Result;
241  Result.Flags = readVaruint32(Ctx);
242  Result.Minimum = readVaruint64(Ctx);
243  if (Result.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
244  Result.Maximum = readVaruint64(Ctx);
245  return Result;
246 }
247 
248 static wasm::WasmTableType readTableType(WasmObjectFile::ReadContext &Ctx) {
249  wasm::WasmTableType TableType;
250  TableType.ElemType = readUint8(Ctx);
251  TableType.Limits = readLimits(Ctx);
252  return TableType;
253 }
254 
255 static Error readSection(WasmSection &Section, WasmObjectFile::ReadContext &Ctx,
256  WasmSectionOrderChecker &Checker) {
257  Section.Offset = Ctx.Ptr - Ctx.Start;
258  Section.Type = readUint8(Ctx);
259  LLVM_DEBUG(dbgs() << "readSection type=" << Section.Type << "\n");
260  uint32_t Size = readVaruint32(Ctx);
261  if (Size == 0)
262  return make_error<StringError>("zero length section",
264  if (Ctx.Ptr + Size > Ctx.End)
265  return make_error<StringError>("section too large",
267  if (Section.Type == wasm::WASM_SEC_CUSTOM) {
268  WasmObjectFile::ReadContext SectionCtx;
269  SectionCtx.Start = Ctx.Ptr;
270  SectionCtx.Ptr = Ctx.Ptr;
271  SectionCtx.End = Ctx.Ptr + Size;
272 
273  Section.Name = readString(SectionCtx);
274 
275  uint32_t SectionNameSize = SectionCtx.Ptr - SectionCtx.Start;
276  Ctx.Ptr += SectionNameSize;
277  Size -= SectionNameSize;
278  }
279 
280  if (!Checker.isValidSectionOrder(Section.Type, Section.Name)) {
281  return make_error<StringError>("out of order section type: " +
282  llvm::to_string(Section.Type),
284  }
285 
286  Section.Content = ArrayRef<uint8_t>(Ctx.Ptr, Size);
287  Ctx.Ptr += Size;
288  return Error::success();
289 }
290 
292  : ObjectFile(Binary::ID_Wasm, Buffer) {
293  ErrorAsOutParameter ErrAsOutParam(&Err);
294  Header.Magic = getData().substr(0, 4);
295  if (Header.Magic != StringRef("\0asm", 4)) {
296  Err = make_error<StringError>("invalid magic number",
298  return;
299  }
300 
301  ReadContext Ctx;
302  Ctx.Start = getData().bytes_begin();
303  Ctx.Ptr = Ctx.Start + 4;
304  Ctx.End = Ctx.Start + getData().size();
305 
306  if (Ctx.Ptr + 4 > Ctx.End) {
307  Err = make_error<StringError>("missing version number",
309  return;
310  }
311 
312  Header.Version = readUint32(Ctx);
313  if (Header.Version != wasm::WasmVersion) {
314  Err = make_error<StringError>("invalid version number: " +
315  Twine(Header.Version),
317  return;
318  }
319 
320  WasmSectionOrderChecker Checker;
321  while (Ctx.Ptr < Ctx.End) {
322  WasmSection Sec;
323  if ((Err = readSection(Sec, Ctx, Checker)))
324  return;
325  if ((Err = parseSection(Sec)))
326  return;
327 
328  Sections.push_back(Sec);
329  }
330 }
331 
332 Error WasmObjectFile::parseSection(WasmSection &Sec) {
333  ReadContext Ctx;
334  Ctx.Start = Sec.Content.data();
335  Ctx.End = Ctx.Start + Sec.Content.size();
336  Ctx.Ptr = Ctx.Start;
337  switch (Sec.Type) {
339  return parseCustomSection(Sec, Ctx);
340  case wasm::WASM_SEC_TYPE:
341  return parseTypeSection(Ctx);
343  return parseImportSection(Ctx);
345  return parseFunctionSection(Ctx);
347  return parseTableSection(Ctx);
349  return parseMemorySection(Ctx);
350  case wasm::WASM_SEC_TAG:
351  return parseTagSection(Ctx);
353  return parseGlobalSection(Ctx);
355  return parseExportSection(Ctx);
357  return parseStartSection(Ctx);
358  case wasm::WASM_SEC_ELEM:
359  return parseElemSection(Ctx);
360  case wasm::WASM_SEC_CODE:
361  return parseCodeSection(Ctx);
362  case wasm::WASM_SEC_DATA:
363  return parseDataSection(Ctx);
365  return parseDataCountSection(Ctx);
366  default:
367  return make_error<GenericBinaryError>(
368  "invalid section type: " + Twine(Sec.Type), object_error::parse_failed);
369  }
370 }
371 
372 Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) {
373  // Legacy "dylink" section support.
374  // See parseDylink0Section for the current "dylink.0" section parsing.
375  HasDylinkSection = true;
376  DylinkInfo.MemorySize = readVaruint32(Ctx);
377  DylinkInfo.MemoryAlignment = readVaruint32(Ctx);
378  DylinkInfo.TableSize = readVaruint32(Ctx);
379  DylinkInfo.TableAlignment = readVaruint32(Ctx);
380  uint32_t Count = readVaruint32(Ctx);
381  while (Count--) {
382  DylinkInfo.Needed.push_back(readString(Ctx));
383  }
384 
385  if (Ctx.Ptr != Ctx.End)
386  return make_error<GenericBinaryError>("dylink section ended prematurely",
388  return Error::success();
389 }
390 
391 Error WasmObjectFile::parseDylink0Section(ReadContext &Ctx) {
392  // See
393  // https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md
394  HasDylinkSection = true;
395 
396  const uint8_t *OrigEnd = Ctx.End;
397  while (Ctx.Ptr < OrigEnd) {
398  Ctx.End = OrigEnd;
399  uint8_t Type = readUint8(Ctx);
400  uint32_t Size = readVaruint32(Ctx);
401  LLVM_DEBUG(dbgs() << "readSubsection type=" << int(Type) << " size=" << Size
402  << "\n");
403  Ctx.End = Ctx.Ptr + Size;
404  uint32_t Count;
405  switch (Type) {
407  DylinkInfo.MemorySize = readVaruint32(Ctx);
408  DylinkInfo.MemoryAlignment = readVaruint32(Ctx);
409  DylinkInfo.TableSize = readVaruint32(Ctx);
410  DylinkInfo.TableAlignment = readVaruint32(Ctx);
411  break;
413  Count = readVaruint32(Ctx);
414  while (Count--) {
415  DylinkInfo.Needed.push_back(readString(Ctx));
416  }
417  break;
419  uint32_t Count = readVaruint32(Ctx);
420  while (Count--) {
421  DylinkInfo.ExportInfo.push_back({readString(Ctx), readVaruint32(Ctx)});
422  }
423  break;
424  }
426  uint32_t Count = readVaruint32(Ctx);
427  while (Count--) {
428  DylinkInfo.ImportInfo.push_back(
429  {readString(Ctx), readString(Ctx), readVaruint32(Ctx)});
430  }
431  break;
432  }
433  default:
434  LLVM_DEBUG(dbgs() << "unknown dylink.0 sub-section: " << Type << "\n");
435  Ctx.Ptr += Size;
436  break;
437  }
438  if (Ctx.Ptr != Ctx.End) {
439  return make_error<GenericBinaryError>(
440  "dylink.0 sub-section ended prematurely", object_error::parse_failed);
441  }
442  }
443 
444  if (Ctx.Ptr != Ctx.End)
445  return make_error<GenericBinaryError>("dylink.0 section ended prematurely",
447  return Error::success();
448 }
449 
450 Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
451  llvm::DenseSet<uint64_t> SeenFunctions;
452  llvm::DenseSet<uint64_t> SeenGlobals;
453  llvm::DenseSet<uint64_t> SeenSegments;
454 
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  if (!Import.Module.empty()) {
644  Info.ImportModule = Import.Module;
645  }
646  }
647  break;
648 
650  Info.ElementIndex = readVaruint32(Ctx);
651  if (!isValidGlobalIndex(Info.ElementIndex) ||
652  IsDefined != isDefinedGlobalIndex(Info.ElementIndex))
653  return make_error<GenericBinaryError>("invalid global symbol index",
655  if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
657  return make_error<GenericBinaryError>("undefined weak global symbol",
659  if (IsDefined) {
660  Info.Name = readString(Ctx);
661  unsigned GlobalIndex = Info.ElementIndex - NumImportedGlobals;
662  wasm::WasmGlobal &Global = Globals[GlobalIndex];
663  GlobalType = &Global.Type;
664  if (Global.SymbolName.empty())
665  Global.SymbolName = Info.Name;
666  } else {
667  wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex];
668  if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
669  Info.Name = readString(Ctx);
670  Info.ImportName = Import.Field;
671  } else {
672  Info.Name = Import.Field;
673  }
674  GlobalType = &Import.Global;
675  if (!Import.Module.empty()) {
676  Info.ImportModule = Import.Module;
677  }
678  }
679  break;
680 
682  Info.ElementIndex = readVaruint32(Ctx);
683  if (!isValidTableNumber(Info.ElementIndex) ||
684  IsDefined != isDefinedTableNumber(Info.ElementIndex))
685  return make_error<GenericBinaryError>("invalid table symbol index",
687  if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
689  return make_error<GenericBinaryError>("undefined weak table symbol",
691  if (IsDefined) {
692  Info.Name = readString(Ctx);
693  unsigned TableNumber = Info.ElementIndex - NumImportedTables;
694  wasm::WasmTable &Table = Tables[TableNumber];
695  TableType = &Table.Type;
696  if (Table.SymbolName.empty())
697  Table.SymbolName = Info.Name;
698  } else {
699  wasm::WasmImport &Import = *ImportedTables[Info.ElementIndex];
700  if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
701  Info.Name = readString(Ctx);
702  Info.ImportName = Import.Field;
703  } else {
704  Info.Name = Import.Field;
705  }
706  TableType = &Import.Table;
707  if (!Import.Module.empty()) {
708  Info.ImportModule = Import.Module;
709  }
710  }
711  break;
712 
714  Info.Name = readString(Ctx);
715  if (IsDefined) {
716  auto Index = readVaruint32(Ctx);
717  if (Index >= DataSegments.size())
718  return make_error<GenericBinaryError>("invalid data symbol index",
720  auto Offset = readVaruint64(Ctx);
721  auto Size = readVaruint64(Ctx);
722  size_t SegmentSize = DataSegments[Index].Data.Content.size();
723  if (Offset > SegmentSize)
724  return make_error<GenericBinaryError>(
725  "invalid data symbol offset: `" + Info.Name + "` (offset: " +
726  Twine(Offset) + " segment size: " + Twine(SegmentSize) + ")",
729  }
730  break;
731 
733  if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
735  return make_error<GenericBinaryError>(
736  "section symbols must have local binding",
738  Info.ElementIndex = readVaruint32(Ctx);
739  // Use somewhat unique section name as symbol name.
740  StringRef SectionName = Sections[Info.ElementIndex].Name;
741  Info.Name = SectionName;
742  break;
743  }
744 
746  Info.ElementIndex = readVaruint32(Ctx);
747  if (!isValidTagIndex(Info.ElementIndex) ||
748  IsDefined != isDefinedTagIndex(Info.ElementIndex))
749  return make_error<GenericBinaryError>("invalid tag symbol index",
751  if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
753  return make_error<GenericBinaryError>("undefined weak global symbol",
755  if (IsDefined) {
756  Info.Name = readString(Ctx);
757  unsigned TagIndex = Info.ElementIndex - NumImportedTags;
758  wasm::WasmTag &Tag = Tags[TagIndex];
759  Signature = &Signatures[Tag.SigIndex];
760  if (Tag.SymbolName.empty())
761  Tag.SymbolName = Info.Name;
762 
763  } else {
764  wasm::WasmImport &Import = *ImportedTags[Info.ElementIndex];
765  if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
766  Info.Name = readString(Ctx);
767  Info.ImportName = Import.Field;
768  } else {
769  Info.Name = Import.Field;
770  }
771  Signature = &Signatures[Import.SigIndex];
772  if (!Import.Module.empty()) {
773  Info.ImportModule = Import.Module;
774  }
775  }
776  break;
777  }
778 
779  default:
780  return make_error<GenericBinaryError>("invalid symbol type: " +
781  Twine(unsigned(Info.Kind)),
783  }
784 
785  if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
787  !SymbolNames.insert(Info.Name).second)
788  return make_error<GenericBinaryError>("duplicate symbol name " +
789  Twine(Info.Name),
791  LinkingData.SymbolTable.emplace_back(Info);
792  Symbols.emplace_back(LinkingData.SymbolTable.back(), GlobalType, TableType,
793  Signature);
794  LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");
795  }
796 
797  return Error::success();
798 }
799 
800 Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
801  uint32_t ComdatCount = readVaruint32(Ctx);
802  StringSet<> ComdatSet;
803  for (unsigned ComdatIndex = 0; ComdatIndex < ComdatCount; ++ComdatIndex) {
804  StringRef Name = readString(Ctx);
805  if (Name.empty() || !ComdatSet.insert(Name).second)
806  return make_error<GenericBinaryError>("bad/duplicate COMDAT name " +
807  Twine(Name),
809  LinkingData.Comdats.emplace_back(Name);
810  uint32_t Flags = readVaruint32(Ctx);
811  if (Flags != 0)
812  return make_error<GenericBinaryError>("unsupported COMDAT flags",
814 
815  uint32_t EntryCount = readVaruint32(Ctx);
816  while (EntryCount--) {
817  unsigned Kind = readVaruint32(Ctx);
818  unsigned Index = readVaruint32(Ctx);
819  switch (Kind) {
820  default:
821  return make_error<GenericBinaryError>("invalid COMDAT entry type",
824  if (Index >= DataSegments.size())
825  return make_error<GenericBinaryError>(
826  "COMDAT data index out of range", object_error::parse_failed);
827  if (DataSegments[Index].Data.Comdat != UINT32_MAX)
828  return make_error<GenericBinaryError>("data segment in two COMDATs",
830  DataSegments[Index].Data.Comdat = ComdatIndex;
831  break;
833  if (!isDefinedFunctionIndex(Index))
834  return make_error<GenericBinaryError>(
835  "COMDAT function index out of range", object_error::parse_failed);
836  if (getDefinedFunction(Index).Comdat != UINT32_MAX)
837  return make_error<GenericBinaryError>("function in two COMDATs",
839  getDefinedFunction(Index).Comdat = ComdatIndex;
840  break;
842  if (Index >= Sections.size())
843  return make_error<GenericBinaryError>(
844  "COMDAT section index out of range", object_error::parse_failed);
845  if (Sections[Index].Type != wasm::WASM_SEC_CUSTOM)
846  return make_error<GenericBinaryError>(
847  "non-custom section in a COMDAT", object_error::parse_failed);
848  Sections[Index].Comdat = ComdatIndex;
849  break;
850  }
851  }
852  }
853  return Error::success();
854 }
855 
856 Error WasmObjectFile::parseProducersSection(ReadContext &Ctx) {
857  llvm::SmallSet<StringRef, 3> FieldsSeen;
858  uint32_t Fields = readVaruint32(Ctx);
859  for (size_t I = 0; I < Fields; ++I) {
860  StringRef FieldName = readString(Ctx);
861  if (!FieldsSeen.insert(FieldName).second)
862  return make_error<GenericBinaryError>(
863  "producers section does not have unique fields",
865  std::vector<std::pair<std::string, std::string>> *ProducerVec = nullptr;
866  if (FieldName == "language") {
867  ProducerVec = &ProducerInfo.Languages;
868  } else if (FieldName == "processed-by") {
869  ProducerVec = &ProducerInfo.Tools;
870  } else if (FieldName == "sdk") {
871  ProducerVec = &ProducerInfo.SDKs;
872  } else {
873  return make_error<GenericBinaryError>(
874  "producers section field is not named one of language, processed-by, "
875  "or sdk",
877  }
878  uint32_t ValueCount = readVaruint32(Ctx);
879  llvm::SmallSet<StringRef, 8> ProducersSeen;
880  for (size_t J = 0; J < ValueCount; ++J) {
881  StringRef Name = readString(Ctx);
883  if (!ProducersSeen.insert(Name).second) {
884  return make_error<GenericBinaryError>(
885  "producers section contains repeated producer",
887  }
888  ProducerVec->emplace_back(std::string(Name), std::string(Version));
889  }
890  }
891  if (Ctx.Ptr != Ctx.End)
892  return make_error<GenericBinaryError>("producers section ended prematurely",
894  return Error::success();
895 }
896 
897 Error WasmObjectFile::parseTargetFeaturesSection(ReadContext &Ctx) {
898  llvm::SmallSet<std::string, 8> FeaturesSeen;
899  uint32_t FeatureCount = readVaruint32(Ctx);
900  for (size_t I = 0; I < FeatureCount; ++I) {
901  wasm::WasmFeatureEntry Feature;
902  Feature.Prefix = readUint8(Ctx);
903  switch (Feature.Prefix) {
907  break;
908  default:
909  return make_error<GenericBinaryError>("unknown feature policy prefix",
911  }
912  Feature.Name = std::string(readString(Ctx));
913  if (!FeaturesSeen.insert(Feature.Name).second)
914  return make_error<GenericBinaryError>(
915  "target features section contains repeated feature \"" +
916  Feature.Name + "\"",
918  TargetFeatures.push_back(Feature);
919  }
920  if (Ctx.Ptr != Ctx.End)
921  return make_error<GenericBinaryError>(
922  "target features section ended prematurely",
924  return Error::success();
925 }
926 
927 Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
928  uint32_t SectionIndex = readVaruint32(Ctx);
929  if (SectionIndex >= Sections.size())
930  return make_error<GenericBinaryError>("invalid section index",
932  WasmSection &Section = Sections[SectionIndex];
933  uint32_t RelocCount = readVaruint32(Ctx);
934  uint32_t EndOffset = Section.Content.size();
935  uint32_t PreviousOffset = 0;
936  while (RelocCount--) {
937  wasm::WasmRelocation Reloc = {};
938  uint32_t type = readVaruint32(Ctx);
939  Reloc.Type = type;
940  Reloc.Offset = readVaruint32(Ctx);
941  if (Reloc.Offset < PreviousOffset)
942  return make_error<GenericBinaryError>("relocations not in offset order",
944  PreviousOffset = Reloc.Offset;
945  Reloc.Index = readVaruint32(Ctx);
946  switch (type) {
947  case wasm::R_WASM_FUNCTION_INDEX_LEB:
948  case wasm::R_WASM_TABLE_INDEX_SLEB:
949  case wasm::R_WASM_TABLE_INDEX_SLEB64:
950  case wasm::R_WASM_TABLE_INDEX_I32:
951  case wasm::R_WASM_TABLE_INDEX_I64:
952  case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
953  case wasm::R_WASM_TABLE_INDEX_REL_SLEB64:
954  if (!isValidFunctionSymbol(Reloc.Index))
955  return make_error<GenericBinaryError>(
956  "invalid relocation function index", object_error::parse_failed);
957  break;
958  case wasm::R_WASM_TABLE_NUMBER_LEB:
959  if (!isValidTableSymbol(Reloc.Index))
960  return make_error<GenericBinaryError>("invalid relocation table index",
962  break;
963  case wasm::R_WASM_TYPE_INDEX_LEB:
964  if (Reloc.Index >= Signatures.size())
965  return make_error<GenericBinaryError>("invalid relocation type index",
967  break;
968  case wasm::R_WASM_GLOBAL_INDEX_LEB:
969  // R_WASM_GLOBAL_INDEX_LEB are can be used against function and data
970  // symbols to refer to their GOT entries.
971  if (!isValidGlobalSymbol(Reloc.Index) &&
972  !isValidDataSymbol(Reloc.Index) &&
973  !isValidFunctionSymbol(Reloc.Index))
974  return make_error<GenericBinaryError>("invalid relocation global index",
976  break;
977  case wasm::R_WASM_GLOBAL_INDEX_I32:
978  if (!isValidGlobalSymbol(Reloc.Index))
979  return make_error<GenericBinaryError>("invalid relocation global index",
981  break;
982  case wasm::R_WASM_TAG_INDEX_LEB:
983  if (!isValidTagSymbol(Reloc.Index))
984  return make_error<GenericBinaryError>("invalid relocation tag index",
986  break;
987  case wasm::R_WASM_MEMORY_ADDR_LEB:
988  case wasm::R_WASM_MEMORY_ADDR_SLEB:
989  case wasm::R_WASM_MEMORY_ADDR_I32:
990  case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
991  case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
992  case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
993  if (!isValidDataSymbol(Reloc.Index))
994  return make_error<GenericBinaryError>("invalid relocation data index",
996  Reloc.Addend = readVarint32(Ctx);
997  break;
998  case wasm::R_WASM_MEMORY_ADDR_LEB64:
999  case wasm::R_WASM_MEMORY_ADDR_SLEB64:
1000  case wasm::R_WASM_MEMORY_ADDR_I64:
1001  case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
1002  case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64:
1003  if (!isValidDataSymbol(Reloc.Index))
1004  return make_error<GenericBinaryError>("invalid relocation data index",
1006  Reloc.Addend = readVarint64(Ctx);
1007  break;
1008  case wasm::R_WASM_FUNCTION_OFFSET_I32:
1009  if (!isValidFunctionSymbol(Reloc.Index))
1010  return make_error<GenericBinaryError>(
1011  "invalid relocation function index", object_error::parse_failed);
1012  Reloc.Addend = readVarint32(Ctx);
1013  break;
1014  case wasm::R_WASM_FUNCTION_OFFSET_I64:
1015  if (!isValidFunctionSymbol(Reloc.Index))
1016  return make_error<GenericBinaryError>(
1017  "invalid relocation function index", object_error::parse_failed);
1018  Reloc.Addend = readVarint64(Ctx);
1019  break;
1020  case wasm::R_WASM_SECTION_OFFSET_I32:
1021  if (!isValidSectionSymbol(Reloc.Index))
1022  return make_error<GenericBinaryError>(
1023  "invalid relocation section index", object_error::parse_failed);
1024  Reloc.Addend = readVarint32(Ctx);
1025  break;
1026  default:
1027  return make_error<GenericBinaryError>("invalid relocation type: " +
1028  Twine(type),
1030  }
1031 
1032  // Relocations must fit inside the section, and must appear in order. They
1033  // also shouldn't overlap a function/element boundary, but we don't bother
1034  // to check that.
1035  uint64_t Size = 5;
1036  if (Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LEB64 ||
1037  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_SLEB64 ||
1038  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_REL_SLEB64)
1039  Size = 10;
1040  if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I32 ||
1041  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I32 ||
1042  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LOCREL_I32 ||
1043  Reloc.Type == wasm::R_WASM_SECTION_OFFSET_I32 ||
1044  Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||
1045  Reloc.Type == wasm::R_WASM_GLOBAL_INDEX_I32)
1046  Size = 4;
1047  if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I64 ||
1048  Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I64 ||
1049  Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I64)
1050  Size = 8;
1051  if (Reloc.Offset + Size > EndOffset)
1052  return make_error<GenericBinaryError>("invalid relocation offset",
1054 
1055  Section.Relocations.push_back(Reloc);
1056  }
1057  if (Ctx.Ptr != Ctx.End)
1058  return make_error<GenericBinaryError>("reloc section ended prematurely",
1060  return Error::success();
1061 }
1062 
1063 Error WasmObjectFile::parseCustomSection(WasmSection &Sec, ReadContext &Ctx) {
1064  if (Sec.Name == "dylink") {
1065  if (Error Err = parseDylinkSection(Ctx))
1066  return Err;
1067  } else if (Sec.Name == "dylink.0") {
1068  if (Error Err = parseDylink0Section(Ctx))
1069  return Err;
1070  } else if (Sec.Name == "name") {
1071  if (Error Err = parseNameSection(Ctx))
1072  return Err;
1073  } else if (Sec.Name == "linking") {
1074  if (Error Err = parseLinkingSection(Ctx))
1075  return Err;
1076  } else if (Sec.Name == "producers") {
1077  if (Error Err = parseProducersSection(Ctx))
1078  return Err;
1079  } else if (Sec.Name == "target_features") {
1080  if (Error Err = parseTargetFeaturesSection(Ctx))
1081  return Err;
1082  } else if (Sec.Name.startswith("reloc.")) {
1083  if (Error Err = parseRelocSection(Sec.Name, Ctx))
1084  return Err;
1085  }
1086  return Error::success();
1087 }
1088 
1089 Error WasmObjectFile::parseTypeSection(ReadContext &Ctx) {
1090  uint32_t Count = readVaruint32(Ctx);
1091  Signatures.reserve(Count);
1092  while (Count--) {
1093  wasm::WasmSignature Sig;
1094  uint8_t Form = readUint8(Ctx);
1095  if (Form != wasm::WASM_TYPE_FUNC) {
1096  return make_error<GenericBinaryError>("invalid signature type",
1098  }
1099  uint32_t ParamCount = readVaruint32(Ctx);
1100  Sig.Params.reserve(ParamCount);
1101  while (ParamCount--) {
1102  uint32_t ParamType = readUint8(Ctx);
1103  Sig.Params.push_back(wasm::ValType(ParamType));
1104  }
1105  uint32_t ReturnCount = readVaruint32(Ctx);
1106  while (ReturnCount--) {
1107  uint32_t ReturnType = readUint8(Ctx);
1108  Sig.Returns.push_back(wasm::ValType(ReturnType));
1109  }
1110  Signatures.push_back(std::move(Sig));
1111  }
1112  if (Ctx.Ptr != Ctx.End)
1113  return make_error<GenericBinaryError>("type section ended prematurely",
1115  return Error::success();
1116 }
1117 
1118 Error WasmObjectFile::parseImportSection(ReadContext &Ctx) {
1119  uint32_t Count = readVaruint32(Ctx);
1120  uint32_t NumTypes = Signatures.size();
1121  Imports.reserve(Count);
1122  for (uint32_t I = 0; I < Count; I++) {
1123  wasm::WasmImport Im;
1124  Im.Module = readString(Ctx);
1125  Im.Field = readString(Ctx);
1126  Im.Kind = readUint8(Ctx);
1127  switch (Im.Kind) {
1129  NumImportedFunctions++;
1130  Im.SigIndex = readVaruint32(Ctx);
1131  if (Im.SigIndex >= NumTypes)
1132  return make_error<GenericBinaryError>("invalid function type",
1134  break;
1136  NumImportedGlobals++;
1137  Im.Global.Type = readUint8(Ctx);
1138  Im.Global.Mutable = readVaruint1(Ctx);
1139  break;
1141  Im.Memory = readLimits(Ctx);
1143  HasMemory64 = true;
1144  break;
1146  Im.Table = readTableType(Ctx);
1147  NumImportedTables++;
1148  auto ElemType = Im.Table.ElemType;
1149  if (ElemType != wasm::WASM_TYPE_FUNCREF &&
1150  ElemType != wasm::WASM_TYPE_EXTERNREF)
1151  return make_error<GenericBinaryError>("invalid table element type",
1153  break;
1154  }
1156  NumImportedTags++;
1157  if (readUint8(Ctx) != 0) // Reserved 'attribute' field
1158  return make_error<GenericBinaryError>("invalid attribute",
1160  Im.SigIndex = readVaruint32(Ctx);
1161  if (Im.SigIndex >= NumTypes)
1162  return make_error<GenericBinaryError>("invalid tag type",
1164  break;
1165  default:
1166  return make_error<GenericBinaryError>("unexpected import kind",
1168  }
1169  Imports.push_back(Im);
1170  }
1171  if (Ctx.Ptr != Ctx.End)
1172  return make_error<GenericBinaryError>("import section ended prematurely",
1174  return Error::success();
1175 }
1176 
1177 Error WasmObjectFile::parseFunctionSection(ReadContext &Ctx) {
1178  uint32_t Count = readVaruint32(Ctx);
1179  Functions.reserve(Count);
1180  uint32_t NumTypes = Signatures.size();
1181  while (Count--) {
1182  uint32_t Type = readVaruint32(Ctx);
1183  if (Type >= NumTypes)
1184  return make_error<GenericBinaryError>("invalid function type",
1187  F.SigIndex = Type;
1188  Functions.push_back(F);
1189  }
1190  if (Ctx.Ptr != Ctx.End)
1191  return make_error<GenericBinaryError>("function section ended prematurely",
1193  return Error::success();
1194 }
1195 
1196 Error WasmObjectFile::parseTableSection(ReadContext &Ctx) {
1197  TableSection = Sections.size();
1198  uint32_t Count = readVaruint32(Ctx);
1199  Tables.reserve(Count);
1200  while (Count--) {
1202  T.Type = readTableType(Ctx);
1203  T.Index = NumImportedTables + Tables.size();
1204  Tables.push_back(T);
1205  auto ElemType = Tables.back().Type.ElemType;
1206  if (ElemType != wasm::WASM_TYPE_FUNCREF &&
1207  ElemType != wasm::WASM_TYPE_EXTERNREF) {
1208  return make_error<GenericBinaryError>("invalid table element type",
1210  }
1211  }
1212  if (Ctx.Ptr != Ctx.End)
1213  return make_error<GenericBinaryError>("table section ended prematurely",
1215  return Error::success();
1216 }
1217 
1218 Error WasmObjectFile::parseMemorySection(ReadContext &Ctx) {
1219  uint32_t Count = readVaruint32(Ctx);
1220  Memories.reserve(Count);
1221  while (Count--) {
1222  auto Limits = readLimits(Ctx);
1223  if (Limits.Flags & wasm::WASM_LIMITS_FLAG_IS_64)
1224  HasMemory64 = true;
1225  Memories.push_back(Limits);
1226  }
1227  if (Ctx.Ptr != Ctx.End)
1228  return make_error<GenericBinaryError>("memory section ended prematurely",
1230  return Error::success();
1231 }
1232 
1233 Error WasmObjectFile::parseTagSection(ReadContext &Ctx) {
1234  TagSection = Sections.size();
1235  uint32_t Count = readVaruint32(Ctx);
1236  Tags.reserve(Count);
1237  uint32_t NumTypes = Signatures.size();
1238  while (Count--) {
1239  if (readUint8(Ctx) != 0) // Reserved 'attribute' field
1240  return make_error<GenericBinaryError>("invalid attribute",
1242  uint32_t Type = readVaruint32(Ctx);
1243  if (Type >= NumTypes)
1244  return make_error<GenericBinaryError>("invalid tag type",
1247  Tag.Index = NumImportedTags + Tags.size();
1248  Tag.SigIndex = Type;
1249  Tags.push_back(Tag);
1250  }
1251 
1252  if (Ctx.Ptr != Ctx.End)
1253  return make_error<GenericBinaryError>("tag section ended prematurely",
1255  return Error::success();
1256 }
1257 
1258 Error WasmObjectFile::parseGlobalSection(ReadContext &Ctx) {
1259  GlobalSection = Sections.size();
1260  uint32_t Count = readVaruint32(Ctx);
1261  Globals.reserve(Count);
1262  while (Count--) {
1264  Global.Index = NumImportedGlobals + Globals.size();
1265  Global.Type.Type = readUint8(Ctx);
1266  Global.Type.Mutable = readVaruint1(Ctx);
1267  if (Error Err = readInitExpr(Global.InitExpr, Ctx))
1268  return Err;
1269  Globals.push_back(Global);
1270  }
1271  if (Ctx.Ptr != Ctx.End)
1272  return make_error<GenericBinaryError>("global section ended prematurely",
1274  return Error::success();
1275 }
1276 
1277 Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
1278  uint32_t Count = readVaruint32(Ctx);
1279  Exports.reserve(Count);
1280  for (uint32_t I = 0; I < Count; I++) {
1281  wasm::WasmExport Ex;
1282  Ex.Name = readString(Ctx);
1283  Ex.Kind = readUint8(Ctx);
1284  Ex.Index = readVaruint32(Ctx);
1285  switch (Ex.Kind) {
1287 
1288  if (!isDefinedFunctionIndex(Ex.Index))
1289  return make_error<GenericBinaryError>("invalid function export",
1291  getDefinedFunction(Ex.Index).ExportName = Ex.Name;
1292  break;
1294  if (!isValidGlobalIndex(Ex.Index))
1295  return make_error<GenericBinaryError>("invalid global export",
1297  break;
1299  if (!isValidTagIndex(Ex.Index))
1300  return make_error<GenericBinaryError>("invalid tag export",
1302  break;
1305  break;
1306  default:
1307  return make_error<GenericBinaryError>("unexpected export kind",
1309  }
1310  Exports.push_back(Ex);
1311  }
1312  if (Ctx.Ptr != Ctx.End)
1313  return make_error<GenericBinaryError>("export section ended prematurely",
1315  return Error::success();
1316 }
1317 
1318 bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const {
1319  return Index < NumImportedFunctions + Functions.size();
1320 }
1321 
1322 bool WasmObjectFile::isDefinedFunctionIndex(uint32_t Index) const {
1323  return Index >= NumImportedFunctions && isValidFunctionIndex(Index);
1324 }
1325 
1326 bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const {
1327  return Index < NumImportedGlobals + Globals.size();
1328 }
1329 
1330 bool WasmObjectFile::isValidTableNumber(uint32_t Index) const {
1331  return Index < NumImportedTables + Tables.size();
1332 }
1333 
1334 bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const {
1335  return Index >= NumImportedGlobals && isValidGlobalIndex(Index);
1336 }
1337 
1338 bool WasmObjectFile::isDefinedTableNumber(uint32_t Index) const {
1339  return Index >= NumImportedTables && isValidTableNumber(Index);
1340 }
1341 
1342 bool WasmObjectFile::isValidTagIndex(uint32_t Index) const {
1343  return Index < NumImportedTags + Tags.size();
1344 }
1345 
1346 bool WasmObjectFile::isDefinedTagIndex(uint32_t Index) const {
1347  return Index >= NumImportedTags && isValidTagIndex(Index);
1348 }
1349 
1350 bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
1351  return Index < Symbols.size() && Symbols[Index].isTypeFunction();
1352 }
1353 
1354 bool WasmObjectFile::isValidTableSymbol(uint32_t Index) const {
1355  return Index < Symbols.size() && Symbols[Index].isTypeTable();
1356 }
1357 
1358 bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const {
1359  return Index < Symbols.size() && Symbols[Index].isTypeGlobal();
1360 }
1361 
1362 bool WasmObjectFile::isValidTagSymbol(uint32_t Index) const {
1363  return Index < Symbols.size() && Symbols[Index].isTypeTag();
1364 }
1365 
1366 bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
1367  return Index < Symbols.size() && Symbols[Index].isTypeData();
1368 }
1369 
1370 bool WasmObjectFile::isValidSectionSymbol(uint32_t Index) const {
1371  return Index < Symbols.size() && Symbols[Index].isTypeSection();
1372 }
1373 
1374 wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) {
1375  assert(isDefinedFunctionIndex(Index));
1376  return Functions[Index - NumImportedFunctions];
1377 }
1378 
1379 const wasm::WasmFunction &
1380 WasmObjectFile::getDefinedFunction(uint32_t Index) const {
1381  assert(isDefinedFunctionIndex(Index));
1382  return Functions[Index - NumImportedFunctions];
1383 }
1384 
1385 wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) {
1386  assert(isDefinedGlobalIndex(Index));
1387  return Globals[Index - NumImportedGlobals];
1388 }
1389 
1390 wasm::WasmTag &WasmObjectFile::getDefinedTag(uint32_t Index) {
1391  assert(isDefinedTagIndex(Index));
1392  return Tags[Index - NumImportedTags];
1393 }
1394 
1395 Error WasmObjectFile::parseStartSection(ReadContext &Ctx) {
1396  StartFunction = readVaruint32(Ctx);
1397  if (!isValidFunctionIndex(StartFunction))
1398  return make_error<GenericBinaryError>("invalid start function",
1400  return Error::success();
1401 }
1402 
1403 Error WasmObjectFile::parseCodeSection(ReadContext &Ctx) {
1404  CodeSection = Sections.size();
1405  uint32_t FunctionCount = readVaruint32(Ctx);
1406  if (FunctionCount != Functions.size()) {
1407  return make_error<GenericBinaryError>("invalid function count",
1409  }
1410 
1411  for (uint32_t i = 0; i < FunctionCount; i++) {
1412  wasm::WasmFunction& Function = Functions[i];
1413  const uint8_t *FunctionStart = Ctx.Ptr;
1414  uint32_t Size = readVaruint32(Ctx);
1415  const uint8_t *FunctionEnd = Ctx.Ptr + Size;
1416 
1417  Function.CodeOffset = Ctx.Ptr - FunctionStart;
1418  Function.Index = NumImportedFunctions + i;
1419  Function.CodeSectionOffset = FunctionStart - Ctx.Start;
1420  Function.Size = FunctionEnd - FunctionStart;
1421 
1422  uint32_t NumLocalDecls = readVaruint32(Ctx);
1423  Function.Locals.reserve(NumLocalDecls);
1424  while (NumLocalDecls--) {
1425  wasm::WasmLocalDecl Decl;
1426  Decl.Count = readVaruint32(Ctx);
1427  Decl.Type = readUint8(Ctx);
1428  Function.Locals.push_back(Decl);
1429  }
1430 
1431  uint32_t BodySize = FunctionEnd - Ctx.Ptr;
1432  Function.Body = ArrayRef<uint8_t>(Ctx.Ptr, BodySize);
1433  // This will be set later when reading in the linking metadata section.
1434  Function.Comdat = UINT32_MAX;
1435  Ctx.Ptr += BodySize;
1436  assert(Ctx.Ptr == FunctionEnd);
1437  }
1438  if (Ctx.Ptr != Ctx.End)
1439  return make_error<GenericBinaryError>("code section ended prematurely",
1441  return Error::success();
1442 }
1443 
1444 Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
1445  uint32_t Count = readVaruint32(Ctx);
1446  ElemSegments.reserve(Count);
1447  while (Count--) {
1448  wasm::WasmElemSegment Segment;
1449  Segment.Flags = readVaruint32(Ctx);
1450 
1454  if (Segment.Flags & ~SupportedFlags)
1455  return make_error<GenericBinaryError>(
1456  "Unsupported flags for element segment", object_error::parse_failed);
1457 
1459  Segment.TableNumber = readVaruint32(Ctx);
1460  else
1461  Segment.TableNumber = 0;
1462  if (!isValidTableNumber(Segment.TableNumber))
1463  return make_error<GenericBinaryError>("invalid TableNumber",
1465 
1466  if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_IS_PASSIVE) {
1467  Segment.Offset.Extended = false;
1469  Segment.Offset.Inst.Value.Int32 = 0;
1470  } else {
1471  if (Error Err = readInitExpr(Segment.Offset, Ctx))
1472  return Err;
1473  }
1474 
1476  Segment.ElemKind = readUint8(Ctx);
1478  if (Segment.ElemKind != uint8_t(wasm::ValType::FUNCREF) &&
1479  Segment.ElemKind != uint8_t(wasm::ValType::EXTERNREF)) {
1480  return make_error<GenericBinaryError>("invalid reference type",
1482  }
1483  } else {
1484  if (Segment.ElemKind != 0)
1485  return make_error<GenericBinaryError>("invalid elemtype",
1487  Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF);
1488  }
1489  } else {
1490  Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF);
1491  }
1492 
1494  return make_error<GenericBinaryError>(
1495  "elem segment init expressions not yet implemented",
1497 
1498  uint32_t NumElems = readVaruint32(Ctx);
1499  while (NumElems--) {
1500  Segment.Functions.push_back(readVaruint32(Ctx));
1501  }
1502  ElemSegments.push_back(Segment);
1503  }
1504  if (Ctx.Ptr != Ctx.End)
1505  return make_error<GenericBinaryError>("elem section ended prematurely",
1507  return Error::success();
1508 }
1509 
1510 Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
1511  DataSection = Sections.size();
1512  uint32_t Count = readVaruint32(Ctx);
1513  if (DataCount && Count != *DataCount)
1514  return make_error<GenericBinaryError>(
1515  "number of data segments does not match DataCount section");
1516  DataSegments.reserve(Count);
1517  while (Count--) {
1518  WasmSegment Segment;
1519  Segment.Data.InitFlags = readVaruint32(Ctx);
1520  Segment.Data.MemoryIndex =
1521  (Segment.Data.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX)
1522  ? readVaruint32(Ctx)
1523  : 0;
1524  if ((Segment.Data.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) {
1525  if (Error Err = readInitExpr(Segment.Data.Offset, Ctx))
1526  return Err;
1527  } else {
1528  Segment.Data.Offset.Extended = false;
1529  Segment.Data.Offset.Inst.Opcode = wasm::WASM_OPCODE_I32_CONST;
1530  Segment.Data.Offset.Inst.Value.Int32 = 0;
1531  }
1532  uint32_t Size = readVaruint32(Ctx);
1533  if (Size > (size_t)(Ctx.End - Ctx.Ptr))
1534  return make_error<GenericBinaryError>("invalid segment size",
1536  Segment.Data.Content = ArrayRef<uint8_t>(Ctx.Ptr, Size);
1537  // The rest of these Data fields are set later, when reading in the linking
1538  // metadata section.
1539  Segment.Data.Alignment = 0;
1540  Segment.Data.LinkingFlags = 0;
1541  Segment.Data.Comdat = UINT32_MAX;
1542  Segment.SectionOffset = Ctx.Ptr - Ctx.Start;
1543  Ctx.Ptr += Size;
1544  DataSegments.push_back(Segment);
1545  }
1546  if (Ctx.Ptr != Ctx.End)
1547  return make_error<GenericBinaryError>("data section ended prematurely",
1549  return Error::success();
1550 }
1551 
1552 Error WasmObjectFile::parseDataCountSection(ReadContext &Ctx) {
1553  DataCount = readVaruint32(Ctx);
1554  return Error::success();
1555 }
1556 
1558  return Header;
1559 }
1560 
1561 void WasmObjectFile::moveSymbolNext(DataRefImpl &Symb) const { Symb.d.b++; }
1562 
1564  uint32_t Result = SymbolRef::SF_None;
1565  const WasmSymbol &Sym = getWasmSymbol(Symb);
1566 
1567  LLVM_DEBUG(dbgs() << "getSymbolFlags: ptr=" << &Sym << " " << Sym << "\n");
1568  if (Sym.isBindingWeak())
1569  Result |= SymbolRef::SF_Weak;
1570  if (!Sym.isBindingLocal())
1571  Result |= SymbolRef::SF_Global;
1572  if (Sym.isHidden())
1573  Result |= SymbolRef::SF_Hidden;
1574  if (!Sym.isDefined())
1575  Result |= SymbolRef::SF_Undefined;
1576  if (Sym.isTypeFunction())
1577  Result |= SymbolRef::SF_Executable;
1578  return Result;
1579 }
1580 
1582  DataRefImpl Ref;
1583  Ref.d.a = 1; // Arbitrary non-zero value so that Ref.p is non-null
1584  Ref.d.b = 0; // Symbol index
1585  return BasicSymbolRef(Ref, this);
1586 }
1587 
1589  DataRefImpl Ref;
1590  Ref.d.a = 1; // Arbitrary non-zero value so that Ref.p is non-null
1591  Ref.d.b = Symbols.size(); // Symbol index
1592  return BasicSymbolRef(Ref, this);
1593 }
1594 
1596  return Symbols[Symb.d.b];
1597 }
1598 
1599 const WasmSymbol &WasmObjectFile::getWasmSymbol(const SymbolRef &Symb) const {
1600  return getWasmSymbol(Symb.getRawDataRefImpl());
1601 }
1602 
1604  return getWasmSymbol(Symb).Info.Name;
1605 }
1606 
1608  auto &Sym = getWasmSymbol(Symb);
1609  if (Sym.Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION &&
1610  isDefinedFunctionIndex(Sym.Info.ElementIndex))
1611  return getDefinedFunction(Sym.Info.ElementIndex).CodeSectionOffset;
1612  else
1613  return getSymbolValue(Symb);
1614 }
1615 
1617  switch (Sym.Info.Kind) {
1622  return Sym.Info.ElementIndex;
1624  // The value of a data symbol is the segment offset, plus the symbol
1625  // offset within the segment.
1626  uint32_t SegmentIndex = Sym.Info.DataRef.Segment;
1627  const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data;
1628  if (Segment.Offset.Extended) {
1629  llvm_unreachable("extended init exprs not supported");
1630  } else if (Segment.Offset.Inst.Opcode == wasm::WASM_OPCODE_I32_CONST) {
1631  return Segment.Offset.Inst.Value.Int32 + Sym.Info.DataRef.Offset;
1632  } else if (Segment.Offset.Inst.Opcode == wasm::WASM_OPCODE_I64_CONST) {
1633  return Segment.Offset.Inst.Value.Int64 + Sym.Info.DataRef.Offset;
1634  } else {
1635  llvm_unreachable("unknown init expr opcode");
1636  }
1637  }
1639  return 0;
1640  }
1641  llvm_unreachable("invalid symbol type");
1642 }
1643 
1645  return getWasmSymbolValue(getWasmSymbol(Symb));
1646 }
1647 
1649  llvm_unreachable("not yet implemented");
1650  return 0;
1651 }
1652 
1654  llvm_unreachable("not yet implemented");
1655  return 0;
1656 }
1657 
1660  const WasmSymbol &Sym = getWasmSymbol(Symb);
1661 
1662  switch (Sym.Info.Kind) {
1664  return SymbolRef::ST_Function;
1666  return SymbolRef::ST_Other;
1668  return SymbolRef::ST_Data;
1670  return SymbolRef::ST_Debug;
1672  return SymbolRef::ST_Other;
1674  return SymbolRef::ST_Other;
1675  }
1676 
1677  llvm_unreachable("unknown WasmSymbol::SymbolType");
1678  return SymbolRef::ST_Other;
1679 }
1680 
1683  const WasmSymbol &Sym = getWasmSymbol(Symb);
1684  if (Sym.isUndefined())
1685  return section_end();
1686 
1687  DataRefImpl Ref;
1688  Ref.d.a = getSymbolSectionIdImpl(Sym);
1689  return section_iterator(SectionRef(Ref, this));
1690 }
1691 
1693  const WasmSymbol &Sym = getWasmSymbol(Symb);
1694  return getSymbolSectionIdImpl(Sym);
1695 }
1696 
1697 uint32_t WasmObjectFile::getSymbolSectionIdImpl(const WasmSymbol &Sym) const {
1698  switch (Sym.Info.Kind) {
1700  return CodeSection;
1702  return GlobalSection;
1704  return DataSection;
1706  return Sym.Info.ElementIndex;
1708  return TagSection;
1710  return TableSection;
1711  default:
1712  llvm_unreachable("unknown WasmSymbol::SymbolType");
1713  }
1714 }
1715 
1716 void WasmObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; }
1717 
1719  const WasmSection &S = Sections[Sec.d.a];
1720  if (S.Type == wasm::WASM_SEC_CUSTOM)
1721  return S.Name;
1722  if (S.Type > wasm::WASM_SEC_LAST_KNOWN)
1724  return wasm::sectionTypeToString(S.Type);
1725 }
1726 
1728 
1730  return Sec.d.a;
1731 }
1732 
1734  const WasmSection &S = Sections[Sec.d.a];
1735  return S.Content.size();
1736 }
1737 
1740  const WasmSection &S = Sections[Sec.d.a];
1741  // This will never fail since wasm sections can never be empty (user-sections
1742  // must have a name and non-user sections each have a defined structure).
1743  return S.Content;
1744 }
1745 
1747  return 1;
1748 }
1749 
1751  return false;
1752 }
1753 
1755  return getWasmSection(Sec).Type == wasm::WASM_SEC_CODE;
1756 }
1757 
1759  return getWasmSection(Sec).Type == wasm::WASM_SEC_DATA;
1760 }
1761 
1762 bool WasmObjectFile::isSectionBSS(DataRefImpl Sec) const { return false; }
1763 
1764 bool WasmObjectFile::isSectionVirtual(DataRefImpl Sec) const { return false; }
1765 
1767  DataRefImpl RelocRef;
1768  RelocRef.d.a = Ref.d.a;
1769  RelocRef.d.b = 0;
1770  return relocation_iterator(RelocationRef(RelocRef, this));
1771 }
1772 
1774  const WasmSection &Sec = getWasmSection(Ref);
1775  DataRefImpl RelocRef;
1776  RelocRef.d.a = Ref.d.a;
1777  RelocRef.d.b = Sec.Relocations.size();
1778  return relocation_iterator(RelocationRef(RelocRef, this));
1779 }
1780 
1782 
1785  return Rel.Offset;
1786 }
1787 
1790  if (Rel.Type == wasm::R_WASM_TYPE_INDEX_LEB)
1791  return symbol_end();
1792  DataRefImpl Sym;
1793  Sym.d.a = 1;
1794  Sym.d.b = Rel.Index;
1795  return symbol_iterator(SymbolRef(Sym, this));
1796 }
1797 
1800  return Rel.Type;
1801 }
1802 
1804  DataRefImpl Ref, SmallVectorImpl<char> &Result) const {
1806  StringRef Res = "Unknown";
1807 
1808 #define WASM_RELOC(name, value) \
1809  case wasm::name: \
1810  Res = #name; \
1811  break;
1812 
1813  switch (Rel.Type) {
1814 #include "llvm/BinaryFormat/WasmRelocs.def"
1815  }
1816 
1817 #undef WASM_RELOC
1818 
1819  Result.append(Res.begin(), Res.end());
1820 }
1821 
1823  DataRefImpl Ref;
1824  Ref.d.a = 0;
1825  return section_iterator(SectionRef(Ref, this));
1826 }
1827 
1829  DataRefImpl Ref;
1830  Ref.d.a = Sections.size();
1831  return section_iterator(SectionRef(Ref, this));
1832 }
1833 
1835  return HasMemory64 ? 8 : 4;
1836 }
1837 
1839 
1841  return HasMemory64 ? Triple::wasm64 : Triple::wasm32;
1842 }
1843 
1845  return SubtargetFeatures();
1846 }
1847 
1848 bool WasmObjectFile::isRelocatableObject() const { return HasLinkingSection; }
1849 
1850 bool WasmObjectFile::isSharedObject() const { return HasDylinkSection; }
1851 
1853  assert(Ref.d.a < Sections.size());
1854  return Sections[Ref.d.a];
1855 }
1856 
1857 const WasmSection &
1859  return getWasmSection(Section.getRawDataRefImpl());
1860 }
1861 
1862 const wasm::WasmRelocation &
1864  return getWasmRelocation(Ref.getRawDataRefImpl());
1865 }
1866 
1867 const wasm::WasmRelocation &
1869  assert(Ref.d.a < Sections.size());
1870  const WasmSection &Sec = Sections[Ref.d.a];
1871  assert(Ref.d.b < Sec.Relocations.size());
1872  return Sec.Relocations[Ref.d.b];
1873 }
1874 
1875 int WasmSectionOrderChecker::getSectionOrder(unsigned ID,
1876  StringRef CustomSectionName) {
1877  switch (ID) {
1878  case wasm::WASM_SEC_CUSTOM:
1879  return StringSwitch<unsigned>(CustomSectionName)
1880  .Case("dylink", WASM_SEC_ORDER_DYLINK)
1881  .Case("dylink.0", WASM_SEC_ORDER_DYLINK)
1882  .Case("linking", WASM_SEC_ORDER_LINKING)
1883  .StartsWith("reloc.", WASM_SEC_ORDER_RELOC)
1884  .Case("name", WASM_SEC_ORDER_NAME)
1885  .Case("producers", WASM_SEC_ORDER_PRODUCERS)
1886  .Case("target_features", WASM_SEC_ORDER_TARGET_FEATURES)
1888  case wasm::WASM_SEC_TYPE:
1889  return WASM_SEC_ORDER_TYPE;
1890  case wasm::WASM_SEC_IMPORT:
1891  return WASM_SEC_ORDER_IMPORT;
1893  return WASM_SEC_ORDER_FUNCTION;
1894  case wasm::WASM_SEC_TABLE:
1895  return WASM_SEC_ORDER_TABLE;
1896  case wasm::WASM_SEC_MEMORY:
1897  return WASM_SEC_ORDER_MEMORY;
1898  case wasm::WASM_SEC_GLOBAL:
1899  return WASM_SEC_ORDER_GLOBAL;
1900  case wasm::WASM_SEC_EXPORT:
1901  return WASM_SEC_ORDER_EXPORT;
1902  case wasm::WASM_SEC_START:
1903  return WASM_SEC_ORDER_START;
1904  case wasm::WASM_SEC_ELEM:
1905  return WASM_SEC_ORDER_ELEM;
1906  case wasm::WASM_SEC_CODE:
1907  return WASM_SEC_ORDER_CODE;
1908  case wasm::WASM_SEC_DATA:
1909  return WASM_SEC_ORDER_DATA;
1911  return WASM_SEC_ORDER_DATACOUNT;
1912  case wasm::WASM_SEC_TAG:
1913  return WASM_SEC_ORDER_TAG;
1914  default:
1915  return WASM_SEC_ORDER_NONE;
1916  }
1917 }
1918 
1919 // Represents the edges in a directed graph where any node B reachable from node
1920 // A is not allowed to appear before A in the section ordering, but may appear
1921 // afterward.
1923  [WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS] = {
1924  // WASM_SEC_ORDER_NONE
1925  {},
1926  // WASM_SEC_ORDER_TYPE
1927  {WASM_SEC_ORDER_TYPE, WASM_SEC_ORDER_IMPORT},
1928  // WASM_SEC_ORDER_IMPORT
1929  {WASM_SEC_ORDER_IMPORT, WASM_SEC_ORDER_FUNCTION},
1930  // WASM_SEC_ORDER_FUNCTION
1931  {WASM_SEC_ORDER_FUNCTION, WASM_SEC_ORDER_TABLE},
1932  // WASM_SEC_ORDER_TABLE
1933  {WASM_SEC_ORDER_TABLE, WASM_SEC_ORDER_MEMORY},
1934  // WASM_SEC_ORDER_MEMORY
1935  {WASM_SEC_ORDER_MEMORY, WASM_SEC_ORDER_TAG},
1936  // WASM_SEC_ORDER_TAG
1937  {WASM_SEC_ORDER_TAG, WASM_SEC_ORDER_GLOBAL},
1938  // WASM_SEC_ORDER_GLOBAL
1939  {WASM_SEC_ORDER_GLOBAL, WASM_SEC_ORDER_EXPORT},
1940  // WASM_SEC_ORDER_EXPORT
1941  {WASM_SEC_ORDER_EXPORT, WASM_SEC_ORDER_START},
1942  // WASM_SEC_ORDER_START
1943  {WASM_SEC_ORDER_START, WASM_SEC_ORDER_ELEM},
1944  // WASM_SEC_ORDER_ELEM
1945  {WASM_SEC_ORDER_ELEM, WASM_SEC_ORDER_DATACOUNT},
1946  // WASM_SEC_ORDER_DATACOUNT
1947  {WASM_SEC_ORDER_DATACOUNT, WASM_SEC_ORDER_CODE},
1948  // WASM_SEC_ORDER_CODE
1949  {WASM_SEC_ORDER_CODE, WASM_SEC_ORDER_DATA},
1950  // WASM_SEC_ORDER_DATA
1951  {WASM_SEC_ORDER_DATA, WASM_SEC_ORDER_LINKING},
1952 
1953  // Custom Sections
1954  // WASM_SEC_ORDER_DYLINK
1955  {WASM_SEC_ORDER_DYLINK, WASM_SEC_ORDER_TYPE},
1956  // WASM_SEC_ORDER_LINKING
1957  {WASM_SEC_ORDER_LINKING, WASM_SEC_ORDER_RELOC, WASM_SEC_ORDER_NAME},
1958  // WASM_SEC_ORDER_RELOC (can be repeated)
1959  {},
1960  // WASM_SEC_ORDER_NAME
1961  {WASM_SEC_ORDER_NAME, WASM_SEC_ORDER_PRODUCERS},
1962  // WASM_SEC_ORDER_PRODUCERS
1963  {WASM_SEC_ORDER_PRODUCERS, WASM_SEC_ORDER_TARGET_FEATURES},
1964  // WASM_SEC_ORDER_TARGET_FEATURES
1965  {WASM_SEC_ORDER_TARGET_FEATURES}};
1966 
1968  StringRef CustomSectionName) {
1969  int Order = getSectionOrder(ID, CustomSectionName);
1970  if (Order == WASM_SEC_ORDER_NONE)
1971  return true;
1972 
1973  // Disallowed predecessors we need to check for
1975 
1976  // Keep track of completed checks to avoid repeating work
1977  bool Checked[WASM_NUM_SEC_ORDERS] = {};
1978 
1979  int Curr = Order;
1980  while (true) {
1981  // Add new disallowed predecessors to work list
1982  for (size_t I = 0;; ++I) {
1983  int Next = DisallowedPredecessors[Curr][I];
1984  if (Next == WASM_SEC_ORDER_NONE)
1985  break;
1986  if (Checked[Next])
1987  continue;
1988  WorkList.push_back(Next);
1989  Checked[Next] = true;
1990  }
1991 
1992  if (WorkList.empty())
1993  break;
1994 
1995  // Consider next disallowed predecessor
1996  Curr = WorkList.pop_back_val();
1997  if (Seen[Curr])
1998  return false;
1999  }
2000 
2001  // Have not seen any disallowed predecessors
2002  Seen[Order] = true;
2003  return true;
2004 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:77
llvm::wasm::WASM_EXTERNAL_GLOBAL
@ WASM_EXTERNAL_GLOBAL
Definition: Wasm.h:277
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::WASM_FEATURE_PREFIX_DISALLOWED
@ WASM_FEATURE_PREFIX_DISALLOWED
Definition: Wasm.h:346
llvm::wasm::WASM_EXTERNAL_MEMORY
@ WASM_EXTERNAL_MEMORY
Definition: Wasm.h:276
llvm::wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER
@ WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER
Definition: Wasm.h:337
llvm::wasm::WasmTag
Definition: Wasm.h:124
llvm::wasm::WASM_OPCODE_I64_MUL
@ WASM_OPCODE_I64_MUL
Definition: Wasm.h:301
llvm::wasm::WasmDataSegment::Offset
WasmInitExpr Offset
Definition: Wasm.h:166
llvm::wasm::WASM_LIMITS_FLAG_IS_64
@ WASM_LIMITS_FLAG_IS_64
Definition: Wasm.h:327
llvm::object::WasmSectionOrderChecker::WASM_NUM_SEC_ORDERS
@ WASM_NUM_SEC_ORDERS
Definition: Wasm.h:341
llvm::StringSwitch::StartsWith
StringSwitch & StartsWith(StringLiteral S, T Value)
Definition: StringSwitch.h:83
llvm::wasm::WASM_OPCODE_REF_NULL
@ WASM_OPCODE_REF_NULL
Definition: Wasm.h:302
LLVM_DUMP_METHOD
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:494
llvm::object::Kind
Kind
Definition: COFFModuleDefinition.cpp:31
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::wasm::WasmElemSegment::Offset
WasmInitExpr Offset
Definition: Wasm.h:179
llvm::object::WasmObjectFile::WasmObjectFile
WasmObjectFile(MemoryBufferRef Object, Error &Err)
Definition: WasmObjectFile.cpp:291
llvm::wasm::WASM_SEC_GLOBAL
@ WASM_SEC_GLOBAL
Definition: Wasm.h:248
llvm::wasm::WASM_DATA_SEGMENT_IS_PASSIVE
@ WASM_DATA_SEGMENT_IS_PASSIVE
Definition: Wasm.h:331
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:1581
llvm::wasm::WASM_OPCODE_GLOBAL_GET
@ WASM_OPCODE_GLOBAL_GET
Definition: Wasm.h:288
type
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:1844
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
llvm::wasm::WASM_DYLINK_IMPORT_INFO
@ WASM_DYLINK_IMPORT_INFO
Definition: Wasm.h:370
llvm::object::WasmSection::Content
ArrayRef< uint8_t > Content
Definition: Wasm.h:111
llvm::Function
Definition: Function.h:60
StringRef.h
llvm::StringSwitch::Default
LLVM_NODISCARD R Default(T Value)
Definition: StringSwitch.h:183
llvm::wasm::WasmVersion
const uint32_t WasmVersion
Definition: Wasm.h:28
llvm::object::ObjectFile::RelocationRef
friend class RelocationRef
Definition: ObjectFile.h:286
llvm::wasm::WASM_INIT_FUNCS
@ WASM_INIT_FUNCS
Definition: Wasm.h:360
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_DATA
@ WASM_SEC_ORDER_DATA
Definition: Wasm.h:323
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:1834
llvm::wasm::WasmFeatureEntry
Definition: Wasm.h:66
llvm::object::WasmSectionOrderChecker::isValidSectionOrder
bool isValidSectionOrder(unsigned ID, StringRef CustomSectionName="")
Definition: WasmObjectFile.cpp:1967
llvm::object::ObjectFile::createWasmObjectFile
static Expected< std::unique_ptr< WasmObjectFile > > createWasmObjectFile(MemoryBufferRef Object)
Definition: WasmObjectFile.cpp:56
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
llvm::wasm::WasmObjectHeader::Version
uint32_t Version
Definition: Wasm.h:36
llvm::object::WasmSymbol::Info
const wasm::WasmSymbolInfo & Info
Definition: Wasm.h:44
llvm::dwarf::Form
Form
Definition: Dwarf.h:132
ErrorHandling.h
llvm::wasm::WasmLinkingData::SymbolTable
std::vector< WasmSymbolInfo > SymbolTable
Definition: Wasm.h:238
llvm::object::WasmSymbol::isDefined
bool isDefined() const
Definition: Wasm.h:67
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
readVaruint32
static uint32_t readVaruint32(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:146
llvm::wasm::WasmFunction::Comdat
uint32_t Comdat
Definition: Wasm.h:158
llvm::wasm::WASM_SYMBOL_BINDING_LOCAL
const unsigned WASM_SYMBOL_BINDING_LOCAL
Definition: Wasm.h:406
llvm::wasm::WASM_OPCODE_I64_CONST
@ WASM_OPCODE_I64_CONST
Definition: Wasm.h:293
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::WasmImport::Table
WasmTableType Table
Definition: Wasm.h:137
llvm::object::WasmSymbol::isTypeFunction
bool isTypeFunction() const
Definition: Wasm.h:49
llvm::wasm::WASM_OPCODE_I32_SUB
@ WASM_OPCODE_I32_SUB
Definition: Wasm.h:297
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_DYLINK
@ WASM_SEC_ORDER_DYLINK
Definition: Wasm.h:327
llvm::object::ObjectFile::getSymbolValue
Expected< uint64_t > getSymbolValue(DataRefImpl Symb) const
Definition: ObjectFile.cpp:56
llvm::wasm::WASM_SYMBOL_TABLE
@ WASM_SYMBOL_TABLE
Definition: Wasm.h:362
llvm::object::relocation_iterator
content_iterator< RelocationRef > relocation_iterator
Definition: ObjectFile.h:76
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_TARGET_FEATURES
@ WASM_SEC_ORDER_TARGET_FEATURES
Definition: Wasm.h:338
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::wasm::WASM_ELEM_SEGMENT_IS_PASSIVE
@ WASM_ELEM_SEGMENT_IS_PASSIVE
Definition: Wasm.h:336
llvm::object::WasmObjectFile::isSectionCompressed
bool isSectionCompressed(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1750
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_CODE
@ WASM_SEC_ORDER_CODE
Definition: Wasm.h:322
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_TABLE
@ WASM_SEC_ORDER_TABLE
Definition: Wasm.h:314
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::wasm::WASM_EXTERNAL_TAG
@ WASM_EXTERNAL_TAG
Definition: Wasm.h:278
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::WasmObjectFile::getSectionName
Expected< StringRef > getSectionName(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1718
llvm::wasm::WASM_SYMBOL_UNDEFINED
const unsigned WASM_SYMBOL_UNDEFINED
Definition: Wasm.h:409
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_ELEM
@ WASM_SEC_ORDER_ELEM
Definition: Wasm.h:320
llvm::wasm::WASM_FEATURE_PREFIX_REQUIRED
@ WASM_FEATURE_PREFIX_REQUIRED
Definition: Wasm.h:345
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:79
llvm::object::WasmObjectFile::getSymbolValueImpl
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1644
llvm::object::DataRefImpl::d
struct llvm::object::DataRefImpl::@332 d
llvm::object::WasmObjectFile::getRelocationTypeName
void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override
Definition: WasmObjectFile.cpp:1803
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_NAME
@ WASM_SEC_ORDER_NAME
Definition: Wasm.h:334
llvm::object::WasmObjectFile::isSectionBSS
bool isSectionBSS(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1762
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::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:654
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:1848
llvm::object::WasmObjectFile::getArch
Triple::ArchType getArch() const override
Definition: WasmObjectFile.cpp:1840
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_SEC_LAST_KNOWN
@ WASM_SEC_LAST_KNOWN
Definition: Wasm.h:256
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_NAMES_LOCAL
@ WASM_NAMES_LOCAL
Definition: Wasm.h:352
llvm::wasm::WASM_NAMES_FUNCTION
@ WASM_NAMES_FUNCTION
Definition: Wasm.h:351
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_LINKING
@ WASM_SEC_ORDER_LINKING
Definition: Wasm.h:329
llvm::wasm::WASM_OPCODE_I32_MUL
@ WASM_OPCODE_I32_MUL
Definition: Wasm.h:298
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_IMPORT
@ WASM_SEC_ORDER_IMPORT
Definition: Wasm.h:312
llvm::object::WasmObjectFile::moveSectionNext
void moveSectionNext(DataRefImpl &Sec) const override
Definition: WasmObjectFile.cpp:1716
llvm::wasm::WasmRelocation::Offset
uint64_t Offset
Definition: Wasm.h:194
llvm::wasm::WASM_SEC_CUSTOM
@ WASM_SEC_CUSTOM
Definition: Wasm.h:242
llvm::object::WasmSymbol::isHidden
bool isHidden() const
Definition: Wasm.h:89
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::ARMBuildAttrs::Section
@ Section
Legacy Tags.
Definition: ARMBuildAttributes.h:82
llvm::StringRef::substr
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:615
llvm::wasm::WASM_OPCODE_I32_CONST
@ WASM_OPCODE_I32_CONST
Definition: Wasm.h:292
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::wasm::WasmElemSegment::TableNumber
uint32_t TableNumber
Definition: Wasm.h:177
llvm::wasm::WASM_SEC_TAG
@ WASM_SEC_TAG
Definition: Wasm.h:255
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::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_TYPE_FUNCREF
@ WASM_TYPE_FUNCREF
Definition: Wasm.h:266
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_TYPE
@ WASM_SEC_ORDER_TYPE
Definition: Wasm.h:311
llvm::wasm::WasmRelocation::Addend
int64_t Addend
Definition: Wasm.h:195
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_TAG
@ WASM_SEC_ORDER_TAG
Definition: Wasm.h:316
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:1863
llvm::wasm::WASM_SEC_MEMORY
@ WASM_SEC_MEMORY
Definition: Wasm.h:247
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_SEC_DATACOUNT
@ WASM_SEC_DATACOUNT
Definition: Wasm.h:254
llvm::object::WasmObjectFile::isSectionText
bool isSectionText(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1754
llvm::object::WasmObjectFile::getSymbolAlignment
uint32_t getSymbolAlignment(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1648
llvm::SubtargetFeatures
Manages the enabling and disabling of subtarget specific features.
Definition: SubtargetFeature.h:183
llvm::object::WasmObjectFile::getSymbolSectionId
uint32_t getSymbolSectionId(SymbolRef Sym) const
Definition: WasmObjectFile.cpp:1692
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::wasm::WASM_SEC_TABLE
@ WASM_SEC_TABLE
Definition: Wasm.h:246
llvm::wasm::WasmFunction::CodeSectionOffset
uint32_t CodeSectionOffset
Definition: Wasm.h:152
llvm::wasm::WasmProducerInfo::Languages
std::vector< std::pair< std::string, std::string > > Languages
Definition: Wasm.h:61
llvm::wasm::WasmTable::SymbolName
StringRef SymbolName
Definition: Wasm.h:91
llvm::object::WasmObjectFile::getSymbolSection
Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1682
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:143
llvm::wasm::WasmDylinkInfo::MemoryAlignment
uint32_t MemoryAlignment
Definition: Wasm.h:52
llvm::wasm::WasmDataReference::Size
uint64_t Size
Definition: Wasm.h:188
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:54
llvm::AMDGPU::ElfNote::SectionName
const char SectionName[]
Definition: AMDGPUPTNote.h:24
llvm::ErrorAsOutParameter
Helper for Errors used as out-parameters.
Definition: Error.h:1097
llvm::wasm::WASM_DYLINK_MEM_INFO
@ WASM_DYLINK_MEM_INFO
Definition: Wasm.h:367
llvm::wasm::WASM_OPCODE_END
@ WASM_OPCODE_END
Definition: Wasm.h:283
llvm::wasm::WASM_SEC_START
@ WASM_SEC_START
Definition: Wasm.h:250
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:1781
llvm::wasm::WasmMetadataVersion
const uint32_t WasmMetadataVersion
Definition: Wasm.h:30
llvm::wasm::NameType::FUNCTION
@ FUNCTION
llvm::wasm::ValType
ValType
Definition: Wasm.h:424
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:1027
llvm::wasm::WasmLocalDecl::Type
uint8_t Type
Definition: Wasm.h:143
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::wasm::WASM_SEC_FUNCTION
@ WASM_SEC_FUNCTION
Definition: Wasm.h:245
llvm::wasm::WasmTable::Type
WasmTableType Type
Definition: Wasm.h:90
llvm::Comdat
Definition: Comdat.h:33
llvm::object::WasmSymbol::isUndefined
bool isUndefined() const
Definition: Wasm.h:69
llvm::wasm::WASM_SEC_EXPORT
@ WASM_SEC_EXPORT
Definition: Wasm.h:249
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:1557
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:1729
llvm::wasm::WasmObjectHeader::Magic
StringRef Magic
Definition: Wasm.h:35
readLEB128
static int64_t readLEB128(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:122
llvm::wasm::NameType::GLOBAL
@ GLOBAL
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_GLOBAL
@ WASM_SEC_ORDER_GLOBAL
Definition: Wasm.h:317
llvm::wasm::WasmInitExprMVP::Value
union llvm::wasm::WasmInitExprMVP::@172 Value
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::DenseSet< uint64_t >
llvm::wasm::WASM_SEC_IMPORT
@ WASM_SEC_IMPORT
Definition: Wasm.h:244
llvm::object::ObjectFile::SymbolRef
friend class SymbolRef
Definition: ObjectFile.h:246
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
type
AMD64 Optimization Manual has some nice information about optimizing integer multiplication by a constant How much of it applies to Intel s X86 implementation There are definite trade offs to xmm0 cvttss2siq rdx jb L3 subss xmm0 rax cvttss2siq rdx xorq rdx rax ret instead of xmm1 cvttss2siq rcx movaps xmm2 subss xmm2 cvttss2siq rax rdx xorq rax ucomiss xmm0 cmovb rax ret Seems like the jb branch has high likelihood of being taken It would have saved a few instructions It s not possible to reference and DH registers in an instruction requiring REX prefix divb and mulb both produce results in AH If isel emits a CopyFromReg which gets turned into a movb and that can be allocated a r8b r15b To get around isel emits a CopyFromReg from AX and then right shift it down by and truncate it It s not pretty but it works We need some register allocation magic to make the hack go which would often require a callee saved register Callees usually need to keep this value live for most of their body so it doesn t add a significant burden on them We currently implement this in however this is suboptimal because it means that it would be quite awkward to implement the optimization for callers A better implementation would be to relax the LLVM IR rules for sret arguments to allow a function with an sret argument to have a non void return type
Definition: README-X86-64.txt:70
llvm::Twine::utohexstr
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:408
llvm::object::WasmSymbol::isBindingWeak
bool isBindingWeak() const
Definition: Wasm.h:73
llvm::StringRef::empty
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_PRODUCERS
@ WASM_SEC_ORDER_PRODUCERS
Definition: Wasm.h:336
Index
uint32_t Index
Definition: ELFObjHandler.cpp:82
uint64_t
llvm::wasm::WASM_FEATURE_PREFIX_USED
@ WASM_FEATURE_PREFIX_USED
Definition: Wasm.h:344
llvm::object::WasmObjectFile::getSymbolType
Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1659
llvm::object::symbol_iterator
Definition: ObjectFile.h:207
llvm::StringRef::end
iterator end() const
Definition: StringRef.h:130
llvm::wasm::WasmElemSegment::Functions
std::vector< uint32_t > Functions
Definition: Wasm.h:180
llvm::object::SymbolRef::ST_Function
@ ST_Function
Definition: ObjectFile.h:177
llvm::wasm::ValType::EXTERNREF
@ EXTERNREF
llvm::wasm::WasmExport::Name
StringRef Name
Definition: Wasm.h:72
llvm::object::WasmObjectFile::section_begin
section_iterator section_begin() const override
Definition: WasmObjectFile.cpp:1822
llvm::wasm::WASM_SYMBOL_EXPLICIT_NAME
const unsigned WASM_SYMBOL_EXPLICIT_NAME
Definition: Wasm.h:411
llvm::wasm::WASM_SEC_DATA
@ WASM_SEC_DATA
Definition: Wasm.h:253
LEB128.h
llvm::wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS
@ WASM_ELEM_SEGMENT_HAS_INIT_EXPRS
Definition: Wasm.h:338
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::object::WasmSectionOrderChecker::WASM_SEC_ORDER_NONE
@ WASM_SEC_ORDER_NONE
Definition: Wasm.h:308
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:1563
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::object::BasicSymbolRef::SF_Undefined
@ SF_Undefined
Definition: SymbolicFile.h:110
llvm::wasm::WasmSignature::Returns
SmallVector< ValType, 1 > Returns
Definition: Wasm.h:435
llvm::wasm::WasmDylinkInfo::TableSize
uint32_t TableSize
Definition: Wasm.h:53
llvm::wasm::WasmImport
Definition: Wasm.h:130
ArrayRef.h
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_RELOC
@ WASM_SEC_ORDER_RELOC
Definition: Wasm.h:331
llvm::wasm::WASM_SYMBOL_TYPE_TAG
@ WASM_SYMBOL_TYPE_TAG
Definition: Wasm.h:387
TemplateParamKind::Type
@ Type
llvm::wasm::WASM_TYPE_FUNC
@ WASM_TYPE_FUNC
Definition: Wasm.h:268
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:1727
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::content_iterator
Definition: SymbolicFile.h:69
llvm::wasm::WASM_OPCODE_F32_CONST
@ WASM_OPCODE_F32_CONST
Definition: Wasm.h:294
llvm::wasm::WASM_NAMES_DATA_SEGMENT
@ WASM_NAMES_DATA_SEGMENT
Definition: Wasm.h:354
llvm::object::WasmObjectFile::getWasmSymbolValue
uint64_t getWasmSymbolValue(const WasmSymbol &Sym) const
Definition: WasmObjectFile.cpp:1616
llvm::object::WasmObjectFile::isSharedObject
bool isSharedObject() const
Definition: WasmObjectFile.cpp:1850
llvm::wasm::WasmInitExprMVP::Global
uint32_t Global
Definition: Wasm.h:101
llvm::StringRef::bytes_begin
const unsigned char * bytes_begin() const
Definition: StringRef.h:132
llvm::ARM::WinEH::ReturnType
ReturnType
Definition: ARMWinEH.h:25
llvm::object::WasmObjectFile::getSymbolName
Expected< StringRef > getSymbolName(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1603
Triple.h
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::wasm::WASM_NAMES_GLOBAL
@ WASM_NAMES_GLOBAL
Definition: Wasm.h:353
llvm::ArrayRef< uint8_t >
llvm::object::section_iterator
content_iterator< SectionRef > section_iterator
Definition: ObjectFile.h:47
llvm::wasm::WasmDylinkInfo::ExportInfo
std::vector< WasmDylinkExportInfo > ExportInfo
Definition: Wasm.h:57
readVarint64
static int64_t readVarint64(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:153
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::object::ObjectFile
This class is the base class for all object file types.
Definition: ObjectFile.h:228
llvm::object::Binary
Definition: Binary.h:32
llvm::object::WasmObjectFile::getSectionContents
Expected< ArrayRef< uint8_t > > getSectionContents(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1739
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_DATACOUNT
@ WASM_SEC_ORDER_DATACOUNT
Definition: Wasm.h:321
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_SEC_ELEM
@ WASM_SEC_ELEM
Definition: Wasm.h:251
llvm::wasm::WASM_SYMBOL_BINDING_MASK
const unsigned WASM_SYMBOL_BINDING_MASK
Definition: Wasm.h:401
llvm::wasm::WASM_SEGMENT_INFO
@ WASM_SEGMENT_INFO
Definition: Wasm.h:359
llvm::wasm::WasmSymbolType
WasmSymbolType
Definition: Wasm.h:382
llvm::wasm::WASM_OPCODE_I64_SUB
@ WASM_OPCODE_I64_SUB
Definition: Wasm.h:300
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_EXTERNAL_TABLE
@ WASM_EXTERNAL_TABLE
Definition: Wasm.h:275
llvm::object::WasmObjectFile::isSectionVirtual
bool isSectionVirtual(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1764
llvm::wasm::WasmTableType::Limits
WasmLimits Limits
Definition: Wasm.h:85
llvm::wasm::WasmSymbolInfo
Definition: Wasm.h:203
llvm::SmallSet::insert
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:182
llvm::wasm::WasmDylinkInfo::Needed
std::vector< StringRef > Needed
Definition: Wasm.h:55
llvm::wasm::WasmImport::Global
WasmGlobalType Global
Definition: Wasm.h:136
llvm::wasm::WasmGlobalType::Type
uint8_t Type
Definition: Wasm.h:113
llvm::object::object_error::invalid_section_index
@ invalid_section_index
llvm::Init
Definition: Record.h:281
llvm::wasm::WASM_LIMITS_FLAG_HAS_MAX
@ WASM_LIMITS_FLAG_HAS_MAX
Definition: Wasm.h:325
readSection
static Error readSection(WasmSection &Section, WasmObjectFile::ReadContext &Ctx, WasmSectionOrderChecker &Checker)
Definition: WasmObjectFile.cpp:255
llvm::wasm::WasmSymbolInfo::DataRef
WasmDataReference DataRef
Definition: Wasm.h:218
llvm::object::WasmObjectFile::isSectionData
bool isSectionData(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1758
llvm::object::WasmObjectFile::getSectionSize
uint64_t getSectionSize(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1733
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:1858
StringSet.h
llvm::StringRef::size
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::object::WasmObjectFile::ReadContext
Definition: Wasm.h:210
llvm::object::WasmObjectFile::getSectionAlignment
uint64_t getSectionAlignment(DataRefImpl Sec) const override
Definition: WasmObjectFile.cpp:1746
llvm::wasm::WasmDataReference::Segment
uint32_t Segment
Definition: Wasm.h:186
llvm::wasm::WASM_COMDAT_DATA
@ WASM_COMDAT_DATA
Definition: Wasm.h:375
llvm::object::WasmObjectFile::moveSymbolNext
void moveSymbolNext(DataRefImpl &Symb) const override
Definition: WasmObjectFile.cpp:1561
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
readFloat32
static int32_t readFloat32(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:84
llvm::wasm::WASM_COMDAT_FUNCTION
@ WASM_COMDAT_FUNCTION
Definition: Wasm.h:376
llvm::wasm::WASM_DYLINK_EXPORT_INFO
@ WASM_DYLINK_EXPORT_INFO
Definition: Wasm.h:369
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:1788
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_CODE
@ WASM_SEC_CODE
Definition: Wasm.h:252
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:1595
llvm::wasm::WasmInitFunc
Definition: Wasm.h:198
llvm::wasm::WasmSymbolInfo::Flags
uint32_t Flags
Definition: Wasm.h:206
llvm::wasm::WasmLocalDecl::Count
uint32_t Count
Definition: Wasm.h:144
readOpcode
static uint8_t readOpcode(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:161
llvm::wasm::WASM_EXTERNAL_FUNCTION
@ WASM_EXTERNAL_FUNCTION
Definition: Wasm.h:274
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:1828
llvm::wasm::WasmDataSegment
Definition: Wasm.h:161
llvm::object::WasmObjectFile::getSymbolAddress
Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override
Definition: WasmObjectFile.cpp:1607
llvm::object::WasmObjectFile::getRelocationOffset
uint64_t getRelocationOffset(DataRefImpl Rel) const override
Definition: WasmObjectFile.cpp:1783
llvm::object::WasmObjectFile::symbol_end
basic_symbol_iterator symbol_end() const override
Definition: WasmObjectFile.cpp:1588
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:1766
llvm::wasm::WasmLinkingData::Version
uint32_t Version
Definition: Wasm.h:235
Wasm.h
llvm::object::SymbolRef::ST_Other
@ ST_Other
Definition: ObjectFile.h:173
llvm::wasm::WasmTable
Definition: Wasm.h:88
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_MEMORY
@ WASM_SEC_ORDER_MEMORY
Definition: Wasm.h:315
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::wasm::WASM_COMDAT_SECTION
@ WASM_COMDAT_SECTION
Definition: Wasm.h:378
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:1653
llvm::wasm::WasmElemSegment
Definition: Wasm.h:175
llvm::object::BasicSymbolRef::SF_Global
@ SF_Global
Definition: SymbolicFile.h:111
llvm::object::BasicSymbolRef::SF_Hidden
@ SF_Hidden
Definition: SymbolicFile.h:120
llvm::to_string
std::string to_string(const T &Value)
Definition: ScopedPrinter.h: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::pdb::PDB_DataKind::Global
@ Global
llvm::SmallVectorImpl< char >
llvm::wasm::WasmFeatureEntry::Name
std::string Name
Definition: Wasm.h:68
llvm::wasm::WASM_TYPE_EXTERNREF
@ WASM_TYPE_EXTERNREF
Definition: Wasm.h:267
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
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:1798
llvm::wasm::WasmInitExprMVP::Opcode
uint8_t Opcode
Definition: Wasm.h:95
llvm::wasm::WASM_SEC_TYPE
@ WASM_SEC_TYPE
Definition: Wasm.h:243
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_EXPORT
@ WASM_SEC_ORDER_EXPORT
Definition: Wasm.h:318
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
llvm::wasm::WASM_OPCODE_F64_CONST
@ WASM_OPCODE_F64_CONST
Definition: Wasm.h:295
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:1773
llvm::SmallVectorImpl::reserve
void reserve(size_type N)
Definition: SmallVector.h:644
llvm::wasm::WasmTableType
Definition: Wasm.h:83
Endian.h
llvm::StringRef::begin
iterator begin() const
Definition: StringRef.h:128
llvm::Triple::wasm64
@ wasm64
Definition: Triple.h:104
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_FUNCTION
@ WASM_SEC_ORDER_FUNCTION
Definition: Wasm.h:313
llvm::wasm::WasmDylinkInfo::TableAlignment
uint32_t TableAlignment
Definition: Wasm.h:54
llvm::wasm::WasmInitExprMVP::Float32
uint32_t Float32
Definition: Wasm.h:99
llvm::wasm::WASM_COMDAT_INFO
@ WASM_COMDAT_INFO
Definition: Wasm.h:361
llvm::wasm::WasmInitExpr::Extended
uint8_t Extended
Definition: Wasm.h:106
llvm::wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX
@ WASM_DATA_SEGMENT_HAS_MEMINDEX
Definition: Wasm.h:332
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:1838
llvm::wasm::WasmExport
Definition: Wasm.h:71
llvm::wasm::WASM_OPCODE_I64_ADD
@ WASM_OPCODE_I64_ADD
Definition: Wasm.h:299
llvm::wasm::WASM_SYMBOL_TYPE_DATA
@ WASM_SYMBOL_TYPE_DATA
Definition: Wasm.h:384
llvm::wasm::WasmSignature
Definition: Wasm.h:434
llvm::wasm::WASM_OPCODE_I32_ADD
@ WASM_OPCODE_I32_ADD
Definition: Wasm.h:296
llvm::object::WasmSectionOrderChecker::WASM_SEC_ORDER_START
@ WASM_SEC_ORDER_START
Definition: Wasm.h:319
readLimits
static wasm::WasmLimits readLimits(WasmObjectFile::ReadContext &Ctx)
Definition: WasmObjectFile.cpp:239
llvm::object::WasmSymbol::isBindingLocal
bool isBindingLocal() const
Definition: Wasm.h:81
SmallSet.h
llvm::wasm::WASM_DYLINK_NEEDED
@ WASM_DYLINK_NEEDED
Definition: Wasm.h:368
ScopedPrinter.h