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

/* 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"
);
}