Auto merge of #2140 - V0ldek:page_size, r=RalfJung
Update GetSystemInfo to work with `page_size` (#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](5f1b033320/src/lib.rs (L206)).
- Fill out the `dwPageSize` field with the `PAGE_SIZE` constant of `4096`.
Closes #2136
This commit is contained in:
commit
b5fc544ae8
10 changed files with 116 additions and 17 deletions
|
|
@ -178,9 +178,11 @@ pub struct AllocExtra {
|
|||
pub struct PrimitiveLayouts<'tcx> {
|
||||
pub unit: TyAndLayout<'tcx>,
|
||||
pub i8: TyAndLayout<'tcx>,
|
||||
pub i16: TyAndLayout<'tcx>,
|
||||
pub i32: TyAndLayout<'tcx>,
|
||||
pub isize: TyAndLayout<'tcx>,
|
||||
pub u8: TyAndLayout<'tcx>,
|
||||
pub u16: TyAndLayout<'tcx>,
|
||||
pub u32: TyAndLayout<'tcx>,
|
||||
pub usize: TyAndLayout<'tcx>,
|
||||
pub bool: TyAndLayout<'tcx>,
|
||||
|
|
@ -194,9 +196,11 @@ impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> {
|
|||
Ok(Self {
|
||||
unit: layout_cx.layout_of(tcx.mk_unit())?,
|
||||
i8: layout_cx.layout_of(tcx.types.i8)?,
|
||||
i16: layout_cx.layout_of(tcx.types.i16)?,
|
||||
i32: layout_cx.layout_of(tcx.types.i32)?,
|
||||
isize: layout_cx.layout_of(tcx.types.isize)?,
|
||||
u8: layout_cx.layout_of(tcx.types.u8)?,
|
||||
u16: layout_cx.layout_of(tcx.types.u16)?,
|
||||
u32: layout_cx.layout_of(tcx.types.u32)?,
|
||||
usize: layout_cx.layout_of(tcx.types.usize)?,
|
||||
bool: layout_cx.layout_of(tcx.types.bool)?,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use rustc_target::spec::abi::Abi;
|
|||
use crate::*;
|
||||
use shims::foreign_items::EmulateByNameResult;
|
||||
use shims::windows::sync::EvalContextExt as _;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
|
||||
|
|
@ -119,10 +120,56 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
system_info.ptr,
|
||||
iter::repeat(0u8).take(system_info.layout.size.bytes() as usize),
|
||||
)?;
|
||||
// Set selected fields.
|
||||
let word_layout = this.machine.layouts.u16;
|
||||
let dword_layout = this.machine.layouts.u32;
|
||||
let usize_layout = this.machine.layouts.usize;
|
||||
|
||||
// Using `mplace_field` is error-prone, see: https://github.com/rust-lang/miri/issues/2136.
|
||||
// Pointer fields have different sizes on different targets.
|
||||
// To avoid all these issue we calculate the offsets ourselves.
|
||||
let field_sizes = [
|
||||
word_layout.size, // 0, wProcessorArchitecture : WORD
|
||||
word_layout.size, // 1, wReserved : WORD
|
||||
dword_layout.size, // 2, dwPageSize : DWORD
|
||||
usize_layout.size, // 3, lpMinimumApplicationAddress : LPVOID
|
||||
usize_layout.size, // 4, lpMaximumApplicationAddress : LPVOID
|
||||
usize_layout.size, // 5, dwActiveProcessorMask : DWORD_PTR
|
||||
dword_layout.size, // 6, dwNumberOfProcessors : DWORD
|
||||
dword_layout.size, // 7, dwProcessorType : DWORD
|
||||
dword_layout.size, // 8, dwAllocationGranularity : DWORD
|
||||
word_layout.size, // 9, wProcessorLevel : WORD
|
||||
word_layout.size, // 10, wProcessorRevision : WORD
|
||||
];
|
||||
let field_offsets: SmallVec<[Size; 11]> = field_sizes
|
||||
.iter()
|
||||
.copied()
|
||||
.scan(Size::ZERO, |a, x| {
|
||||
let res = Some(*a);
|
||||
*a += x;
|
||||
res
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Set page size.
|
||||
let page_size = system_info.offset(
|
||||
field_offsets[2],
|
||||
MemPlaceMeta::None,
|
||||
dword_layout,
|
||||
&this.tcx,
|
||||
)?;
|
||||
this.write_scalar(
|
||||
Scalar::from_int(PAGE_SIZE, dword_layout.size),
|
||||
&page_size.into(),
|
||||
)?;
|
||||
// Set number of processors.
|
||||
let dword_size = Size::from_bytes(4);
|
||||
let num_cpus = this.mplace_field(&system_info, 6)?;
|
||||
this.write_scalar(Scalar::from_int(NUM_CPUS, dword_size), &num_cpus.into())?;
|
||||
let num_cpus = system_info.offset(
|
||||
field_offsets[6],
|
||||
MemPlaceMeta::None,
|
||||
dword_layout,
|
||||
&this.tcx,
|
||||
)?;
|
||||
this.write_scalar(Scalar::from_int(NUM_CPUS, dword_layout.size), &num_cpus.into())?;
|
||||
}
|
||||
|
||||
// Thread-local storage
|
||||
|
|
|
|||
33
test-cargo-miri/Cargo.lock
generated
33
test-cargo-miri/Cargo.lock
generated
|
|
@ -22,6 +22,7 @@ dependencies = [
|
|||
"issue_1705",
|
||||
"issue_1760",
|
||||
"issue_rust_86261",
|
||||
"page_size",
|
||||
"rand",
|
||||
"serde_derive",
|
||||
]
|
||||
|
|
@ -123,6 +124,16 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "page_size"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eebde548fbbf1ea81a99b128872779c437752fb99f217c45245e1a61dcd9edcd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.10"
|
||||
|
|
@ -233,3 +244,25 @@ name = "wasi"
|
|||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ rand = { version = "0.8", features = ["small_rng"] }
|
|||
getrandom_1 = { package = "getrandom", version = "0.1" }
|
||||
getrandom_2 = { package = "getrandom", version = "0.2" }
|
||||
serde_derive = "1.0" # not actually used, but exercises some unique code path (`--extern` .so file)
|
||||
page_size = "0.4.1"
|
||||
|
||||
[lib]
|
||||
test = false # test that this is respected (will show in the output)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
|
|||
|
||||
imported main
|
||||
|
||||
running 7 tests
|
||||
..i....
|
||||
test result: ok. 6 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out
|
||||
running 8 tests
|
||||
..i.....
|
||||
test result: ok. 7 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
|
|||
|
||||
imported main
|
||||
|
||||
running 7 tests
|
||||
..i....
|
||||
test result: ok. 6 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out
|
||||
running 8 tests
|
||||
..i.....
|
||||
test result: ok. 7 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out
|
||||
|
||||
|
||||
running 4 tests
|
||||
|
|
|
|||
|
|
@ -8,5 +8,5 @@ imported main
|
|||
running 1 test
|
||||
test simple1 ... ok
|
||||
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 6 filtered out
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 7 filtered out
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ imported main
|
|||
running 1 test
|
||||
test simple1 ... ok
|
||||
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 6 filtered out
|
||||
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 7 filtered out
|
||||
|
||||
|
||||
running 0 tests
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
|
||||
running 7 tests
|
||||
running 8 tests
|
||||
test cargo_env ... ok
|
||||
test do_panic - should panic ... ok
|
||||
test does_not_work_on_miri ... ignored
|
||||
test entropy_rng ... ok
|
||||
test fail_index_check - should panic ... ok
|
||||
test page_size ... ok
|
||||
test simple1 ... ok
|
||||
test simple2 ... ok
|
||||
|
||||
test result: ok. 6 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out
|
||||
test result: ok. 7 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use rand::{SeedableRng, Rng, rngs::SmallRng};
|
||||
use rand::{rngs::SmallRng, Rng, SeedableRng};
|
||||
|
||||
// Having more than 1 test does seem to make a difference
|
||||
// (i.e., this calls ptr::swap which having just one test does not).
|
||||
|
|
@ -49,14 +49,27 @@ fn cargo_env() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected="Explicit panic")]
|
||||
fn do_panic() { // In large, friendly letters :)
|
||||
#[should_panic(expected = "Explicit panic")]
|
||||
fn do_panic() // In large, friendly letters :)
|
||||
{
|
||||
panic!("Explicit panic from test!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(unconditional_panic)]
|
||||
#[should_panic(expected="the len is 0 but the index is 42")]
|
||||
#[should_panic(expected = "the len is 0 but the index is 42")]
|
||||
fn fail_index_check() {
|
||||
[][42]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn page_size() {
|
||||
let page_size = page_size::get();
|
||||
|
||||
// In particular, this checks that it is not 0.
|
||||
assert!(
|
||||
page_size.next_power_of_two() == page_size,
|
||||
"page size not a power of two: {}",
|
||||
page_size
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue