Skip to content

Commit 02f6d50

Browse files
committed
adapt to modified rustc, all tests pass (with rustc changes)
1 parent 4f46cd9 commit 02f6d50

File tree

5 files changed

+57
-87
lines changed

5 files changed

+57
-87
lines changed

src/alloc_addresses/mod.rs

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -468,53 +468,36 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
468468
/// This overapproximates the modifications which external code might make to memory:
469469
/// We set all reachable allocations as initialized, mark all reachable provenances as exposed
470470
/// and overwrite them with `Provenance::WILDCARD`.
471-
fn prepare_exposed_for_native_call(&mut self) -> InterpResult<'tcx> {
471+
fn prepare_exposed_for_native_call(&mut self, paranoid: bool) -> InterpResult<'tcx> {
472472
let this = self.eval_context_mut();
473473
// We need to make a deep copy of this list, but it's fine; it also serves as scratch space
474474
// for the search within `prepare_for_native_call`.
475475
let exposed: Vec<AllocId> =
476476
this.machine.alloc_addresses.get_mut().exposed.iter().copied().collect();
477-
this.prepare_for_native_call(exposed)
477+
this.prepare_for_native_call(exposed, paranoid)
478478
}
479479

480-
/// Similar to `prepare_exposed_for_native_call`, but makes use of information obtained about
481-
/// memory accesses during FFI to determine which provenances should be exposed and which
482-
/// new allocations were created and possibly exposed.
480+
/// Makes use of information obtained about memory accesses during FFI to determine which
481+
/// provenances should be exposed. Note that if `prepare_exposed_for_native_call` was not
482+
/// called before the FFI (with `paranoid` set to false) then some of the writes may be
483+
/// lost!
483484
fn apply_events(&mut self, events: crate::shims::trace::MemEvents) -> InterpResult<'tcx> {
484485
let this = self.eval_context_mut();
485-
//let accesses = events.accesses;
486-
/*let handle = this.machine.alloc_addresses.borrow();
487-
for id in &handle.exposed {
488-
let &base_addr = handle.base_addr.get(id).unwrap();
489-
let info = this.get_alloc_info(*id);
490-
491-
//let found = vec![];
492-
for (acc_base, acc_len, acc_kind) in &events.accesses {
493-
// If ranges overlap
494-
if *acc_base <= base_addr.strict_add(info.size.bytes())
495-
&& base_addr <= acc_base.strict_add(*acc_len)
496-
{
497-
if info.mutbl.is_not() && acc_kind.did_write() {
498-
throw_ub_format!(""); // TODO: fill this in lol
499-
}
500-
501-
if acc_kind.did_read() {
502-
let src = Pointer::from_addr_invalid(*acc_base);
503-
this.read_immediate_raw(&src);
504-
self.expose_provenance(provenance)
505-
}
506-
507-
if acc_kind.did_write() {
508-
//let alloc = self.alloc_id_from_addr(addr, size, only_exposed_allocations)
509-
}
510-
}
511-
}
512-
}*/
513-
/*for (acc_base, acc_len, acc_kind) in &events.accesses {
514-
let alloc_id = self.alloc_id_from_addr(addr, size, only_exposed_allocations)
515-
}*/
486+
let exposed: Vec<AllocId> = this.machine.alloc_addresses.get_mut().exposed.iter().copied().collect();
487+
let accesses = events.accesses.into_iter().map(|(range, kind)| {
488+
// Can't get around this without pulling in serde as a dependency of rustc, because
489+
// the MemEvents need to be sent over IPC, or manually implementing serialisation/
490+
// deserialisation for it, which is a lot of extra code for little gain
491+
let kind = match kind {
492+
k if k == 0 => ForeignAccessKind::Read,
493+
k if k == 1 => ForeignAccessKind::Write,
494+
k if k == 2 => ForeignAccessKind::ReadWrite,
495+
_ => unreachable!(),
496+
};
497+
(range, kind)
498+
}).collect();
516499

517-
interp_ok(())
500+
this.apply_accesses(exposed, accesses)
518501
}
519502
}
520503

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ extern crate tracing;
5454
extern crate rustc_abi;
5555
extern crate rustc_apfloat;
5656
extern crate rustc_ast;
57-
extern crate rustc_attr_parsing;
57+
extern crate rustc_attr_data_structures;
5858
extern crate rustc_const_eval;
5959
extern crate rustc_data_structures;
6060
extern crate rustc_errors;

src/machine.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rand::rngs::StdRng;
1313
use rand::{Rng, SeedableRng};
1414
use rustc_abi::{Align, ExternAbi, Size};
1515
use rustc_apfloat::{Float, FloatConvert};
16-
use rustc_attr_parsing::InlineAttr;
16+
use rustc_attr_data_structures::InlineAttr;
1717
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1818
#[allow(unused)]
1919
use rustc_data_structures::static_assert_size;

src/shims/native_lib.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
180180
}
181181
}
182182

183-
if super::trace::Supervisor::init().is_err() {
184-
// Worst-case prepare all exposed memory.
185-
this.prepare_exposed_for_native_call()?;
186-
}
183+
// Prepare all exposed memory, depending on whether we have a supervisor process.
184+
this.prepare_exposed_for_native_call(super::trace::Supervisor::init().is_err())?;
187185

188186
// Convert them to `libffi::high::Arg` type.
189187
let libffi_args = libffi_args
@@ -194,7 +192,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
194192
// Call the function and store output, depending on return type in the function signature.
195193
let ret = this.call_native_with_args(link_name, dest, code_ptr, libffi_args)?;
196194
if let Some(events) = super::trace::Supervisor::get_events() {
197-
eprintln!("accesses: {events:#018x?}");
198195
this.apply_events(events)?;
199196
}
200197
this.write_immediate(*ret, dest)?;
@@ -206,13 +203,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
206203
unsafe fn do_native_call<T: libffi::high::CType>(ptr: CodePtr, args: &[ffi::Arg<'_>]) -> T {
207204
use shims::trace::Supervisor;
208205

209-
let ret = unsafe {
206+
unsafe {
210207
Supervisor::start_ffi();
211208
let ret = ffi::call(ptr, args);
212209
Supervisor::end_ffi();
213210
ret
214-
};
215-
ret
211+
}
216212
}
217213

218214
#[cfg(not(all(unix, any(target_arch = "x86", target_arch = "x86_64"))))]

src/shims/trace.rs

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
use std::ops::Range;
2+
13
use ipc_channel::ipc;
24
use nix::sys::{ptrace, signal, wait};
35
use nix::unistd;
6+
use rustc_const_eval::interpret::ForeignAccessKind;
47

58
use crate::discrete_alloc;
69
use crate::helpers::ToU64;
@@ -186,45 +189,28 @@ pub enum TraceRequest {
186189

187190
#[derive(serde::Serialize, serde::Deserialize, Debug)]
188191
pub struct MemEvents {
189-
pub accesses: Vec<(u64, u64, MemAccessType)>,
190-
pub mappings: Vec<(u64, u64)>,
192+
pub accesses: Vec<(Range<u64>, i32)>,
193+
pub mappings: Vec<Range<u64>>,
191194
}
192195

193-
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
194-
pub enum MemAccessType {
195-
Read,
196-
Write,
197-
ReadWrite,
196+
trait UpdateAcc {
197+
fn update(&mut self, other: ForeignAccessKind);
198198
}
199199

200-
impl MemAccessType {
201-
fn update(&mut self, other: MemAccessType) {
200+
impl UpdateAcc for ForeignAccessKind {
201+
fn update(&mut self, other: ForeignAccessKind) {
202202
match self {
203-
MemAccessType::Read =>
203+
ForeignAccessKind::Read =>
204204
match other {
205-
MemAccessType::Read => (),
206-
_ => *self = MemAccessType::ReadWrite,
205+
ForeignAccessKind::Read => (),
206+
_ => *self = ForeignAccessKind::ReadWrite,
207207
},
208-
MemAccessType::Write =>
208+
ForeignAccessKind::Write =>
209209
match other {
210-
MemAccessType::Write => (),
211-
_ => *self = MemAccessType::ReadWrite,
210+
ForeignAccessKind::Write => (),
211+
_ => *self = ForeignAccessKind::ReadWrite,
212212
},
213-
MemAccessType::ReadWrite => (),
214-
}
215-
}
216-
217-
pub fn did_read(&self) -> bool {
218-
match self {
219-
MemAccessType::Write => false,
220-
_ => true,
221-
}
222-
}
223-
224-
pub fn did_write(&self) -> bool {
225-
match self {
226-
MemAccessType::Read => false,
227-
_ => true,
213+
ForeignAccessKind::ReadWrite => (),
228214
}
229215
}
230216
}
@@ -284,7 +270,7 @@ impl Iterator for ChildListener {
284270
/// created before the fork are the same).
285271
fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
286272
// Things that we return to the child process
287-
let mut accesses: Vec<(u64, u64, MemAccessType)> = vec![];
273+
let mut accesses: Vec<(u64, u64, ForeignAccessKind)> = vec![];
288274
let mut mappings: Vec<(u64, u64)> = vec![];
289275

290276
// Memory allocated on the MiriMachine
@@ -422,7 +408,12 @@ fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
422408

423409
TraceRequest::EndFfi => {
424410
signal::kill(main_pid, signal::SIGSTOP).unwrap();
425-
t_event.send(MemEvents { accesses, mappings }).unwrap();
411+
t_event.send(MemEvents {
412+
accesses: accesses.into_iter().map(|(addr, len, kind)| {
413+
(addr..addr+len, kind as i32)
414+
}).collect(),
415+
mappings: mappings.into_iter().map(|(addr, len)| (addr..addr+len)).collect(),
416+
}).unwrap();
426417
accesses = vec![];
427418
mappings = vec![];
428419
if let Err(ret) = wait_for_signal(main_pid, signal::SIGSTOP, false) {
@@ -572,7 +563,7 @@ fn handle_munmap(
572563
fn handle_segfault(
573564
pid: unistd::Pid,
574565
ch_pages: &[u64],
575-
accesses: &mut Vec<(u64, u64, MemAccessType)>,
566+
accesses: &mut Vec<(u64, u64, ForeignAccessKind)>,
576567
) -> Result<(), i32> {
577568
let siginfo = ptrace::getsiginfo(pid).unwrap();
578569
let addr = unsafe { siginfo.si_addr().addr().to_u64() };
@@ -627,14 +618,14 @@ fn handle_segfault(
627618
let instr = decoder.decode();
628619
let memsize = instr.op_code().memory_size().size().to_u64();
629620
let mem = fac.info(&instr).used_memory();
630-
let acc = mem.iter().fold(None, |mut curr: Option<MemAccessType>, m| {
621+
let acc = mem.iter().fold(None, |mut curr: Option<ForeignAccessKind>, m| {
631622
if let Some(m) = match m.access() {
632-
iced_x86::OpAccess::Read => Some(MemAccessType::Read),
633-
iced_x86::OpAccess::CondRead => Some(MemAccessType::Read),
634-
iced_x86::OpAccess::Write => Some(MemAccessType::Write),
635-
iced_x86::OpAccess::CondWrite => Some(MemAccessType::Write),
636-
iced_x86::OpAccess::ReadWrite => Some(MemAccessType::ReadWrite),
637-
iced_x86::OpAccess::ReadCondWrite => Some(MemAccessType::ReadWrite),
623+
iced_x86::OpAccess::Read => Some(ForeignAccessKind::Read),
624+
iced_x86::OpAccess::CondRead => Some(ForeignAccessKind::Read),
625+
iced_x86::OpAccess::Write => Some(ForeignAccessKind::Write),
626+
iced_x86::OpAccess::CondWrite => Some(ForeignAccessKind::Write),
627+
iced_x86::OpAccess::ReadWrite => Some(ForeignAccessKind::ReadWrite),
628+
iced_x86::OpAccess::ReadCondWrite => Some(ForeignAccessKind::ReadWrite),
638629
_ => None,
639630
} {
640631
if let Some(curr) = curr.as_mut() {

0 commit comments

Comments
 (0)