Files
my-kern/kernel/debug/debug.c
Rick Rongen 20ab9e1d6e feat: gdt, attributes move, reorder
Added late gdt setup with initial tss
Moved attributes to include root
Reordered some imports
2021-03-21 17:34:38 +01:00

118 lines
3.4 KiB
C

//
// Created by rick on 08-03-21.
//
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <elf.h>
#define DEBUG_INIT
#include <myke/debug/debug.h>
#include <myke/libk/libk.h>
#include <myke/libk/kprint.h>
static struct elf32_section_header *elf_headers = NULL;
static struct elf32_section_header *elf_shstrtab = NULL;
static struct elf32_section_header *elf_symtab = NULL;
static struct elf32_section_header *elf_strtab = NULL;
static uint32_t elf_header_cnt;
static const char *elf_name_symtab = ".symtab";
static const char *elf_name_strtab = ".strtab";
struct stackframe {
struct stackframe *ebp;
uint32_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 *) elf_shstrtab->sh_addr + 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 *) elf_strtab->sh_addr + ndx);
}
void debug_find_sections(uint32_t shndx) {
elf_shstrtab = &elf_headers[shndx];
for (uint32_t i = 0; i < elf_header_cnt; ++i) {
struct elf32_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, elf_name_symtab) == 0) {
elf_symtab = current;
continue;
}
if (strcmp(name, elf_name_strtab) == 0) {
elf_strtab = current;
continue;
}
}
}
void debug_store_info(struct multiboot_info *info) {
if (!(info->flags & MULTIBOOT_INFO_ELF_SHDR)) {
return;
}
if (sizeof(struct elf32_section_header) != info->u.elf_sec.size) {
k_panics("ELF size not correct");
}
elf_headers = calloc(info->u.elf_sec.num, sizeof(struct elf32_section_header));
memcpy(elf_headers, (const void *) info->u.elf_sec.addr, sizeof(struct elf32_section_header) * info->u.elf_sec.num);
elf_header_cnt = info->u.elf_sec.num;
debug_find_sections(info->u.elf_sec.shndx);
}
struct elf32_symtab_entry *debug_get_entry_for_addr(uint32_t addr) {
if (elf_symtab == NULL) {
return NULL;
}
struct elf32_symtab_entry *first = (struct elf32_symtab_entry *) elf_symtab->sh_addr;
uint32_t num = elf_symtab->sh_size / sizeof(struct elf32_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) {
struct stackframe *frame = __builtin_frame_address(0);
void (*printer)(const char *) = do_sync ? kprint_sync : kprint;
printer("\n\n## Stack Trace ##\n");
char msg[1024] = {0};
while (frame->ebp != NULL) {
struct elf32_symtab_entry *entry = debug_get_entry_for_addr(frame->eip);
if (entry == NULL) {
sprintf(msg, "#unknown (%x)\n", frame->eip);
} else {
sprintf(msg, "%s (%x)\n", debug_get_strtab_entry(entry->st_name), frame->eip);
};
printer(msg);
frame = frame->ebp;
}
printer("\n");
}