From 671b7c7b54fcab46b6e8bfc8c2d661fe55df0bf5 Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Tue, 26 Feb 2019 23:59:18 +0800 Subject: [PATCH] Implement backtrace support for x86_64 --- kernel/src/arch/x86_64/linker.ld | 2 ++ kernel/src/backtrace.rs | 26 +++++++++++++++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/kernel/src/arch/x86_64/linker.ld b/kernel/src/arch/x86_64/linker.ld index a84b37d0..a03f48ec 100644 --- a/kernel/src/arch/x86_64/linker.ld +++ b/kernel/src/arch/x86_64/linker.ld @@ -13,7 +13,9 @@ SECTIONS { .text ALIGN(4K): { + stext = .; *(.text .text.*) + etext = .; } .data ALIGN(4K): diff --git a/kernel/src/backtrace.rs b/kernel/src/backtrace.rs index abf95fb5..3d569166 100644 --- a/kernel/src/backtrace.rs +++ b/kernel/src/backtrace.rs @@ -1,13 +1,13 @@ use core::mem::size_of; +use rcore_memory::PAGE_SIZE; extern "C" { fn stext(); fn etext(); } -/// Returns the current frame pointer. +/// Returns the current frame pointer.or stack base pointer #[inline(always)] -#[cfg(any(target_arch = "aarch64", target_arch = "riscv32", target_arch = "riscv64"))] pub fn fp() -> usize { let ptr: usize; #[cfg(target_arch = "aarch64")] @@ -18,13 +18,16 @@ pub fn fp() -> usize { unsafe { asm!("mv $0, s0" : "=r"(ptr)); } + #[cfg(target_arch = "x86_64")] + unsafe { + asm!("mov %rbp, $0" : "=r"(ptr)); + } ptr } -/// Returns the current link register. +/// Returns the current link register.or return address #[inline(always)] -#[cfg(any(target_arch = "aarch64", target_arch = "riscv32", target_arch = "riscv64"))] pub fn lr() -> usize { let ptr: usize; #[cfg(target_arch = "aarch64")] @@ -35,13 +38,16 @@ pub fn lr() -> usize { unsafe { asm!("mv $0, ra" : "=r"(ptr)); } + #[cfg(target_arch = "x86_64")] + unsafe { + asm!("movq 8(%rbp), $0" : "=r"(ptr)); + } ptr } // Print the backtrace starting from the caller pub fn backtrace() { - #[cfg(any(target_arch = "aarch64", target_arch = "riscv32", target_arch = "riscv64"))] unsafe { let mut current_pc = lr(); let mut current_fp = fp(); @@ -61,6 +67,16 @@ pub fn backtrace() { current_pc = *(current_fp as *const usize).offset(1); } } + #[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); + if (current_fp >= 0x0000_57ac_0000_0000 + 512 * PAGE_SIZE - size_of::()) { + break; + } + current_pc = *(current_fp as *const usize).offset(1); + } } } }