33#define DEBUG_TYPE "wasm-object"
36using namespace object;
62#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
69 auto ObjectFile = std::make_unique<WasmObjectFile>(Buffer, Err);
71 return std::move(Err);
76#define VARINT7_MAX ((1 << 7) - 1)
77#define VARINT7_MIN (-(1 << 7))
78#define VARUINT7_MAX (1 << 7)
79#define VARUINT1_MAX (1)
99 memcpy(&Result, Ctx.
Ptr,
sizeof(Result));
100 Ctx.
Ptr +=
sizeof(Result);
105 if (Ctx.
Ptr + 8 > Ctx.
End)
108 memcpy(&Result, Ctx.
Ptr,
sizeof(Result));
109 Ctx.
Ptr +=
sizeof(Result);
115 const char *
Error =
nullptr;
125 if (Ctx.
Ptr + StringLen > Ctx.
End)
128 StringRef(
reinterpret_cast<const char *
>(Ctx.
Ptr), StringLen);
129 Ctx.
Ptr += StringLen;
135 const char *
Error =
nullptr;
152 if (Result > INT32_MAX || Result < INT32_MIN)
159 if (Result > UINT32_MAX)
178 auto Start = Ctx.
Ptr;
201 return make_error<GenericBinaryError>(
"invalid type for ref.null",
240 return make_error<GenericBinaryError>(
241 Twine(
"invalid opcode in init_expr: ") +
Twine(
unsigned(Opcode)),
268 Section.Offset = Ctx.
Ptr - Ctx.
Start;
270 LLVM_DEBUG(
dbgs() <<
"readSection type=" << Section.Type <<
"\n");
273 const uint8_t *PreSizePtr = Ctx.
Ptr;
275 Section.HeaderSecSizeEncodingLen = Ctx.
Ptr - PreSizePtr;
277 return make_error<StringError>(
"zero length section",
280 return make_error<StringError>(
"section too large",
291 Ctx.
Ptr += SectionNameSize;
292 Size -= SectionNameSize;
296 return make_error<StringError>(
"out of order section type: " +
311 Err = make_error<StringError>(
"invalid magic number",
321 if (Ctx.
Ptr + 4 > Ctx.
End) {
322 Err = make_error<StringError>(
"missing version number",
329 Err = make_error<StringError>(
"invalid version number: " +
336 while (Ctx.
Ptr < Ctx.
End) {
340 if ((Err = parseSection(Sec)))
343 Sections.push_back(Sec);
354 return parseCustomSection(Sec, Ctx);
356 return parseTypeSection(Ctx);
358 return parseImportSection(Ctx);
360 return parseFunctionSection(Ctx);
362 return parseTableSection(Ctx);
364 return parseMemorySection(Ctx);
366 return parseTagSection(Ctx);
368 return parseGlobalSection(Ctx);
370 return parseExportSection(Ctx);
372 return parseStartSection(Ctx);
374 return parseElemSection(Ctx);
376 return parseCodeSection(Ctx);
378 return parseDataSection(Ctx);
380 return parseDataCountSection(Ctx);
382 return make_error<GenericBinaryError>(
387Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) {
390 HasDylinkSection =
true;
400 if (Ctx.Ptr != Ctx.End)
401 return make_error<GenericBinaryError>(
"dylink section ended prematurely",
406Error WasmObjectFile::parseDylink0Section(ReadContext &Ctx) {
409 HasDylinkSection =
true;
411 const uint8_t *OrigEnd = Ctx.End;
412 while (Ctx.Ptr < OrigEnd) {
418 Ctx.End = Ctx.Ptr +
Size;
453 if (Ctx.Ptr != Ctx.End) {
454 return make_error<GenericBinaryError>(
459 if (Ctx.Ptr != Ctx.End)
460 return make_error<GenericBinaryError>(
"dylink.0 section ended prematurely",
465Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
470 while (Ctx.Ptr < Ctx.End) {
473 const uint8_t *SubSectionEnd = Ctx.Ptr +
Size;
485 return make_error<GenericBinaryError>(
487 if (!isValidFunctionIndex(
Index) ||
Name.empty())
488 return make_error<GenericBinaryError>(
"invalid function name entry",
491 if (isDefinedFunctionIndex(
Index))
496 return make_error<GenericBinaryError>(
"global named more than once",
498 if (!isValidGlobalIndex(
Index) ||
Name.empty())
499 return make_error<GenericBinaryError>(
"invalid global name entry",
504 return make_error<GenericBinaryError>(
506 if (
Index > DataSegments.size())
507 return make_error<GenericBinaryError>(
"invalid data segment name entry",
520 if (Ctx.Ptr != SubSectionEnd)
521 return make_error<GenericBinaryError>(
525 if (Ctx.Ptr != Ctx.End)
526 return make_error<GenericBinaryError>(
"name section ended prematurely",
531Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {
532 HasLinkingSection =
true;
536 return make_error<GenericBinaryError>(
537 "unexpected metadata version: " +
Twine(LinkingData.
Version) +
542 const uint8_t *OrigEnd = Ctx.End;
543 while (Ctx.Ptr < OrigEnd) {
549 Ctx.End = Ctx.Ptr +
Size;
552 if (
Error Err = parseLinkingSectionSymtab(Ctx))
557 if (Count > DataSegments.size())
558 return make_error<GenericBinaryError>(
"too many segment names",
574 if (!isValidFunctionSymbol(
Init.Symbol))
575 return make_error<GenericBinaryError>(
"invalid function symbol: " +
583 if (
Error Err = parseLinkingSectionComdat(Ctx))
590 if (Ctx.Ptr != Ctx.End)
591 return make_error<GenericBinaryError>(
594 if (Ctx.Ptr != OrigEnd)
595 return make_error<GenericBinaryError>(
"linking section ended prematurely",
600Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
603 Symbols.reserve(Count);
606 std::vector<wasm::WasmImport *> ImportedGlobals;
607 std::vector<wasm::WasmImport *> ImportedFunctions;
608 std::vector<wasm::WasmImport *> ImportedTags;
609 std::vector<wasm::WasmImport *> ImportedTables;
610 ImportedGlobals.reserve(Imports.size());
611 ImportedFunctions.reserve(Imports.size());
612 ImportedTags.reserve(Imports.size());
613 ImportedTables.reserve(Imports.size());
614 for (
auto &
I : Imports) {
616 ImportedFunctions.emplace_back(&
I);
618 ImportedGlobals.emplace_back(&
I);
620 ImportedTags.emplace_back(&
I);
622 ImportedTables.emplace_back(&
I);
638 if (!isValidFunctionIndex(
Info.ElementIndex) ||
639 IsDefined != isDefinedFunctionIndex(
Info.ElementIndex))
640 return make_error<GenericBinaryError>(
"invalid function symbol index",
644 unsigned FuncIndex =
Info.ElementIndex - NumImportedFunctions;
646 Signature = &Signatures[
Function.SigIndex];
657 Signature = &Signatures[
Import.SigIndex];
664 if (!isValidGlobalIndex(
Info.ElementIndex) ||
665 IsDefined != isDefinedGlobalIndex(
Info.ElementIndex))
666 return make_error<GenericBinaryError>(
"invalid global symbol index",
670 return make_error<GenericBinaryError>(
"undefined weak global symbol",
674 unsigned GlobalIndex =
Info.ElementIndex - NumImportedGlobals;
676 GlobalType = &
Global.Type;
677 if (
Global.SymbolName.empty())
687 GlobalType = &
Import.Global;
694 if (!isValidTableNumber(
Info.ElementIndex) ||
695 IsDefined != isDefinedTableNumber(
Info.ElementIndex))
696 return make_error<GenericBinaryError>(
"invalid table symbol index",
700 return make_error<GenericBinaryError>(
"undefined weak table symbol",
704 unsigned TableNumber =
Info.ElementIndex - NumImportedTables;
706 TableType = &Table.
Type;
717 TableType = &
Import.Table;
726 if (
Index >= DataSegments.size())
727 return make_error<GenericBinaryError>(
"invalid data segment index",
731 size_t SegmentSize = DataSegments[
Index].Data.Content.size();
733 return make_error<GenericBinaryError>(
734 "invalid data symbol offset: `" +
Info.Name +
"` (offset: " +
744 return make_error<GenericBinaryError>(
745 "section symbols must have local binding",
756 if (!isValidTagIndex(
Info.ElementIndex) ||
757 IsDefined != isDefinedTagIndex(
Info.ElementIndex))
758 return make_error<GenericBinaryError>(
"invalid tag symbol index",
762 return make_error<GenericBinaryError>(
"undefined weak global symbol",
766 unsigned TagIndex =
Info.ElementIndex - NumImportedTags;
768 Signature = &Signatures[
Tag.SigIndex];
769 if (
Tag.SymbolName.empty())
780 Signature = &Signatures[
Import.SigIndex];
787 return make_error<GenericBinaryError>(
"invalid symbol type: " +
795 return make_error<GenericBinaryError>(
"duplicate symbol name " +
799 Symbols.emplace_back(LinkingData.
SymbolTable.back(), GlobalType, TableType,
801 LLVM_DEBUG(
dbgs() <<
"Adding symbol: " << Symbols.back() <<
"\n");
807Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
810 for (
unsigned ComdatIndex = 0; ComdatIndex < ComdatCount; ++ComdatIndex) {
813 return make_error<GenericBinaryError>(
"bad/duplicate COMDAT name " +
819 return make_error<GenericBinaryError>(
"unsupported COMDAT flags",
823 while (EntryCount--) {
828 return make_error<GenericBinaryError>(
"invalid COMDAT entry type",
831 if (
Index >= DataSegments.size())
832 return make_error<GenericBinaryError>(
834 if (DataSegments[
Index].
Data.Comdat != UINT32_MAX)
835 return make_error<GenericBinaryError>(
"data segment in two COMDATs",
837 DataSegments[
Index].Data.Comdat = ComdatIndex;
840 if (!isDefinedFunctionIndex(
Index))
841 return make_error<GenericBinaryError>(
843 if (getDefinedFunction(
Index).
Comdat != UINT32_MAX)
844 return make_error<GenericBinaryError>(
"function in two COMDATs",
849 if (
Index >= Sections.size())
850 return make_error<GenericBinaryError>(
853 return make_error<GenericBinaryError>(
855 Sections[
Index].Comdat = ComdatIndex;
863Error WasmObjectFile::parseProducersSection(ReadContext &Ctx) {
866 for (
size_t I = 0;
I < Fields; ++
I) {
868 if (!FieldsSeen.
insert(FieldName).second)
869 return make_error<GenericBinaryError>(
870 "producers section does not have unique fields",
872 std::vector<std::pair<std::string, std::string>> *ProducerVec =
nullptr;
873 if (FieldName ==
"language") {
875 }
else if (FieldName ==
"processed-by") {
876 ProducerVec = &ProducerInfo.
Tools;
877 }
else if (FieldName ==
"sdk") {
878 ProducerVec = &ProducerInfo.
SDKs;
880 return make_error<GenericBinaryError>(
881 "producers section field is not named one of language, processed-by, "
887 for (
size_t J = 0; J < ValueCount; ++J) {
891 return make_error<GenericBinaryError>(
892 "producers section contains repeated producer",
895 ProducerVec->emplace_back(std::string(
Name), std::string(Version));
898 if (Ctx.Ptr != Ctx.End)
899 return make_error<GenericBinaryError>(
"producers section ended prematurely",
904Error WasmObjectFile::parseTargetFeaturesSection(ReadContext &Ctx) {
916 return make_error<GenericBinaryError>(
"unknown feature policy prefix",
920 if (!FeaturesSeen.
insert(Feature.
Name).second)
921 return make_error<GenericBinaryError>(
922 "target features section contains repeated feature \"" +
925 TargetFeatures.push_back(Feature);
927 if (Ctx.Ptr != Ctx.End)
928 return make_error<GenericBinaryError>(
929 "target features section ended prematurely",
936 if (SectionIndex >= Sections.size())
937 return make_error<GenericBinaryError>(
"invalid section index",
943 while (RelocCount--) {
948 if (Reloc.
Offset < PreviousOffset)
949 return make_error<GenericBinaryError>(
"relocations not in offset order",
951 PreviousOffset = Reloc.
Offset;
954 case wasm::R_WASM_FUNCTION_INDEX_LEB:
955 case wasm::R_WASM_FUNCTION_INDEX_I32:
956 case wasm::R_WASM_TABLE_INDEX_SLEB:
957 case wasm::R_WASM_TABLE_INDEX_SLEB64:
958 case wasm::R_WASM_TABLE_INDEX_I32:
959 case wasm::R_WASM_TABLE_INDEX_I64:
960 case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
961 case wasm::R_WASM_TABLE_INDEX_REL_SLEB64:
962 if (!isValidFunctionSymbol(Reloc.
Index))
963 return make_error<GenericBinaryError>(
966 case wasm::R_WASM_TABLE_NUMBER_LEB:
967 if (!isValidTableSymbol(Reloc.
Index))
968 return make_error<GenericBinaryError>(
"invalid relocation table index",
971 case wasm::R_WASM_TYPE_INDEX_LEB:
972 if (Reloc.
Index >= Signatures.size())
973 return make_error<GenericBinaryError>(
"invalid relocation type index",
976 case wasm::R_WASM_GLOBAL_INDEX_LEB:
979 if (!isValidGlobalSymbol(Reloc.
Index) &&
980 !isValidDataSymbol(Reloc.
Index) &&
981 !isValidFunctionSymbol(Reloc.
Index))
982 return make_error<GenericBinaryError>(
"invalid relocation global index",
985 case wasm::R_WASM_GLOBAL_INDEX_I32:
986 if (!isValidGlobalSymbol(Reloc.
Index))
987 return make_error<GenericBinaryError>(
"invalid relocation global index",
990 case wasm::R_WASM_TAG_INDEX_LEB:
991 if (!isValidTagSymbol(Reloc.
Index))
992 return make_error<GenericBinaryError>(
"invalid relocation tag index",
995 case wasm::R_WASM_MEMORY_ADDR_LEB:
996 case wasm::R_WASM_MEMORY_ADDR_SLEB:
997 case wasm::R_WASM_MEMORY_ADDR_I32:
998 case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
999 case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
1000 case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
1001 if (!isValidDataSymbol(Reloc.
Index))
1002 return make_error<GenericBinaryError>(
"invalid relocation data index",
1006 case wasm::R_WASM_MEMORY_ADDR_LEB64:
1007 case wasm::R_WASM_MEMORY_ADDR_SLEB64:
1008 case wasm::R_WASM_MEMORY_ADDR_I64:
1009 case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
1010 case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64:
1011 if (!isValidDataSymbol(Reloc.
Index))
1012 return make_error<GenericBinaryError>(
"invalid relocation data index",
1016 case wasm::R_WASM_FUNCTION_OFFSET_I32:
1017 if (!isValidFunctionSymbol(Reloc.
Index))
1018 return make_error<GenericBinaryError>(
1022 case wasm::R_WASM_FUNCTION_OFFSET_I64:
1023 if (!isValidFunctionSymbol(Reloc.
Index))
1024 return make_error<GenericBinaryError>(
1028 case wasm::R_WASM_SECTION_OFFSET_I32:
1029 if (!isValidSectionSymbol(Reloc.
Index))
1030 return make_error<GenericBinaryError>(
1035 return make_error<GenericBinaryError>(
"invalid relocation type: " +
1044 if (Reloc.
Type == wasm::R_WASM_MEMORY_ADDR_LEB64 ||
1045 Reloc.
Type == wasm::R_WASM_MEMORY_ADDR_SLEB64 ||
1046 Reloc.
Type == wasm::R_WASM_MEMORY_ADDR_REL_SLEB64)
1048 if (Reloc.
Type == wasm::R_WASM_TABLE_INDEX_I32 ||
1049 Reloc.
Type == wasm::R_WASM_MEMORY_ADDR_I32 ||
1050 Reloc.
Type == wasm::R_WASM_MEMORY_ADDR_LOCREL_I32 ||
1051 Reloc.
Type == wasm::R_WASM_SECTION_OFFSET_I32 ||
1052 Reloc.
Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||
1053 Reloc.
Type == wasm::R_WASM_FUNCTION_INDEX_I32 ||
1054 Reloc.
Type == wasm::R_WASM_GLOBAL_INDEX_I32)
1056 if (Reloc.
Type == wasm::R_WASM_TABLE_INDEX_I64 ||
1057 Reloc.
Type == wasm::R_WASM_MEMORY_ADDR_I64 ||
1058 Reloc.
Type == wasm::R_WASM_FUNCTION_OFFSET_I64)
1061 return make_error<GenericBinaryError>(
"invalid relocation offset",
1064 Section.Relocations.push_back(Reloc);
1066 if (Ctx.Ptr != Ctx.End)
1067 return make_error<GenericBinaryError>(
"reloc section ended prematurely",
1072Error WasmObjectFile::parseCustomSection(
WasmSection &Sec, ReadContext &Ctx) {
1073 if (Sec.
Name ==
"dylink") {
1074 if (
Error Err = parseDylinkSection(Ctx))
1076 }
else if (Sec.
Name ==
"dylink.0") {
1077 if (
Error Err = parseDylink0Section(Ctx))
1079 }
else if (Sec.
Name ==
"name") {
1080 if (
Error Err = parseNameSection(Ctx))
1082 }
else if (Sec.
Name ==
"linking") {
1083 if (
Error Err = parseLinkingSection(Ctx))
1085 }
else if (Sec.
Name ==
"producers") {
1086 if (
Error Err = parseProducersSection(Ctx))
1088 }
else if (Sec.
Name ==
"target_features") {
1089 if (
Error Err = parseTargetFeaturesSection(Ctx))
1092 if (
Error Err = parseRelocSection(Sec.
Name, Ctx))
1098Error WasmObjectFile::parseTypeSection(ReadContext &Ctx) {
1100 Signatures.reserve(Count);
1105 return make_error<GenericBinaryError>(
"invalid signature type",
1110 while (ParamCount--) {
1115 while (ReturnCount--) {
1119 Signatures.push_back(std::move(Sig));
1121 if (Ctx.Ptr != Ctx.End)
1122 return make_error<GenericBinaryError>(
"type section ended prematurely",
1127Error WasmObjectFile::parseImportSection(ReadContext &Ctx) {
1129 uint32_t NumTypes = Signatures.size();
1130 Imports.reserve(Count);
1138 NumImportedFunctions++;
1141 return make_error<GenericBinaryError>(
"invalid function type",
1145 NumImportedGlobals++;
1156 NumImportedTables++;
1160 return make_error<GenericBinaryError>(
"invalid table element type",
1167 return make_error<GenericBinaryError>(
"invalid attribute",
1171 return make_error<GenericBinaryError>(
"invalid tag type",
1175 return make_error<GenericBinaryError>(
"unexpected import kind",
1178 Imports.push_back(Im);
1180 if (Ctx.Ptr != Ctx.End)
1181 return make_error<GenericBinaryError>(
"import section ended prematurely",
1186Error WasmObjectFile::parseFunctionSection(ReadContext &Ctx) {
1188 Functions.reserve(Count);
1189 uint32_t NumTypes = Signatures.size();
1192 if (
Type >= NumTypes)
1193 return make_error<GenericBinaryError>(
"invalid function type",
1197 Functions.push_back(
F);
1199 if (Ctx.Ptr != Ctx.End)
1200 return make_error<GenericBinaryError>(
"function section ended prematurely",
1205Error WasmObjectFile::parseTableSection(ReadContext &Ctx) {
1206 TableSection = Sections.size();
1208 Tables.reserve(Count);
1212 T.Index = NumImportedTables + Tables.size();
1213 Tables.push_back(
T);
1214 auto ElemType = Tables.back().Type.ElemType;
1217 return make_error<GenericBinaryError>(
"invalid table element type",
1221 if (Ctx.Ptr != Ctx.End)
1222 return make_error<GenericBinaryError>(
"table section ended prematurely",
1227Error WasmObjectFile::parseMemorySection(ReadContext &Ctx) {
1229 Memories.reserve(Count);
1234 Memories.push_back(Limits);
1236 if (Ctx.Ptr != Ctx.End)
1237 return make_error<GenericBinaryError>(
"memory section ended prematurely",
1242Error WasmObjectFile::parseTagSection(ReadContext &Ctx) {
1243 TagSection = Sections.size();
1245 Tags.reserve(Count);
1246 uint32_t NumTypes = Signatures.size();
1249 return make_error<GenericBinaryError>(
"invalid attribute",
1252 if (
Type >= NumTypes)
1253 return make_error<GenericBinaryError>(
"invalid tag type",
1256 Tag.Index = NumImportedTags + Tags.size();
1258 Tags.push_back(
Tag);
1261 if (Ctx.Ptr != Ctx.End)
1262 return make_error<GenericBinaryError>(
"tag section ended prematurely",
1267Error WasmObjectFile::parseGlobalSection(ReadContext &Ctx) {
1268 GlobalSection = Sections.size();
1270 Globals.reserve(Count);
1273 Global.Index = NumImportedGlobals + Globals.size();
1278 Globals.push_back(
Global);
1280 if (Ctx.Ptr != Ctx.End)
1281 return make_error<GenericBinaryError>(
"global section ended prematurely",
1286Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
1288 Exports.reserve(Count);
1297 if (!isDefinedFunctionIndex(Ex.
Index))
1298 return make_error<GenericBinaryError>(
"invalid function export",
1303 if (!isValidGlobalIndex(Ex.
Index))
1304 return make_error<GenericBinaryError>(
"invalid global export",
1308 if (!isValidTagIndex(Ex.
Index))
1309 return make_error<GenericBinaryError>(
"invalid tag export",
1316 return make_error<GenericBinaryError>(
"unexpected export kind",
1319 Exports.push_back(Ex);
1321 if (Ctx.Ptr != Ctx.End)
1322 return make_error<GenericBinaryError>(
"export section ended prematurely",
1327bool WasmObjectFile::isValidFunctionIndex(
uint32_t Index)
const {
1328 return Index < NumImportedFunctions + Functions.size();
1331bool WasmObjectFile::isDefinedFunctionIndex(
uint32_t Index)
const {
1332 return Index >= NumImportedFunctions && isValidFunctionIndex(
Index);
1335bool WasmObjectFile::isValidGlobalIndex(
uint32_t Index)
const {
1336 return Index < NumImportedGlobals + Globals.size();
1339bool WasmObjectFile::isValidTableNumber(
uint32_t Index)
const {
1340 return Index < NumImportedTables + Tables.size();
1343bool WasmObjectFile::isDefinedGlobalIndex(
uint32_t Index)
const {
1344 return Index >= NumImportedGlobals && isValidGlobalIndex(
Index);
1347bool WasmObjectFile::isDefinedTableNumber(
uint32_t Index)
const {
1348 return Index >= NumImportedTables && isValidTableNumber(
Index);
1352 return Index < NumImportedTags + Tags.size();
1355bool WasmObjectFile::isDefinedTagIndex(
uint32_t Index)
const {
1356 return Index >= NumImportedTags && isValidTagIndex(
Index);
1359bool WasmObjectFile::isValidFunctionSymbol(
uint32_t Index)
const {
1360 return Index < Symbols.size() && Symbols[
Index].isTypeFunction();
1363bool WasmObjectFile::isValidTableSymbol(
uint32_t Index)
const {
1364 return Index < Symbols.size() && Symbols[
Index].isTypeTable();
1367bool WasmObjectFile::isValidGlobalSymbol(
uint32_t Index)
const {
1368 return Index < Symbols.size() && Symbols[
Index].isTypeGlobal();
1371bool WasmObjectFile::isValidTagSymbol(
uint32_t Index)
const {
1372 return Index < Symbols.size() && Symbols[
Index].isTypeTag();
1375bool WasmObjectFile::isValidDataSymbol(
uint32_t Index)
const {
1376 return Index < Symbols.size() && Symbols[
Index].isTypeData();
1379bool WasmObjectFile::isValidSectionSymbol(
uint32_t Index)
const {
1380 return Index < Symbols.size() && Symbols[
Index].isTypeSection();
1385 return Functions[
Index - NumImportedFunctions];
1391 return Functions[
Index - NumImportedFunctions];
1396 return Globals[
Index - NumImportedGlobals];
1401 return Tags[
Index - NumImportedTags];
1404Error WasmObjectFile::parseStartSection(ReadContext &Ctx) {
1406 if (!isValidFunctionIndex(StartFunction))
1407 return make_error<GenericBinaryError>(
"invalid start function",
1412Error WasmObjectFile::parseCodeSection(ReadContext &Ctx) {
1413 CodeSection = Sections.size();
1415 if (FunctionCount != Functions.size()) {
1416 return make_error<GenericBinaryError>(
"invalid function count",
1420 for (
uint32_t i = 0; i < FunctionCount; i++) {
1422 const uint8_t *FunctionStart = Ctx.Ptr;
1424 const uint8_t *FunctionEnd = Ctx.Ptr +
Size;
1426 Function.CodeOffset = Ctx.Ptr - FunctionStart;
1427 Function.Index = NumImportedFunctions + i;
1428 Function.CodeSectionOffset = FunctionStart - Ctx.Start;
1429 Function.Size = FunctionEnd - FunctionStart;
1432 Function.Locals.reserve(NumLocalDecls);
1433 while (NumLocalDecls--) {
1440 uint32_t BodySize = FunctionEnd - Ctx.Ptr;
1444 Ctx.Ptr += BodySize;
1445 assert(Ctx.Ptr == FunctionEnd);
1447 if (Ctx.Ptr != Ctx.End)
1448 return make_error<GenericBinaryError>(
"code section ended prematurely",
1453Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
1455 ElemSegments.reserve(Count);
1463 if (Segment.
Flags & ~SupportedFlags)
1464 return make_error<GenericBinaryError>(
1472 return make_error<GenericBinaryError>(
"invalid TableNumber",
1489 return make_error<GenericBinaryError>(
"invalid reference type",
1494 return make_error<GenericBinaryError>(
"invalid elemtype",
1503 return make_error<GenericBinaryError>(
1504 "elem segment init expressions not yet implemented",
1508 while (NumElems--) {
1511 ElemSegments.push_back(Segment);
1513 if (Ctx.Ptr != Ctx.End)
1514 return make_error<GenericBinaryError>(
"elem section ended prematurely",
1519Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
1520 DataSection = Sections.size();
1522 if (DataCount && Count != *DataCount)
1523 return make_error<GenericBinaryError>(
1524 "number of data segments does not match DataCount section");
1525 DataSegments.reserve(Count);
1542 if (
Size > (
size_t)(Ctx.End - Ctx.Ptr))
1543 return make_error<GenericBinaryError>(
"invalid segment size",
1553 DataSegments.push_back(Segment);
1555 if (Ctx.Ptr != Ctx.End)
1556 return make_error<GenericBinaryError>(
"data section ended prematurely",
1561Error WasmObjectFile::parseDataCountSection(ReadContext &Ctx) {
1577 if (
Sym.isBindingWeak())
1579 if (!
Sym.isBindingLocal())
1583 if (!
Sym.isDefined())
1585 if (
Sym.isTypeFunction())
1600 Ref.d.b = Symbols.size();
1605 return Symbols[Symb.
d.
b];
1619 isDefinedFunctionIndex(
Sym.Info.ElementIndex))
1626 switch (
Sym.Info.Kind) {
1631 return Sym.Info.ElementIndex;
1671 switch (
Sym.Info.Kind) {
1693 if (
Sym.isUndefined())
1697 Ref.d.a = getSymbolSectionIdImpl(
Sym);
1703 return getSymbolSectionIdImpl(
Sym);
1707 switch (
Sym.Info.Kind) {
1711 return GlobalSection;
1715 return Sym.Info.ElementIndex;
1719 return TableSection;
1777 RelocRef.
d.
a =
Ref.d.a;
1785 RelocRef.
d.
a =
Ref.d.a;
1799 if (Rel.
Type == wasm::R_WASM_TYPE_INDEX_LEB)
1817#define WASM_RELOC(name, value) \
1823#include "llvm/BinaryFormat/WasmRelocs.def"
1828 Result.append(Res.
begin(), Res.
end());
1839 Ref.d.a = Sections.size();
1844 return HasMemory64 ? 8 : 4;
1863 return Sections[
Ref.d.a];
1884int WasmSectionOrderChecker::getSectionOrder(
unsigned ID,
1932 [WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS] = {
1936 {WASM_SEC_ORDER_TYPE, WASM_SEC_ORDER_IMPORT},
1938 {WASM_SEC_ORDER_IMPORT, WASM_SEC_ORDER_FUNCTION},
1940 {WASM_SEC_ORDER_FUNCTION, WASM_SEC_ORDER_TABLE},
1942 {WASM_SEC_ORDER_TABLE, WASM_SEC_ORDER_MEMORY},
1944 {WASM_SEC_ORDER_MEMORY, WASM_SEC_ORDER_TAG},
1946 {WASM_SEC_ORDER_TAG, WASM_SEC_ORDER_GLOBAL},
1948 {WASM_SEC_ORDER_GLOBAL, WASM_SEC_ORDER_EXPORT},
1950 {WASM_SEC_ORDER_EXPORT, WASM_SEC_ORDER_START},
1952 {WASM_SEC_ORDER_START, WASM_SEC_ORDER_ELEM},
1954 {WASM_SEC_ORDER_ELEM, WASM_SEC_ORDER_DATACOUNT},
1956 {WASM_SEC_ORDER_DATACOUNT, WASM_SEC_ORDER_CODE},
1958 {WASM_SEC_ORDER_CODE, WASM_SEC_ORDER_DATA},
1960 {WASM_SEC_ORDER_DATA, WASM_SEC_ORDER_LINKING},
1964 {WASM_SEC_ORDER_DYLINK, WASM_SEC_ORDER_TYPE},
1966 {WASM_SEC_ORDER_LINKING, WASM_SEC_ORDER_RELOC, WASM_SEC_ORDER_NAME},
1970 {WASM_SEC_ORDER_NAME, WASM_SEC_ORDER_PRODUCERS},
1972 {WASM_SEC_ORDER_PRODUCERS, WASM_SEC_ORDER_TARGET_FEATURES},
1974 {WASM_SEC_ORDER_TARGET_FEATURES}};
1978 int Order = getSectionOrder(
ID, CustomSectionName);
1991 for (
size_t I = 0;; ++
I) {
1998 Checked[Next] =
true;
2001 if (WorkList.
empty())
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 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.
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).
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
bool startswith(StringRef Prefix) const
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
bool isSharedObject() const
const wasm::WasmRelocation & getWasmRelocation(const RelocationRef &Ref) 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
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.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
content_iterator< SectionRef > section_iterator
content_iterator< RelocationRef > relocation_iterator
uint32_t read32le(const void *P)
const unsigned WASM_SYMBOL_UNDEFINED
@ WASM_FEATURE_PREFIX_USED
@ WASM_FEATURE_PREFIX_REQUIRED
@ WASM_FEATURE_PREFIX_DISALLOWED
@ WASM_DATA_SEGMENT_IS_PASSIVE
@ WASM_DATA_SEGMENT_HAS_MEMINDEX
@ WASM_NAMES_DATA_SEGMENT
const unsigned WASM_SYMBOL_BINDING_GLOBAL
const unsigned WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND
@ WASM_LIMITS_FLAG_HAS_MAX
const uint32_t WasmMetadataVersion
const unsigned WASM_SYMBOL_BINDING_WEAK
const unsigned WASM_SYMBOL_BINDING_LOCAL
@ WASM_SYMBOL_TYPE_GLOBAL
@ WASM_SYMBOL_TYPE_SECTION
@ WASM_SYMBOL_TYPE_FUNCTION
const uint32_t WasmVersion
@ WASM_ELEM_SEGMENT_HAS_INIT_EXPRS
@ WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER
@ WASM_ELEM_SEGMENT_IS_PASSIVE
@ WASM_DYLINK_EXPORT_INFO
@ WASM_DYLINK_IMPORT_INFO
const unsigned WASM_SYMBOL_BINDING_MASK
llvm::StringRef sectionTypeToString(uint32_t type)
const unsigned WASM_SYMBOL_EXPLICIT_NAME
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.
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::@178 Value
std::vector< WasmSymbolInfo > SymbolTable
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
WasmDataReference DataRef
struct llvm::object::DataRefImpl::@351 d