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.3 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>
/*
* i386 stack frame layout:
*
* 12(%ebp) ...
* 8(%ebp) argument 1 (if applicable)
* 4(%ebp) caller %eip (after the call instruction, pushed by hardware)
* ------------------------------------------------------------
* (%ebp) caller %ebp (pushed in callee prologue)
* -4(%ebp) local variable 1
* -8(%ebp) local variable 2
* -12(%ebp) ...
*/
__naked void ktrace_print(void)
{
__asm__ volatile(
" pushl %ebp \n"
" call ktrace_print_from \n"
" ret \n"
);
}
void ktrace_print_from(void *frame)
{
void **ebp = (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 (ebp >= (void **)image_start && ebp < (void **)image_end) {
/* arch/x86/boot/setup32.S pushes two `nil's as the initial stack frame */
if (ebp[1] == nil)
break;
/* caller return address is immediately above the stack frame */
kprintf(" %p\n", ebp[1]);
if (ebp[1] >= isr_start && ebp[1] < isr_end)
break;
ebp = *ebp;
}
}
__naked void *ktrace_return_addr(void)
{
__asm__ volatile(
" movl 4(%ebp), %eax \n"
" ret \n"
);
}