@@ -258,11 +258,6 @@ fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
258258 // Memory allocated on the MiriMachine
259259 let mut ch_pages = vec ! [ ] ;
260260
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-
266261 // Straight up magic numbers we need
267262 let malloc_addr = libc:: malloc as usize ;
268263 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>) -> ! {
275270 let mut retcode = 0 ;
276271
277272 #[ allow( clippy:: cast_possible_wrap) ]
278- #[ allow( clippy:: arithmetic_side_effects) ]
279273 ' listen: for evt in listener {
280274 match evt {
281275 ExecEvent :: Status ( wait_status) =>
@@ -316,71 +310,25 @@ fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
316310 wait:: WaitStatus :: PtraceSyscall ( pid) => {
317311 let regs = ptrace:: getregs ( pid) . unwrap ( ) ;
318312 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
321316 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 ( ) ;
349320 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 _ ) ) ;
358323 }
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+ _ => ( ) ,
381330 }
382331
383- enter = !enter;
384332 ptrace:: syscall ( pid, None ) . unwrap ( ) ;
385333 }
386334 _ => ( ) ,
@@ -428,6 +376,53 @@ fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
428376 std:: process:: exit ( retcode) ;
429377}
430378
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+
431426#[ allow( clippy:: cast_possible_wrap) ]
432427#[ allow( clippy:: arithmetic_side_effects) ]
433428fn handle_segfault (
@@ -604,6 +599,8 @@ fn intercept_retptr(
604599 ptr
605600}
606601
602+
603+
607604// We only get dropped into these functions via offsetting the instr pointer
608605// manually, so we *must not ever* unwind from it
609606pub unsafe extern "C" fn mempr_off ( ) {
0 commit comments