Skip to content

Cannot use 0 as an address in wasm in with opt-level >= 1 #57897

@surma

Description

@surma

I want to use Rust to work on the raw chunk of memory that WebAssembly creates for me. Consider the following rust code:

#![no_std]
#![no_main]

use core::panic::PanicInfo;
use core::slice::from_raw_parts_mut;

#[no_mangle]
fn test() {
  let in_b: &mut [u32];

  unsafe {
    in_b = from_raw_parts_mut::<u32>(0 as *mut u32, 3);
  }

  in_b[0] = 123;
}


#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
  loop {}
}

Compile with

rustc --target=wasm32-unknown-unknown -o rust.wasm rotate.rs

And load with this HTML file:

<!DOCTYPE html>
<script>
  async function init() {
    const { instance } = await WebAssembly.instantiate(
      await fetch("/rust.wasm").then(r => r.arrayBuffer())
    );
    instance.exports.test();
    console.log(new Uint32Array(instance.exports.memory.buffer, 0).slice(0, 3));
  }
  init();
</script>

This will work fine (i.e. no errors).

If you add -C opt-level=1 (or 2 or 3) to the rustc invocation, the wasm module will fail with unreachable.

If you change the rust code as following

-    in_b = from_raw_parts_mut::<u32>(0 as *mut u32, 3);
+    in_b = from_raw_parts_mut::<u32>(4 as *mut u32, 3);

the code will work again.

I think if I can use 0 as an address in a debug build I should also be able to do it in release mode 😄

cc @ashleygwilliams

Metadata

Metadata

Assignees

No one assigned

    Labels

    O-wasmTarget: WASM (WebAssembly), http://webassembly.org/

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions