Skip to content

Commit 33ef561

Browse files
committed
DO NOT MERGE - scratchwork
This shows how the base address, if it can be acquired, can be used to call external C functions. There are numerous TODOs, including the big one of coming up with a way to access the bytes address without the huge hole punch I put in rustc. This also requires that the bytes addresses in rustc become properly aligned. Double dereference passes, as do most tests. Of the few that remain, some of them make questionable assumptions (which we might need some way to retain or put behind an option for sanitization) like that it is fundamentally possible for two allocations to end up next to each other - this won't happen when we're using a real heap. The simd tests failing are concerning, but can be looked into.
1 parent 47c9546 commit 33ef561

File tree

6 files changed

+42
-52
lines changed

6 files changed

+42
-52
lines changed

src/intptrcast.rs

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ pub struct GlobalStateInner {
3737
/// Whether an allocation has been exposed or not. This cannot be put
3838
/// into `AllocExtra` for the same reason as `base_addr`.
3939
exposed: FxHashSet<AllocId>,
40-
/// This is used as a memory address when a new pointer is casted to an integer. It
41-
/// is always larger than any address that was previously made part of a block.
42-
next_base_addr: u64,
4340
/// The provenance to use for int2ptr casts
4441
provenance_mode: ProvenanceMode,
4542
}
@@ -50,7 +47,6 @@ impl GlobalStateInner {
5047
int_to_ptr_map: Vec::default(),
5148
base_addr: FxHashMap::default(),
5249
exposed: FxHashSet::default(),
53-
next_base_addr: STACK_ADDR,
5450
provenance_mode: config.provenance_mode,
5551
}
5652
}
@@ -157,6 +153,19 @@ impl<'mir, 'tcx> GlobalStateInner {
157153
}
158154

159155
fn alloc_base_addr(ecx: &MiriEvalContext<'mir, 'tcx>, alloc_id: AllocId) -> u64 {
156+
// TODO avoid hole punch
157+
// TODO avoid bytes hole punch
158+
// TODO avoid leaked address hack
159+
let base_addr: u64 = match ecx.get_alloc_raw(alloc_id) {
160+
Ok(ref alloc) => {
161+
let temp = alloc.bytes.as_ptr() as u64;
162+
assert!(temp % 16 == 0);
163+
temp
164+
}
165+
// Grabbing u128 for max alignment
166+
Err(_) => Box::leak(Box::new(0u128)) as *const u128 as u64,
167+
};
168+
// With our hack, base_addr should always be fully aligned
160169
let mut global_state = ecx.machine.intptrcast.borrow_mut();
161170
let global_state = &mut *global_state;
162171

@@ -167,34 +176,22 @@ impl<'mir, 'tcx> GlobalStateInner {
167176
// it became dangling. Hence we allow dead allocations.
168177
let (size, align, _kind) = ecx.get_alloc_info(alloc_id);
169178

170-
// This allocation does not have a base address yet, pick one.
171-
// Leave some space to the previous allocation, to give it some chance to be less aligned.
172-
let slack = {
173-
let mut rng = ecx.machine.rng.borrow_mut();
174-
// This means that `(global_state.next_base_addr + slack) % 16` is uniformly distributed.
175-
rng.gen_range(0..16)
176-
};
177-
// From next_base_addr + slack, round up to adjust for alignment.
178-
let base_addr = global_state.next_base_addr.checked_add(slack).unwrap();
179-
let base_addr = Self::align_addr(base_addr, align.bytes());
179+
// This allocation does not have a base address yet, assign its bytes base.
180180
entry.insert(base_addr);
181181
trace!(
182-
"Assigning base address {:#x} to allocation {:?} (size: {}, align: {}, slack: {})",
182+
"Assigning base address {:#x} to allocation {:?} (size: {}, align: {})",
183183
base_addr,
184184
alloc_id,
185185
size.bytes(),
186186
align.bytes(),
187-
slack,
188187
);
189188

190-
// Remember next base address. If this allocation is zero-sized, leave a gap
191-
// of at least 1 to avoid two allocations having the same base address.
192-
// (The logic in `alloc_id_from_addr` assumes unique addresses, and different
193-
// function/vtable pointers need to be distinguishable!)
194-
global_state.next_base_addr = base_addr.checked_add(max(size.bytes(), 1)).unwrap();
195-
// Given that `next_base_addr` increases in each allocation, pushing the
196-
// corresponding tuple keeps `int_to_ptr_map` sorted
189+
// TODO replace int_to_ptr_map's data structure, since even if we binary search for
190+
// the insert location, the insertion is still linear (due to copies)
191+
// I've done it the dumb obviously correct way for now.
192+
global_state.int_to_ptr_map.retain(|&(ref a,_)| a != &base_addr);
197193
global_state.int_to_ptr_map.push((base_addr, alloc_id));
194+
global_state.int_to_ptr_map.sort();
198195

199196
base_addr
200197
}

src/shims/ffi_support.rs

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -68,33 +68,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
6868
TyKind::Uint(UintTy::Usize) => {
6969
return Ok(CArg::USize(k.to_machine_usize(cx)?.try_into().unwrap()));
7070
}
71-
// mut pointers
72-
TyKind::RawPtr(TypeAndMut{ ty: some_ty, mutbl: rustc_hir::Mutability::Mut} ) => {
73-
match some_ty.kind() {
74-
TyKind::Int(IntTy::I32) => {
75-
println!("REEEE i32 pointer ARG");
76-
},
77-
TyKind::RawPtr(TypeAndMut{ ty: some_ty, mutbl: rustc_hir::Mutability::Mut} ) => {
78-
match some_ty.kind() {
79-
TyKind::Int(IntTy::I32) => {
80-
println!("RECURSION BRO: **i32 arg");
81-
match k {
82-
ScalarMaybeUninit::Scalar(Scalar::Ptr(ptr, sz)) => {
83-
let (alloc_id, _, _) = cx.ptr_get_alloc_id(ptr.into())?;
84-
let ree = cx.memory.alloc_map().get(alloc_id).unwrap().1.extra.real_pointer;//get_bytes_with_uninit_and_ptr(cx, fake_range).unwrap();
85-
println!("{:?}", ree);
86-
let inner_carg = CArg::ConstPtrUInt8(ree);
87-
return Ok(CArg::RecMutPtrCarg(Box::new(inner_carg)));
88-
// return Ok(CArg::USize(the_int.try_to_u64().unwrap().try_into().unwrap()));
89-
// println!("{:?}", s.assert_int())
90-
},
91-
_ => {}
92-
}
93-
},
94-
_ => { }
95-
}
71+
// pointers
72+
TyKind::RawPtr(TypeAndMut{..} ) => {
73+
match k {
74+
ScalarMaybeUninit::Scalar(Scalar::Ptr(ptr, sz)) => {
75+
let qq = ptr.into_parts().1.bytes_usize();
76+
// TODO select correct types rather than yoloing
77+
return Ok(CArg::RecConstPtrCarg(Box::new(CArg::ConstPtrInt32(qq as *const i32))))
9678
}
97-
_ => { }
79+
_ => {}
9880
}
9981
}
10082
_ => {}

tests/extern-so/libcode.version

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
CODEABI_1.0 {
2-
global: *add_one_int*;
2+
global: *double_deref*;
3+
*add_one_int*;
34
*printer*;
45
*test_stack_spill*;
56
*get_unsigned_int*;

tests/extern-so/test.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#include <stdio.h>
22

3+
int double_deref(const int **p) {
4+
return **p;
5+
}
6+
37
int add_one_int(int x) {
48
return 2 + x;
59
}

tests/pass/extern-so/call_extern_c_fcts.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//@compile-flags: -Zmiri-extern-so-file=tests/extern-so/libtestlib.so
44

55
extern "C" {
6+
fn double_deref(x: *const *const i32) -> i32;
67
fn add_one_int(x: i32) -> i32;
78
fn add_int16(x: i16) -> i16;
89
fn test_stack_spill(
@@ -44,5 +45,10 @@ fn main() {
4445
// test void function that prints from C -- call it twice
4546
printer();
4647
printer();
48+
49+
let base: i32 = 42;
50+
let base_p: *const i32 = &base as *const i32;
51+
let base_pp: *const *const i32 = &base_p as *const *const i32;
52+
assert_eq!(double_deref(base_pp), 42);
4753
}
4854
}

ui_test/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -624,8 +624,8 @@ pub enum Mode {
624624

625625
impl Mode {
626626
fn ok(self, status: ExitStatus) -> Errors {
627-
match (status.code().unwrap(), self) {
628-
(1, Mode::Fail) | (101, Mode::Panic) | (0, Mode::Pass) => vec![],
627+
match (status.code(), self) {
628+
(Some(1), Mode::Fail) | (Some(101), Mode::Panic) | (Some(0), Mode::Pass) => vec![],
629629
_ => vec![Error::ExitStatus(self, status)],
630630
}
631631
}

0 commit comments

Comments
 (0)