Skip to content

Commit 26f0681

Browse files
authored
Merge pull request #449 from filecoin-project/fix/syscall-abi
Use repr(packed, C) for syscall types
2 parents 02bf297 + c6072f1 commit 26f0681

File tree

11 files changed

+81
-21
lines changed

11 files changed

+81
-21
lines changed

fvm/CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
Changes to the reference FVM implementation.
44

5-
## [Unreleased]
5+
## 0.7.0 [UNRELEASED]
6+
7+
This release contains exactly one (breaking) change.
8+
9+
BREAKING: Updates the FVM to the latest syscall struct alignment
10+
(https://github.com/filecoin-project/fvm-specs/issues/63).
611

712
## 0.6.0 [2022-04-13]
813

fvm/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ ahash = "0.7"
2020
num-derive = "0.3.3"
2121
cid = { version = "0.8.2", default-features = false, features = ["serde-codec"] }
2222
multihash = { version = "0.16.1", default-features = false }
23-
fvm_shared = { version = "0.5.1", path = "../shared", features = ["crypto"] }
23+
fvm_shared = { version = "0.6.0", path = "../shared", features = ["crypto"] }
2424
fvm_ipld_hamt = { version = "0.5.0", path = "../ipld/hamt"}
2525
fvm_ipld_amt = { version = "0.4.0", path = "../ipld/amt"}
2626
fvm_ipld_blockstore = { version = "0.1.0", path = "../ipld/blockstore" }

fvm/src/syscalls/bind.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::mem;
22

33
use fvm_shared::error::ErrorNumber;
4+
use fvm_shared::sys::SyscallSafe;
45
use wasmtime::{Caller, Linker, Trap, WasmTy};
56

67
use super::context::Memory;
@@ -50,14 +51,14 @@ pub(super) trait BindSyscall<Args, Ret, Func> {
5051
/// results that can be handled by wasmtime. See the documentation on `BindSyscall` for details.
5152
#[doc(hidden)]
5253
pub trait IntoSyscallResult: Sized {
53-
type Value: Copy + Sized + 'static;
54+
type Value: SyscallSafe;
5455
fn into(self) -> Result<Result<Self::Value, SyscallError>, Abort>;
5556
}
5657

5758
// Implementations for syscalls that abort on error.
5859
impl<T> IntoSyscallResult for Result<T, Abort>
5960
where
60-
T: Copy + Sized + 'static,
61+
T: SyscallSafe,
6162
{
6263
type Value = T;
6364
fn into(self) -> Result<Result<Self::Value, SyscallError>, Abort> {
@@ -68,7 +69,7 @@ where
6869
// Implementations for normal syscalls.
6970
impl<T> IntoSyscallResult for kernel::Result<T>
7071
where
71-
T: Copy + Sized + 'static,
72+
T: SyscallSafe,
7273
{
7374
type Value = T;
7475
fn into(self) -> Result<Result<Self::Value, SyscallError>, Abort> {
@@ -135,7 +136,7 @@ macro_rules! impl_bind_syscalls {
135136
K: Kernel,
136137
Func: Fn(Context<'_, K> $(, $t)*) -> Ret + Send + Sync + 'static,
137138
Ret: IntoSyscallResult,
138-
$($t: WasmTy,)*
139+
$($t: WasmTy+SyscallSafe,)*
139140
{
140141
fn bind(
141142
&mut self,

fvm/src/syscalls/vm.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use fvm_shared::error::ExitCode;
2+
use fvm_shared::sys::SyscallSafe;
23
use fvm_shared::version::NetworkVersion;
34

45
use super::error::Abort;
@@ -11,6 +12,8 @@ use crate::Kernel;
1112
#[derive(Copy, Clone)]
1213
pub enum Never {}
1314

15+
unsafe impl SyscallSafe for Never {}
16+
1417
// NOTE: this won't clobber the last syscall error because it directly returns a "trap".
1518
pub fn abort(
1619
context: Context<'_, impl Kernel>,

sdk/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
## [Unreleased]
44

5+
## 0.6.0 [2022-04-14]
6+
7+
BREAKING: Upgrades to fvm_shared 0.6.0, and the new syscall struct alignment.
8+
https://github.com/filecoin-project/fvm-specs/issues/63
9+
510
## 0.5.0 [2022-04-11]
611

712
Upgrades the SDK to fvm_shared 0.5.0. This release includes a significant breaking change to exit codes.

sdk/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "fvm_sdk"
33
description = "Filecoin Virtual Machine actor development SDK"
4-
version = "0.5.0"
4+
version = "0.6.0"
55
license = "MIT OR Apache-2.0"
66
authors = ["Protocol Labs", "Filecoin Core Devs"]
77
edition = "2018"
@@ -12,7 +12,7 @@ crate-type = ["lib"]
1212

1313
[dependencies]
1414
cid = { version = "0.8.2", default-features = false }
15-
fvm_shared = { version = "0.5.1", path = "../shared" }
15+
fvm_shared = { version = "0.6.0", path = "../shared" }
1616
## num-traits; disabling default features makes it play nice with no_std.
1717
num-traits = { version = "0.2.14", default-features = false }
1818
lazy_static = { version = "1.4.0", optional = true }

shared/CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# Changelog
22

3-
## [Unreleased]
3+
## 0.6.0 [2022-04-14]
4+
5+
BREAKING: Switch syscall struct alignment: https://github.com/filecoin-project/fvm-specs/issues/63
6+
7+
Actors built against this new version of fvm_shared will be incompatible with prior FVM versions,
8+
and vice-versa.
49

510
## 0.5.1 [2022-04-11]
611

shared/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "fvm_shared"
33
description = "Filecoin Virtual Machine shared types and functions"
4-
version = "0.5.1"
4+
version = "0.6.0"
55
edition = "2021"
66
license = "MIT OR Apache-2.0"
77
authors = ["ChainSafe Systems <[email protected]>", "Protocol Labs", "Filecoin Core Devs"]

shared/src/sys/mod.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ pub type Codec = u64;
1111
///
1212
/// Internally, this type is a tuple of `u64`s storing the "low" and "high" bits of a little-endian
1313
/// u128.
14-
#[repr(C)]
1514
#[derive(Debug, Copy, Clone)]
15+
#[repr(packed, C)]
1616
pub struct TokenAmount {
1717
pub lo: u64,
1818
pub hi: u64,
@@ -43,3 +43,38 @@ impl<'a> TryFrom<&'a crate::econ::TokenAmount> for TokenAmount {
4343
})
4444
}
4545
}
46+
47+
/// An unsafe trait to mark "syscall safe" types. These types must be safe to memcpy to and from
48+
/// WASM. This means:
49+
///
50+
/// 1. Repr C & packed alignment (no reordering, no padding).
51+
/// 2. Copy, Sized, and no pointers.
52+
/// 3. No floats (non-determinism).
53+
///
54+
/// # Safety
55+
///
56+
/// Incorrectly implementing this could lead to undefined behavior in types passed between wasm and
57+
/// rust.
58+
pub unsafe trait SyscallSafe: Copy + Sized + 'static {}
59+
60+
macro_rules! assert_syscall_safe {
61+
($($t:ty,)*) => {
62+
$(unsafe impl SyscallSafe for $t {})*
63+
}
64+
}
65+
66+
assert_syscall_safe! {
67+
(),
68+
69+
u8, u16, u32, u64,
70+
i8, i16, i32, i64,
71+
72+
TokenAmount,
73+
out::actor::ResolveAddress,
74+
out::ipld::IpldOpen,
75+
out::ipld::IpldStat,
76+
out::send::Send,
77+
out::crypto::VerifyConsensusFault,
78+
}
79+
80+
unsafe impl<T, const N: usize> SyscallSafe for [T; N] where T: SyscallSafe {}

shared/src/sys/out.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,33 @@
77
//!
88
//! Read more at https://github.com/rust-lang/rust/issues/73755.
99
10+
// NOTE: When possible, pack fields such that loads will be power-of-two aligned. Un-aligned loads
11+
// _can_ be done (LLVM will generate the appropriate code) but are slower.
12+
//
13+
// Read up on https://doc.rust-lang.org/reference/type-layout.html for more information.
14+
//
15+
// Also, please also read the docs on super::SyscallSafe before modifying any of these types.
16+
1017
pub mod actor {
11-
#[repr(C)]
1218
#[derive(Debug, Copy, Clone)]
19+
#[repr(packed, C)]
1320
pub struct ResolveAddress {
14-
pub resolved: i32,
1521
pub value: u64,
22+
pub resolved: i32,
1623
}
1724
}
1825

1926
pub mod ipld {
20-
#[repr(C)]
2127
#[derive(Debug, Copy, Clone)]
28+
#[repr(packed, C)]
2229
pub struct IpldOpen {
23-
/// TODO could be more efficient to align id, size, codec, depending on padding.
24-
pub id: u32,
2530
pub codec: u64,
31+
pub id: u32,
2632
pub size: u32,
2733
}
2834

29-
#[repr(C)]
3035
#[derive(Debug, Copy, Clone)]
36+
#[repr(packed, C)]
3137
pub struct IpldStat {
3238
pub codec: u64,
3339
pub size: u32,
@@ -37,8 +43,8 @@ pub mod ipld {
3743
pub mod send {
3844
use crate::sys::BlockId;
3945

40-
#[repr(C)]
4146
#[derive(Debug, Copy, Clone)]
47+
#[repr(packed, C)]
4248
pub struct Send {
4349
pub exit_code: u32,
4450
pub return_id: BlockId,
@@ -48,11 +54,11 @@ pub mod send {
4854
pub mod crypto {
4955
use crate::{ActorID, ChainEpoch};
5056

51-
#[repr(C)]
5257
#[derive(Debug, Copy, Clone)]
58+
#[repr(packed, C)]
5359
pub struct VerifyConsensusFault {
54-
pub fault: u32,
5560
pub epoch: ChainEpoch,
5661
pub target: ActorID,
62+
pub fault: u32,
5763
}
5864
}

0 commit comments

Comments
 (0)