#include "Symbols.h" #include "Log.h" #include "arch/MMU.h" #include "boot/bootboot.h" #include "fs/InitRD.h" #include #include #include extern const BOOTBOOT bootboot; static bool g_symbols_loaded = false; struct Symbol { u64 address; char symbol[256]; }; Vector g_symbols; extern const u8 kernel_start; extern const u8 kernel_end; static int sscanf(const char* str, const char* format, ...) { va_list ap; va_start(ap, format); int rc = scanf_impl(str, format, ap); va_end(ap); return rc; } namespace Symbols { Result load() { const u64 virtual_initrd_address = MMU::translate_physical_address(bootboot.initrd_ptr); TarStream stream; stream.initialize((void*)virtual_initrd_address, bootboot.initrd_size); TarStream::Entry file; while (TRY(stream.read_next_entry(file))) { if (file.name.view() == "ksyms") { char* string = strtok(const_cast((const char*)file.data()), "\n"); if (!string) return {}; do { Symbol symbol; memset(symbol.symbol, 0, sizeof(symbol.symbol)); char unused; int nread; sscanf(string, "%lx %c %n", &symbol.address, &unused, &nread); strlcpy(symbol.symbol, string + nread, sizeof(symbol)); TRY(g_symbols.try_append(symbol)); } while ((string = strtok(nullptr, "\n"))); kinfoln("Successfully loaded %zu kernel debug symbols", g_symbols.size()); g_symbols_loaded = true; return {}; } } return {}; } StringView lookup(u64 address) { if (!g_symbols_loaded) return StringView {}; if (address < (u64)&kernel_start) return StringView {}; if (address >= (u64)&kernel_end) return StringView {}; for (isize i = (isize)g_symbols.size() - 1; i >= 0; i--) { if (g_symbols[i].address < address) { usize index = i + 1; if (index == g_symbols.size()) return StringView {}; return StringView { g_symbols[index].symbol }; } } return StringView {}; } }