bytecodealliance / lucet

Lucet, the Sandboxing WebAssembly Compiler.
Apache License 2.0
4.07k stars 165 forks source link

Use of global for data offset causes lucetc error #169

Open kanaka opened 5 years ago

kanaka commented 5 years ago

Consider the following code:

(module

  (memory 1)
  (global $memoryBase i32 (i32.const 0))
  (data
    (global.get $memoryBase)
    "abcd")

  (func $main (nop))

  (export "_start" (func $main))
)

Attempting to compile with lucetc-wasi has the following results (shows from .wat followed by from .wasm):

# lucetc-wasi wasitests/data_global_offset.wat -o wasitests/data_global_offset.so
Error(Validate("test.wast:6:6: error: initializer expression can only reference an imported global\n    (global.get $memoryBase)\n     ^^^^^^^^^^\n"))

# wasm-as wasitests/data_global_offset.wat -o wasitests/data_global_offset.wasm
# lucetc-wasi wasitests/data_global_offset.wasm -o wasitests/data_global_offset.so
LucetcError { inner: ErrorMessage { msg: "cannot create sparse data: data initializer uses global as base" }

Unsupported }

wasm-as has no problem compiling the module and wasmtime has no problem running the resulting module.

pchickey commented 5 years ago

Hi @kanaka, thanks for the report. This is a known bug - we don't support import globals, or the use of globals in init expressions yet. We didn't prioritize implementing these because none of the toolchains we use emits them, but we plan to implement them soon as part of spec compliance.

awortman-fastly commented 5 years ago

Hi! Following up on this: I've been working on import/export and globals support lately, and there's a few angles to this one:

First, I think wasm-as might be in the wrong in accepting your example program. As the first quoted error indicates, validation failed, but wasm-as happily accepts. That lead me to The Spec:

Indeed, the following program:

(module

  (global $memoryBase (import "env" "mem_base") i32)
  (memory 1)
  (data
    (global.get $memoryBase)
    "abcd")

  (func $main (nop))

  (export "_start" (func $main))
)

validates and is rejected by lucetc later. There's a small digression about what wasm-as actually produces, but it looks like the right program assuming the global.get constraint is loosened.

With regard to the second program, that's definitely on us. While imported globals are supported lucetc (as of #204), the runtime provides no mechanism to satisfy imported globals (à la bindings.json for import functions/hostcalls), so it will fall over there instead.

I'm hoping to spend some time this week adjusting the data representation to be amenable to a runtime-defined base, whichever way globals pans out.