Skip to content

Support position independent code in higher half #285

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
phil-opp opened this issue Nov 24, 2022 · 7 comments · Fixed by #289
Closed

Support position independent code in higher half #285

phil-opp opened this issue Nov 24, 2022 · 7 comments · Fixed by #289
Labels
enhancement New feature or request

Comments

@phil-opp
Copy link
Member

When a PIC kernel is located in higher half, we currently try to allocate 33554177 entries in the level 4 page table, which of course fails. This is the reason that we currently use the static relocation model for our higher half test:

"relocation-model=static", # pic in higher half not supported yet

I think the issue is in these lines:

// Find the highest virtual memory address and the biggest alignment.
let load_program_headers = elf_file
.program_iter()
.filter(|h| matches!(h.get_type(), Ok(Type::Load)));
let size = load_program_headers
.clone()
.map(|h| h.virtual_addr() + h.mem_size())
.max()
.unwrap_or(0);
let align = load_program_headers.map(|h| h.align()).max().unwrap_or(1);
used_entries.get_free_address(size, align).as_u64()

Looks like we only consider the end address for the size calculation, without taking the start address into account. I think we should be able to fix this by using the difference between the max and min address as size instead.

@phil-opp
Copy link
Member Author

cc @Freax13

@phil-opp
Copy link
Member Author

I started to look into this in https://github.com/rust-osdev/bootloader/tree/higher-half-pic. Not sure if my approach is right, though. The current error is "the relocation table must end in the elf file".

@Freax13
Copy link
Member

Freax13 commented Nov 24, 2022

Unless I'm missing something, specifying a image base address for a PIC kernel is meaningless because they're supposed to be able to be relocated anywhere. Instead the dynamic_start config value should be used (and already is for our higher half kernel test).
Removing those two lines should do the trick:

bootloader/Cargo.toml

Lines 96 to 97 in 17ba816

"-C",
"link-args=--image-base 0xFFFF800000000000",

@Freax13
Copy link
Member

Freax13 commented Nov 24, 2022

I'll take a look at your approach of changing how we calculate the size later today.

@phil-opp
Copy link
Member Author

Thanks a lot! This issue is not that urgent, so no hurry.

Unless I'm missing something, specifying a image base address for a PIC kernel is meaningless because they're supposed to be able to be relocated anywhere.

I guess there are different possible ways to handle this. For example, we could try to default to the image base address if it's still free when ASLR is disabled. Or we could treat it as a fallback for the dynamic_start if it isn't specified. Or we just ignore it.

Either way, we should not panic on PIC kernels with a higher half base address. It should be possible to change the relocation mode without adjusting all addresses in a linker script.

@Freax13
Copy link
Member

Freax13 commented Nov 24, 2022

I guess there are different possible ways to handle this. For example, we could try to default to the image base address if it's still free when ASLR is disabled. Or we could treat it as a fallback for the dynamic_start if it isn't specified. Or we just ignore it.

There is some precedence for treating the base address as the default: glibc used to treat the base address as the preferred address for PIEs when the LD_USE_LOAD_BIAS environment variable was set to 1. This was used in conjunction with prelinking which is a process that assigns static load addresses to shared libraries and PIEs at build time. Prelinking isn't used anymore which is why LD_USE_LOAD_BIAS was removed from glibc earlier this year.

Either way, we should not panic on PIC kernels with a higher half base address. It should be possible to change the relocation mode without adjusting all addresses in a linker script.

Agreed.

@Freax13
Copy link
Member

Freax13 commented Nov 24, 2022

The current error is "the relocation table must end in the elf file".

We currently assume that the address given by the RELA entry is an offset into the file. This is incorrect, it's actually a virtual address pointing to mapped memory. The fix for this isn't entirely trivial because we need to translate the virtual address to a physical address (or in other words we need to translate from the kernel's address space to the bootloader's address space). I'm working on a fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants