// SPDX-License-Identifier: MIT OR Apache-2.0 // // Copyright (c) 2022 Andre Richter //! Debug symbol support. use crate::memory::{Address, Virtual}; use core::{cell::UnsafeCell, slice}; use debug_symbol_types::Symbol; //-------------------------------------------------------------------------------------------------- // Private Definitions //-------------------------------------------------------------------------------------------------- // Symbol from the linker script. extern "Rust" { static __kernel_symbols_start: UnsafeCell<()>; } //-------------------------------------------------------------------------------------------------- // Global instances //-------------------------------------------------------------------------------------------------- /// This will be patched to the correct value by the "kernel symbols tool" after linking. This given /// value here is just a (safe) dummy. #[no_mangle] static NUM_KERNEL_SYMBOLS: u64 = 0; //-------------------------------------------------------------------------------------------------- // Private Code //-------------------------------------------------------------------------------------------------- fn kernel_symbol_section_virt_start_addr() -> Address { Address::new(unsafe { __kernel_symbols_start.get() as usize }) } fn kernel_symbols_slice() -> &'static [Symbol] { let ptr = kernel_symbol_section_virt_start_addr().as_usize() as *const Symbol; unsafe { let num = core::ptr::read_volatile(&NUM_KERNEL_SYMBOLS as *const u64) as usize; slice::from_raw_parts(ptr, num) } } //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- /// Retrieve the symbol corresponding to a virtual address, if any. pub fn lookup_symbol(addr: Address) -> Option<&'static Symbol> { kernel_symbols_slice() .iter() .find(|&i| i.contains(addr.as_usize())) } //-------------------------------------------------------------------------------------------------- // Testing //-------------------------------------------------------------------------------------------------- #[cfg(test)] mod tests { use super::*; use test_macros::kernel_test; /// Sanity of symbols module. #[kernel_test] fn symbols_sanity() { let first_sym = lookup_symbol(Address::new( crate::common::is_aligned as *const usize as usize, )) .unwrap() .name(); assert_eq!(first_sym, "libkernel::common::is_aligned"); let second_sym = lookup_symbol(Address::new(crate::version as *const usize as usize)) .unwrap() .name(); assert_eq!(second_sym, "libkernel::version"); } }