LLVM: lib/Object/WasmObjectFile.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

28#include

29#include

30#include

31

32#define DEBUG_TYPE "wasm-object"

33

34using namespace llvm;

35using namespace object;

36

45 }

47 Out << ", hidden";

48 } else {

49 Out << ", default";

50 }

51 Out << "]";

58 }

59}

60

61#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)

63#endif

64

68 auto ObjectFile = std::make_unique(Buffer, Err);

69 if (Err)

70 return std::move(Err);

71

73}

74

75#define VARINT7_MAX ((1 << 7) - 1)

76#define VARINT7_MIN (-(1 << 7))

77#define VARUINT7_MAX (1 << 7)

78#define VARUINT1_MAX (1)

79

81 if (Ctx.Ptr == Ctx.End)

83 return *Ctx.Ptr++;

84}

85

87 if (Ctx.Ptr + 4 > Ctx.End)

90 Ctx.Ptr += 4;

91 return Result;

92}

93

95 if (Ctx.Ptr + 4 > Ctx.End)

97 int32_t Result = 0;

98 memcpy(&Result, Ctx.Ptr, sizeof(Result));

99 Ctx.Ptr += sizeof(Result);

100 return Result;

101}

102

104 if (Ctx.Ptr + 8 > Ctx.End)

106 int64_t Result = 0;

107 memcpy(&Result, Ctx.Ptr, sizeof(Result));

108 Ctx.Ptr += sizeof(Result);

109 return Result;

110}

111

113 unsigned Count;

114 const char *Error = nullptr;

118 Ctx.Ptr += Count;

119 return Result;

120}

121

124 if (Ctx.Ptr + StringLen > Ctx.End)

127 StringRef(reinterpret_cast<const char *>(Ctx.Ptr), StringLen);

128 Ctx.Ptr += StringLen;

129 return Return;

130}

131

133 unsigned Count;

134 const char *Error = nullptr;

138 Ctx.Ptr += Count;

139 return Result;

140}

141

146 return Result;

147}

148

151 if (Result > INT32_MAX || Result < INT32_MIN)

153 return Result;

154}

155

158 if (Result > UINT32_MAX)

160 return Result;

161}

162

165}

166

169}

170

173}

174

177

178

179 switch (Code) {

189 }

192 }

194}

195

198 auto Start = Ctx.Ptr;

199

205 break;

208 break;

211 break;

214 break;

217 break;

220 break;

221 }

222 default:

224 }

225

230 }

231

233 Ctx.Ptr = Start;

234 while (true) {

236 switch (Opcode) {

243 break;

246 break;

249 break;

256 break;

258 break;

259

260

261

267 break;

271 break;

273 break;

277 default:

278 return make_error(

279 Twine("invalid opcode in init_expr: ") + Twine(unsigned(Opcode)),

281 }

282 }

283 }

284

286}

287

294 return Result;

295}

296

300 TableType.ElemType = ElemType;

302 return TableType;

303}

304

308 LLVM_DEBUG(dbgs() << "readSection type=" << Section.Type << "\n");

309

310

313 Section.HeaderSecSizeEncodingLen = Ctx.Ptr - PreSizePtr;

314 Section.Offset = Ctx.Ptr - Ctx.Start;

315 if (Size == 0)

316 return make_error("zero length section",

319 return make_error("section too large",

324 SectionCtx.Ptr = Ctx.Ptr;

326

327 Section.Name = readString(SectionCtx);

328

329 uint32_t SectionNameSize = SectionCtx.Ptr - SectionCtx.Start;

330 Ctx.Ptr += SectionNameSize;

331 Size -= SectionNameSize;

332 }

333

334 if (!Checker.isValidSectionOrder(Section.Type, Section.Name)) {

335 return make_error("out of order section type: " +

338 }

339

343}

344

350 Err = make_error("invalid magic number",

352 return;

353 }

354

359

360 if (Ctx.Ptr + 4 > Ctx.End) {

361 Err = make_error("missing version number",

363 return;

364 }

365

368 Err = make_error("invalid version number: " +

371 return;

372 }

373

375 while (Ctx.Ptr < Ctx.End) {

377 if ((Err = readSection(Sec, Ctx, Checker)))

378 return;

379 if ((Err = parseSection(Sec)))

380 return;

381

382 Sections.push_back(Sec);

383 }

384}

385

387 ReadContext Ctx;

389 Ctx.End = Ctx.Start + Sec.Content.size();

390 Ctx.Ptr = Ctx.Start;

391 switch (Sec.Type) {

393 return parseCustomSection(Sec, Ctx);

395 return parseTypeSection(Ctx);

397 return parseImportSection(Ctx);

399 return parseFunctionSection(Ctx);

401 return parseTableSection(Ctx);

403 return parseMemorySection(Ctx);

405 return parseTagSection(Ctx);

407 return parseGlobalSection(Ctx);

409 return parseExportSection(Ctx);

411 return parseStartSection(Ctx);

413 return parseElemSection(Ctx);

415 return parseCodeSection(Ctx);

417 return parseDataSection(Ctx);

419 return parseDataCountSection(Ctx);

420 default:

421 return make_error(

423 }

424}

425

426Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) {

427

428

429 HasDylinkSection = true;

435 while (Count--) {

437 }

438

439 if (Ctx.Ptr != Ctx.End)

440 return make_error("dylink section ended prematurely",

443}

444

445Error WasmObjectFile::parseDylink0Section(ReadContext &Ctx) {

446

447

448 HasDylinkSection = true;

449

450 const uint8_t *OrigEnd = Ctx.End;

451 while (Ctx.Ptr < OrigEnd) {

452 Ctx.End = OrigEnd;

456 << "\n");

457 Ctx.End = Ctx.Ptr + Size;

459 switch (Type) {

465 break;

468 while (Count--) {

470 }

471 break;

474 while (Count--) {

476 }

477 break;

478 }

481 while (Count--) {

484 }

485 break;

486 }

487 default:

488 LLVM_DEBUG(dbgs() << "unknown dylink.0 sub-section: " << Type << "\n");

489 Ctx.Ptr += Size;

490 break;

491 }

492 if (Ctx.Ptr != Ctx.End) {

493 return make_error(

495 }

496 }

497

498 if (Ctx.Ptr != Ctx.End)

499 return make_error("dylink.0 section ended prematurely",

502}

503

504Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {

508

509

510

511 bool PopulateSymbolTable = !HasLinkingSection && !HasDylinkSection;

512

513

514

515 if (PopulateSymbolTable)

516 Symbols.clear();

517

518 while (Ctx.Ptr < Ctx.End) {

521 const uint8_t *SubSectionEnd = Ctx.Ptr + Size;

522

523 switch (Type) {

528 while (Count--) {

534 0,

535 std::nullopt,

536 std::nullopt,

537 std::nullopt,

538 { Index}};

543 if (!SeenFunctions.insert(Index).second)

544 return make_error(

546 if (!isValidFunctionIndex(Index) || Name.empty())

547 return make_error("invalid function name entry",

549

550 if (isDefinedFunctionIndex(Index)) {

552 F.DebugName = Name;

553 Signature = &Signatures[F.SigIndex];

554 if (F.ExportName) {

555 Info.ExportName = F.ExportName;

557 } else {

559 }

560 } else {

562 }

564 if (!SeenGlobals.insert(Index).second)

565 return make_error("global named more than once",

567 if (!isValidGlobalIndex(Index) || Name.empty())

568 return make_error("invalid global name entry",

572 if (isDefinedGlobalIndex(Index)) {

573 GlobalType = &getDefinedGlobal(Index).Type;

574 } else {

576 }

577 } else {

578 if (!SeenSegments.insert(Index).second)

579 return make_error(

581 if (Index > DataSegments.size())

582 return make_error("invalid data segment name entry",

587 assert(Index < DataSegments.size());

589 Index, 0, DataSegments[Index].Data.Content.size()};

590 }

592 if (PopulateSymbolTable)

593 Symbols.emplace_back(Info, GlobalType, TableType, Signature);

594 }

595 break;

596 }

597

599 default:

600 Ctx.Ptr += Size;

601 break;

602 }

603 if (Ctx.Ptr != SubSectionEnd)

604 return make_error(

606 }

607

608 if (Ctx.Ptr != Ctx.End)

609 return make_error("name section ended prematurely",

612}

613

614Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {

615 HasLinkingSection = true;

616

619 return make_error(

620 "unexpected metadata version: " + Twine(LinkingData.Version) +

623 }

624

625 const uint8_t *OrigEnd = Ctx.End;

626 while (Ctx.Ptr < OrigEnd) {

627 Ctx.End = OrigEnd;

631 << "\n");

632 Ctx.End = Ctx.Ptr + Size;

633 switch (Type) {

635 if (Error Err = parseLinkingSectionSymtab(Ctx))

636 return Err;

637 break;

640 if (Count > DataSegments.size())

641 return make_error("too many segment names",

644 DataSegments[I].Data.Name = readString(Ctx);

646 DataSegments[I].Data.LinkingFlags = readVaruint32(Ctx);

647 }

648 break;

649 }

657 if (!isValidFunctionSymbol(Init.Symbol))

658 return make_error("invalid function symbol: " +

662 }

663 break;

664 }

666 if (Error Err = parseLinkingSectionComdat(Ctx))

667 return Err;

668 break;

669 default:

670 Ctx.Ptr += Size;

671 break;

672 }

673 if (Ctx.Ptr != Ctx.End)

674 return make_error(

676 }

677 if (Ctx.Ptr != OrigEnd)

678 return make_error("linking section ended prematurely",

681}

682

683Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {

685

686

687 Symbols.clear();

688 Symbols.reserve(Count);

690

691 std::vector<wasm::WasmImport *> ImportedGlobals;

692 std::vector<wasm::WasmImport *> ImportedFunctions;

693 std::vector<wasm::WasmImport *> ImportedTags;

694 std::vector<wasm::WasmImport *> ImportedTables;

695 ImportedGlobals.reserve(Imports.size());

696 ImportedFunctions.reserve(Imports.size());

697 ImportedTags.reserve(Imports.size());

698 ImportedTables.reserve(Imports.size());

699 for (auto &I : Imports) {

701 ImportedFunctions.emplace_back(&I);

703 ImportedGlobals.emplace_back(&I);

705 ImportedTags.emplace_back(&I);

707 ImportedTables.emplace_back(&I);

708 }

709

710 while (Count--) {

715

719

720 switch (Info.Kind) {

723 if (!isValidFunctionIndex(Info.ElementIndex) ||

724 IsDefined != isDefinedFunctionIndex(Info.ElementIndex))

725 return make_error("invalid function symbol index",

727 if (IsDefined) {

729 unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions;

731 Signature = &Signatures[Function.SigIndex];

734 } else {

739 } else {

741 }

742 Signature = &Signatures[Import.SigIndex];

744 }

745 break;

746

749 if (!isValidGlobalIndex(Info.ElementIndex) ||

750 IsDefined != isDefinedGlobalIndex(Info.ElementIndex))

751 return make_error("invalid global symbol index",

755 return make_error("undefined weak global symbol",

757 if (IsDefined) {

759 unsigned GlobalIndex = Info.ElementIndex - NumImportedGlobals;

761 GlobalType = &Global.Type;

762 if (Global.SymbolName.empty())

764 } else {

769 } else {

771 }

772 GlobalType = &Import.Global;

774 }

775 break;

776

779 if (!isValidTableNumber(Info.ElementIndex) ||

780 IsDefined != isDefinedTableNumber(Info.ElementIndex))

781 return make_error("invalid table symbol index",

785 return make_error("undefined weak table symbol",

787 if (IsDefined) {

789 unsigned TableNumber = Info.ElementIndex - NumImportedTables;

791 TableType = &Table.Type;

794 } else {

799 } else {

801 }

802 TableType = &Import.Table;

804 }

805 break;

806

809 if (IsDefined) {

814 if (static_cast<size_t>(Index) >= DataSegments.size())

815 return make_error(

816 "invalid data segment index: " + Twine(Index),

818 size_t SegmentSize = DataSegments[Index].Data.Content.size();

819 if (Offset > SegmentSize)

820 return make_error(

821 "invalid data symbol offset: `" + Info.Name +

823 " segment size: " + Twine(SegmentSize) + ")",

825 }

827 }

828 break;

829

833 return make_error(

834 "section symbols must have local binding",

837

840 break;

841 }

842

845 if (!isValidTagIndex(Info.ElementIndex) ||

846 IsDefined != isDefinedTagIndex(Info.ElementIndex))

847 return make_error("invalid tag symbol index",

851 return make_error("undefined weak global symbol",

853 if (IsDefined) {

855 unsigned TagIndex = Info.ElementIndex - NumImportedTags;

857 Signature = &Signatures[Tag.SigIndex];

858 if (Tag.SymbolName.empty())

859 Tag.SymbolName = Info.Name;

860

861 } else {

866 } else {

868 }

869 Signature = &Signatures[Import.SigIndex];

871 }

872 break;

873 }

874

875 default:

876 return make_error("invalid symbol type: " +

879 }

880

883 !SymbolNames.insert(Info.Name).second)

884 return make_error("duplicate symbol name " +

887 Symbols.emplace_back(Info, GlobalType, TableType, Signature);

888 LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");

889 }

890

892}

893

894Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {

897 for (unsigned ComdatIndex = 0; ComdatIndex < ComdatCount; ++ComdatIndex) {

900 return make_error("bad/duplicate COMDAT name " +

905 if (Flags != 0)

906 return make_error("unsupported COMDAT flags",

908

910 while (EntryCount--) {

913 switch (Kind) {

914 default:

915 return make_error("invalid COMDAT entry type",

918 if (Index >= DataSegments.size())

919 return make_error(

921 if (DataSegments[Index].Data.Comdat != UINT32_MAX)

922 return make_error("data segment in two COMDATs",

924 DataSegments[Index].Data.Comdat = ComdatIndex;

925 break;

927 if (!isDefinedFunctionIndex(Index))

928 return make_error(

930 if (getDefinedFunction(Index).Comdat != UINT32_MAX)

931 return make_error("function in two COMDATs",

933 getDefinedFunction(Index).Comdat = ComdatIndex;

934 break;

936 if (Index >= Sections.size())

937 return make_error(

940 return make_error(

942 Sections[Index].Comdat = ComdatIndex;

943 break;

944 }

945 }

946 }

948}

949

950Error WasmObjectFile::parseProducersSection(ReadContext &Ctx) {

953 for (size_t I = 0; I < Fields; ++I) {

955 if (!FieldsSeen.insert(FieldName).second)

956 return make_error(

957 "producers section does not have unique fields",

959 std::vector<std::pair<std::string, std::string>> *ProducerVec = nullptr;

960 if (FieldName == "language") {

961 ProducerVec = &ProducerInfo.Languages;

962 } else if (FieldName == "processed-by") {

963 ProducerVec = &ProducerInfo.Tools;

964 } else if (FieldName == "sdk") {

965 ProducerVec = &ProducerInfo.SDKs;

966 } else {

967 return make_error(

968 "producers section field is not named one of language, processed-by, "

969 "or sdk",

971 }

974 for (size_t J = 0; J < ValueCount; ++J) {

977 if (!ProducersSeen.insert(Name).second) {

978 return make_error(

979 "producers section contains repeated producer",

981 }

982 ProducerVec->emplace_back(std::string(Name), std::string(Version));

983 }

984 }

985 if (Ctx.Ptr != Ctx.End)

986 return make_error("producers section ended prematurely",

989}

990

991Error WasmObjectFile::parseTargetFeaturesSection(ReadContext &Ctx) {

997 switch (Feature.Prefix) {

1000 break;

1001 default:

1002 return make_error("unknown feature policy prefix",

1004 }

1006 if (!FeaturesSeen.insert(Feature.Name).second)

1007 return make_error(

1008 "target features section contains repeated feature \"" +

1009 Feature.Name + "\"",

1011 TargetFeatures.push_back(Feature);

1012 }

1013 if (Ctx.Ptr != Ctx.End)

1014 return make_error(

1015 "target features section ended prematurely",

1018}

1019

1020Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {

1022 if (SectionIndex >= Sections.size())

1023 return make_error("invalid section index",

1028 uint32_t PreviousOffset = 0;

1029 while (RelocCount--) {

1032 Reloc.Type = type;

1034 if (Reloc.Offset < PreviousOffset)

1035 return make_error("relocations not in offset order",

1037

1038 auto badReloc = [&](StringRef msg) {

1039 return make_error(

1040 msg + ": " + Twine(Symbols[Reloc.Index].Info.Name),

1042 };

1043

1044 PreviousOffset = Reloc.Offset;

1046 switch (type) {

1047 case wasm::R_WASM_FUNCTION_INDEX_LEB:

1048 case wasm::R_WASM_FUNCTION_INDEX_I32:

1049 case wasm::R_WASM_TABLE_INDEX_SLEB:

1050 case wasm::R_WASM_TABLE_INDEX_SLEB64:

1051 case wasm::R_WASM_TABLE_INDEX_I32:

1052 case wasm::R_WASM_TABLE_INDEX_I64:

1053 case wasm::R_WASM_TABLE_INDEX_REL_SLEB:

1054 case wasm::R_WASM_TABLE_INDEX_REL_SLEB64:

1055 if (!isValidFunctionSymbol(Reloc.Index))

1056 return badReloc("invalid function relocation");

1057 break;

1058 case wasm::R_WASM_TABLE_NUMBER_LEB:

1059 if (!isValidTableSymbol(Reloc.Index))

1060 return badReloc("invalid table relocation");

1061 break;

1062 case wasm::R_WASM_TYPE_INDEX_LEB:

1063 if (Reloc.Index >= Signatures.size())

1064 return badReloc("invalid relocation type index");

1065 break;

1066 case wasm::R_WASM_GLOBAL_INDEX_LEB:

1067

1068

1069 if (!isValidGlobalSymbol(Reloc.Index) &&

1070 !isValidDataSymbol(Reloc.Index) &&

1071 !isValidFunctionSymbol(Reloc.Index))

1072 return badReloc("invalid global relocation");

1073 break;

1074 case wasm::R_WASM_GLOBAL_INDEX_I32:

1075 if (!isValidGlobalSymbol(Reloc.Index))

1076 return badReloc("invalid global relocation");

1077 break;

1078 case wasm::R_WASM_TAG_INDEX_LEB:

1079 if (!isValidTagSymbol(Reloc.Index))

1080 return badReloc("invalid tag relocation");

1081 break;

1082 case wasm::R_WASM_MEMORY_ADDR_LEB:

1083 case wasm::R_WASM_MEMORY_ADDR_SLEB:

1084 case wasm::R_WASM_MEMORY_ADDR_I32:

1085 case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:

1086 case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:

1087 case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:

1088 if (!isValidDataSymbol(Reloc.Index))

1089 return badReloc("invalid data relocation");

1091 break;

1092 case wasm::R_WASM_MEMORY_ADDR_LEB64:

1093 case wasm::R_WASM_MEMORY_ADDR_SLEB64:

1094 case wasm::R_WASM_MEMORY_ADDR_I64:

1095 case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:

1096 case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64:

1097 if (!isValidDataSymbol(Reloc.Index))

1098 return badReloc("invalid data relocation");

1100 break;

1101 case wasm::R_WASM_FUNCTION_OFFSET_I32:

1102 if (!isValidFunctionSymbol(Reloc.Index))

1103 return badReloc("invalid function relocation");

1105 break;

1106 case wasm::R_WASM_FUNCTION_OFFSET_I64:

1107 if (!isValidFunctionSymbol(Reloc.Index))

1108 return badReloc("invalid function relocation");

1110 break;

1111 case wasm::R_WASM_SECTION_OFFSET_I32:

1112 if (!isValidSectionSymbol(Reloc.Index))

1113 return badReloc("invalid section relocation");

1115 break;

1116 default:

1117 return make_error("invalid relocation type: " +

1120 }

1121

1122

1123

1124

1126 if (Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LEB64 ||

1127 Reloc.Type == wasm::R_WASM_MEMORY_ADDR_SLEB64 ||

1128 Reloc.Type == wasm::R_WASM_MEMORY_ADDR_REL_SLEB64)

1130 if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I32 ||

1131 Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I32 ||

1132 Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LOCREL_I32 ||

1133 Reloc.Type == wasm::R_WASM_SECTION_OFFSET_I32 ||

1134 Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||

1135 Reloc.Type == wasm::R_WASM_FUNCTION_INDEX_I32 ||

1136 Reloc.Type == wasm::R_WASM_GLOBAL_INDEX_I32)

1138 if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I64 ||

1139 Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I64 ||

1140 Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I64)

1142 if (Reloc.Offset + Size > EndOffset)

1143 return make_error("invalid relocation offset",

1145

1146 Section.Relocations.push_back(Reloc);

1147 }

1148 if (Ctx.Ptr != Ctx.End)

1149 return make_error("reloc section ended prematurely",

1152}

1153

1154Error WasmObjectFile::parseCustomSection(WasmSection &Sec, ReadContext &Ctx) {

1155 if (Sec.Name == "dylink") {

1156 if (Error Err = parseDylinkSection(Ctx))

1157 return Err;

1158 } else if (Sec.Name == "dylink.0") {

1159 if (Error Err = parseDylink0Section(Ctx))

1160 return Err;

1161 } else if (Sec.Name == "name") {

1162 if (Error Err = parseNameSection(Ctx))

1163 return Err;

1164 } else if (Sec.Name == "linking") {

1165 if (Error Err = parseLinkingSection(Ctx))

1166 return Err;

1167 } else if (Sec.Name == "producers") {

1168 if (Error Err = parseProducersSection(Ctx))

1169 return Err;

1170 } else if (Sec.Name == "target_features") {

1171 if (Error Err = parseTargetFeaturesSection(Ctx))

1172 return Err;

1174 if (Error Err = parseRelocSection(Sec.Name, Ctx))

1175 return Err;

1176 }

1178}

1179

1180Error WasmObjectFile::parseTypeSection(ReadContext &Ctx) {

1181 auto parseFieldDef = [&]() {

1183 parseValType(Ctx, TypeCode);

1185 };

1186

1188 Signatures.reserve(Count);

1189 while (Count--) {

1193

1194

1196 if (RecSize == 0)

1197 return make_error("Rec group size cannot be 0",

1199 Signatures.reserve(Signatures.size() + RecSize);

1200 Count += RecSize;

1202 Signatures.push_back(std::move(Sig));

1203 HasUnmodeledTypes = true;

1204 continue;

1205 }

1207

1208

1209

1212 if (Supers > 0) {

1213 if (Supers != 1)

1214 return make_error(

1217 }

1219 }

1222 while (FieldCount--) {

1223 parseFieldDef();

1224 }

1226 parseFieldDef();

1227 } else {

1228 return make_error("bad form",

1230 }

1232 Signatures.push_back(std::move(Sig));

1233 HasUnmodeledTypes = true;

1234 continue;

1235 }

1236

1239 while (ParamCount--) {

1242 }

1244 while (ReturnCount--) {

1247 }

1248

1249 Signatures.push_back(std::move(Sig));

1250 }

1251 if (Ctx.Ptr != Ctx.End)

1252 return make_error("type section ended prematurely",

1255}

1256

1257Error WasmObjectFile::parseImportSection(ReadContext &Ctx) {

1259 uint32_t NumTypes = Signatures.size();

1260 Imports.reserve(Count);

1266 switch (Im.Kind) {

1268 NumImportedFunctions++;

1270 if (Im.SigIndex >= NumTypes)

1271 return make_error("invalid function type",

1273 break;

1275 NumImportedGlobals++;

1278 break;

1282 HasMemory64 = true;

1283 break;

1286 NumImportedTables++;

1292 return make_error("invalid table element type",

1294 break;

1295 }

1297 NumImportedTags++;

1298 if (readUint8(Ctx) != 0)

1299 return make_error("invalid attribute",

1302 if (Im.SigIndex >= NumTypes)

1303 return make_error("invalid tag type",

1305 break;

1306 default:

1307 return make_error("unexpected import kind",

1309 }

1310 Imports.push_back(Im);

1311 }

1312 if (Ctx.Ptr != Ctx.End)

1313 return make_error("import section ended prematurely",

1316}

1317

1318Error WasmObjectFile::parseFunctionSection(ReadContext &Ctx) {

1320 Functions.reserve(Count);

1321 uint32_t NumTypes = Signatures.size();

1322 while (Count--) {

1324 if (Type >= NumTypes)

1325 return make_error("invalid function type",

1328 F.SigIndex = Type;

1329 Functions.push_back(F);

1330 }

1331 if (Ctx.Ptr != Ctx.End)

1332 return make_error("function section ended prematurely",

1335}

1336

1337Error WasmObjectFile::parseTableSection(ReadContext &Ctx) {

1338 TableSection = Sections.size();

1340 Tables.reserve(Count);

1341 while (Count--) {

1344 T.Index = NumImportedTables + Tables.size();

1345 Tables.push_back(T);

1346 auto ElemType = Tables.back().Type.ElemType;

1351 return make_error("invalid table element type",

1353 }

1354 }

1355 if (Ctx.Ptr != Ctx.End)

1356 return make_error("table section ended prematurely",

1359}

1360

1361Error WasmObjectFile::parseMemorySection(ReadContext &Ctx) {

1363 Memories.reserve(Count);

1364 while (Count--) {

1367 HasMemory64 = true;

1368 Memories.push_back(Limits);

1369 }

1370 if (Ctx.Ptr != Ctx.End)

1371 return make_error("memory section ended prematurely",

1374}

1375

1376Error WasmObjectFile::parseTagSection(ReadContext &Ctx) {

1377 TagSection = Sections.size();

1379 Tags.reserve(Count);

1380 uint32_t NumTypes = Signatures.size();

1381 while (Count--) {

1382 if (readUint8(Ctx) != 0)

1383 return make_error("invalid attribute",

1386 if (Type >= NumTypes)

1387 return make_error("invalid tag type",

1390 Tag.Index = NumImportedTags + Tags.size();

1393 Tags.push_back(Tag);

1394 }

1395

1396 if (Ctx.Ptr != Ctx.End)

1397 return make_error("tag section ended prematurely",

1400}

1401

1402Error WasmObjectFile::parseGlobalSection(ReadContext &Ctx) {

1403 GlobalSection = Sections.size();

1404 const uint8_t *SectionStart = Ctx.Ptr;

1406 Globals.reserve(Count);

1407 while (Count--) {

1409 Global.Index = NumImportedGlobals + Globals.size();

1410 const uint8_t *GlobalStart = Ctx.Ptr;

1411 Global.Offset = static_cast<uint32_t>(GlobalStart - SectionStart);

1416 return Err;

1417 Global.Size = static_cast<uint32_t>(Ctx.Ptr - GlobalStart);

1418 Globals.push_back(Global);

1419 }

1420 if (Ctx.Ptr != Ctx.End)

1421 return make_error("global section ended prematurely",

1424}

1425

1426Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {

1428 Exports.reserve(Count);

1429 Symbols.reserve(Count);

1440 Info.Flags = 0;

1441 switch (Ex.Kind) {

1443 if (!isValidFunctionIndex(Ex.Index))

1444 return make_error("invalid function export",

1448 if (isDefinedFunctionIndex(Ex.Index)) {

1450 unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions;

1452 Signature = &Signatures[Function.SigIndex];

1453 }

1454

1455

1456

1457 break;

1458 }

1460 if (!isValidGlobalIndex(Ex.Index))

1461 return make_error("invalid global export",

1465 if (isDefinedGlobalIndex(Ex.Index)) {

1466 auto Global = getDefinedGlobal(Ex.Index);

1467 if (Global.InitExpr.Extended) {

1468 auto Inst = Global.InitExpr.Inst;

1470 Offset = Inst.Value.Int32;

1472 Offset = Inst.Value.Int64;

1473 }

1474 }

1475 }

1477 break;

1478 }

1480 if (!isValidTagIndex(Ex.Index))

1481 return make_error("invalid tag export",

1485 break;

1487 break;

1491 break;

1492 default:

1493 return make_error("unexpected export kind",

1495 }

1496 Exports.push_back(Ex);

1498 Symbols.emplace_back(Info, GlobalType, TableType, Signature);

1499 LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");

1500 }

1501 }

1502 if (Ctx.Ptr != Ctx.End)

1503 return make_error("export section ended prematurely",

1506}

1507

1508bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const {

1509 return Index < NumImportedFunctions + Functions.size();

1510}

1511

1512bool WasmObjectFile::isDefinedFunctionIndex(uint32_t Index) const {

1513 return Index >= NumImportedFunctions && isValidFunctionIndex(Index);

1514}

1515

1516bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const {

1517 return Index < NumImportedGlobals + Globals.size();

1518}

1519

1520bool WasmObjectFile::isValidTableNumber(uint32_t Index) const {

1521 return Index < NumImportedTables + Tables.size();

1522}

1523

1524bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const {

1525 return Index >= NumImportedGlobals && isValidGlobalIndex(Index);

1526}

1527

1528bool WasmObjectFile::isDefinedTableNumber(uint32_t Index) const {

1529 return Index >= NumImportedTables && isValidTableNumber(Index);

1530}

1531

1532bool WasmObjectFile::isValidTagIndex(uint32_t Index) const {

1533 return Index < NumImportedTags + Tags.size();

1534}

1535

1536bool WasmObjectFile::isDefinedTagIndex(uint32_t Index) const {

1537 return Index >= NumImportedTags && isValidTagIndex(Index);

1538}

1539

1540bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {

1541 return Index < Symbols.size() && Symbols[Index].isTypeFunction();

1542}

1543

1544bool WasmObjectFile::isValidTableSymbol(uint32_t Index) const {

1545 return Index < Symbols.size() && Symbols[Index].isTypeTable();

1546}

1547

1548bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const {

1549 return Index < Symbols.size() && Symbols[Index].isTypeGlobal();

1550}

1551

1552bool WasmObjectFile::isValidTagSymbol(uint32_t Index) const {

1553 return Index < Symbols.size() && Symbols[Index].isTypeTag();

1554}

1555

1556bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {

1557 return Index < Symbols.size() && Symbols[Index].isTypeData();

1558}

1559

1560bool WasmObjectFile::isValidSectionSymbol(uint32_t Index) const {

1561 return Index < Symbols.size() && Symbols[Index].isTypeSection();

1562}

1563

1565 assert(isDefinedFunctionIndex(Index));

1566 return Functions[Index - NumImportedFunctions];

1567}

1568

1570WasmObjectFile::getDefinedFunction(uint32_t Index) const {

1571 assert(isDefinedFunctionIndex(Index));

1572 return Functions[Index - NumImportedFunctions];

1573}

1574

1576 assert(isDefinedGlobalIndex(Index));

1577 return Globals[Index - NumImportedGlobals];

1578}

1579

1581 assert(isDefinedTagIndex(Index));

1582 return Tags[Index - NumImportedTags];

1583}

1584

1585Error WasmObjectFile::parseStartSection(ReadContext &Ctx) {

1587 if (!isValidFunctionIndex(StartFunction))

1588 return make_error("invalid start function",

1591}

1592

1593Error WasmObjectFile::parseCodeSection(ReadContext &Ctx) {

1594 CodeSection = Sections.size();

1596 if (FunctionCount != Functions.size()) {

1597 return make_error("invalid function count",

1599 }

1600

1601 for (uint32_t i = 0; i < FunctionCount; i++) {

1603 const uint8_t *FunctionStart = Ctx.Ptr;

1605 const uint8_t *FunctionEnd = Ctx.Ptr + Size;

1606

1607 Function.CodeOffset = Ctx.Ptr - FunctionStart;

1608 Function.Index = NumImportedFunctions + i;

1609 Function.CodeSectionOffset = FunctionStart - Ctx.Start;

1610 Function.Size = FunctionEnd - FunctionStart;

1611

1613 Function.Locals.reserve(NumLocalDecls);

1614 while (NumLocalDecls--) {

1618 Function.Locals.push_back(Decl);

1619 }

1620

1621 uint32_t BodySize = FunctionEnd - Ctx.Ptr;

1622

1623 if (Ctx.Ptr + BodySize > Ctx.End) {

1624 return make_error("Function extends beyond buffer",

1626 }

1628

1629 Function.Comdat = UINT32_MAX;

1630 Ctx.Ptr += BodySize;

1631 assert(Ctx.Ptr == FunctionEnd);

1632 }

1633 if (Ctx.Ptr != Ctx.End)

1634 return make_error("code section ended prematurely",

1637}

1638

1639Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {

1641 ElemSegments.reserve(Count);

1642 while (Count--) {

1645

1649 if (Segment.Flags & ~SupportedFlags)

1650 return make_error(

1652

1658 } else {

1660 }

1661 bool HasTableNumber =

1664 bool HasElemKind =

1667 bool HasElemType =

1670 bool HasInitExprs =

1672

1673 if (HasTableNumber)

1675 else

1677

1678 if (!isValidTableNumber(Segment.TableNumber))

1679 return make_error("invalid TableNumber",

1681

1686 } else {

1688 return Err;

1689 }

1690

1691 if (HasElemKind) {

1699 return make_error("invalid elem type",

1701 }

1702 } else {

1703 if (ElemKind != 0)

1704 return make_error("invalid elem type",

1707 }

1708 } else if (HasElemType) {

1710 Segment.ElemKind = ElemType;

1711 } else {

1713 }

1714

1716

1717 if (HasInitExprs) {

1718 while (NumElems--) {

1721 return Err;

1722 }

1723 } else {

1724 while (NumElems--) {

1726 }

1727 }

1728 ElemSegments.push_back(Segment);

1729 }

1730 if (Ctx.Ptr != Ctx.End)

1731 return make_error("elem section ended prematurely",

1734}

1735

1736Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {

1737 DataSection = Sections.size();

1739 if (DataCount && Count != *DataCount)

1740 return make_error(

1741 "number of data segments does not match DataCount section");

1742 DataSegments.reserve(Count);

1743 while (Count--) {

1749 : 0;

1752 return Err;

1753 } else {

1757 }

1759 if (Size > (size_t)(Ctx.End - Ctx.Ptr))

1760 return make_error("invalid segment size",

1763

1764

1769 Ctx.Ptr += Size;

1770 DataSegments.push_back(Segment);

1771 }

1772 if (Ctx.Ptr != Ctx.End)

1773 return make_error("data section ended prematurely",

1776}

1777

1778Error WasmObjectFile::parseDataCountSection(ReadContext &Ctx) {

1781}

1782

1784 return Header;

1785}

1786

1788

1792

1794 if (Sym.isBindingWeak())

1796 if (Sym.isBindingLocal())

1798 if (Sym.isHidden())

1800 if (Sym.isDefined())

1802 if (Sym.isTypeFunction())

1804 return Result;

1805}

1806

1809 Ref.d.a = 1;

1810 Ref.d.b = 0;

1812}

1813

1816 Ref.d.a = 1;

1817 Ref.d.b = Symbols.size();

1819}

1820

1822 return Symbols[Symb.d.b];

1823}

1824

1827}

1828

1831}

1832

1835 if (Sym.isDefined())

1836 return 0;

1838 if (!Sec)

1842 isDefinedFunctionIndex(Sym.Info.ElementIndex)) {

1844 SectionAddress;

1845 }

1847 isDefinedGlobalIndex(Sym.Info.ElementIndex)) {

1848 return getDefinedGlobal(Sym.Info.ElementIndex).Offset + SectionAddress;

1849 }

1850

1852}

1853

1855 switch (Sym.Info.Kind) {

1860 return Sym.Info.ElementIndex;

1862

1863

1864 uint32_t SegmentIndex = Sym.Info.DataRef.Segment;

1873 return Sym.Info.DataRef.Offset;

1874 } else {

1876 }

1877 }

1879 return 0;

1880 }

1882}

1883

1886}

1887

1890 return 0;

1891}

1892

1895 return 0;

1896}

1897

1901

1902 switch (Sym.Info.Kind) {

1915 }

1916

1919}

1920

1924 if (Sym.isUndefined())

1926

1928 Ref.d.a = getSymbolSectionIdImpl(Sym);

1930}

1931

1934 return getSymbolSectionIdImpl(Sym);

1935}

1936

1938 switch (Sym.Info.Kind) {

1940 return CodeSection;

1942 return GlobalSection;

1944 return DataSection;

1946 return Sym.Info.ElementIndex;

1948 return TagSection;

1950 return TableSection;

1951 default:

1953 }

1954}

1955

1958 if (Sym.isDefined())

1959 return 0;

1960 if (Sym.isTypeGlobal())

1961 return getDefinedGlobal(Sym.Info.ElementIndex).Size;

1962 if (Sym.isTypeData())

1963 return Sym.Info.DataRef.Size;

1964 if (Sym.isTypeFunction())

1966

1967

1968

1969 return 0;

1970}

1971

1973

1977 return S.Name;

1981}

1982

1984

1985

1986

1988 : Sections[Sec.d.a].Offset;

1989}

1990

1992 return Sec.d.a;

1993}

1994

1998}

1999

2003

2004

2006}

2007

2009 return 1;

2010}

2011

2013 return false;

2014}

2015

2018}

2019

2022}

2023

2025

2027

2030 RelocRef.d.a = Ref.d.a;

2031 RelocRef.d.b = 0;

2033}

2034

2038 RelocRef.d.a = Ref.d.a;

2041}

2042

2044

2048}

2049

2052 if (Rel.Type == wasm::R_WASM_TYPE_INDEX_LEB)

2055 Sym.d.a = 1;

2058}

2059

2062 return Rel.Type;

2063}

2064

2069

2070#define WASM_RELOC(name, value) \

2071 case wasm:📛 \

2072 Res = #name; \

2073 break;

2074

2075 switch (Rel.Type) {

2076#include "llvm/BinaryFormat/WasmRelocs.def"

2077 }

2078

2079#undef WASM_RELOC

2080

2081 Result.append(Res.begin(), Res.end());

2082}

2083

2086 Ref.d.a = 0;

2088}

2089

2092 Ref.d.a = Sections.size();

2094}

2095

2097 return HasMemory64 ? 8 : 4;

2098}

2099

2101

2104}

2105

2108}

2109

2111

2113

2115 assert(Ref.d.a < Sections.size());

2116 return Sections[Ref.d.a];

2117}

2118

2122}

2123

2127}

2128

2131 assert(Ref.d.a < Sections.size());

2135}

2136

2137int WasmSectionOrderChecker::getSectionOrder(unsigned ID,

2139 switch (ID) {

2176 default:

2178 }

2179}

2180

2181

2182

2183

2185 [WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS] = {

2186

2187 {},

2188

2189 {WASM_SEC_ORDER_TYPE, WASM_SEC_ORDER_IMPORT},

2190

2191 {WASM_SEC_ORDER_IMPORT, WASM_SEC_ORDER_FUNCTION},

2192

2193 {WASM_SEC_ORDER_FUNCTION, WASM_SEC_ORDER_TABLE},

2194

2195 {WASM_SEC_ORDER_TABLE, WASM_SEC_ORDER_MEMORY},

2196

2197 {WASM_SEC_ORDER_MEMORY, WASM_SEC_ORDER_TAG},

2198

2199 {WASM_SEC_ORDER_TAG, WASM_SEC_ORDER_GLOBAL},

2200

2201 {WASM_SEC_ORDER_GLOBAL, WASM_SEC_ORDER_EXPORT},

2202

2203 {WASM_SEC_ORDER_EXPORT, WASM_SEC_ORDER_START},

2204

2205 {WASM_SEC_ORDER_START, WASM_SEC_ORDER_ELEM},

2206

2207 {WASM_SEC_ORDER_ELEM, WASM_SEC_ORDER_DATACOUNT},

2208

2209 {WASM_SEC_ORDER_DATACOUNT, WASM_SEC_ORDER_CODE},

2210

2211 {WASM_SEC_ORDER_CODE, WASM_SEC_ORDER_DATA},

2212

2213 {WASM_SEC_ORDER_DATA, WASM_SEC_ORDER_LINKING},

2214

2215

2216

2217 {WASM_SEC_ORDER_DYLINK, WASM_SEC_ORDER_TYPE},

2218

2219 {WASM_SEC_ORDER_LINKING, WASM_SEC_ORDER_RELOC, WASM_SEC_ORDER_NAME},

2220

2221 {},

2222

2223 {WASM_SEC_ORDER_NAME, WASM_SEC_ORDER_PRODUCERS},

2224

2225 {WASM_SEC_ORDER_PRODUCERS, WASM_SEC_ORDER_TARGET_FEATURES},

2226

2227 {WASM_SEC_ORDER_TARGET_FEATURES}};

2228

2231 int Order = getSectionOrder(ID, CustomSectionName);

2233 return true;

2234

2235

2237

2238

2240

2241 int Curr = Order;

2242 while (true) {

2243

2244 for (size_t I = 0;; ++I) {

2247 break;

2248 if (Checked[Next])

2249 continue;

2251 Checked[Next] = true;

2252 }

2253

2254 if (WorkList.empty())

2255 break;

2256

2257

2259 if (Seen[Curr])

2260 return false;

2261 }

2262

2263

2264 Seen[Order] = true;

2265 return true;

2266}

Analysis containing CSE Info

#define LLVM_DUMP_METHOD

Mark debug helper function definitions like dump() that should not be stripped from debug builds.

This file defines the DenseSet and SmallDenseSet classes.

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the SmallSet class.

StringSet - A set-like wrapper for the StringMap.

This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...

static uint8_t readVaruint1(WasmObjectFile::ReadContext &Ctx)

static Error readInitExpr(wasm::WasmInitExpr &Expr, WasmObjectFile::ReadContext &Ctx)

static int32_t readVarint32(WasmObjectFile::ReadContext &Ctx)

static wasm::WasmTableType readTableType(WasmObjectFile::ReadContext &Ctx)

static wasm::WasmLimits readLimits(WasmObjectFile::ReadContext &Ctx)

static uint64_t readVaruint64(WasmObjectFile::ReadContext &Ctx)

static Error readSection(WasmSection &Section, WasmObjectFile::ReadContext &Ctx, WasmSectionOrderChecker &Checker)

static int64_t readLEB128(WasmObjectFile::ReadContext &Ctx)

static uint32_t readVaruint32(WasmObjectFile::ReadContext &Ctx)

static uint32_t readUint32(WasmObjectFile::ReadContext &Ctx)

static uint8_t readOpcode(WasmObjectFile::ReadContext &Ctx)

static StringRef readString(WasmObjectFile::ReadContext &Ctx)

static uint8_t readUint8(WasmObjectFile::ReadContext &Ctx)

static int32_t readFloat32(WasmObjectFile::ReadContext &Ctx)

static uint64_t readULEB128(WasmObjectFile::ReadContext &Ctx)

static int64_t readFloat64(WasmObjectFile::ReadContext &Ctx)

static wasm::ValType parseValType(WasmObjectFile::ReadContext &Ctx, uint32_t Code)

static int64_t readVarint64(WasmObjectFile::ReadContext &Ctx)

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

Implements a dense probed hash-table based set.

Helper for Errors used as out-parameters.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

reference get()

Returns a reference to the stored T value.

SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...

std::pair< const_iterator, bool > insert(const T &V)

insert - Insert an element into the set if it isn't already there.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void reserve(size_type N)

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

constexpr StringRef substr(size_t Start, size_t N=npos) const

Return a reference to the substring from [Start, Start + N).

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr bool empty() const

empty - Check if the string is empty.

constexpr size_t size() const

size - Get the string size.

const unsigned char * bytes_begin() const

StringSet - A wrapper for StringMap that provides set-like functionality.

std::pair< typename Base::iterator, bool > insert(StringRef key)

A switch()-like statement whose cases are string literals.

StringSwitch & Case(StringLiteral S, T Value)

StringSwitch & StartsWith(StringLiteral S, T Value)

Manages the enabling and disabling of subtarget specific features.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

static Twine utohexstr(const uint64_t &Val)

The instances of the Type class are immutable: once they are created, they are never changed.

std::pair< iterator, bool > insert(const ValueT &V)

This is a value type class that represents a single symbol in the list of symbols in the object file.

DataRefImpl getRawDataRefImpl() const

StringRef getData() const

This class is the base class for all object file types.

friend class RelocationRef

static Expected< std::unique_ptr< WasmObjectFile > > createWasmObjectFile(MemoryBufferRef Object)

Expected< uint64_t > getSymbolValue(DataRefImpl Symb) const

This is a value type class that represents a single relocation in the list of relocations in the obje...

This is a value type class that represents a single section in the list of sections in the object fil...

This is a value type class that represents a single symbol in the list of symbols in the object file.

basic_symbol_iterator symbol_begin() const override

relocation_iterator section_rel_end(DataRefImpl Sec) const override

void moveSymbolNext(DataRefImpl &Symb) const override

uint64_t getSectionAlignment(DataRefImpl Sec) const override

uint64_t getRelocationOffset(DataRefImpl Rel) const override

Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override

uint64_t getWasmSymbolValue(const WasmSymbol &Sym) const

uint64_t getSymbolValueImpl(DataRefImpl Symb) const override

bool isSectionText(DataRefImpl Sec) const override

bool isSectionBSS(DataRefImpl Sec) const override

basic_symbol_iterator symbol_end() const override

Expected< uint32_t > getSymbolFlags(DataRefImpl Symb) const override

section_iterator section_begin() const override

bool isRelocatableObject() const override

True if this is a relocatable object (.o/.obj).

void moveRelocationNext(DataRefImpl &Rel) const override

uint32_t getSymbolSectionId(SymbolRef Sym) const

bool isSectionCompressed(DataRefImpl Sec) const override

bool isSectionVirtual(DataRefImpl Sec) const override

uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override

void getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl< char > &Result) const override

StringRef getFileFormatName() const override

Expected< StringRef > getSymbolName(DataRefImpl Symb) const override

relocation_iterator section_rel_begin(DataRefImpl Sec) const override

uint8_t getBytesInAddress() const override

The number of bytes used to represent an address in this object file format.

WasmObjectFile(MemoryBufferRef Object, Error &Err)

section_iterator section_end() const override

Expected< ArrayRef< uint8_t > > getSectionContents(DataRefImpl Sec) const override

uint64_t getSectionIndex(DataRefImpl Sec) const override

uint32_t getSymbolAlignment(DataRefImpl Symb) const override

uint64_t getSectionSize(DataRefImpl Sec) const override

Triple::ArchType getArch() const override

uint64_t getRelocationType(DataRefImpl Rel) const override

const WasmSection & getWasmSection(const SectionRef &Section) const

Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override

symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override

Expected< SubtargetFeatures > getFeatures() const override

const wasm::WasmObjectHeader & getHeader() const

void moveSectionNext(DataRefImpl &Sec) const override

uint32_t getNumImportedFunctions() const

bool isSharedObject() const

const wasm::WasmRelocation & getWasmRelocation(const RelocationRef &Ref) const

uint32_t getSymbolSize(SymbolRef Sym) const

ArrayRef< wasm::WasmFunction > functions() const

const WasmSymbol & getWasmSymbol(const DataRefImpl &Symb) const

uint64_t getSectionAddress(DataRefImpl Sec) const override

Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override

bool isSectionData(DataRefImpl Sec) const override

Expected< StringRef > getSectionName(DataRefImpl Sec) const override

bool isValidSectionOrder(unsigned ID, StringRef CustomSectionName="")

@ WASM_SEC_ORDER_TARGET_FEATURES

@ WASM_SEC_ORDER_PRODUCERS

@ WASM_SEC_ORDER_DATACOUNT

@ WASM_SEC_ORDER_FUNCTION

static int DisallowedPredecessors[WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS]

unsigned getBinding() const

LLVM_DUMP_METHOD void dump() const

wasm::WasmSymbolInfo Info

void print(raw_ostream &Out) const

This class implements an extremely fast bulk output stream that can only output to a stream.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

content_iterator< SectionRef > section_iterator

content_iterator< RelocationRef > relocation_iterator

uint32_t read32le(const void *P)

const unsigned WASM_SYMBOL_UNDEFINED

@ WASM_ELEM_SEGMENT_HAS_INIT_EXPRS

@ WASM_ELEM_SEGMENT_IS_DECLARATIVE

@ WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER

@ WASM_ELEM_SEGMENT_IS_PASSIVE

const unsigned WASM_SYMBOL_BINDING_GLOBAL

const uint32_t WasmMetadataVersion

const unsigned WASM_SYMBOL_BINDING_WEAK

const unsigned WASM_SYMBOL_BINDING_LOCAL

@ WASM_NAMES_DATA_SEGMENT

@ WASM_SYMBOL_TYPE_GLOBAL

@ WASM_SYMBOL_TYPE_SECTION

@ WASM_SYMBOL_TYPE_FUNCTION

const uint32_t WasmVersion

@ WASM_OPCODE_ARRAY_NEW_FIXED

@ WASM_OPCODE_ARRAY_NEW_DEFAULT

@ WASM_OPCODE_STRUCT_NEW_DEFAULT

const unsigned WASM_SYMBOL_BINDING_MASK

@ WASM_LIMITS_FLAG_HAS_MAX

@ WASM_DATA_SEGMENT_IS_PASSIVE

@ WASM_DATA_SEGMENT_HAS_MEMINDEX

llvm::StringRef sectionTypeToString(uint32_t type)

const unsigned WASM_SYMBOL_EXPLICIT_NAME

@ WASM_FEATURE_PREFIX_USED

@ WASM_FEATURE_PREFIX_DISALLOWED

const unsigned WASM_SYMBOL_ABSOLUTE

@ WASM_DYLINK_EXPORT_INFO

@ WASM_DYLINK_IMPORT_INFO

const unsigned WASM_ELEM_SEGMENT_MASK_HAS_ELEM_DESC

This is an optimization pass for GlobalISel generic memory operations.

std::string to_string(const T &Value)

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.

@ Import

Import information from summary.

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.

Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)

Create formatted StringError object.

raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

void report_fatal_error(Error Err, bool gen_crash_diag=true)

Report a serious error, calling any installed error handler.

@ Global

Append to llvm.global_dtors.

@ Ref

The access may reference the value stored in memory.

const char * toString(DWARFSectionKind Kind)

ArrayRef< uint8_t > Content

std::vector< wasm::WasmRelocation > Relocations

wasm::WasmDataSegment Data

ArrayRef< uint8_t > Content

std::vector< StringRef > Needed

std::vector< WasmDylinkExportInfo > ExportInfo

std::vector< WasmDylinkImportInfo > ImportInfo

std::vector< uint32_t > Functions

std::optional< StringRef > ExportName

uint32_t CodeSectionOffset

union llvm::wasm::WasmInitExprMVP::@187 Value

std::vector< WasmInitFunc > InitFunctions

std::vector< StringRef > Comdats

std::vector< std::pair< std::string, std::string > > SDKs

std::vector< std::pair< std::string, std::string > > Languages

std::vector< std::pair< std::string, std::string > > Tools

SmallVector< ValType, 1 > Returns

SmallVector< ValType, 4 > Params

enum llvm::wasm::WasmSignature::@192 Kind

WasmDataReference DataRef

struct llvm::object::DataRefImpl::@370 d