Skip to content

Commit 14cfe9f

Browse files
committed
Add _umtx_op shim to freebsd
This fixes the `concurrent-panic.rs` test on freebsd Signed-off-by: InfRandomness <[email protected]>
1 parent 984b46c commit 14cfe9f

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed

src/shims/unix/freebsd/foreign_items.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use rustc_middle::mir;
22
use rustc_span::Symbol;
33
use rustc_target::spec::abi::Abi;
44

5+
use crate::shims::unix::freebsd::futex::futex;
56
use crate::*;
67
use shims::foreign_items::EmulateByNameResult;
78

@@ -32,6 +33,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
3233
this.write_scalar(errno_place.to_ref(this).to_scalar()?, dest)?;
3334
}
3435

36+
// Futex, equivalent to Linux's SYS_futex syscall
37+
"_umtx_op" => {
38+
let [obj, op, val, uaddr, uaddr2] =
39+
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
40+
futex(
41+
this,
42+
obj,
43+
this.read_scalar(op)?.to_i32()?,
44+
this.read_scalar(val)?.to_u64()?,
45+
uaddr,
46+
uaddr2,
47+
);
48+
this.write_scalar(Scalar::from_i32(1), dest)?;
49+
}
3550
_ => return Ok(EmulateByNameResult::NotSupported),
3651
}
3752
Ok(EmulateByNameResult::NeedsJumping)

src/shims/unix/freebsd/futex.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use crate::helpers::EvalContextExt as HEvalContext;
2+
use crate::sync::EvalContextExt as SEvalContext;
3+
use crate::thread::EvalContextExt as TEvalContext;
4+
use crate::InterpResult;
5+
use crate::OpTy;
6+
use crate::{MiriEvalContext, Tag};
7+
8+
enum OpType {
9+
UmtxOpWait = 2,
10+
//TODO: other types
11+
}
12+
13+
impl TryFrom<i32> for OpType {
14+
type Error = &'static str;
15+
16+
fn try_from(value: i32) -> Result<Self, Self::Error> {
17+
match value {
18+
2 => Ok(OpType::UmtxOpWait),
19+
_ => Err("Unsupported Futex operation"),
20+
}
21+
}
22+
}
23+
24+
pub fn futex<'tcx>(
25+
this: &mut MiriEvalContext<'_, 'tcx>,
26+
obj: &OpTy<'tcx, Tag>,
27+
op: i32,
28+
val: u64,
29+
uaddr: &OpTy<'tcx, Tag>,
30+
uaddr2: &OpTy<'tcx, Tag>,
31+
) -> Option<InterpResult<'tcx>> {
32+
// Object to operate on
33+
let obj = obj;
34+
// Operation type
35+
let _op_type = op;
36+
// Current value pointed to by `obj`
37+
let val = val;
38+
// Pointer that's purpose depends on the op_type
39+
let _uaddr = this.read_pointer(uaddr).ok()?;
40+
// Pointer that's purpose depends on the op_type
41+
let _uaddr2 = this.read_pointer(uaddr2).ok()?;
42+
match OpType::try_from(op) {
43+
Ok(op) =>
44+
match op {
45+
OpType::UmtxOpWait =>
46+
if this.read_scalar(obj).ok()?.to_u64().ok()? == val {
47+
this.futex_wait(
48+
this.read_scalar(obj).ok()?.to_u64().ok()?,
49+
this.get_active_thread(),
50+
u32::MAX,
51+
);
52+
None
53+
} else {
54+
// The `val` value is invalid. Double check this against the manual.
55+
let einval = this.eval_libc("EINVAL").ok()?;
56+
this.set_last_error(einval).ok()?;
57+
None
58+
},
59+
},
60+
Err(_) => {
61+
// The `op` value is invalid.
62+
let einval = this.eval_libc("EINVAL").ok()?;
63+
this.set_last_error(einval).ok()?;
64+
None
65+
}
66+
}
67+
}

src/shims/unix/freebsd/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pub mod dlsym;
22
pub mod foreign_items;
3+
pub mod futex;

0 commit comments

Comments
 (0)