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>(
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;
729 if (
static_cast<size_t>(
Index) >= DataSegments.size())
730 return make_error<GenericBinaryError>(
731 "invalid data segment index: " +
Twine(
Index),
733 size_t SegmentSize = DataSegments[
Index].Data.Content.size();
735 return make_error<GenericBinaryError>(
736 "invalid data symbol offset: `" +
Info.Name +
738 " segment size: " +
Twine(SegmentSize) +
")",
748 return make_error<GenericBinaryError>(
749 "section symbols must have local binding",
760 if (!isValidTagIndex(
Info.ElementIndex) ||
761 IsDefined != isDefinedTagIndex(
Info.ElementIndex))
762 return make_error<GenericBinaryError>(
"invalid tag symbol index",
766 return make_error<GenericBinaryError>(
"undefined weak global symbol",
770 unsigned TagIndex =
Info.ElementIndex - NumImportedTags;
772 Signature = &Signatures[
Tag.SigIndex];
773 if (
Tag.SymbolName.empty())
784 Signature = &Signatures[
Import.SigIndex];
791 return make_error<GenericBinaryError>(
"invalid symbol type: " +
799 return make_error<GenericBinaryError>(
"duplicate symbol name " +
803 Symbols.emplace_back(LinkingData.
SymbolTable.back(), GlobalType, TableType,
805 LLVM_DEBUG(
dbgs() <<
"Adding symbol: " << Symbols.back() <<
"\n");
811Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
814 for (
unsigned ComdatIndex = 0; ComdatIndex < ComdatCount; ++ComdatIndex) {
817 return make_error<GenericBinaryError>(
"bad/duplicate COMDAT name " +
823 return make_error<GenericBinaryError>(
"unsupported COMDAT flags",
827 while (EntryCount--) {
832 return make_error<GenericBinaryError>(
"invalid COMDAT entry type",
835 if (
Index >= DataSegments.size())
836 return make_error<GenericBinaryError>(
838 if (DataSegments[
Index].
Data.Comdat != UINT32_MAX)
839 return make_error<GenericBinaryError>(
"data segment in two COMDATs",
841 DataSegments[
Index].Data.Comdat = ComdatIndex;
844 if (!isDefinedFunctionIndex(
Index))
845 return make_error<GenericBinaryError>(
847 if (getDefinedFunction(
Index).
Comdat != UINT32_MAX)
848 return make_error<GenericBinaryError>(
"function in two COMDATs",
853 if (
Index >= Sections.size())
854 return make_error<GenericBinaryError>(
857 return make_error<GenericBinaryError>(
859 Sections[
Index].Comdat = ComdatIndex;
867Error WasmObjectFile::parseProducersSection(ReadContext &Ctx) {
870 for (
size_t I = 0;
I < Fields; ++
I) {
872 if (!FieldsSeen.
insert(FieldName).second)
873 return make_error<GenericBinaryError>(
874 "producers section does not have unique fields",
876 std::vector<std::pair<std::string, std::string>> *ProducerVec =
nullptr;
877 if (FieldName ==
"language") {
879 }
else if (FieldName ==
"processed-by") {
880 ProducerVec = &ProducerInfo.
Tools;
881 }
else if (FieldName ==
"sdk") {
882 ProducerVec = &ProducerInfo.
SDKs;
884 return make_error<GenericBinaryError>(
885 "producers section field is not named one of language, processed-by, "
891 for (
size_t J = 0; J < ValueCount; ++J) {
895 return make_error<GenericBinaryError>(
896 "producers section contains repeated producer",
899 ProducerVec->emplace_back(std::string(
Name), std::string(Version));
902 if (Ctx.Ptr != Ctx.End)
903 return make_error<GenericBinaryError>(
"producers section ended prematurely",
908Error WasmObjectFile::parseTargetFeaturesSection(ReadContext &Ctx) {
920 return make_error<GenericBinaryError>(
"unknown feature policy prefix",
924 if (!FeaturesSeen.
insert(Feature.
Name).second)
925 return make_error<GenericBinaryError>(
926 "target features section contains repeated feature \"" +
929 TargetFeatures.push_back(Feature);
931 if (Ctx.Ptr != Ctx.End)
932 return make_error<GenericBinaryError>(
933 "target features section ended prematurely",
940 if (SectionIndex >= Sections.size())
941 return make_error<GenericBinaryError>(
"invalid section index",
947 while (RelocCount--) {
952 if (Reloc.
Offset < PreviousOffset)
953 return make_error<GenericBinaryError>(
"relocations not in offset order",
955 PreviousOffset = Reloc.
Offset;
958 case wasm::R_WASM_FUNCTION_INDEX_LEB:
959 case wasm::R_WASM_FUNCTION_INDEX_I32:
960 case wasm::R_WASM_TABLE_INDEX_SLEB:
961 case wasm::R_WASM_TABLE_INDEX_SLEB64:
962 case wasm::R_WASM_TABLE_INDEX_I32:
963 case wasm::R_WASM_TABLE_INDEX_I64:
964 case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
965 case wasm::R_WASM_TABLE_INDEX_REL_SLEB64:
966 if (!isValidFunctionSymbol(Reloc.
Index))
967 return make_error<GenericBinaryError>(
970 case wasm::R_WASM_TABLE_NUMBER_LEB:
971 if (!isValidTableSymbol(Reloc.
Index))
972 return make_error<GenericBinaryError>(
"invalid relocation table index",
975 case wasm::R_WASM_TYPE_INDEX_LEB:
976 if (Reloc.
Index >= Signatures.size())
977 return make_error<GenericBinaryError>(
"invalid relocation type index",
980 case wasm::R_WASM_GLOBAL_INDEX_LEB:
983 if (!isValidGlobalSymbol(Reloc.
Index) &&
984 !isValidDataSymbol(Reloc.
Index) &&
985 !isValidFunctionSymbol(Reloc.
Index))
986 return make_error<GenericBinaryError>(
"invalid relocation global index",
989 case wasm::R_WASM_GLOBAL_INDEX_I32:
990 if (!isValidGlobalSymbol(Reloc.
Index))
991 return make_error<GenericBinaryError>(
"invalid relocation global index",
994 case wasm::R_WASM_TAG_INDEX_LEB:
995 if (!isValidTagSymbol(Reloc.
Index))
996 return make_error<GenericBinaryError>(
"invalid relocation tag index",
999 case wasm::R_WASM_MEMORY_ADDR_LEB:
1000 case wasm::R_WASM_MEMORY_ADDR_SLEB:
1001 case wasm::R_WASM_MEMORY_ADDR_I32:
1002 case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
1003 case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
1004 case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
1005 if (!isValidDataSymbol(Reloc.
Index))
1006 return make_error<GenericBinaryError>(
"invalid relocation data index",
1010 case wasm::R_WASM_MEMORY_ADDR_LEB64:
1011 case wasm::R_WASM_MEMORY_ADDR_SLEB64:
1012 case wasm::R_WASM_MEMORY_ADDR_I64:
1013 case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
1014 case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64:
1015 if (!isValidDataSymbol(Reloc.
Index))
1016 return make_error<GenericBinaryError>(
"invalid relocation data index",
1020 case wasm::R_WASM_FUNCTION_OFFSET_I32:
1021 if (!isValidFunctionSymbol(Reloc.
Index))
1022 return make_error<GenericBinaryError>(
1026 case wasm::R_WASM_FUNCTION_OFFSET_I64:
1027 if (!isValidFunctionSymbol(Reloc.
Index))
1028 return make_error<GenericBinaryError>(
1032 case wasm::R_WASM_SECTION_OFFSET_I32:
1033 if (!isValidSectionSymbol(Reloc.
Index))
1034 return make_error<GenericBinaryError>(
1039 return make_error<GenericBinaryError>(
"invalid relocation type: " +
1048 if (Reloc.
Type == wasm::R_WASM_MEMORY_ADDR_LEB64 ||
1049 Reloc.
Type == wasm::R_WASM_MEMORY_ADDR_SLEB64 ||
1050 Reloc.
Type == wasm::R_WASM_MEMORY_ADDR_REL_SLEB64)
1052 if (Reloc.
Type == wasm::R_WASM_TABLE_INDEX_I32 ||
1053 Reloc.
Type == wasm::R_WASM_MEMORY_ADDR_I32 ||
1054 Reloc.
Type == wasm::R_WASM_MEMORY_ADDR_LOCREL_I32 ||
1055 Reloc.
Type == wasm::R_WASM_SECTION_OFFSET_I32 ||
1056 Reloc.
Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||
1057 Reloc.
Type == wasm::R_WASM_FUNCTION_INDEX_I32 ||
1058 Reloc.
Type == wasm::R_WASM_GLOBAL_INDEX_I32)
1060 if (Reloc.
Type == wasm::R_WASM_TABLE_INDEX_I64 ||
1061 Reloc.
Type == wasm::R_WASM_MEMORY_ADDR_I64 ||
1062 Reloc.
Type == wasm::R_WASM_FUNCTION_OFFSET_I64)
1065 return make_error<GenericBinaryError>(
"invalid relocation offset",
1068 Section.Relocations.push_back(Reloc);
1070 if (Ctx.Ptr != Ctx.End)
1071 return make_error<GenericBinaryError>(
"reloc section ended prematurely",
1076Error WasmObjectFile::parseCustomSection(
WasmSection &Sec, ReadContext &Ctx) {
1077 if (Sec.
Name ==
"dylink") {
1078 if (
Error Err = parseDylinkSection(Ctx))
1080 }
else if (Sec.
Name ==
"dylink.0") {
1081 if (
Error Err = parseDylink0Section(Ctx))
1083 }
else if (Sec.
Name ==
"name") {
1084 if (
Error Err = parseNameSection(Ctx))
1086 }
else if (Sec.
Name ==
"linking") {
1087 if (
Error Err = parseLinkingSection(Ctx))
1089 }
else if (Sec.
Name ==
"producers") {
1090 if (
Error Err = parseProducersSection(Ctx))
1092 }
else if (Sec.
Name ==
"target_features") {
1093 if (
Error Err = parseTargetFeaturesSection(Ctx))
1096 if (
Error Err = parseRelocSection(Sec.
Name, Ctx))
1102Error WasmObjectFile::parseTypeSection(ReadContext &Ctx) {
1104 Signatures.reserve(Count);
1109 return make_error<GenericBinaryError>(
"invalid signature type",
1114 while (ParamCount--) {
1119 while (ReturnCount--) {
1123 Signatures.push_back(std::move(Sig));
1125 if (Ctx.Ptr != Ctx.End)
1126 return make_error<GenericBinaryError>(
"type section ended prematurely",
1131Error WasmObjectFile::parseImportSection(ReadContext &Ctx) {
1133 uint32_t NumTypes = Signatures.size();
1134 Imports.reserve(Count);
1142 NumImportedFunctions++;
1145 return make_error<GenericBinaryError>(
"invalid function type",
1149 NumImportedGlobals++;
1160 NumImportedTables++;
1164 return make_error<GenericBinaryError>(
"invalid table element type",
1171 return make_error<GenericBinaryError>(
"invalid attribute",
1175 return make_error<GenericBinaryError>(
"invalid tag type",
1179 return make_error<GenericBinaryError>(
"unexpected import kind",
1182 Imports.push_back(Im);
1184 if (Ctx.Ptr != Ctx.End)
1185 return make_error<GenericBinaryError>(
"import section ended prematurely",
1190Error WasmObjectFile::parseFunctionSection(ReadContext &Ctx) {
1192 Functions.reserve(Count);
1193 uint32_t NumTypes = Signatures.size();
1196 if (
Type >= NumTypes)
1197 return make_error<GenericBinaryError>(
"invalid function type",
1201 Functions.push_back(
F);
1203 if (Ctx.Ptr != Ctx.End)
1204 return make_error<GenericBinaryError>(
"function section ended prematurely",
1209Error WasmObjectFile::parseTableSection(ReadContext &Ctx) {
1210 TableSection = Sections.size();
1212 Tables.reserve(Count);
1216 T.Index = NumImportedTables + Tables.size();
1217 Tables.push_back(
T);
1218 auto ElemType = Tables.back().Type.ElemType;
1221 return make_error<GenericBinaryError>(
"invalid table element type",
1225 if (Ctx.Ptr != Ctx.End)
1226 return make_error<GenericBinaryError>(
"table section ended prematurely",
1231Error WasmObjectFile::parseMemorySection(ReadContext &Ctx) {
1233 Memories.reserve(Count);
1238 Memories.push_back(Limits);
1240 if (Ctx.Ptr != Ctx.End)
1241 return make_error<GenericBinaryError>(
"memory section ended prematurely",
1246Error WasmObjectFile::parseTagSection(ReadContext &Ctx) {
1247 TagSection = Sections.size();
1249 Tags.reserve(Count);
1250 uint32_t NumTypes = Signatures.size();
1253 return make_error<GenericBinaryError>(
"invalid attribute",
1256 if (
Type >= NumTypes)
1257 return make_error<GenericBinaryError>(
"invalid tag type",
1260 Tag.Index = NumImportedTags + Tags.size();
1262 Tags.push_back(
Tag);
1265 if (Ctx.Ptr != Ctx.End)
1266 return make_error<GenericBinaryError>(
"tag section ended prematurely",
1271Error WasmObjectFile::parseGlobalSection(ReadContext &Ctx) {
1272 GlobalSection = Sections.size();
1274 Globals.reserve(Count);
1277 Global.Index = NumImportedGlobals + Globals.size();
1282 Globals.push_back(
Global);
1284 if (Ctx.Ptr != Ctx.End)
1285 return make_error<GenericBinaryError>(
"global section ended prematurely",
1290Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
1292 Exports.reserve(Count);
1301 if (!isDefinedFunctionIndex(Ex.
Index))
1302 return make_error<GenericBinaryError>(
"invalid function export",
1307 if (!isValidGlobalIndex(Ex.
Index))
1308 return make_error<GenericBinaryError>(
"invalid global export",
1312 if (!isValidTagIndex(Ex.
Index))
1313 return make_error<GenericBinaryError>(
"invalid tag export",
1320 return make_error<GenericBinaryError>(
"unexpected export kind",
1323 Exports.push_back(Ex);
1325 if (Ctx.Ptr != Ctx.End)
1326 return make_error<GenericBinaryError>(
"export section ended prematurely",
1331bool WasmObjectFile::isValidFunctionIndex(
uint32_t Index)
const {
1332 return Index < NumImportedFunctions + Functions.size();
1335bool WasmObjectFile::isDefinedFunctionIndex(
uint32_t Index)
const {
1336 return Index >= NumImportedFunctions && isValidFunctionIndex(
Index);
1339bool WasmObjectFile::isValidGlobalIndex(
uint32_t Index)
const {
1340 return Index < NumImportedGlobals + Globals.size();
1343bool WasmObjectFile::isValidTableNumber(
uint32_t Index)
const {
1344 return Index < NumImportedTables + Tables.size();
1347bool WasmObjectFile::isDefinedGlobalIndex(
uint32_t Index)
const {
1348 return Index >= NumImportedGlobals && isValidGlobalIndex(
Index);
1351bool WasmObjectFile::isDefinedTableNumber(
uint32_t Index)
const {
1352 return Index >= NumImportedTables && isValidTableNumber(
Index);
1356 return Index < NumImportedTags + Tags.size();
1359bool WasmObjectFile::isDefinedTagIndex(
uint32_t Index)
const {
1360 return Index >= NumImportedTags && isValidTagIndex(
Index);
1363bool WasmObjectFile::isValidFunctionSymbol(
uint32_t Index)
const {
1364 return Index < Symbols.size() && Symbols[
Index].isTypeFunction();
1367bool WasmObjectFile::isValidTableSymbol(
uint32_t Index)
const {
1368 return Index < Symbols.size() && Symbols[
Index].isTypeTable();
1371bool WasmObjectFile::isValidGlobalSymbol(
uint32_t Index)
const {
1372 return Index < Symbols.size() && Symbols[
Index].isTypeGlobal();
1375bool WasmObjectFile::isValidTagSymbol(
uint32_t Index)
const {
1376 return Index < Symbols.size() && Symbols[
Index].isTypeTag();
1379bool WasmObjectFile::isValidDataSymbol(
uint32_t Index)
const {
1380 return Index < Symbols.size() && Symbols[
Index].isTypeData();
1383bool WasmObjectFile::isValidSectionSymbol(
uint32_t Index)
const {
1384 return Index < Symbols.size() && Symbols[
Index].isTypeSection();
1389 return Functions[
Index - NumImportedFunctions];
1395 return Functions[
Index - NumImportedFunctions];
1400 return Globals[
Index - NumImportedGlobals];
1405 return Tags[
Index - NumImportedTags];
1408Error WasmObjectFile::parseStartSection(ReadContext &Ctx) {
1410 if (!isValidFunctionIndex(StartFunction))
1411 return make_error<GenericBinaryError>(
"invalid start function",
1416Error WasmObjectFile::parseCodeSection(ReadContext &Ctx) {
1417 CodeSection = Sections.size();
1419 if (FunctionCount != Functions.size()) {
1420 return make_error<GenericBinaryError>(
"invalid function count",
1424 for (
uint32_t i = 0; i < FunctionCount; i++) {
1426 const uint8_t *FunctionStart = Ctx.Ptr;
1428 const uint8_t *FunctionEnd = Ctx.Ptr +
Size;
1430 Function.CodeOffset = Ctx.Ptr - FunctionStart;
1431 Function.Index = NumImportedFunctions + i;
1432 Function.CodeSectionOffset = FunctionStart - Ctx.Start;
1433 Function.Size = FunctionEnd - FunctionStart;
1436 Function.Locals.reserve(NumLocalDecls);
1437 while (NumLocalDecls--) {
1444 uint32_t BodySize = FunctionEnd - Ctx.Ptr;
1448 Ctx.Ptr += BodySize;
1449 assert(Ctx.Ptr == FunctionEnd);
1451 if (Ctx.Ptr != Ctx.End)
1452 return make_error<GenericBinaryError>(
"code section ended prematurely",
1457Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
1459 ElemSegments.reserve(Count);
1467 if (Segment.
Flags & ~SupportedFlags)
1468 return make_error<GenericBinaryError>(
1476 return make_error<GenericBinaryError>(
"invalid TableNumber",
1493 return make_error<GenericBinaryError>(
"invalid reference type",
1498 return make_error<GenericBinaryError>(
"invalid elemtype",
1507 return make_error<GenericBinaryError>(
1508 "elem segment init expressions not yet implemented",
1512 while (NumElems--) {
1515 ElemSegments.push_back(Segment);
1517 if (Ctx.Ptr != Ctx.End)
1518 return make_error<GenericBinaryError>(
"elem section ended prematurely",
1523Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
1524 DataSection = Sections.size();
1526 if (DataCount && Count != *DataCount)
1527 return make_error<GenericBinaryError>(
1528 "number of data segments does not match DataCount section");
1529 DataSegments.reserve(Count);
1546 if (
Size > (
size_t)(Ctx.End - Ctx.Ptr))
1547 return make_error<GenericBinaryError>(
"invalid segment size",
1557 DataSegments.push_back(Segment);
1559 if (Ctx.Ptr != Ctx.End)
1560 return make_error<GenericBinaryError>(
"data section ended prematurely",
1565Error WasmObjectFile::parseDataCountSection(ReadContext &Ctx) {
1581 if (
Sym.isBindingWeak())
1583 if (!
Sym.isBindingLocal())
1587 if (!
Sym.isDefined())
1589 if (
Sym.isTypeFunction())
1604 Ref.d.b = Symbols.size();
1609 return Symbols[Symb.
d.
b];
1623 isDefinedFunctionIndex(
Sym.Info.ElementIndex))
1630 switch (
Sym.Info.Kind) {
1635 return Sym.Info.ElementIndex;
1675 switch (
Sym.Info.Kind) {
1697 if (
Sym.isUndefined())
1701 Ref.d.a = getSymbolSectionIdImpl(
Sym);
1707 return getSymbolSectionIdImpl(
Sym);
1711 switch (
Sym.Info.Kind) {
1715 return GlobalSection;
1719 return Sym.Info.ElementIndex;
1723 return TableSection;
1781 RelocRef.
d.
a =
Ref.d.a;
1789 RelocRef.
d.
a =
Ref.d.a;
1803 if (Rel.
Type == wasm::R_WASM_TYPE_INDEX_LEB)
1821#define WASM_RELOC(name, value) \
1827#include "llvm/BinaryFormat/WasmRelocs.def"
1832 Result.append(Res.
begin(), Res.
end());
1843 Ref.d.a = Sections.size();
1848 return HasMemory64 ? 8 : 4;
1867 return Sections[
Ref.d.a];
1888int WasmSectionOrderChecker::getSectionOrder(
unsigned ID,
1936 [WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS] = {
1940 {WASM_SEC_ORDER_TYPE, WASM_SEC_ORDER_IMPORT},
1942 {WASM_SEC_ORDER_IMPORT, WASM_SEC_ORDER_FUNCTION},
1944 {WASM_SEC_ORDER_FUNCTION, WASM_SEC_ORDER_TABLE},
1946 {WASM_SEC_ORDER_TABLE, WASM_SEC_ORDER_MEMORY},
1948 {WASM_SEC_ORDER_MEMORY, WASM_SEC_ORDER_TAG},
1950 {WASM_SEC_ORDER_TAG, WASM_SEC_ORDER_GLOBAL},
1952 {WASM_SEC_ORDER_GLOBAL, WASM_SEC_ORDER_EXPORT},
1954 {WASM_SEC_ORDER_EXPORT, WASM_SEC_ORDER_START},
1956 {WASM_SEC_ORDER_START, WASM_SEC_ORDER_ELEM},
1958 {WASM_SEC_ORDER_ELEM, WASM_SEC_ORDER_DATACOUNT},
1960 {WASM_SEC_ORDER_DATACOUNT, WASM_SEC_ORDER_CODE},
1962 {WASM_SEC_ORDER_CODE, WASM_SEC_ORDER_DATA},
1964 {WASM_SEC_ORDER_DATA, WASM_SEC_ORDER_LINKING},
1968 {WASM_SEC_ORDER_DYLINK, WASM_SEC_ORDER_TYPE},
1970 {WASM_SEC_ORDER_LINKING, WASM_SEC_ORDER_RELOC, WASM_SEC_ORDER_NAME},
1974 {WASM_SEC_ORDER_NAME, WASM_SEC_ORDER_PRODUCERS},
1976 {WASM_SEC_ORDER_PRODUCERS, WASM_SEC_ORDER_TARGET_FEATURES},
1978 {WASM_SEC_ORDER_TARGET_FEATURES}};
1982 int Order = getSectionOrder(
ID, CustomSectionName);
1995 for (
size_t I = 0;; ++
I) {
2002 Checked[Next] =
true;
2005 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)
static constexpr uint32_t Opcode
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
const unsigned WASM_SYMBOL_ABSOLUTE
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::@353 d