bootloader
bootloader copied to clipboard
Add support for kernel info
Fixes: #164
cc @phil-opp?
Thinking more about this, I'm not sure if the kernel_base and kernel_size fields really make sense since not all kernels are continous in virtual memory. Perhaps you can clarify how these fields are required for implementing unwinding? Perhaps we can find a better solution.
@phil-opp Basically in stack unwinding we load the kernel bytes from the provided kernel_base and kernel_size then just ElfFile::new(kernel_slice)
and then we walk through the RBP and
for data in symbol_table { // symbol table got from the symtab elf section
let st_value = data.value() as usize;
let st_size = data.size() as usize;
if rip >= st_value && rip < (st_value + st_size) {
let mangled_name = data.get_name(&kernel_elf);
...
}
} // basically what you could do using `readelf` and include it using `include_bytes` but this is runtime thinggy
This is roughly how you would do this
@phil-opp a better alternative solution would be to pass the symbol tab (symtab) section in the KernelInfo itself as we are loading the ELF in the bootloader right (so we would save, an ELF load on unwind)? What we actually are looking for is the kernel slide. Slide that the bootloader applied over the kernel's load address as a positive offset.
Wouldn't both strategies fail in release mode? You don't have debugging information in release mode, which, if I remember right, means you have no symbol table either.
On 6/16/21, Anhad Singh @.***> wrote:
@phil-opp a better alternative solution would be to pass the symbol tab (symtab) section in the KernelInfo itself as we are loading the ELF in the bootloader right (so we would save an ELF load on unwind)?
-- You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub: https://github.com/rust-osdev/bootloader/pull/177#issuecomment-862131983
-- Signed, Ethin D. Probst
The symbol table can be manually stripped, but it is kept by default. It is not part of the debuginfo but required by the linker to do it's job.
@Andy-Python-Programmer Sorry for the delay, the past two months were quite busy for me.
Basically in stack unwinding we load the kernel bytes from the provided kernel_base and kernel_size then just
ElfFile::new(kernel_slice)
Thanks for the explanation, I think I understand it now. However, I'm not sure if it would work as implemented. The problem is that I'm not sure if we keep the unused (i.e. not loaded) parts of the ELF file reserved in physical memory after switching to the kernel. And even if we do currently, we might want to optimize this in the future.
So it would probably be better to add a config option for keeping the ELF file in physical memory after loading (similar to the existing config options). Only if it is enabled, we could fill an Optional
kernel_elf_address
field with the physical address range of the ELF file (and reserve it in the physical memory map if we don't do it already).
The stack_top
and stack_size
field are independent of this and can be always set. So they should probably go into a different field. We should also note in the docs that these describe a virtual address range.
There is a new PR that implements something similar: https://github.com/rust-osdev/bootloader/pull/346