Add symbol table handling and debug backtrace

This commit is contained in:
Mark
2020-01-29 20:12:52 +02:00
parent 977ca16f82
commit bccd620eec
7 changed files with 148 additions and 5 deletions
+73
View File
@@ -4,6 +4,7 @@
#include "sys/attr.h"
#include "sys/spin.h"
#include "sys/config.h"
#include "sys/elf.h"
#include <stdint.h>
#if defined(ARCH_AMD64)
@@ -11,6 +12,78 @@
#include "sys/amd64/hw/rs232.h"
#endif
////
static uintptr_t g_symtab_ptr = 0;
static uintptr_t g_strtab_ptr = 0;
static size_t g_symtab_size = 0;
static size_t g_strtab_size = 0;
void debug_symbol_table_set(uintptr_t s0, uintptr_t s1, size_t z0, size_t z1) {
g_symtab_ptr = s0;
g_symtab_size = z0;
g_strtab_ptr = s1;
g_strtab_size = z1;
}
int debug_symbol_find(uintptr_t addr, const char **name, uintptr_t *base) {
if (g_symtab_ptr && g_strtab_ptr) {
size_t offset = 0;
Elf64_Sym *sym;
while (offset < g_symtab_size) {
sym = (Elf64_Sym *) (g_symtab_ptr + offset);
if (ELF_ST_TYPE(sym->st_info) == STT_FUNC) {
if (sym->st_value <= addr && sym->st_value + sym->st_size >= addr) {
*base = sym->st_value;
if (sym->st_name < g_strtab_size) {
*name = (const char *) (g_strtab_ptr + sym->st_name);
} else {
*name = "<invalid>";
}
return 0;
}
}
offset += sizeof(Elf64_Sym);
}
}
return -1;
}
void debug_backtrace(uintptr_t rbp, int depth, int limit) {
// Typical layout:
// rbp + 08 == rip
// rbp + 00 == rbp_1
if (!limit) {
return;
}
uintptr_t rip = ((uintptr_t *) rbp)[1];
uintptr_t rbp_next = ((uintptr_t *) rbp)[0];
uintptr_t base;
const char *name;
if (debug_symbol_find(rip, &name, &base) == 0) {
kfatal("%d: %p <%s + %04x>\n", depth, rip, name, rip - base);
} else {
kfatal("%d: %p (unknown)\n", depth, rip);
}
if (rbp_next == 0) {
kfatal("-- End of frame chain\n");
return;
}
debug_backtrace(rbp_next, depth + 1, limit - 1);
}
////
static const char *s_debug_xs_set0 = "0123456789abcdef";
static const char *s_debug_xs_set1 = "0123456789ABCDEF";