Skip to content

Commit b5fc544

Browse files
committed
Auto merge of rust-lang#2140 - V0ldek:page_size, r=RalfJung
Update GetSystemInfo to work with `page_size` (rust-lang#2136) - Change logic in GetSystemInfo shim to take into account the two possible layouts of `SYSTEM_INFO`, the first-field-is-union used by [winapi::um::sysinfoapi::SYSTEM_INFO](https://docs.rs/winapi/latest/winapi/um/sysinfoapi/struct.SYSTEM_INFO.html), and first-two-fields-are-inlined-union used by [num_cpus](https://github.com/seanmonstar/num_cpus/blob/5f1b03332000b4c4274b5bd35fac516049ff1c6b/src/lib.rs#L206). - Fill out the `dwPageSize` field with the `PAGE_SIZE` constant of `4096`. Closes rust-lang#2136
2 parents 38111b3 + 9a5c9a5 commit b5fc544

10 files changed

+116
-17
lines changed

src/machine.rs

+4
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,11 @@ pub struct AllocExtra {
178178
pub struct PrimitiveLayouts<'tcx> {
179179
pub unit: TyAndLayout<'tcx>,
180180
pub i8: TyAndLayout<'tcx>,
181+
pub i16: TyAndLayout<'tcx>,
181182
pub i32: TyAndLayout<'tcx>,
182183
pub isize: TyAndLayout<'tcx>,
183184
pub u8: TyAndLayout<'tcx>,
185+
pub u16: TyAndLayout<'tcx>,
184186
pub u32: TyAndLayout<'tcx>,
185187
pub usize: TyAndLayout<'tcx>,
186188
pub bool: TyAndLayout<'tcx>,
@@ -194,9 +196,11 @@ impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> {
194196
Ok(Self {
195197
unit: layout_cx.layout_of(tcx.mk_unit())?,
196198
i8: layout_cx.layout_of(tcx.types.i8)?,
199+
i16: layout_cx.layout_of(tcx.types.i16)?,
197200
i32: layout_cx.layout_of(tcx.types.i32)?,
198201
isize: layout_cx.layout_of(tcx.types.isize)?,
199202
u8: layout_cx.layout_of(tcx.types.u8)?,
203+
u16: layout_cx.layout_of(tcx.types.u16)?,
200204
u32: layout_cx.layout_of(tcx.types.u32)?,
201205
usize: layout_cx.layout_of(tcx.types.usize)?,
202206
bool: layout_cx.layout_of(tcx.types.bool)?,

src/shims/windows/foreign_items.rs

+50-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_target::spec::abi::Abi;
88
use crate::*;
99
use shims::foreign_items::EmulateByNameResult;
1010
use shims::windows::sync::EvalContextExt as _;
11+
use smallvec::SmallVec;
1112

1213
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
1314
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
@@ -119,10 +120,56 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
119120
system_info.ptr,
120121
iter::repeat(0u8).take(system_info.layout.size.bytes() as usize),
121122
)?;
123+
// Set selected fields.
124+
let word_layout = this.machine.layouts.u16;
125+
let dword_layout = this.machine.layouts.u32;
126+
let usize_layout = this.machine.layouts.usize;
127+
128+
// Using `mplace_field` is error-prone, see: https://github.com/rust-lang/miri/issues/2136.
129+
// Pointer fields have different sizes on different targets.
130+
// To avoid all these issue we calculate the offsets ourselves.
131+
let field_sizes = [
132+
word_layout.size, // 0, wProcessorArchitecture : WORD
133+
word_layout.size, // 1, wReserved : WORD
134+
dword_layout.size, // 2, dwPageSize : DWORD
135+
usize_layout.size, // 3, lpMinimumApplicationAddress : LPVOID
136+
usize_layout.size, // 4, lpMaximumApplicationAddress : LPVOID
137+
usize_layout.size, // 5, dwActiveProcessorMask : DWORD_PTR
138+
dword_layout.size, // 6, dwNumberOfProcessors : DWORD
139+
dword_layout.size, // 7, dwProcessorType : DWORD
140+
dword_layout.size, // 8, dwAllocationGranularity : DWORD
141+
word_layout.size, // 9, wProcessorLevel : WORD
142+
word_layout.size, // 10, wProcessorRevision : WORD
143+
];
144+
let field_offsets: SmallVec<[Size; 11]> = field_sizes
145+
.iter()
146+
.copied()
147+
.scan(Size::ZERO, |a, x| {
148+
let res = Some(*a);
149+
*a += x;
150+
res
151+
})
152+
.collect();
153+
154+
// Set page size.
155+
let page_size = system_info.offset(
156+
field_offsets[2],
157+
MemPlaceMeta::None,
158+
dword_layout,
159+
&this.tcx,
160+
)?;
161+
this.write_scalar(
162+
Scalar::from_int(PAGE_SIZE, dword_layout.size),
163+
&page_size.into(),
164+
)?;
122165
// Set number of processors.
123-
let dword_size = Size::from_bytes(4);
124-
let num_cpus = this.mplace_field(&system_info, 6)?;
125-
this.write_scalar(Scalar::from_int(NUM_CPUS, dword_size), &num_cpus.into())?;
166+
let num_cpus = system_info.offset(
167+
field_offsets[6],
168+
MemPlaceMeta::None,
169+
dword_layout,
170+
&this.tcx,
171+
)?;
172+
this.write_scalar(Scalar::from_int(NUM_CPUS, dword_layout.size), &num_cpus.into())?;
126173
}
127174

128175
// Thread-local storage

test-cargo-miri/Cargo.lock

+33
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test-cargo-miri/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ rand = { version = "0.8", features = ["small_rng"] }
2222
getrandom_1 = { package = "getrandom", version = "0.1" }
2323
getrandom_2 = { package = "getrandom", version = "0.2" }
2424
serde_derive = "1.0" # not actually used, but exercises some unique code path (`--extern` .so file)
25+
page_size = "0.4.1"
2526

2627
[lib]
2728
test = false # test that this is respected (will show in the output)

test-cargo-miri/test.cross-target.stdout.ref

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
55

66
imported main
77

8-
running 7 tests
9-
..i....
10-
test result: ok. 6 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out
8+
running 8 tests
9+
..i.....
10+
test result: ok. 7 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out
1111

test-cargo-miri/test.default.stdout.ref

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
55

66
imported main
77

8-
running 7 tests
9-
..i....
10-
test result: ok. 6 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out
8+
running 8 tests
9+
..i.....
10+
test result: ok. 7 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out
1111

1212

1313
running 4 tests

test-cargo-miri/test.filter.cross-target.stdout.ref

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ imported main
88
running 1 test
99
test simple1 ... ok
1010

11-
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 6 filtered out
11+
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 7 filtered out
1212

test-cargo-miri/test.filter.stdout.ref

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ imported main
88
running 1 test
99
test simple1 ... ok
1010

11-
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 6 filtered out
11+
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 7 filtered out
1212

1313

1414
running 0 tests
+3-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11

2-
running 7 tests
2+
running 8 tests
33
test cargo_env ... ok
44
test do_panic - should panic ... ok
55
test does_not_work_on_miri ... ignored
66
test entropy_rng ... ok
77
test fail_index_check - should panic ... ok
8+
test page_size ... ok
89
test simple1 ... ok
910
test simple2 ... ok
1011

11-
test result: ok. 6 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out
12+
test result: ok. 7 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out
1213

test-cargo-miri/tests/test.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rand::{SeedableRng, Rng, rngs::SmallRng};
1+
use rand::{rngs::SmallRng, Rng, SeedableRng};
22

33
// Having more than 1 test does seem to make a difference
44
// (i.e., this calls ptr::swap which having just one test does not).
@@ -49,14 +49,27 @@ fn cargo_env() {
4949
}
5050

5151
#[test]
52-
#[should_panic(expected="Explicit panic")]
53-
fn do_panic() { // In large, friendly letters :)
52+
#[should_panic(expected = "Explicit panic")]
53+
fn do_panic() // In large, friendly letters :)
54+
{
5455
panic!("Explicit panic from test!");
5556
}
5657

5758
#[test]
5859
#[allow(unconditional_panic)]
59-
#[should_panic(expected="the len is 0 but the index is 42")]
60+
#[should_panic(expected = "the len is 0 but the index is 42")]
6061
fn fail_index_check() {
6162
[][42]
6263
}
64+
65+
#[test]
66+
fn page_size() {
67+
let page_size = page_size::get();
68+
69+
// In particular, this checks that it is not 0.
70+
assert!(
71+
page_size.next_power_of_two() == page_size,
72+
"page size not a power of two: {}",
73+
page_size
74+
);
75+
}

0 commit comments

Comments
 (0)