Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix alignment and padding of the WASIX snapshot type to align with wasix-libc #5259

Merged
merged 2 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion lib/wasi-types/src/wasi/wasix_manual.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,31 @@ pub union EventUnion {
#[repr(C)]
pub struct StackSnapshot {
pub user: u64,
pub hash: u128,
// The hash is defined as two u64s in wasix-libc, so we must do the same
// here to make sure the alignment and padding are the same.
pub hash_lower: u64,
pub hash_upper: u64,
}

impl StackSnapshot {
pub fn new(user: u64, hash: u128) -> Self {
Self {
user,
Arshia001 marked this conversation as resolved.
Show resolved Hide resolved
hash_lower: (hash & 0xffff_ffff_ffff_ffff) as u64,
hash_upper: (hash >> 64) as u64,
}
}

pub fn hash(&self) -> u128 {
((self.hash_upper as u128) << 64) | (self.hash_lower as u128)
}
}

#[test]
fn snapshot_hash_roundtrip() {
let hash = 0x1234_5678_90ab_cdef_0987_6543_fedc_ba12;
let snapshot = StackSnapshot::new(0, hash);
assert_eq!(snapshot.hash(), hash);
}

/// An event that occurred.
Expand Down
9 changes: 3 additions & 6 deletions lib/wasix/src/syscalls/wasix/stack_checkpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub fn stack_checkpoint<M: MemorySize>(

// We clear the target memory location before we grab the stack so that
// it correctly hashes
if let Err(err) = snapshot_ptr.write(&memory, StackSnapshot { hash: 0, user: 0 }) {
if let Err(err) = snapshot_ptr.write(&memory, StackSnapshot::new(0, 0)) {
warn!(
%err
);
Expand Down Expand Up @@ -67,10 +67,7 @@ pub fn stack_checkpoint<M: MemorySize>(
};

// Build a stack snapshot
let snapshot = StackSnapshot {
hash,
user: ret_offset.into(),
};
let snapshot = StackSnapshot::new(ret_offset.into(), hash);

// Get a reference directly to the bytes of snapshot
let val_bytes = unsafe {
Expand Down Expand Up @@ -115,7 +112,7 @@ pub fn stack_checkpoint<M: MemorySize>(
&rewind_stack[..],
&store_data[..],
);
trace!(hash = snapshot.hash, user = snapshot.user);
trace!(hash = snapshot.hash(), user = snapshot.user);

// Save the stack snapshot
let env = ctx.data();
Expand Down
6 changes: 3 additions & 3 deletions lib/wasix/src/syscalls/wasix/stack_restore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub fn stack_restore<M: MemorySize>(
let memory = unsafe { env.memory_view(&ctx) };
let snapshot = match snapshot_ptr.read(&memory) {
Ok(a) => {
trace!("with_ret={}, hash={}, user={}", val, a.hash, a.user);
trace!("with_ret={}, hash={}, user={}", val, a.hash(), a.user);
a
}
Err(err) => {
Expand All @@ -33,7 +33,7 @@ pub fn stack_restore<M: MemorySize>(
// Let the stack (or fail trying!)
let env = ctx.data();
if let Some((mut memory_stack, rewind_stack, store_data)) =
env.thread.get_snapshot(snapshot.hash)
env.thread.get_snapshot(snapshot.hash())
{
let env = ctx.data();
let memory = unsafe { env.memory_view(&ctx) };
Expand Down Expand Up @@ -61,7 +61,7 @@ pub fn stack_restore<M: MemorySize>(
} else {
warn!(
"snapshot stack restore failed - the snapshot can not be found and hence restored (hash={})",
snapshot.hash
snapshot.hash()
);
OnCalledAction::Trap(Box::new(WasiError::Exit(Errno::Unknown.into())))
}
Expand Down
43 changes: 43 additions & 0 deletions tests/wasix/setjmp-longjmp/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <sys/types.h>

int main()
{
// Put variables on both ends to make sure the setjmp
// code doesn't overwrite anything by mistake
unsigned long long int before = 10;
jmp_buf jmp;
unsigned long long int after = 20;

if (setjmp(jmp) == 0)
{
if (before != 10 || after != 20)
{
printf("oops 1\n");
exit(1);
}
longjmp(jmp, 1);
printf("oops 2\n");
exit(2);
}
else
{
if (before != 10 || after != 20)
{
printf("oops 3\n");
exit(3);
}
before = 50;
after = 60;
}

if (before != 50 || after != 60)
{
printf("oops 4\n");
exit(4);
}

return 0;
}
3 changes: 3 additions & 0 deletions tests/wasix/setjmp-longjmp/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

$WASMER -q run main.wasm
Loading