Skip to content

Commit a9dc279

Browse files
committed
Move get/set_at_offset helpers to global helpers file
1 parent e54619b commit a9dc279

File tree

2 files changed

+45
-70
lines changed

2 files changed

+45
-70
lines changed

src/helpers.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,37 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
467467
}
468468
}
469469
}
470+
471+
fn read_scalar_at_offset(
472+
&self,
473+
op: OpTy<'tcx, Tag>,
474+
offset: u64,
475+
layout: TyAndLayout<'tcx>,
476+
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
477+
let this = self.eval_context_ref();
478+
let op_place = this.deref_operand(op)?;
479+
let offset = Size::from_bytes(offset);
480+
// Ensure that the following read at an offset is within bounds
481+
assert!(op_place.layout.size >= offset + layout.size);
482+
let value_place = op_place.offset(offset, MemPlaceMeta::None, layout, this)?;
483+
this.read_scalar(value_place.into())
484+
}
485+
486+
fn write_scalar_at_offset(
487+
&mut self,
488+
op: OpTy<'tcx, Tag>,
489+
offset: u64,
490+
value: impl Into<ScalarMaybeUninit<Tag>>,
491+
layout: TyAndLayout<'tcx>,
492+
) -> InterpResult<'tcx, ()> {
493+
let this = self.eval_context_mut();
494+
let op_place = this.deref_operand(op)?;
495+
let offset = Size::from_bytes(offset);
496+
// Ensure that the following read at an offset is within bounds
497+
assert!(op_place.layout.size >= offset + layout.size);
498+
let value_place = op_place.offset(offset, MemPlaceMeta::None, layout, this)?;
499+
this.write_scalar(value, value_place.into())
500+
}
470501
}
471502

472503
/// Check that the number of args is what we expect.

src/shims/posix/sync.rs

Lines changed: 14 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -2,57 +2,11 @@ use std::convert::TryInto;
22
use std::time::{Duration, SystemTime};
33
use std::ops::Not;
44

5-
use rustc_middle::ty::{layout::TyAndLayout, TyKind, TypeAndMut};
6-
use rustc_target::abi::{LayoutOf, Size};
7-
85
use crate::*;
96
use stacked_borrows::Tag;
107
use thread::Time;
118

129

13-
fn assert_ptr_target_min_size<'mir, 'tcx: 'mir>(
14-
ecx: &MiriEvalContext<'mir, 'tcx>,
15-
operand: OpTy<'tcx, Tag>,
16-
min_size: u64,
17-
) -> InterpResult<'tcx, ()> {
18-
let target_ty = match operand.layout.ty.kind {
19-
TyKind::RawPtr(TypeAndMut { ty, mutbl: _ }) => ty,
20-
_ => panic!("Argument to pthread function was not a raw pointer"),
21-
};
22-
let target_layout = ecx.layout_of(target_ty)?;
23-
assert!(target_layout.size.bytes() >= min_size);
24-
Ok(())
25-
}
26-
27-
fn get_at_offset<'mir, 'tcx: 'mir>(
28-
ecx: &MiriEvalContext<'mir, 'tcx>,
29-
op: OpTy<'tcx, Tag>,
30-
offset: u64,
31-
layout: TyAndLayout<'tcx>,
32-
min_size: u64,
33-
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
34-
// Ensure that the following read at an offset to the attr pointer is within bounds
35-
assert_ptr_target_min_size(ecx, op, min_size)?;
36-
let op_place = ecx.deref_operand(op)?;
37-
let value_place = op_place.offset(Size::from_bytes(offset), MemPlaceMeta::None, layout, ecx)?;
38-
ecx.read_scalar(value_place.into())
39-
}
40-
41-
fn set_at_offset<'mir, 'tcx: 'mir>(
42-
ecx: &mut MiriEvalContext<'mir, 'tcx>,
43-
op: OpTy<'tcx, Tag>,
44-
offset: u64,
45-
value: impl Into<ScalarMaybeUninit<Tag>>,
46-
layout: TyAndLayout<'tcx>,
47-
min_size: u64,
48-
) -> InterpResult<'tcx, ()> {
49-
// Ensure that the following write at an offset to the attr pointer is within bounds
50-
assert_ptr_target_min_size(ecx, op, min_size)?;
51-
let op_place = ecx.deref_operand(op)?;
52-
let value_place = op_place.offset(Size::from_bytes(offset), MemPlaceMeta::None, layout, ecx)?;
53-
ecx.write_scalar(value.into(), value_place.into())
54-
}
55-
5610
// pthread_mutexattr_t is either 4 or 8 bytes, depending on the platform.
5711

5812
// Our chosen memory layout for emulation (does not have to match the platform layout!):
@@ -66,8 +20,6 @@ fn set_at_offset<'mir, 'tcx: 'mir>(
6620
/// in `pthread_mutexattr_settype` function.
6721
const PTHREAD_MUTEX_NORMAL_FLAG: i32 = 0x8000000;
6822

69-
const PTHREAD_MUTEXATTR_T_MIN_SIZE: u64 = 4;
70-
7123
fn is_mutex_kind_default<'mir, 'tcx: 'mir>(
7224
ecx: &mut MiriEvalContext<'mir, 'tcx>,
7325
kind: Scalar<Tag>,
@@ -88,15 +40,15 @@ fn mutexattr_get_kind<'mir, 'tcx: 'mir>(
8840
ecx: &MiriEvalContext<'mir, 'tcx>,
8941
attr_op: OpTy<'tcx, Tag>,
9042
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
91-
get_at_offset(ecx, attr_op, 0, ecx.machine.layouts.i32, PTHREAD_MUTEXATTR_T_MIN_SIZE)
43+
ecx.read_scalar_at_offset(attr_op, 0, ecx.machine.layouts.i32)
9244
}
9345

9446
fn mutexattr_set_kind<'mir, 'tcx: 'mir>(
9547
ecx: &mut MiriEvalContext<'mir, 'tcx>,
9648
attr_op: OpTy<'tcx, Tag>,
9749
kind: impl Into<ScalarMaybeUninit<Tag>>,
9850
) -> InterpResult<'tcx, ()> {
99-
set_at_offset(ecx, attr_op, 0, kind, ecx.machine.layouts.i32, PTHREAD_MUTEXATTR_T_MIN_SIZE)
51+
ecx.write_scalar_at_offset(attr_op, 0, kind, ecx.machine.layouts.i32)
10052
}
10153

10254
// pthread_mutex_t is between 24 and 48 bytes, depending on the platform.
@@ -108,14 +60,12 @@ fn mutexattr_set_kind<'mir, 'tcx: 'mir>(
10860
// bytes 12-15 or 16-19 (depending on platform): mutex kind, as an i32
10961
// (the kind has to be at its offset for compatibility with static initializer macros)
11062

111-
const PTHREAD_MUTEX_T_MIN_SIZE: u64 = 24;
112-
11363
fn mutex_get_kind<'mir, 'tcx: 'mir>(
11464
ecx: &mut MiriEvalContext<'mir, 'tcx>,
11565
mutex_op: OpTy<'tcx, Tag>,
11666
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
11767
let offset = if ecx.pointer_size().bytes() == 8 { 16 } else { 12 };
118-
get_at_offset(ecx, mutex_op, offset, ecx.machine.layouts.i32, PTHREAD_MUTEX_T_MIN_SIZE)
68+
ecx.read_scalar_at_offset(mutex_op, offset, ecx.machine.layouts.i32)
11969
}
12070

12171
fn mutex_set_kind<'mir, 'tcx: 'mir>(
@@ -124,22 +74,22 @@ fn mutex_set_kind<'mir, 'tcx: 'mir>(
12474
kind: impl Into<ScalarMaybeUninit<Tag>>,
12575
) -> InterpResult<'tcx, ()> {
12676
let offset = if ecx.pointer_size().bytes() == 8 { 16 } else { 12 };
127-
set_at_offset(ecx, mutex_op, offset, kind, ecx.machine.layouts.i32, PTHREAD_MUTEX_T_MIN_SIZE)
77+
ecx.write_scalar_at_offset(mutex_op, offset, kind, ecx.machine.layouts.i32)
12878
}
12979

13080
fn mutex_get_id<'mir, 'tcx: 'mir>(
13181
ecx: &MiriEvalContext<'mir, 'tcx>,
13282
mutex_op: OpTy<'tcx, Tag>,
13383
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
134-
get_at_offset(ecx, mutex_op, 4, ecx.machine.layouts.u32, PTHREAD_MUTEX_T_MIN_SIZE)
84+
ecx.read_scalar_at_offset(mutex_op, 4, ecx.machine.layouts.u32)
13585
}
13686

13787
fn mutex_set_id<'mir, 'tcx: 'mir>(
13888
ecx: &mut MiriEvalContext<'mir, 'tcx>,
13989
mutex_op: OpTy<'tcx, Tag>,
14090
id: impl Into<ScalarMaybeUninit<Tag>>,
14191
) -> InterpResult<'tcx, ()> {
142-
set_at_offset(ecx, mutex_op, 4, id, ecx.machine.layouts.u32, PTHREAD_MUTEX_T_MIN_SIZE)
92+
ecx.write_scalar_at_offset(mutex_op, 4, id, ecx.machine.layouts.u32)
14393
}
14494

14595
fn mutex_get_or_create_id<'mir, 'tcx: 'mir>(
@@ -165,21 +115,19 @@ fn mutex_get_or_create_id<'mir, 'tcx: 'mir>(
165115
// (need to avoid this because it is set by static initializer macros)
166116
// bytes 4-7: rwlock id as u32 or 0 if id is not assigned yet.
167117

168-
const PTHREAD_RWLOCK_T_MIN_SIZE: u64 = 32;
169-
170118
fn rwlock_get_id<'mir, 'tcx: 'mir>(
171119
ecx: &MiriEvalContext<'mir, 'tcx>,
172120
rwlock_op: OpTy<'tcx, Tag>,
173121
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
174-
get_at_offset(ecx, rwlock_op, 4, ecx.machine.layouts.u32, PTHREAD_RWLOCK_T_MIN_SIZE)
122+
ecx.read_scalar_at_offset(rwlock_op, 4, ecx.machine.layouts.u32)
175123
}
176124

177125
fn rwlock_set_id<'mir, 'tcx: 'mir>(
178126
ecx: &mut MiriEvalContext<'mir, 'tcx>,
179127
rwlock_op: OpTy<'tcx, Tag>,
180128
id: impl Into<ScalarMaybeUninit<Tag>>,
181129
) -> InterpResult<'tcx, ()> {
182-
set_at_offset(ecx, rwlock_op, 4, id, ecx.machine.layouts.u32, PTHREAD_RWLOCK_T_MIN_SIZE)
130+
ecx.write_scalar_at_offset(rwlock_op, 4, id, ecx.machine.layouts.u32)
183131
}
184132

185133
fn rwlock_get_or_create_id<'mir, 'tcx: 'mir>(
@@ -204,21 +152,19 @@ fn rwlock_get_or_create_id<'mir, 'tcx: 'mir>(
204152
// store an i32 in the first four bytes equal to the corresponding libc clock id constant
205153
// (e.g. CLOCK_REALTIME).
206154

207-
const PTHREAD_CONDATTR_T_MIN_SIZE: u64 = 4;
208-
209155
fn condattr_get_clock_id<'mir, 'tcx: 'mir>(
210156
ecx: &MiriEvalContext<'mir, 'tcx>,
211157
attr_op: OpTy<'tcx, Tag>,
212158
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
213-
get_at_offset(ecx, attr_op, 0, ecx.machine.layouts.i32, PTHREAD_CONDATTR_T_MIN_SIZE)
159+
ecx.read_scalar_at_offset(attr_op, 0, ecx.machine.layouts.i32)
214160
}
215161

216162
fn condattr_set_clock_id<'mir, 'tcx: 'mir>(
217163
ecx: &mut MiriEvalContext<'mir, 'tcx>,
218164
attr_op: OpTy<'tcx, Tag>,
219165
clock_id: impl Into<ScalarMaybeUninit<Tag>>,
220166
) -> InterpResult<'tcx, ()> {
221-
set_at_offset(ecx, attr_op, 0, clock_id, ecx.machine.layouts.i32, PTHREAD_CONDATTR_T_MIN_SIZE)
167+
ecx.write_scalar_at_offset(attr_op, 0, clock_id, ecx.machine.layouts.i32)
222168
}
223169

224170
// pthread_cond_t
@@ -230,21 +176,19 @@ fn condattr_set_clock_id<'mir, 'tcx: 'mir>(
230176
// bytes 4-7: the conditional variable id as u32 or 0 if id is not assigned yet.
231177
// bytes 8-11: the clock id constant as i32
232178

233-
const PTHREAD_COND_T_MIN_SIZE: u64 = 12;
234-
235179
fn cond_get_id<'mir, 'tcx: 'mir>(
236180
ecx: &MiriEvalContext<'mir, 'tcx>,
237181
cond_op: OpTy<'tcx, Tag>,
238182
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
239-
get_at_offset(ecx, cond_op, 4, ecx.machine.layouts.u32, PTHREAD_COND_T_MIN_SIZE)
183+
ecx.read_scalar_at_offset(cond_op, 4, ecx.machine.layouts.u32)
240184
}
241185

242186
fn cond_set_id<'mir, 'tcx: 'mir>(
243187
ecx: &mut MiriEvalContext<'mir, 'tcx>,
244188
cond_op: OpTy<'tcx, Tag>,
245189
id: impl Into<ScalarMaybeUninit<Tag>>,
246190
) -> InterpResult<'tcx, ()> {
247-
set_at_offset(ecx, cond_op, 4, id, ecx.machine.layouts.u32, PTHREAD_COND_T_MIN_SIZE)
191+
ecx.write_scalar_at_offset(cond_op, 4, id, ecx.machine.layouts.u32)
248192
}
249193

250194
fn cond_get_or_create_id<'mir, 'tcx: 'mir>(
@@ -267,15 +211,15 @@ fn cond_get_clock_id<'mir, 'tcx: 'mir>(
267211
ecx: &MiriEvalContext<'mir, 'tcx>,
268212
cond_op: OpTy<'tcx, Tag>,
269213
) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
270-
get_at_offset(ecx, cond_op, 8, ecx.machine.layouts.i32, PTHREAD_COND_T_MIN_SIZE)
214+
ecx.read_scalar_at_offset(cond_op, 8, ecx.machine.layouts.i32)
271215
}
272216

273217
fn cond_set_clock_id<'mir, 'tcx: 'mir>(
274218
ecx: &mut MiriEvalContext<'mir, 'tcx>,
275219
cond_op: OpTy<'tcx, Tag>,
276220
clock_id: impl Into<ScalarMaybeUninit<Tag>>,
277221
) -> InterpResult<'tcx, ()> {
278-
set_at_offset(ecx, cond_op, 8, clock_id, ecx.machine.layouts.i32, PTHREAD_COND_T_MIN_SIZE)
222+
ecx.write_scalar_at_offset(cond_op, 8, clock_id, ecx.machine.layouts.i32)
279223
}
280224

281225
/// Try to reacquire the mutex associated with the condition variable after we

0 commit comments

Comments
 (0)