summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/wasm-binary.h8
-rw-r--r--src/wasm.h1
-rw-r--r--src/wasm/wasm-binary.cpp88
-rw-r--r--src/wasm/wasm.cpp1
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";