Expose kernel symbols at runtime
So that we don't have to convert instruction pointers to line numbers via an external command like:
$ addr2line -ie o.qemu/kernel.elf ffffffffc024ddcf ffffffffc024e232
As of 7ad3e039, Ward now has a full listing of the kernel symbols mapped into the kernel address space. This doesn't have line numbers, but it does include (mangled) function names.
Symbol lookup works!
Sample panic:
cpu0-sh: panic: test failure
ffffffffc0287c6f <fat32_cluster_cache::cluster::mark_dirty()+31>
ffffffffc02865bf <fat32_alloc_table::requisition_free_cluster(unsigned int*)+175>
ffffffffc028eac3 <vnode_fat32::create_and_insert_file(char const*, unsigned int, unsigned int*, unsigned int*)+67>
ffffffffc0291011 <vnode_fat32::create_file(char const*, bool)+417>
ffffffffc027248d <filesystem::create_file(sref<vnode, void> const&, char const*, bool)+93>
ffffffffc023d583 <sys_openat(int, userptr_str, int, ...)+307>
ffffffffc023aaab <syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)+123>
ffffffffc024dd8b <sysentry_c+75>
ffffffffc024f926 <sysentry+238>
000000000040e34b
Sample page fault:
kernel trap 14 (#PF) err 0x2 cpu 0 cs 16 ss 24
rip ffffffffc0287c5e rsp ffffff0006c97810 rbp ffffff0006c97868
cr2 0000000000000000 cr3 0000000006d16002 cr4 00000000000306b0
rdi ffffff000453c800 rsi 0000000000000003 rdx ffffff00069214a8
rcx 0000000005f5e100 r8 ffffffffc17ae100 r9 ffffffffc17ae1c0
rax ffffff00069214a8 rbx ffffff00045b4100 r10 0000000000000000
r11 ffffffffc1460880 r12 ffffff00045b4110 r13 ffffff00045b4118
r14 0000000000000001 r15 ffffff0006c978c0 rflags 0000000000010286
proc: name sh pid 36 kstack 0xffffff0006c90000 qstack 0xffffff0006c78000
page fault: non-present page writing 0000000000000000 from kernel mode
ffffffffc028eac3 <vnode_fat32::create_and_insert_file(char const*, unsigned int, unsigned int*, unsigned int*)+67>
ffffffffc0291011 <vnode_fat32::create_file(char const*, bool)+417>
ffffffffc027248d <filesystem::create_file(sref<vnode, void> const&, char const*, bool)+93>
ffffffffc023d583 <sys_openat(int, userptr_str, int, ...)+307>
ffffffffc023aaab <syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)+123>
ffffffffc024dd8b <sysentry_c+75>
ffffffffc024f926 <sysentry+238>
000000000040e34b
We could stand to look up a few more things, like rip, but the basic idea works.
I just did a quick experiment on getting actual filenames/line numbers using a Rust program that just sweeps through all addresses in the .text segment and uses the addr2line library to resolve the program location. The whole thing takes only 0.2 seconds to run and in total there there were only 76609 valid address that didn't match the line number of the previous address. My main conclusion is that it should be totally feasible to provide a compact representation of this at runtime. The code is on the loc branch if you want to take a look.