2019-01-08 18:10:51 +04:00
|
|
|
use core::mem::size_of;
|
2019-01-08 15:08:17 +04:00
|
|
|
|
2019-01-08 07:04:39 +04:00
|
|
|
extern "C" {
|
|
|
|
fn stext();
|
|
|
|
fn etext();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the current frame pointer.
|
|
|
|
#[inline(always)]
|
2019-01-08 08:05:29 +04:00
|
|
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv32", target_arch = "riscv64"))]
|
2019-01-08 07:04:39 +04:00
|
|
|
pub fn fp() -> usize {
|
|
|
|
let ptr: usize;
|
2019-01-08 07:33:31 +04:00
|
|
|
#[cfg(target_arch = "aarch64")]
|
2019-01-08 07:04:39 +04:00
|
|
|
unsafe {
|
|
|
|
asm!("mov $0, x29" : "=r"(ptr));
|
|
|
|
}
|
2019-01-08 08:05:29 +04:00
|
|
|
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
|
2019-01-08 07:33:31 +04:00
|
|
|
unsafe {
|
|
|
|
asm!("mv $0, s0" : "=r"(ptr));
|
|
|
|
}
|
2019-01-08 07:04:39 +04:00
|
|
|
|
|
|
|
ptr
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the current link register.
|
|
|
|
#[inline(always)]
|
2019-01-08 08:05:29 +04:00
|
|
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv32", target_arch = "riscv64"))]
|
2019-01-08 07:04:39 +04:00
|
|
|
pub fn lr() -> usize {
|
|
|
|
let ptr: usize;
|
2019-01-08 07:33:31 +04:00
|
|
|
#[cfg(target_arch = "aarch64")]
|
2019-01-08 07:04:39 +04:00
|
|
|
unsafe {
|
|
|
|
asm!("mov $0, x30" : "=r"(ptr));
|
|
|
|
}
|
2019-01-08 08:05:29 +04:00
|
|
|
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
|
2019-01-08 07:33:31 +04:00
|
|
|
unsafe {
|
|
|
|
asm!("mv $0, ra" : "=r"(ptr));
|
|
|
|
}
|
2019-01-08 07:04:39 +04:00
|
|
|
|
|
|
|
ptr
|
|
|
|
}
|
|
|
|
|
|
|
|
// Print the backtrace starting from the caller
|
|
|
|
pub fn backtrace() {
|
2019-01-08 08:05:29 +04:00
|
|
|
#[cfg(any(target_arch = "aarch64", target_arch = "riscv32", target_arch = "riscv64"))]
|
2019-01-08 07:04:39 +04:00
|
|
|
unsafe {
|
|
|
|
let mut current_pc = lr();
|
|
|
|
let mut current_fp = fp();
|
|
|
|
let mut stack_num = 0;
|
|
|
|
while current_pc >= stext as usize && current_pc <= etext as usize && current_fp as usize != 0 {
|
2019-01-08 15:08:17 +04:00
|
|
|
println!("#{} {:#018X} fp {:#018X}", stack_num, current_pc - size_of::<usize>(), current_fp);
|
2019-01-08 07:04:39 +04:00
|
|
|
stack_num = stack_num + 1;
|
2019-01-08 08:05:29 +04:00
|
|
|
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
|
2019-01-08 07:33:31 +04:00
|
|
|
{
|
2019-01-08 08:05:29 +04:00
|
|
|
current_fp = *(current_fp as *const usize).offset(-2);
|
2019-01-08 07:33:31 +04:00
|
|
|
current_pc = *(current_fp as *const usize).offset(-1);
|
|
|
|
}
|
|
|
|
#[cfg(target_arch = "aarch64")]
|
|
|
|
{
|
|
|
|
current_fp = *(current_fp as *const usize);
|
|
|
|
if current_fp != 0 {
|
|
|
|
current_pc = *(current_fp as *const usize).offset(1);
|
|
|
|
}
|
2019-01-08 07:04:39 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|