diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm-binary.h | 8 | ||||
-rw-r--r-- | src/wasm.h | 1 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 88 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 1 |
4 files changed, 90 insertions, 8 deletions
diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 0c95f2b44..d8d712f62 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -403,6 +403,7 @@ namespace UserSections { extern const char* Name; extern const char* SourceMapUrl; extern const char* Dylink; +extern const char* Dylink0; extern const char* Linking; extern const char* Producers; extern const char* TargetFeatures; @@ -435,7 +436,10 @@ enum Subsection { NameElem = 8, NameData = 9, // see: https://github.com/WebAssembly/gc/issues/193 - NameField = 10 + NameField = 10, + + DylinkMemInfo = 1, + DylinkNeeded = 2, }; } // namespace UserSections @@ -1230,6 +1234,7 @@ public: void writeUserSection(const UserSection& section); void writeFeaturesSection(); void writeDylinkSection(); + void writeLegacyDylinkSection(); void initializeDebugInfo(); void writeSourceMapProlog(); @@ -1557,6 +1562,7 @@ public: void readNames(size_t); void readFeatures(size_t); void readDylink(size_t); + void readDylink0(size_t); // Debug information reading helpers void setDebugLocations(std::istream* sourceMap_) { sourceMap = sourceMap_; } diff --git a/src/wasm.h b/src/wasm.h index 2efbbfd9c..d0d904b7c 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1833,6 +1833,7 @@ public: // The optional "dylink" section is used in dynamic linking. class DylinkSection { public: + bool isLegacy = false; Index memorySize, memoryAlignment, tableSize, tableAlignment; std::vector<Name> neededDynlibs; std::vector<char> tail; diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index b6a5daf14..dad6f9320 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1067,7 +1067,7 @@ void WasmBinaryWriter::writeFeaturesSection() { finishSection(start); } -void WasmBinaryWriter::writeDylinkSection() { +void WasmBinaryWriter::writeLegacyDylinkSection() { if (!wasm->dylinkSection) { return; } @@ -1082,9 +1082,41 @@ void WasmBinaryWriter::writeDylinkSection() { for (auto& neededDynlib : wasm->dylinkSection->neededDynlibs) { writeInlineString(neededDynlib.c_str()); } + finishSection(start); +} - writeData(wasm->dylinkSection->tail.data(), wasm->dylinkSection->tail.size()); +void WasmBinaryWriter::writeDylinkSection() { + if (!wasm->dylinkSection) { + return; + } + + if (wasm->dylinkSection->isLegacy) { + writeLegacyDylinkSection(); + return; + } + + auto start = startSection(BinaryConsts::User); + writeInlineString(BinaryConsts::UserSections::Dylink0); + + auto substart = + startSubsection(BinaryConsts::UserSections::Subsection::DylinkMemInfo); + o << U32LEB(wasm->dylinkSection->memorySize); + o << U32LEB(wasm->dylinkSection->memoryAlignment); + o << U32LEB(wasm->dylinkSection->tableSize); + o << U32LEB(wasm->dylinkSection->tableAlignment); + finishSubsection(substart); + + if (wasm->dylinkSection->neededDynlibs.size()) { + substart = + startSubsection(BinaryConsts::UserSections::Subsection::DylinkNeeded); + o << U32LEB(wasm->dylinkSection->neededDynlibs.size()); + for (auto& neededDynlib : wasm->dylinkSection->neededDynlibs) { + writeInlineString(neededDynlib.c_str()); + } + finishSubsection(substart); + } + writeData(wasm->dylinkSection->tail.data(), wasm->dylinkSection->tail.size()); finishSection(start); } @@ -1435,6 +1467,7 @@ void WasmBinaryBuilder::read() { } void WasmBinaryBuilder::readUserSection(size_t payloadLen) { + BYN_TRACE("== readUserSection\n"); auto oldPos = pos; Name sectionName = getInlineString(); size_t read = pos - oldPos; @@ -1452,6 +1485,8 @@ void WasmBinaryBuilder::readUserSection(size_t payloadLen) { readFeatures(payloadLen); } else if (sectionName.equals(BinaryConsts::UserSections::Dylink)) { readDylink(payloadLen); + } else if (sectionName.equals(BinaryConsts::UserSections::Dylink0)) { + readDylink0(payloadLen); } else { // an unfamiliar custom section if (sectionName.equals(BinaryConsts::UserSections::Linking)) { @@ -3252,6 +3287,7 @@ void WasmBinaryBuilder::readDylink(size_t payloadLen) { auto sectionPos = pos; + wasm.dylinkSection->isLegacy = true; wasm.dylinkSection->memorySize = getU32LEB(); wasm.dylinkSection->memoryAlignment = getU32LEB(); wasm.dylinkSection->tableSize = getU32LEB(); @@ -3262,12 +3298,50 @@ void WasmBinaryBuilder::readDylink(size_t payloadLen) { wasm.dylinkSection->neededDynlibs.push_back(getInlineString()); } - size_t remaining = (sectionPos + payloadLen) - pos; - auto tail = getByteView(remaining); - wasm.dylinkSection->tail = {tail.first, tail.second}; - if (pos != sectionPos + payloadLen) { - throwError("bad features section size"); + throwError("bad dylink section size"); + } +} + +void WasmBinaryBuilder::readDylink0(size_t payloadLen) { + BYN_TRACE("== readDylink0\n"); + auto sectionPos = pos; + uint32_t lastType = 0; + + wasm.dylinkSection = make_unique<DylinkSection>(); + while (pos < sectionPos + payloadLen) { + auto oldPos = pos; + auto dylinkType = getU32LEB(); + if (lastType && dylinkType <= lastType) { + std::cerr << "warning: out-of-order dylink.0 subsection: " << dylinkType + << std::endl; + } + lastType = dylinkType; + auto subsectionSize = getU32LEB(); + auto subsectionPos = pos; + if (dylinkType == BinaryConsts::UserSections::Subsection::DylinkMemInfo) { + wasm.dylinkSection->memorySize = getU32LEB(); + wasm.dylinkSection->memoryAlignment = getU32LEB(); + wasm.dylinkSection->tableSize = getU32LEB(); + wasm.dylinkSection->tableAlignment = getU32LEB(); + } else if (dylinkType == + BinaryConsts::UserSections::Subsection::DylinkNeeded) { + size_t numNeededDynlibs = getU32LEB(); + for (size_t i = 0; i < numNeededDynlibs; ++i) { + wasm.dylinkSection->neededDynlibs.push_back(getInlineString()); + } + } else { + // Unknown subsection. Stop parsing now and store the rest of + // the section verbatim. + pos = oldPos; + size_t remaining = (sectionPos + payloadLen) - pos; + auto tail = getByteView(remaining); + wasm.dylinkSection->tail = {tail.first, tail.second}; + break; + } + if (pos != subsectionPos + subsectionSize) { + throwError("bad dylink.0 subsection position change"); + } } } diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 761c17116..2861c4cee 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -31,6 +31,7 @@ namespace UserSections { const char* Name = "name"; const char* SourceMapUrl = "sourceMappingURL"; const char* Dylink = "dylink"; +const char* Dylink0 = "dylink.0"; const char* Linking = "linking"; const char* Producers = "producers"; const char* TargetFeatures = "target_features"; |