Implement backtrace support for AArch64

master
Jiajie Chen 6 years ago
parent 61eda6b19e
commit d8edd1a7db

@ -0,0 +1,48 @@
extern "C" {
fn stext();
fn etext();
}
/// Returns the current frame pointer.
#[inline(always)]
#[cfg(target_arch = "aarch64")]
pub fn fp() -> usize {
let ptr: usize;
unsafe {
asm!("mov $0, x29" : "=r"(ptr));
}
ptr
}
/// Returns the current link register.
#[inline(always)]
#[cfg(target_arch = "aarch64")]
pub fn lr() -> usize {
let ptr: usize;
unsafe {
asm!("mov $0, x30" : "=r"(ptr));
}
ptr
}
// Print the backtrace starting from the caller
pub fn backtrace() {
#[cfg(target_arch = "aarch64")]
unsafe {
let mut current_pc = lr();
let mut current_fp = fp();
let mut stack_num = 0;
println!("pc {:#018X} fp {:#018X}", current_pc, current_fp);
while current_pc >= stext as usize && current_pc <= etext as usize && current_fp as usize != 0 {
println!("#{} {:#018X}", stack_num, current_pc);
stack_num = stack_num + 1;
current_fp = *(current_fp as *const usize);
if current_fp as usize != 0 {
current_pc = *(current_fp as *const usize).offset(1);
}
println!("pc {:#018X} fp {:#018X}", current_pc, current_fp);
}
}
}

@ -3,6 +3,7 @@
use core::panic::PanicInfo; use core::panic::PanicInfo;
use core::alloc::Layout; use core::alloc::Layout;
use log::*; use log::*;
use crate::backtrace;
#[lang = "eh_personality"] #[lang = "eh_personality"]
extern fn eh_personality() { extern fn eh_personality() {
@ -13,6 +14,7 @@ fn panic(info: &PanicInfo) -> ! {
let location = info.location().unwrap(); let location = info.location().unwrap();
let message = info.message().unwrap(); let message = info.message().unwrap();
error!("\n\nPANIC in {} at line {}\n {}", location.file(), location.line(), message); error!("\n\nPANIC in {} at line {}\n {}", location.file(), location.line(), message);
backtrace::backtrace();
loop { crate::arch::cpu::halt() } loop { crate::arch::cpu::halt() }
} }

@ -28,6 +28,7 @@ mod fs;
mod sync; mod sync;
mod trap; mod trap;
mod shell; mod shell;
mod backtrace;
#[allow(dead_code)] #[allow(dead_code)]
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]

@ -31,5 +31,6 @@
"target-endian": "little", "target-endian": "little",
"target-pointer-width": "64", "target-pointer-width": "64",
"target-family": "unix", "target-family": "unix",
"disable-redzone": true "disable-redzone": true,
"eliminate-frame-pointer": false
} }

Loading…
Cancel
Save