Skip to content

Commit c27040e

Browse files
authored
read unknown users sections as binary data stored on the Module (WebAssembly#918)
1 parent a32c0ef commit c27040e

6 files changed

Lines changed: 79 additions & 4 deletions

File tree

src/passes/Print.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,11 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
735735
visitFunction(child.get());
736736
o << maybeNewLine;
737737
}
738+
for (auto& section : curr->userSections) {
739+
doIndent(o, indent);
740+
o << ";; custom section \"" << section.name << "\", size " << section.data.size();
741+
o << maybeNewLine;
742+
}
738743
decIndent();
739744
o << maybeNewLine;
740745
currModule = nullptr;

src/wasm-binary.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,7 @@ class WasmBinaryBuilder {
638638
WasmBinaryBuilder(Module& wasm, std::vector<char>& input, bool debug) : wasm(wasm), allocator(wasm.allocator), input(input), debug(debug) {}
639639

640640
void read();
641-
void readUserSection();
641+
void readUserSection(size_t payloadLen);
642642
bool more() { return pos < input.size();}
643643

644644
uint8_t getInt8();

src/wasm.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,6 +1528,14 @@ class Global {
15281528
bool mutable_;
15291529
};
15301530

1531+
// "Opaque" data, not part of the core wasm spec, that is held in binaries.
1532+
// May be parsed/handled by utility code elsewhere, but not in wasm.h
1533+
class UserSection {
1534+
public:
1535+
std::string name;
1536+
std::vector<char> data;
1537+
};
1538+
15311539
class Module {
15321540
public:
15331541
// wasm contents (generally you shouldn't access these from outside, except maybe for iterating; use add*() and the get() functions)
@@ -1541,6 +1549,8 @@ class Module {
15411549
Memory memory;
15421550
Name start;
15431551

1552+
std::vector<UserSection> userSections;
1553+
15441554
MixedArena allocator;
15451555

15461556
private:

src/wasm/wasm-binary.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,8 @@ void WasmBinaryBuilder::read() {
951951
case BinaryConsts::Section::Data: readDataSegments(); break;
952952
case BinaryConsts::Section::Table: readFunctionTableDeclaration(); break;
953953
default: {
954-
readUserSection();
954+
readUserSection(payloadLen);
955+
assert(pos <= oldPos + payloadLen);
955956
pos = oldPos + payloadLen;
956957
}
957958
}
@@ -963,12 +964,21 @@ void WasmBinaryBuilder::read() {
963964
processFunctions();
964965
}
965966

966-
void WasmBinaryBuilder::readUserSection() {
967+
void WasmBinaryBuilder::readUserSection(size_t payloadLen) {
968+
auto oldPos = pos;
967969
Name sectionName = getInlineString();
968970
if (sectionName.equals(BinaryConsts::UserSections::Name)) {
969971
readNames();
970972
} else {
971-
std::cerr << "unfamiliar section: " << sectionName << std::endl;
973+
// an unfamiliar custom section
974+
wasm.userSections.resize(wasm.userSections.size() + 1);
975+
auto& section = wasm.userSections.back();
976+
section.name = sectionName.str;
977+
auto sectionSize = payloadLen - (pos - oldPos);
978+
section.data.resize(sectionSize);
979+
for (size_t i = 0; i < sectionSize; i++) {
980+
section.data[i] = getInt8();
981+
}
972982
}
973983
}
974984

test/dylib.wasm

306 Bytes
Binary file not shown.

test/dylib.wasm.fromBinary

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
(module
2+
(type $0 (func (param i32) (result i32)))
3+
(type $1 (func (result i32)))
4+
(type $2 (func))
5+
(import "env" "memoryBase" (global $import$0 i32))
6+
(import "env" "_puts" (func $import$1 (param i32) (result i32)))
7+
(import "env" "memory" (memory $0 256))
8+
(import "env" "table" (table 0 anyfunc))
9+
(import "env" "tableBase" (global $import$4 i32))
10+
(global $global$0 (mut i32) (i32.const 0))
11+
(global $global$1 (mut i32) (i32.const 0))
12+
(global $global$2 i32 (i32.const 0))
13+
(data (get_global $import$0) "hello, world!")
14+
(export "__post_instantiate" (func $2))
15+
(export "_main" (func $0))
16+
(export "runPostSets" (func $1))
17+
(export "_str" (global $global$2))
18+
(func $0 (type $1) (result i32)
19+
(block $label$0 i32
20+
(drop
21+
(call $import$1
22+
(get_global $import$0)
23+
)
24+
)
25+
(i32.const 0)
26+
)
27+
)
28+
(func $1 (type $2)
29+
(nop)
30+
)
31+
(func $2 (type $2)
32+
(block $label$0
33+
(set_global $global$0
34+
(i32.add
35+
(get_global $import$0)
36+
(i32.const 16)
37+
)
38+
)
39+
(set_global $global$1
40+
(i32.add
41+
(get_global $global$0)
42+
(i32.const 5242880)
43+
)
44+
)
45+
(call $1)
46+
)
47+
)
48+
;; custom section "dylink", size 5
49+
)
50+

0 commit comments

Comments
 (0)