diff --git a/src/debugger.rs b/src/debugger.rs index f02faeaf54..75ec5df490 100644 --- a/src/debugger.rs +++ b/src/debugger.rs @@ -1,118 +1,17 @@ use crate::{ context::Context, - memory::Frame, + memory::{get_page_info, the_zeroed_frame, Frame, RefCount}, paging::{RmmA, RmmArch, TableKind, PAGE_SIZE}, }; use alloc::sync::Arc; use hashbrown::{HashMap, HashSet}; use spinning_top::RwSpinlock; -//TODO: combine arches into one function (aarch64 one is newest) - /// Super unsafe due to page table switching and raw pointers! pub unsafe fn debugger(target_id: Option<*const RwSpinlock>) { println!("DEBUGGER START"); println!(); - unsafe { debugger_arch(target_id) }; - - println!("DEBUGGER END"); -} - -#[cfg(target_arch = "aarch64")] -pub unsafe fn debugger_arch(target_id: Option<*const RwSpinlock>) { - use crate::memory::{get_page_info, RefCount}; - - let mut tree = HashMap::new(); - let mut spaces = HashSet::new(); - - let old_table = unsafe { RmmA::table(TableKind::User) }; - - for context_lock in crate::context::contexts().iter() { - if target_id.map_or(false, |target_id| Arc::as_ptr(&context_lock.0) != target_id) { - continue; - } - let context = context_lock.0.read(); - println!("{:p}: {}", Arc::as_ptr(&context_lock.0), context.name); - - println!("status: {:?}", context.status); - if !context.status_reason.is_empty() { - println!("reason: {}", context.status_reason); - } - - // Switch to context page table to ensure syscall debug and stack dump will work - if let Some(ref space) = context.addr_space { - let new_as = spaces.insert(space.acquire_read().table.utable.table().phys().data()); - - unsafe { - RmmA::set_table( - TableKind::User, - space.acquire_read().table.utable.table().phys(), - ); - check_page_table_consistency(&mut *space.acquire_write(), new_as, &mut tree); - } - - if let Some([a, b, c, d, e, f]) = context.current_syscall() { - println!( - "syscall: {}", - crate::syscall::debug::format_call(a, b, c, d, e, f) - ); - } - - { - let space = space.acquire_read(); - if !space.grants.is_empty() { - println!("grants:"); - for (base, grant) in space.grants.iter() { - println!( - " virt 0x{:016x}:0x{:016x} size 0x{:08x} {:?}", - base.start_address().data(), - base.next_by(grant.page_count() - 1).start_address().data() + 0xFFF, - grant.page_count() * PAGE_SIZE, - grant.provider, - ); - } - } - } - - if let Some(regs) = context.regs() { - println!("regs:"); - regs.dump(); - - dump_stack(&*context, regs.iret.sp_el0); - } - - // Switch to original page table - unsafe { RmmA::set_table(TableKind::User, old_table) }; - } - - println!(); - } - for (frame, (count, p)) in tree { - let Some(info) = get_page_info(frame) else { - assert!(p); - continue; - }; - let rc = info.refcount(); - let (c, s) = match rc { - None => (0, false), - Some(RefCount::One) => (1, false), - Some(RefCount::Cow(c)) => (c.get(), false), - Some(RefCount::Shared(s)) => (s.get(), true), - }; - if c != count { - println!( - "frame refcount mismatch for {:?} ({} != {} s {})", - frame, c, count, s - ); - } - } -} - -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] -pub unsafe fn debugger_arch(target_id: Option<*const RwSpinlock>) { - use crate::memory::{get_page_info, the_zeroed_frame, RefCount}; - let mut tree = HashMap::new(); let mut spaces = HashSet::new(); @@ -148,7 +47,7 @@ pub unsafe fn debugger_arch(target_id: Option<*const RwSpinlock>) { TableKind::User, space.acquire_read().table.utable.table().phys(), ); - #[cfg(target_arch = "x86_64")] + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] check_page_table_consistency(&mut space.acquire_write(), was_new, &mut tree); } } @@ -170,6 +69,17 @@ pub unsafe fn debugger_arch(target_id: Option<*const RwSpinlock>) { for (base, info) in addr_space.grants.iter() { let size = info.page_count() * PAGE_SIZE; + #[cfg(target_arch = "aarch64")] + println!( + " virt 0x{:016x}:0x{:016x} size 0x{:08x} {:?}", + base.start_address().data(), + base.next_by(info.page_count() - 1).start_address().data() + 0xFFF, + size, + info.provider, + ); + + // FIXME riscv64 implementation + #[cfg(target_arch = "x86")] println!( " virt 0x{:08x}:0x{:08x} size 0x{:08x} {:?}", @@ -194,6 +104,11 @@ pub unsafe fn debugger_arch(target_id: Option<*const RwSpinlock>) { println!("regs:"); regs.dump(); + #[cfg(target_arch = "aarch64")] + dump_stack(&*context, regs.iret.sp_el0); + + // FIXME riscv64 implementation + #[cfg(target_arch = "x86")] dump_stack(&*context, regs.iret.esp); @@ -214,7 +129,7 @@ pub unsafe fn debugger_arch(target_id: Option<*const RwSpinlock>) { println!(); } - #[cfg(target_arch = "x86_64")] + #[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))] crate::scheme::proc::foreach_addrsp(|addrsp| { let was_new = spaces.insert(addrsp.acquire_read().table.utable.table().phys().data()); unsafe { check_page_table_consistency(&mut *addrsp.acquire_write(), was_new, &mut tree) }; @@ -242,6 +157,8 @@ pub unsafe fn debugger_arch(target_id: Option<*const RwSpinlock>) { "({} kernel-owned references were not counted)", temporarily_taken_htbufs ); + + println!("DEBUGGER END"); } fn dump_stack(context: &Context, mut sp: usize) {