You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
2.8 KiB
Rust

// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2022 Andre Richter <andre.o.richter@gmail.com>
//! 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<Virtual> {
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<Virtual>) -> 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");
}
}