The best way for an outside program to access certain data from a WebAssembly binary is using a custom section.
For example, given this code:
#[link_section = "my-data"]
pub static FIRST: [u8; 13] = *b"Hello, World!";
#[link_section = "some-more-data"]
pub static SECOND: [u8; 6] = [1, 2, 3, 4, 5, 6];
// you can add more data to the same section
#[link_section = "my-data"]
pub static THIRD: [u8; 4] = u32::to_be_bytes(0xdead_beef);
I can compile it to a *.wasm
file and use the wasm-objdump
from WABT to see where the different sections are.
$ wasm-objdump --headers custom_sections.wasm
custom_sections.wasm: file format wasm 0x1
Sections:
Table start=0x0000000a end=0x0000000f (size=0x00000005) count: 1
Memory start=0x00000011 end=0x00000014 (size=0x00000003) count: 1
Global start=0x00000016 end=0x0000002f (size=0x00000019) count: 3
Export start=0x00000031 end=0x00000056 (size=0x00000025) count: 3
Custom start=0x0000005a end=0x00063bf2 (size=0x00063b98) ".debug_info"
Custom start=0x00063bf5 end=0x00063d49 (size=0x00000154) ".debug_pubtypes"
Custom start=0x00063d4d end=0x0008f1eb (size=0x0002b49e) ".debug_ranges"
Custom start=0x0008f1ee end=0x00090247 (size=0x00001059) ".debug_abbrev"
Custom start=0x00090249 end=0x0009025e (size=0x00000015) "some-more-data"
Custom start=0x00090262 end=0x000d1ea5 (size=0x00041c43) ".debug_line"
Custom start=0x000d1ea7 end=0x000d1ec0 (size=0x00000019) "my-data"
Custom start=0x000d1ec4 end=0x0017980c (size=0x000a7948) ".debug_str"
Custom start=0x00179810 end=0x001b7df2 (size=0x0003e5e2) ".debug_pubnames"
Custom start=0x001b7df4 end=0x001b7e0d (size=0x00000019) "name"
Custom start=0x001b7e0f end=0x001b7e64 (size=0x00000055) "producers"
I can also inspect the my-data
sections.
$ wasm-objdump --section=my-data --full-contents custom_sections.wasm
custom_sections.wasm: file format wasm 0x1
Contents of section Custom:
00d1ea7: 076d 792d 6461 7461 4865 6c6c 6f2c 2057 .my-dataHello, W
00d1eb7: 6f72 6c64 21de adbe ef orld!....
You'll notice the bytes for Hello, World!
and 0xdead_beef
have been concatenated. Depending on your data, you may need to set things up so there's a way to tell when one variable ends and another begins (e.g. by prefixing each section of bytes with its length).
Most WebAssembly libraries have a way for reading custom sections. For example, the wasmparser
crate has a Payload::CustomSection(...)
variant, and in the browser you can use WebAssembly.Module.customSections()
.
Of course, your WebAssembly binary can use FIRST
, SECOND
, and THIRD
just like any other static
variable.