Skip to content

Commit b0c3bd3

Browse files
committed
Support new dylink.0 custom section format
See also: llvm change: https://reviews.llvm.org/D109595 wabt change: WebAssembly/wabt#1707 emscripten change: emscripten-core/emscripten#15019
1 parent fc310a6 commit b0c3bd3

File tree

6 files changed

+93
-11
lines changed

6 files changed

+93
-11
lines changed

src/wasm-binary.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ namespace UserSections {
403403
extern const char* Name;
404404
extern const char* SourceMapUrl;
405405
extern const char* Dylink;
406+
extern const char* Dylink0;
406407
extern const char* Linking;
407408
extern const char* Producers;
408409
extern const char* TargetFeatures;
@@ -435,7 +436,10 @@ enum Subsection {
435436
NameElem = 8,
436437
NameData = 9,
437438
// see: https://github.com/WebAssembly/gc/issues/193
438-
NameField = 10
439+
NameField = 10,
440+
441+
DylinkMemInfo = 1,
442+
DylinkNeeded = 2,
439443
};
440444

441445
} // namespace UserSections
@@ -1230,6 +1234,7 @@ class WasmBinaryWriter {
12301234
void writeUserSection(const UserSection& section);
12311235
void writeFeaturesSection();
12321236
void writeDylinkSection();
1237+
void writeLegacyDylinkSection();
12331238

12341239
void initializeDebugInfo();
12351240
void writeSourceMapProlog();
@@ -1557,6 +1562,7 @@ class WasmBinaryBuilder {
15571562
void readNames(size_t);
15581563
void readFeatures(size_t);
15591564
void readDylink(size_t);
1565+
void readDylink0(size_t);
15601566

15611567
// Debug information reading helpers
15621568
void setDebugLocations(std::istream* sourceMap_) { sourceMap = sourceMap_; }

src/wasm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,6 +1833,7 @@ class UserSection {
18331833
// The optional "dylink" section is used in dynamic linking.
18341834
class DylinkSection {
18351835
public:
1836+
bool isLegacy = false;
18361837
Index memorySize, memoryAlignment, tableSize, tableAlignment;
18371838
std::vector<Name> neededDynlibs;
18381839
std::vector<char> tail;

src/wasm/wasm-binary.cpp

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,7 +1067,7 @@ void WasmBinaryWriter::writeFeaturesSection() {
10671067
finishSection(start);
10681068
}
10691069

1070-
void WasmBinaryWriter::writeDylinkSection() {
1070+
void WasmBinaryWriter::writeLegacyDylinkSection() {
10711071
if (!wasm->dylinkSection) {
10721072
return;
10731073
}
@@ -1082,9 +1082,41 @@ void WasmBinaryWriter::writeDylinkSection() {
10821082
for (auto& neededDynlib : wasm->dylinkSection->neededDynlibs) {
10831083
writeInlineString(neededDynlib.c_str());
10841084
}
1085+
finishSection(start);
1086+
}
10851087

1086-
writeData(wasm->dylinkSection->tail.data(), wasm->dylinkSection->tail.size());
1088+
void WasmBinaryWriter::writeDylinkSection() {
1089+
if (!wasm->dylinkSection) {
1090+
return;
1091+
}
1092+
1093+
if (wasm->dylinkSection->isLegacy) {
1094+
writeLegacyDylinkSection();
1095+
return;
1096+
}
1097+
1098+
auto start = startSection(BinaryConsts::User);
1099+
writeInlineString(BinaryConsts::UserSections::Dylink0);
1100+
1101+
auto substart =
1102+
startSubsection(BinaryConsts::UserSections::Subsection::DylinkMemInfo);
1103+
o << U32LEB(wasm->dylinkSection->memorySize);
1104+
o << U32LEB(wasm->dylinkSection->memoryAlignment);
1105+
o << U32LEB(wasm->dylinkSection->tableSize);
1106+
o << U32LEB(wasm->dylinkSection->tableAlignment);
1107+
finishSubsection(substart);
1108+
1109+
if (wasm->dylinkSection->neededDynlibs.size()) {
1110+
substart =
1111+
startSubsection(BinaryConsts::UserSections::Subsection::DylinkNeeded);
1112+
o << U32LEB(wasm->dylinkSection->neededDynlibs.size());
1113+
for (auto& neededDynlib : wasm->dylinkSection->neededDynlibs) {
1114+
writeInlineString(neededDynlib.c_str());
1115+
}
1116+
finishSubsection(substart);
1117+
}
10871118

1119+
writeData(wasm->dylinkSection->tail.data(), wasm->dylinkSection->tail.size());
10881120
finishSection(start);
10891121
}
10901122

@@ -1435,6 +1467,7 @@ void WasmBinaryBuilder::read() {
14351467
}
14361468

14371469
void WasmBinaryBuilder::readUserSection(size_t payloadLen) {
1470+
BYN_TRACE("== readUserSection\n");
14381471
auto oldPos = pos;
14391472
Name sectionName = getInlineString();
14401473
size_t read = pos - oldPos;
@@ -1452,6 +1485,8 @@ void WasmBinaryBuilder::readUserSection(size_t payloadLen) {
14521485
readFeatures(payloadLen);
14531486
} else if (sectionName.equals(BinaryConsts::UserSections::Dylink)) {
14541487
readDylink(payloadLen);
1488+
} else if (sectionName.equals(BinaryConsts::UserSections::Dylink0)) {
1489+
readDylink0(payloadLen);
14551490
} else {
14561491
// an unfamiliar custom section
14571492
if (sectionName.equals(BinaryConsts::UserSections::Linking)) {
@@ -3252,6 +3287,7 @@ void WasmBinaryBuilder::readDylink(size_t payloadLen) {
32523287

32533288
auto sectionPos = pos;
32543289

3290+
wasm.dylinkSection->isLegacy = true;
32553291
wasm.dylinkSection->memorySize = getU32LEB();
32563292
wasm.dylinkSection->memoryAlignment = getU32LEB();
32573293
wasm.dylinkSection->tableSize = getU32LEB();
@@ -3262,12 +3298,50 @@ void WasmBinaryBuilder::readDylink(size_t payloadLen) {
32623298
wasm.dylinkSection->neededDynlibs.push_back(getInlineString());
32633299
}
32643300

3265-
size_t remaining = (sectionPos + payloadLen) - pos;
3266-
auto tail = getByteView(remaining);
3267-
wasm.dylinkSection->tail = {tail.first, tail.second};
3268-
32693301
if (pos != sectionPos + payloadLen) {
3270-
throwError("bad features section size");
3302+
throwError("bad dylink section size");
3303+
}
3304+
}
3305+
3306+
void WasmBinaryBuilder::readDylink0(size_t payloadLen) {
3307+
BYN_TRACE("== readDylink0\n");
3308+
auto sectionPos = pos;
3309+
uint32_t lastType = 0;
3310+
3311+
wasm.dylinkSection = make_unique<DylinkSection>();
3312+
while (pos < sectionPos + payloadLen) {
3313+
auto oldPos = pos;
3314+
auto dylinkType = getU32LEB();
3315+
if (lastType && dylinkType <= lastType) {
3316+
std::cerr << "warning: out-of-order dylink.0 subsection: " << dylinkType
3317+
<< std::endl;
3318+
}
3319+
lastType = dylinkType;
3320+
auto subsectionSize = getU32LEB();
3321+
auto subsectionPos = pos;
3322+
if (dylinkType == BinaryConsts::UserSections::Subsection::DylinkMemInfo) {
3323+
wasm.dylinkSection->memorySize = getU32LEB();
3324+
wasm.dylinkSection->memoryAlignment = getU32LEB();
3325+
wasm.dylinkSection->tableSize = getU32LEB();
3326+
wasm.dylinkSection->tableAlignment = getU32LEB();
3327+
} else if (dylinkType ==
3328+
BinaryConsts::UserSections::Subsection::DylinkNeeded) {
3329+
size_t numNeededDynlibs = getU32LEB();
3330+
for (size_t i = 0; i < numNeededDynlibs; ++i) {
3331+
wasm.dylinkSection->neededDynlibs.push_back(getInlineString());
3332+
}
3333+
} else {
3334+
// Unknown subsection. Stop parsing now and store the rest of
3335+
// the section verbatim.
3336+
pos = oldPos;
3337+
size_t remaining = (sectionPos + payloadLen) - pos;
3338+
auto tail = getByteView(remaining);
3339+
wasm.dylinkSection->tail = {tail.first, tail.second};
3340+
break;
3341+
}
3342+
if (pos != subsectionPos + subsectionSize) {
3343+
throwError("bad dylink.0 subsection position change");
3344+
}
32713345
}
32723346
}
32733347

src/wasm/wasm.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ namespace UserSections {
3131
const char* Name = "name";
3232
const char* SourceMapUrl = "sourceMappingURL";
3333
const char* Dylink = "dylink";
34+
const char* Dylink0 = "dylink.0";
3435
const char* Linking = "linking";
3536
const char* Producers = "producers";
3637
const char* TargetFeatures = "target_features";

test/lit/binary/dylink.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
# `dylink.test.wasm` was generated using emscripten to build a side
44
# module with two TLS exports (which adds extra information to the
55
# dylink section) using:
6-
# `emcc -s SIDE_MODULE side.c`
6+
# `emcc -s USE_PTHREAD -s SIDE_MODULE side.c`
77
#
88
# side.c:
99
# _Thread_local int foo = 10;
1010
# _Thread_local int bar = 11;
1111
#
12-
# and then removing all sections except the dylink section using:
13-
# `llvm-objcopy --only-section=dylink`
12+
# and then removing all sections except the dylink.0 section using:
13+
# `llvm-objcopy --only-section=dylink.0`
1414
RUN: wasm-opt -O1 %s.wasm -o %t.o
1515
RUN: cmp %s.wasm %t.o

test/lit/binary/dylink.test.wasm

3 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)