Skip to content

Commit e31e6e0

Browse files
committed
Add support for panicking in the emulated application when unsupported syscalls are encountered
1 parent 453affa commit e31e6e0

File tree

6 files changed

+60
-5
lines changed

6 files changed

+60
-5
lines changed

src/bin/miri.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ fn main() {
233233
"-Zmiri-ignore-leaks" => {
234234
miri_config.ignore_leaks = true;
235235
}
236+
"-Zmiri-panic-on-unsupported-syscalls" => {
237+
miri_config.panic_on_unsupported = true;
238+
}
236239
"-Zmiri-track-raw-pointers" => {
237240
miri_config.track_raw = true;
238241
}

src/eval.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ pub struct MiriConfig {
5757
/// If `Some`, enable the `measureme` profiler, writing results to a file
5858
/// with the specified prefix.
5959
pub measureme_out: Option<String>,
60+
/// Panic when unsupported functionality is encountered
61+
pub panic_on_unsupported: bool,
6062
}
6163

6264
impl Default for MiriConfig {
@@ -77,6 +79,7 @@ impl Default for MiriConfig {
7779
data_race_detector: true,
7880
cmpxchg_weak_failure_rate: 0.8,
7981
measureme_out: None,
82+
panic_on_unsupported: false,
8083
}
8184
}
8285
}

src/machine.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,11 @@ pub struct Evaluator<'mir, 'tcx> {
291291
/// Used with `profiler` to cache the `StringId`s for event names
292292
/// uesd with `measureme`.
293293
string_cache: FxHashMap<String, measureme::StringId>,
294+
295+
/// Whether to raise a panic in the context of the evaluated process when unsupported
296+
/// functionality is encountered. If `false`, an error is propagated in the Miri application context
297+
/// instead (default behavior)
298+
pub(crate) panic_on_unsupported: bool,
294299
}
295300

296301
impl<'mir, 'tcx> Evaluator<'mir, 'tcx> {
@@ -318,6 +323,7 @@ impl<'mir, 'tcx> Evaluator<'mir, 'tcx> {
318323
static_roots: Vec::new(),
319324
profiler,
320325
string_cache: Default::default(),
326+
panic_on_unsupported: config.panic_on_unsupported,
321327
}
322328
}
323329
}

src/shims/posix/linux/foreign_items.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
182182
id if id == sys_futex => {
183183
futex(this, args, dest)?;
184184
}
185-
id => throw_unsup_format!("Miri does not support syscall ID {}", id),
185+
id => {
186+
let error_msg = format!("unsupported Miri functionality: syscall ID {} is not emulated", id);
187+
if this.eval_context_ref().machine.panic_on_unsupported {
188+
// message is slightly different here to make automated analysis easier
189+
this.start_panic(error_msg.as_ref(), StackPopUnwind::NotAllowed)?;
190+
return Ok(false);
191+
} else {
192+
throw_unsup_format!("{}", error_msg);
193+
}
194+
}
186195
}
187196
}
188197

@@ -214,7 +223,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
214223
this.write_null(dest)?;
215224
}
216225

217-
_ => throw_unsup_format!("can't call foreign function: {}", link_name),
226+
_ => {
227+
let error_msg = format!("unsupported Miri functionality: can't call foreign function {:?}", link_name);
228+
if this.eval_context_ref().machine.panic_on_unsupported {
229+
// message is slightly different here to make automated analysis easier
230+
this.start_panic(error_msg.as_ref(), StackPopUnwind::NotAllowed)?;
231+
return Ok(false);
232+
} else {
233+
throw_unsup_format!("{}", error_msg);
234+
}
235+
}
218236
};
219237

220238
Ok(true)

src/shims/posix/macos/foreign_items.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
156156
this.write_scalar(addr, dest)?;
157157
}
158158

159-
_ => throw_unsup_format!("can't call foreign function: {}", link_name),
159+
_ => {
160+
let error_msg = format!("unsupported Miri functionality: can't call foreign function {:?}", link_name);
161+
if this.eval_context_ref().machine.panic_on_unsupported {
162+
// message is slightly different here to make automated analysis easier
163+
this.start_panic(error_msg.as_ref(), StackPopUnwind::NotAllowed)?;
164+
return Ok(false);
165+
} else {
166+
throw_unsup_format!("{}", error_msg);
167+
}
168+
}
160169
};
161170

162171
Ok(true)

src/shims/windows/foreign_items.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
342342
// Better error for attempts to create a thread
343343
"CreateThread" => {
344344
check_abi(abi, Abi::System { unwind: false })?;
345-
throw_unsup_format!("Miri does not support concurrency on Windows");
345+
346+
let error_msg = "unsupported Miri functionality: concurrency is not supported on Windows";
347+
if this.eval_context_ref().machine.panic_on_unsupported {
348+
this.start_panic(error_msg, StackPopUnwind::NotAllowed)?;
349+
return Ok(false);
350+
} else {
351+
throw_unsup_format!("{}", error_msg);
352+
}
346353
}
347354

348355
// Incomplete shims that we "stub out" just to get pre-main initialization code to work.
@@ -415,7 +422,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
415422
this.write_scalar(Scalar::from_i32(1), dest)?;
416423
}
417424

418-
_ => throw_unsup_format!("can't call foreign function: {}", link_name),
425+
_ => {
426+
let error_msg = format!("unsupported Miri functionality: can't call foreign function {:?}", link_name);
427+
if this.eval_context_ref().machine.panic_on_unsupported {
428+
// message is slightly different here to make automated analysis easier
429+
this.start_panic(error_msg.as_ref(), StackPopUnwind::NotAllowed)?;
430+
return Ok(false);
431+
} else {
432+
throw_unsup_format!("{}", error_msg);
433+
}
434+
}
419435
}
420436

421437
Ok(true)

0 commit comments

Comments
 (0)