2019-01-08 18:10:51 +04:00
|
|
|
use core::mem::size_of;
|
2019-02-26 19:59:18 +04:00
|
|
|
use rcore_memory::PAGE_SIZE;
|
2019-01-08 15:08:17 +04:00
|
|
|
|
2019-01-08 07:04:39 +04:00
|
|
|
extern "C" {
|
|
|
|
fn stext();
|
|
|
|
fn etext();
|
|
|
|
}
|
|
|
|
|
2019-02-26 19:59:18 +04:00
|
|
|
/// Returns the current frame pointer.or stack base pointer
|
2019-01-08 07:04:39 +04:00
|
|
|
#[inline(always)]
|
|
|
|
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-02-26 19:59:18 +04:00
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
|
unsafe {
|
|
|
|
asm!("mov %rbp, $0" : "=r"(ptr));
|
|
|
|
}
|
2019-04-05 19:31:30 +04:00
|
|
|
#[cfg(any(target_arch = "mips"))]
|
|
|
|
unsafe {
|
2019-04-06 10:15:55 +04:00
|
|
|
// read $sp
|
|
|
|
asm!("ori $0, $$29, 0" : "=r"(ptr));
|
2019-04-05 19:31:30 +04:00
|
|
|
}
|
2019-01-08 07:04:39 +04:00
|
|
|
|
|
|
|
ptr
|
|
|
|
}
|
|
|
|
|
2019-02-26 19:59:18 +04:00
|
|
|
/// Returns the current link register.or return address
|
2019-01-08 07:04:39 +04:00
|
|
|
#[inline(always)]
|
|
|
|
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-04-05 19:31:30 +04:00
|
|
|
#[cfg(any(target_arch = "riscv32",
|
2019-04-05 20:45:41 +04:00
|
|
|
target_arch = "riscv64"))]
|
2019-01-08 07:33:31 +04:00
|
|
|
unsafe {
|
|
|
|
asm!("mv $0, ra" : "=r"(ptr));
|
|
|
|
}
|
2019-02-26 19:59:18 +04:00
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
|
unsafe {
|
|
|
|
asm!("movq 8(%rbp), $0" : "=r"(ptr));
|
|
|
|
}
|
2019-01-08 07:04:39 +04:00
|
|
|
|
2019-04-05 20:45:41 +04:00
|
|
|
#[cfg(target_arch = "mips")]
|
|
|
|
unsafe {
|
2019-04-05 20:55:08 +04:00
|
|
|
asm!("ori $0, $$31, 0" : "=r"(ptr));
|
2019-04-05 20:45:41 +04:00
|
|
|
}
|
|
|
|
|
2019-01-08 07:04:39 +04:00
|
|
|
ptr
|
|
|
|
}
|
|
|
|
|
2019-04-06 10:15:55 +04:00
|
|
|
|
2019-01-08 07:04:39 +04:00
|
|
|
// Print the backtrace starting from the caller
|
|
|
|
pub fn backtrace() {
|
|
|
|
unsafe {
|
|
|
|
let mut current_pc = lr();
|
|
|
|
let mut current_fp = fp();
|
|
|
|
let mut stack_num = 0;
|
2019-04-06 10:15:55 +04:00
|
|
|
|
|
|
|
// adjust sp to the top address of backtrace() function
|
|
|
|
#[cfg(target_arch = "mips")]
|
|
|
|
{
|
|
|
|
let func_base = backtrace as *const isize;
|
|
|
|
let sp_offset = (*func_base << 16) >> 16;
|
|
|
|
current_fp = ((current_fp as isize) - sp_offset) as usize;
|
|
|
|
}
|
|
|
|
|
2019-04-06 10:43:10 +04:00
|
|
|
println!("=== BEGIN rCore stack trace ===");
|
|
|
|
|
2019-03-27 14:35:08 +04:00
|
|
|
while current_pc >= stext as usize
|
|
|
|
&& current_pc <= etext as usize
|
|
|
|
&& current_fp as usize != 0
|
|
|
|
{
|
2019-04-06 10:15:55 +04:00
|
|
|
// print current backtrace
|
|
|
|
match size_of::<usize>() {
|
|
|
|
4 => {
|
|
|
|
println!(
|
2019-04-06 10:43:10 +04:00
|
|
|
"#{:02} PC: {:#010X} FP: {:#010X}",
|
2019-04-06 10:15:55 +04:00
|
|
|
stack_num,
|
|
|
|
current_pc - size_of::<usize>(),
|
|
|
|
current_fp
|
|
|
|
);
|
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
println!(
|
2019-04-06 10:43:10 +04:00
|
|
|
"#{:02} PC: {:#018X} FP: {:#018X}",
|
2019-04-06 10:15:55 +04:00
|
|
|
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
|
|
|
}
|
2019-04-06 10:15:55 +04:00
|
|
|
#[cfg(target_arch = "mips")]
|
|
|
|
{
|
|
|
|
// the prologue of function is always like:
|
|
|
|
// main+0: 27bd____ addiu sp, sp, -____
|
|
|
|
// main+4: afbf____ sw ra, ____(sp)
|
|
|
|
let mut code_ptr = current_pc as *const isize;
|
|
|
|
code_ptr = code_ptr.offset(-1);
|
|
|
|
|
|
|
|
// get the stack size of last function
|
|
|
|
while (*code_ptr as usize >> 16) != 0x27bd {
|
|
|
|
code_ptr = code_ptr.offset(-1);
|
|
|
|
}
|
|
|
|
let sp_offset = (*code_ptr << 16) >> 16;
|
|
|
|
trace!("Found addiu sp @ {:08X}({:08x}) with sp offset {}", code_ptr as usize, *code_ptr, sp_offset);
|
|
|
|
|
|
|
|
// get the return address offset of last function
|
|
|
|
let mut last_fun_found = false;
|
|
|
|
while (code_ptr as usize) < current_pc {
|
|
|
|
if (*code_ptr as usize >> 16) == 0xafbf {
|
|
|
|
last_fun_found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
code_ptr = code_ptr.offset(1);
|
|
|
|
}
|
|
|
|
if last_fun_found {
|
|
|
|
// unwind stack
|
|
|
|
let ra_offset = (*code_ptr << 16) >> 16;
|
|
|
|
trace!("Found sw ra @ {:08X}({:08x}) with ra offset {}", code_ptr as usize, *code_ptr, ra_offset);
|
|
|
|
current_pc = *(((current_fp as isize) + ra_offset) as *const usize);
|
|
|
|
current_fp = ((current_fp as isize) - sp_offset) as usize;
|
|
|
|
trace!("New PC {:08X} FP {:08X}", current_pc, current_fp);
|
|
|
|
continue;
|
|
|
|
} else {
|
2019-04-06 10:43:10 +04:00
|
|
|
trace!("No sw ra found, probably due to optimizations.");
|
2019-04-06 10:15:55 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-02-26 19:59:18 +04:00
|
|
|
#[cfg(target_arch = "x86_64")]
|
|
|
|
{
|
|
|
|
// Kernel stack at 0x0000_57ac_0000_0000 (defined in bootloader crate)
|
|
|
|
// size = 512 pages
|
|
|
|
current_fp = *(current_fp as *const usize).offset(0);
|
2019-03-27 14:35:08 +04:00
|
|
|
if current_fp >= 0x0000_57ac_0000_0000 + 512 * PAGE_SIZE - size_of::<usize>()
|
|
|
|
&& current_fp <= 0xffff_ff00_0000_0000
|
|
|
|
{
|
2019-02-26 19:59:18 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
current_pc = *(current_fp as *const usize).offset(1);
|
|
|
|
}
|
2019-01-08 07:04:39 +04:00
|
|
|
}
|
2019-04-06 10:43:10 +04:00
|
|
|
println!("=== END rCore stack trace ===");
|
2019-01-08 07:04:39 +04:00
|
|
|
}
|
|
|
|
}
|