spike: validate WASM phase 0
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Phase 0 helper: dump a wasm module's imports, exports, and dylink.0
|
||||
custom section (memory/table size requirements). Doubles as the reference
|
||||
for the loader's dylink.0 parsing (§6 step 4)."""
|
||||
import sys, struct
|
||||
|
||||
def uleb(buf, pos):
|
||||
result = 0
|
||||
shift = 0
|
||||
while True:
|
||||
b = buf[pos]
|
||||
pos += 1
|
||||
result |= (b & 0x7f) << shift
|
||||
if not (b & 0x80):
|
||||
return result, pos
|
||||
shift += 7
|
||||
|
||||
def name(buf, pos):
|
||||
n, pos = uleb(buf, pos)
|
||||
return buf[pos:pos+n].decode("utf-8", "replace"), pos + n
|
||||
|
||||
def limits(buf, pos):
|
||||
flags = buf[pos]; pos += 1
|
||||
mn, pos = uleb(buf, pos)
|
||||
mx = None
|
||||
if flags & 1:
|
||||
mx, pos = uleb(buf, pos)
|
||||
return (mn, mx), pos
|
||||
|
||||
KIND = {0: "func", 1: "table", 2: "memory", 3: "global"}
|
||||
VALTYPE = {0x7f: "i32", 0x7e: "i64", 0x7d: "f32", 0x7c: "f64", 0x70: "funcref", 0x6f: "externref"}
|
||||
|
||||
def main(fn):
|
||||
buf = open(fn, "rb").read()
|
||||
assert buf[:8] == b"\0asm\x01\0\0\0", "not a wasm module"
|
||||
pos = 8
|
||||
while pos < len(buf):
|
||||
sec_id = buf[pos]; pos += 1
|
||||
size, pos = uleb(buf, pos)
|
||||
end = pos + size
|
||||
if sec_id == 0:
|
||||
sname, p = name(buf, pos)
|
||||
if sname == "dylink.0":
|
||||
print("== dylink.0 ==")
|
||||
while p < end:
|
||||
sub = buf[p]; p += 1
|
||||
sublen, p = uleb(buf, p)
|
||||
subend = p + sublen
|
||||
if sub == 1: # WASM_DYLINK_MEM_INFO
|
||||
memsize, p2 = uleb(buf, p)
|
||||
memalign, p2 = uleb(buf, p2)
|
||||
tabsize, p2 = uleb(buf, p2)
|
||||
tabalign, p2 = uleb(buf, p2)
|
||||
print(f" mem_info: memsize={memsize} memalign=2^{memalign} tablesize={tabsize} tablealign=2^{tabalign}")
|
||||
else:
|
||||
print(f" subsection type={sub} len={sublen}")
|
||||
p = subend
|
||||
elif sname in ("uce.abi",):
|
||||
print(f"== custom section {sname} ({end - p} bytes) ==")
|
||||
elif sec_id == 2:
|
||||
count, p = uleb(buf, pos)
|
||||
print(f"== imports ({count}) ==")
|
||||
for _ in range(count):
|
||||
mod, p = name(buf, p)
|
||||
nm, p = name(buf, p)
|
||||
kind = buf[p]; p += 1
|
||||
detail = ""
|
||||
if kind == 0:
|
||||
_, p = uleb(buf, p)
|
||||
elif kind == 1:
|
||||
et = buf[p]; p += 1
|
||||
lim, p = limits(buf, p)
|
||||
detail = f" {VALTYPE.get(et, hex(et))} {lim}"
|
||||
elif kind == 2:
|
||||
lim, p = limits(buf, p)
|
||||
detail = f" {lim}"
|
||||
elif kind == 3:
|
||||
vt = buf[p]; p += 1
|
||||
mut = buf[p]; p += 1
|
||||
detail = f" {VALTYPE.get(vt, hex(vt))}{' mut' if mut else ''}"
|
||||
print(f" {KIND.get(kind, kind):6} {mod}.{nm}{detail}")
|
||||
elif sec_id == 7:
|
||||
count, p = uleb(buf, pos)
|
||||
print(f"== exports ({count}) ==")
|
||||
for _ in range(count):
|
||||
nm, p = name(buf, p)
|
||||
kind = buf[p]; p += 1
|
||||
_, p = uleb(buf, p)
|
||||
print(f" {KIND.get(kind, kind):6} {nm}")
|
||||
pos = end
|
||||
|
||||
if __name__ == "__main__":
|
||||
for fn in sys.argv[1:]:
|
||||
print(f"### {fn}")
|
||||
main(fn)
|
||||
Reference in New Issue
Block a user