Skip to content

Commit fbe501e

Browse files
committed
Auto merge of rust-lang#103721 - RalfJung:miri, r=RalfJung
update Miri Noteworthy PRs: - rust-lang/miri#2624 - rust-lang/miri#2626 - rust-lang/miri#2630 - rust-lang/miri#2631
2 parents b776a79 + 6bbf016 commit fbe501e

25 files changed

+346
-74
lines changed

.github/workflows/ci.yml

+4-8
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ on:
1010
branches:
1111
- 'master'
1212
schedule:
13-
- cron: '5 15 * * *' # At 15:05 UTC every day.
13+
- cron: '6 6 * * *' # At 6:06 UTC every day.
1414

1515
env:
1616
CARGO_UNSTABLE_SPARSE_REGISTRY: 'true'
@@ -24,16 +24,12 @@ jobs:
2424
strategy:
2525
fail-fast: false
2626
matrix:
27-
build: [linux64, macos, win32]
2827
include:
29-
- build: linux64
30-
os: ubuntu-latest
28+
- os: ubuntu-latest
3129
host_target: x86_64-unknown-linux-gnu
32-
- build: macos
33-
os: macos-latest
30+
- os: macos-latest
3431
host_target: x86_64-apple-darwin
35-
- build: win32
36-
os: windows-latest
32+
- os: windows-latest
3733
host_target: i686-pc-windows-msvc
3834
steps:
3935
- uses: actions/checkout@v3

ci.sh

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ case $HOST_TARGET in
9393
;;
9494
i686-pc-windows-msvc)
9595
MIRI_TEST_TARGET=x86_64-unknown-linux-gnu run_tests
96+
MIRI_TEST_TARGET=x86_64-pc-windows-gnu run_tests
9697
;;
9798
*)
9899
echo "FATAL: unknown OS"

src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ pub use crate::eval::{
9898
pub use crate::helpers::{CurrentSpan, EvalContextExt as _};
9999
pub use crate::intptrcast::ProvenanceMode;
100100
pub use crate::machine::{
101-
AllocExtra, FrameData, MiriInterpCx, MiriInterpCxExt, MiriMachine, MiriMemoryKind, Provenance,
102-
ProvenanceExtra, PAGE_SIZE, STACK_ADDR, STACK_SIZE,
101+
AllocExtra, FrameData, MiriInterpCx, MiriInterpCxExt, MiriMachine, MiriMemoryKind,
102+
PrimitiveLayouts, Provenance, ProvenanceExtra, PAGE_SIZE, STACK_ADDR, STACK_SIZE,
103103
};
104104
pub use crate::mono_hash_map::MonoHashMap;
105105
pub use crate::operator::EvalContextExt as _;

src/machine.rs

+30
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,14 @@ pub struct PrimitiveLayouts<'tcx> {
276276
pub i8: TyAndLayout<'tcx>,
277277
pub i16: TyAndLayout<'tcx>,
278278
pub i32: TyAndLayout<'tcx>,
279+
pub i64: TyAndLayout<'tcx>,
280+
pub i128: TyAndLayout<'tcx>,
279281
pub isize: TyAndLayout<'tcx>,
280282
pub u8: TyAndLayout<'tcx>,
281283
pub u16: TyAndLayout<'tcx>,
282284
pub u32: TyAndLayout<'tcx>,
285+
pub u64: TyAndLayout<'tcx>,
286+
pub u128: TyAndLayout<'tcx>,
283287
pub usize: TyAndLayout<'tcx>,
284288
pub bool: TyAndLayout<'tcx>,
285289
pub mut_raw_ptr: TyAndLayout<'tcx>, // *mut ()
@@ -296,16 +300,42 @@ impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> {
296300
i8: layout_cx.layout_of(tcx.types.i8)?,
297301
i16: layout_cx.layout_of(tcx.types.i16)?,
298302
i32: layout_cx.layout_of(tcx.types.i32)?,
303+
i64: layout_cx.layout_of(tcx.types.i64)?,
304+
i128: layout_cx.layout_of(tcx.types.i128)?,
299305
isize: layout_cx.layout_of(tcx.types.isize)?,
300306
u8: layout_cx.layout_of(tcx.types.u8)?,
301307
u16: layout_cx.layout_of(tcx.types.u16)?,
302308
u32: layout_cx.layout_of(tcx.types.u32)?,
309+
u64: layout_cx.layout_of(tcx.types.u64)?,
310+
u128: layout_cx.layout_of(tcx.types.u128)?,
303311
usize: layout_cx.layout_of(tcx.types.usize)?,
304312
bool: layout_cx.layout_of(tcx.types.bool)?,
305313
mut_raw_ptr: layout_cx.layout_of(mut_raw_ptr)?,
306314
const_raw_ptr: layout_cx.layout_of(const_raw_ptr)?,
307315
})
308316
}
317+
318+
pub fn uint(&self, size: Size) -> Option<TyAndLayout<'tcx>> {
319+
match size.bits() {
320+
8 => Some(self.u8),
321+
16 => Some(self.u16),
322+
32 => Some(self.u32),
323+
64 => Some(self.u64),
324+
128 => Some(self.u128),
325+
_ => None,
326+
}
327+
}
328+
329+
pub fn int(&self, size: Size) -> Option<TyAndLayout<'tcx>> {
330+
match size.bits() {
331+
8 => Some(self.i8),
332+
16 => Some(self.i16),
333+
32 => Some(self.i32),
334+
64 => Some(self.i64),
335+
128 => Some(self.i128),
336+
_ => None,
337+
}
338+
}
309339
}
310340

311341
/// The machine itself.

src/shims/intrinsics/mod.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_middle::{
1111
mir,
1212
ty::{self, FloatTy, Ty},
1313
};
14-
use rustc_target::abi::Integer;
14+
use rustc_target::abi::{Integer, Size};
1515

1616
use crate::*;
1717
use atomic::EvalContextExt as _;
@@ -120,6 +120,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
120120
this.write_bytes_ptr(ptr, iter::repeat(val_byte).take(byte_count.bytes_usize()))?;
121121
}
122122

123+
"ptr_mask" => {
124+
let [ptr, mask] = check_arg_count(args)?;
125+
126+
let ptr = this.read_pointer(ptr)?;
127+
let mask = this.read_scalar(mask)?.to_machine_usize(this)?;
128+
129+
let masked_addr = Size::from_bytes(ptr.addr().bytes() & mask);
130+
131+
this.write_pointer(Pointer::new(ptr.provenance, masked_addr), dest)?;
132+
}
133+
123134
// Floating-point operations
124135
"fabsf32" => {
125136
let [f] = check_arg_count(args)?;

src/shims/unix/linux/sync.rs

+13-27
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
use std::time::SystemTime;
2+
13
use crate::concurrency::thread::{MachineCallback, Time};
24
use crate::*;
3-
use rustc_target::abi::{Align, Size};
4-
use std::time::SystemTime;
55

66
/// Implementation of the SYS_futex syscall.
77
/// `args` is the arguments *after* the syscall number.
@@ -28,13 +28,14 @@ pub fn futex<'tcx>(
2828
// The first three arguments (after the syscall number itself) are the same to all futex operations:
2929
// (int *addr, int op, int val).
3030
// We checked above that these definitely exist.
31-
let addr = this.read_immediate(&args[0])?;
31+
let addr = this.read_pointer(&args[0])?;
3232
let op = this.read_scalar(&args[1])?.to_i32()?;
3333
let val = this.read_scalar(&args[2])?.to_i32()?;
3434

3535
let thread = this.get_active_thread();
36-
let addr_scalar = addr.to_scalar();
37-
let addr_usize = addr_scalar.to_machine_usize(this)?;
36+
// This is a vararg function so we have to bring our own type for this pointer.
37+
let addr = MPlaceTy::from_aligned_ptr(addr, this.machine.layouts.i32);
38+
let addr_usize = addr.ptr.addr().bytes();
3839

3940
let futex_private = this.eval_libc_i32("FUTEX_PRIVATE_FLAG")?;
4041
let futex_wait = this.eval_libc_i32("FUTEX_WAIT")?;
@@ -89,9 +90,11 @@ pub fn futex<'tcx>(
8990
let timeout_time = if this.ptr_is_null(timeout.ptr)? {
9091
None
9192
} else {
92-
this.check_no_isolation(
93-
"`futex` syscall with `op=FUTEX_WAIT` and non-null timeout",
94-
)?;
93+
if op & futex_realtime != 0 {
94+
this.check_no_isolation(
95+
"`futex` syscall with `op=FUTEX_WAIT` and non-null timeout with `FUTEX_CLOCK_REALTIME`",
96+
)?;
97+
}
9598
let duration = match this.read_timespec(&timeout)? {
9699
Some(duration) => duration,
97100
None => {
@@ -117,15 +120,6 @@ pub fn futex<'tcx>(
117120
}
118121
})
119122
};
120-
// Check the pointer for alignment and validity.
121-
// The API requires `addr` to be a 4-byte aligned pointer, and will
122-
// use the 4 bytes at the given address as an (atomic) i32.
123-
this.check_ptr_access_align(
124-
addr_scalar.to_pointer(this)?,
125-
Size::from_bytes(4),
126-
Align::from_bytes(4).unwrap(),
127-
CheckInAllocMsg::MemoryAccessTest,
128-
)?;
129123
// There may be a concurrent thread changing the value of addr
130124
// and then invoking the FUTEX_WAKE syscall. It is critical that the
131125
// effects of this and the other thread are correctly observed,
@@ -172,14 +166,7 @@ pub fn futex<'tcx>(
172166
this.atomic_fence(AtomicFenceOrd::SeqCst)?;
173167
// Read an `i32` through the pointer, regardless of any wrapper types.
174168
// It's not uncommon for `addr` to be passed as another type than `*mut i32`, such as `*const AtomicI32`.
175-
let futex_val = this
176-
.read_scalar_at_offset_atomic(
177-
&addr.into(),
178-
0,
179-
this.machine.layouts.i32,
180-
AtomicReadOrd::Relaxed,
181-
)?
182-
.to_i32()?;
169+
let futex_val = this.read_scalar_atomic(&addr, AtomicReadOrd::Relaxed)?.to_i32()?;
183170
if val == futex_val {
184171
// The value still matches, so we block the thread make it wait for FUTEX_WAKE.
185172
this.block_thread(thread);
@@ -214,11 +201,10 @@ pub fn futex<'tcx>(
214201
}
215202
}
216203

217-
let dest = dest.clone();
218204
this.register_timeout_callback(
219205
thread,
220206
timeout_time,
221-
Box::new(Callback { thread, addr_usize, dest }),
207+
Box::new(Callback { thread, addr_usize, dest: dest.clone() }),
222208
);
223209
}
224210
} else {

src/shims/unix/macos/foreign_items.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
177177
let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
178178
let thread = this.pthread_self()?;
179179
let max_len = this.eval_libc("MAXTHREADNAMESIZE")?.to_machine_usize(this)?;
180-
this.pthread_setname_np(
180+
let res = this.pthread_setname_np(
181181
thread,
182182
this.read_scalar(name)?,
183183
max_len.try_into().unwrap(),
184184
)?;
185+
// Contrary to the manpage, `pthread_setname_np` on macOS still
186+
// returns an integer indicating success.
187+
this.write_scalar(res, dest)?;
185188
}
186189
"pthread_getname_np" => {
187190
let [thread, name, len] =

src/shims/unix/sync.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -743,8 +743,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
743743
) -> InterpResult<'tcx> {
744744
let this = self.eval_context_mut();
745745

746-
this.check_no_isolation("`pthread_cond_timedwait`")?;
747-
748746
let id = this.condvar_get_or_create_id(cond_op, CONDVAR_ID_OFFSET)?;
749747
let mutex_id = this.mutex_get_or_create_id(mutex_op, MUTEX_ID_OFFSET)?;
750748
let active_thread = this.get_active_thread();
@@ -761,6 +759,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
761759
};
762760

763761
let timeout_time = if clock_id == this.eval_libc_i32("CLOCK_REALTIME")? {
762+
this.check_no_isolation("`pthread_cond_timedwait` with `CLOCK_REALTIME`")?;
764763
Time::RealTime(SystemTime::UNIX_EPOCH.checked_add(duration).unwrap())
765764
} else if clock_id == this.eval_libc_i32("CLOCK_MONOTONIC")? {
766765
Time::Monotonic(this.machine.clock.anchor().checked_add(duration).unwrap())

src/shims/windows/dlsym.rs

+15
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@ use log::trace;
66

77
use crate::helpers::check_arg_count;
88
use crate::shims::windows::handle::{EvalContextExt as _, Handle, PseudoHandle};
9+
use crate::shims::windows::sync::EvalContextExt as _;
910
use crate::*;
1011

1112
#[derive(Debug, Copy, Clone)]
1213
pub enum Dlsym {
1314
NtWriteFile,
1415
SetThreadDescription,
16+
WaitOnAddress,
17+
WakeByAddressSingle,
1518
}
1619

1720
impl Dlsym {
@@ -22,6 +25,8 @@ impl Dlsym {
2225
"GetSystemTimePreciseAsFileTime" => None,
2326
"NtWriteFile" => Some(Dlsym::NtWriteFile),
2427
"SetThreadDescription" => Some(Dlsym::SetThreadDescription),
28+
"WaitOnAddress" => Some(Dlsym::WaitOnAddress),
29+
"WakeByAddressSingle" => Some(Dlsym::WakeByAddressSingle),
2530
_ => throw_unsup_format!("unsupported Windows dlsym: {}", name),
2631
})
2732
}
@@ -127,6 +132,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
127132

128133
this.write_null(dest)?;
129134
}
135+
Dlsym::WaitOnAddress => {
136+
let [ptr_op, compare_op, size_op, timeout_op] = check_arg_count(args)?;
137+
138+
this.WaitOnAddress(ptr_op, compare_op, size_op, timeout_op, dest)?;
139+
}
140+
Dlsym::WakeByAddressSingle => {
141+
let [ptr_op] = check_arg_count(args)?;
142+
143+
this.WakeByAddressSingle(ptr_op)?;
144+
}
130145
}
131146

132147
trace!("{:?}", this.dump_place(**dest));

0 commit comments

Comments
 (0)