@@ -258,11 +258,6 @@ fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
258
258
// Memory allocated on the MiriMachine
259
259
let mut ch_pages = vec ! [ ] ;
260
260
261
- // Random bits of syscall-related state
262
- let mut enter = true ;
263
- let mut flush_mapped = None ;
264
- let mut munmap_args = None ;
265
-
266
261
// Straight up magic numbers we need
267
262
let malloc_addr = libc:: malloc as usize ;
268
263
let malloc_bytes = unsafe { ( malloc_addr as * mut i64 ) . read_volatile ( ) } ; // i'm sorry
@@ -275,7 +270,6 @@ fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
275
270
let mut retcode = 0 ;
276
271
277
272
#[ allow( clippy:: cast_possible_wrap) ]
278
- #[ allow( clippy:: arithmetic_side_effects) ]
279
273
' listen: for evt in listener {
280
274
match evt {
281
275
ExecEvent :: Status ( wait_status) =>
@@ -316,71 +310,25 @@ fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
316
310
wait:: WaitStatus :: PtraceSyscall ( pid) => {
317
311
let regs = ptrace:: getregs ( pid) . unwrap ( ) ;
318
312
let syscall_nr = regs. syscall_nr ( ) ;
319
- if enter {
320
- if syscall_nr as i64 == libc:: SYS_mmap {
313
+ match syscall_nr as i64 {
314
+ n if n == libc:: SYS_mmap => {
315
+ // No need for a discrete fn here, it's very tiny
321
316
let len = regs. arg2 ( ) ;
322
- flush_mapped = Some ( len) ;
323
- } else if syscall_nr as i64 == libc:: SYS_munmap {
324
- // The unmap call might hit multiple mappings we've saved,
325
- // or overlap with them partially (or both)
326
- let um_start = regs. arg1 ( ) ;
327
- let um_len = regs. arg2 ( ) ;
328
- let um_end = um_start + um_len;
329
- let mut idxes = vec ! [ ] ;
330
- for ( idx, & ( mp_start, len) ) in mappings. iter ( ) . enumerate ( ) {
331
- let mp_end = mp_start + len;
332
- let cond = ( mp_start..mp_end) . contains ( & um_start)
333
- || ( mp_start..mp_end) . contains ( & um_end)
334
- || ( um_start..um_end) . contains ( & mp_start) ;
335
-
336
- if cond {
337
- idxes. push ( idx) ;
338
- }
339
- }
340
- if !idxes. is_empty ( ) {
341
- // We iterate thru this later while removing elements so if
342
- // it's not reversed we will mess up the mappings badly!
343
- idxes. reverse ( ) ;
344
- munmap_args = Some ( ( idxes, um_start, um_len) ) ;
345
- }
346
- } // TODO: handle brk/sbrk
347
- } else {
348
- if syscall_nr as i64 == libc:: SYS_mmap {
317
+ ptrace:: syscall ( pid, None ) . unwrap ( ) ;
318
+ let _ = wait:: waitpid ( pid, None ) . unwrap ( ) ;
319
+ let regs = ptrace:: getregs ( pid) . unwrap ( ) ;
349
320
if regs. retval ( ) as isize > 0 {
350
- if let Some ( len) = flush_mapped. take ( ) {
351
- let addr = regs. retval ( ) ;
352
- mappings. push ( ( addr, len as _ ) ) ;
353
- } else {
354
- eprintln ! (
355
- "Process returned from mmap syscall without entering it? Attempting to continue..."
356
- ) ;
357
- }
321
+ let addr = regs. retval ( ) ;
322
+ mappings. push ( ( addr, len as _ ) ) ;
358
323
}
359
- } else if syscall_nr as i64 == libc:: SYS_munmap {
360
- if let Some ( ( idxes, um_start, um_len) ) = munmap_args. take ( ) {
361
- if regs. retval ( ) as isize > 0 {
362
- // Unmap succeeded, so take out the mapping(s) from our list
363
- // but it may be only partial so we may readd some sections
364
- for idx in idxes {
365
- let um_end = um_start + um_len;
366
- let ( mp_start, mp_len) = mappings. remove ( idx) ;
367
- let mp_end = mp_len + mp_len;
368
-
369
- if mp_start < um_start {
370
- let preserved_len_head = um_start - mp_start;
371
- mappings. push ( ( mp_start, preserved_len_head) ) ;
372
- }
373
- if mp_end > um_end {
374
- let preserved_len_tail = mp_end - um_end;
375
- mappings. push ( ( um_end, preserved_len_tail) ) ;
376
- }
377
- }
378
- }
379
- }
380
- }
324
+ } ,
325
+ n if n == libc:: SYS_munmap => {
326
+ handle_munmap ( pid, regs, & mut mappings) ;
327
+ } ,
328
+ // TODO: handle brk/sbrk
329
+ _ => ( ) ,
381
330
}
382
331
383
- enter = !enter;
384
332
ptrace:: syscall ( pid, None ) . unwrap ( ) ;
385
333
}
386
334
_ => ( ) ,
@@ -428,6 +376,53 @@ fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
428
376
std:: process:: exit ( retcode) ;
429
377
}
430
378
379
+ #[ allow( clippy:: arithmetic_side_effects) ]
380
+ #[ allow( clippy:: cast_possible_wrap) ]
381
+ fn handle_munmap ( pid : unistd:: Pid , regs : libc:: user_regs_struct , mappings : & mut Vec < ( usize , usize ) > ) {
382
+ // The unmap call might hit multiple mappings we've saved,
383
+ // or overlap with them partially (or both)
384
+ let um_start = regs. arg1 ( ) ;
385
+ let um_len = regs. arg2 ( ) ;
386
+ let um_end = um_start + um_len;
387
+ let mut idxes = vec ! [ ] ;
388
+ for ( idx, & ( mp_start, len) ) in mappings. iter ( ) . enumerate ( ) {
389
+ let mp_end = mp_start + len;
390
+ let cond = ( mp_start..mp_end) . contains ( & um_start)
391
+ || ( mp_start..mp_end) . contains ( & um_end)
392
+ || ( um_start..um_end) . contains ( & mp_start) ;
393
+
394
+ if cond {
395
+ idxes. push ( idx) ;
396
+ }
397
+ }
398
+ // We iterate thru this while removing elements so if
399
+ // it's not reversed we will mess up the mappings badly!
400
+ idxes. reverse ( ) ;
401
+
402
+ ptrace:: syscall ( pid, None ) . unwrap ( ) ;
403
+ let _ = wait:: waitpid ( pid, None ) . unwrap ( ) ;
404
+ let regs = ptrace:: getregs ( pid) . unwrap ( ) ;
405
+
406
+ if regs. retval ( ) as isize > 0 {
407
+ // Unmap succeeded, so take out the mapping(s) from our list
408
+ // but it may be only partial so we may readd some sections
409
+ for idx in idxes {
410
+ let um_end = um_start + um_len;
411
+ let ( mp_start, mp_len) = mappings. remove ( idx) ;
412
+ let mp_end = mp_len + mp_len;
413
+
414
+ if mp_start < um_start {
415
+ let preserved_len_head = um_start - mp_start;
416
+ mappings. push ( ( mp_start, preserved_len_head) ) ;
417
+ }
418
+ if mp_end > um_end {
419
+ let preserved_len_tail = mp_end - um_end;
420
+ mappings. push ( ( um_end, preserved_len_tail) ) ;
421
+ }
422
+ }
423
+ }
424
+ }
425
+
431
426
#[ allow( clippy:: cast_possible_wrap) ]
432
427
#[ allow( clippy:: arithmetic_side_effects) ]
433
428
fn handle_segfault (
@@ -604,6 +599,8 @@ fn intercept_retptr(
604
599
ptr
605
600
}
606
601
602
+
603
+
607
604
// We only get dropped into these functions via offsetting the instr pointer
608
605
// manually, so we *must not ever* unwind from it
609
606
pub unsafe extern "C" fn mempr_off ( ) {
0 commit comments