Added late gdt setup with initial tss Moved attributes to include root Reordered some imports
118 lines
3.4 KiB
C
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");
|
|
}
|