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.
55 lines
1.4 KiB
C
55 lines
1.4 KiB
C
/* Copyright (C) 2021,2022 fef <owo@fef.moe>. All rights reserved. */
|
|
|
|
#include <gay/kprintf.h>
|
|
#include <gay/ktrace.h>
|
|
#include <gay/linker.h>
|
|
|
|
/*
|
|
* amd64 stack frame layout:
|
|
*
|
|
* 24(%rbp) ...
|
|
* 16(%rbp) argument 7 (if applicable, args 1-6 are passed in registers)
|
|
* 8(%rbp) caller %rip (after the call instruction, pushed by hardware)
|
|
* ------------------------------------------------------------
|
|
* (%rbp) caller %rbp (pushed in callee prologue)
|
|
* -8(%rbp) local variable 1
|
|
* -16(%rbp) local variable 2
|
|
* -24(%rbp) ...
|
|
*/
|
|
|
|
__naked void ktrace_print(void)
|
|
{
|
|
__asm__ volatile(
|
|
" movq %rbp, %rdi \n"
|
|
" jmp ktrace_print_from \n"
|
|
);
|
|
}
|
|
|
|
void ktrace_print_from(void *frame)
|
|
{
|
|
void **rbp = (void **)frame;
|
|
kprintf("Stack trace:\n");
|
|
|
|
/* XXX Rather than spitting out raw addresses, parse the kernel image's
|
|
* ELF sections to figure out what the address actually belongs to */
|
|
while (rbp >= (void **)image_start && rbp < (void **)image_end) {
|
|
/* arch/x86/boot/setup64.S pushes two `nil's as the initial stack frame */
|
|
if (rbp[1] == nil)
|
|
break;
|
|
/* Caller return address is immediately above the stack frame.
|
|
* XXX This prints the position *after* the call instruction. */
|
|
kprintf(" %p\n", rbp[1]);
|
|
if (rbp[1] >= isr_start && rbp[1] < isr_end)
|
|
break;
|
|
rbp = *rbp;
|
|
}
|
|
}
|
|
|
|
__naked void *ktrace_return_addr(void)
|
|
{
|
|
__asm__ volatile(
|
|
" movq 8(%rbp), %rax \n"
|
|
" ret \n"
|
|
);
|
|
}
|