feat: ported debug logging

This commit is contained in:
2023-09-27 22:26:50 +02:00
parent 7411fb55ea
commit 0567926814
10 changed files with 342 additions and 11 deletions

View File

@@ -0,0 +1,123 @@
//
// Created by rick on 08-03-21.
//
#include <stdio.h>
#include <string.h>
#include <elf.h>
#include <stdbool.h>
#include <yak/rt/debug/debug.h>
#include <yak/rt/kprint.h>
static uintptr_t kernel_start;
static struct elf64_section_header *elf_headers = NULL;
static struct elf64_section_header *elf_shstrtab = NULL;
static struct elf64_section_header *elf_symtab = NULL;
static struct elf64_section_header *elf_strtab = NULL;
static uint32_t elf_header_cnt;
struct stackframe {
struct stackframe *ebp;
uintptr_t eip;
};
char *debug_get_shstrtab_entry(uint32_t ndx) {
if (elf_shstrtab == NULL) {
return NULL;
}
if (ndx > elf_shstrtab->sh_size) {
return NULL;
}
return ((char *) kernel_start + elf_shstrtab->sh_offset + ndx);
}
char *debug_get_strtab_entry(uint32_t ndx) {
if (elf_strtab == NULL) {
return NULL;
}
if (ndx > elf_strtab->sh_size) {
return NULL;
}
return ((char *) kernel_start + elf_strtab->sh_offset + ndx);
}
void debug_find_sections(uint32_t shndx) {
elf_shstrtab = &elf_headers[shndx];
for (uint32_t i = 0; i < elf_header_cnt; ++i) {
struct elf64_section_header *current = &elf_headers[i];
char *name = debug_get_shstrtab_entry(current->sh_name);
if (name == NULL) {
printf("Name was NULL\n");
continue;
}
if (strcmp(name, ".symtab") == 0) {
elf_symtab = current;
continue;
}
if (strcmp(name, ".strtab") == 0) {
elf_strtab = current;
continue;
}
}
}
void debug_store_info(void *kernel) {
struct elf_file_header* elf_header = (struct elf_file_header*)kernel;
if (elf_header->ei_magic != ELF_MAGIC) {
printf("Unsupported magic for kernel header\n");
return;
}
// todo support other then 64 little
if (elf_header->ei_class != ELF_CLASS_64 || elf_header->ei_data != ELF_ENDIAN_LITTLE) {
printf("Kernel not a 64bit little endian elf\n");
return;
}
if (elf_header->elf64.e_shentsize != sizeof(struct elf64_section_header)) {
printf("Elf section headers not correct size\n");
}
kernel_start = (uintptr_t) kernel;
elf_headers = (struct elf64_section_header *) (kernel_start + elf_header->elf64.e_shoff);
elf_header_cnt = elf_header->elf64.e_shnum;
debug_find_sections(elf_header->elf64.e_shstrndx);
}
struct elf64_symtab_entry *debug_get_entry_for_addr(uintptr_t addr) {
if (elf_symtab == NULL) {
return NULL;
}
struct elf64_symtab_entry *first = (struct elf64_symtab_entry *) (kernel_start + elf_symtab->sh_offset);
uint32_t num = elf_symtab->sh_size / sizeof(struct elf64_symtab_entry);
for (uint32_t i = 0; i < num; ++i) {
// only functions for now
if (ELF32_ST_TYPE(first[i].st_info) != STT_FUNC) {
continue;
}
if (addr >= first[i].st_value && addr < (first[i].st_value + first[i].st_size)) {
return &first[i];
}
}
return NULL;
}
void debug_backtrace(bool do_sync) {
// todo support non-x86
struct stackframe *frame = __builtin_frame_address(0);
void (*printer)(const char *) = do_sync ? kprint_now : kprint;
printer("\n\n## Stack Trace ##\n");
char msg[1024] = {0};
while (frame->ebp != NULL) {
struct elf64_symtab_entry *entry = debug_get_entry_for_addr(frame->eip);
if (entry == NULL) {
snprintf(msg, 1024,"#unknown (%lx)\n", frame->eip);
} else {
snprintf(msg, 1024, "%s (%lx)\n", debug_get_strtab_entry(entry->st_name), frame->eip);
};
printer(msg);
frame = frame->ebp;
}
printer("\n");
}

View File

@@ -1,6 +1,6 @@
#include <yak/rt/kmain.h>
#include <yak/rt/panic.h>
#include "yak/platform/generic/platform.h"
#include <yak/platform/generic/platform.h>
void kmain() {
_init();

View File

@@ -9,8 +9,13 @@
print_function print_functions[MAX_PRINT_FUNCTIONS] = {0};
void kprint_now(char* msg) {
char* m = msg;
void kprint(const char* msg) {
// todo async
kprint_now(msg);
}
void kprint_now(const char* msg) {
const char* m = msg;
while (*m != 0) {
kprint_putc_now(*m);
m++;

View File

@@ -5,8 +5,10 @@
#include <stddef.h>
#include <stdio.h>
#include <limine.h>
#include <yak/rt/kprint.h>
#include <yak/rt/debug/debug.h>
#include <yak/rt/kmain.h>
#include <yak/rt/kprint.h>
static struct limine_bootloader_info_request limine_bootloader_info_request = {
.id = LIMINE_BOOTLOADER_INFO_REQUEST,
@@ -110,5 +112,9 @@ void limine_init() {
printf("Booted using limine from an unknown bootloader\n");
}
if (limine_kernel_file_request.response != NULL) {
debug_store_info(limine_kernel_file_request.response->kernel_file->address);
}
kmain();
}

View File

@@ -3,13 +3,18 @@
//
#include <yak/rt/panic.h>
#include "yak/rt/kprint.h"
#include "yak/platform/generic/platform.h"
#include <yak/rt/kprint.h>
#include <yak/platform/generic/platform.h>
#ifdef USE_DEBUG
#include <yak/rt/debug/debug.h>
#endif
void __attribute__((__noreturn__)) panic(char *reason) {
kprint_now(reason);
#ifdef USE_DEBUG
debug_backtrace(true);
#endif
// todo stack trace
kprint_now(reason);
halt_forever();
}