-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Adding an option to force compiling a crate as PIE (instead of PIC) #87934
Comments
Please consider filing a Major Change Proposal for this. I don't expect it to be controversial. Adding this as a new See also: Adding a new option to rustc |
I'm not sure and MCP is necessary, a PR with implementation would be enough, this should be a trivial change from the compiler side. |
I would appreciate this change. I think adding I am working on a Rust kernel that will relocate itself and this would be much better than translating GOT, vtables, etc. at runtime. |
I added I had envisioned PIE not having a GOT, and string and vtables containing relative addresses and every access would be relative to program counter, but maybe my understanding is incorrect. |
Thank you all! I've started the MCP in rust-lang/compiler-team#461 just to be sure. I'll upload a PR shortly. @darbysauter I don't think |
#88820 is the prototype PR. |
I finally got around to testing your PR. I used: The binary is different compared to pic, but the GOT still contains absolute addresses, vtables still contain absolute addresses, etc. I am not sure entirely what is different between the two, but it looks as if I will just need to translate the addresses. Maybe what I am looking for doesn't exist. Thanks for the help! |
|
Also the GOT will always contain absolute addresses at runtime. PIC/PIE only make the code use relative addresses. All data, including the GOT, still uses absolute addresses. |
What is the difference between PIC and PIE I can't seem to find any good explanations online. There also seems to be 2 different factors, compiling as PIC/PIE and linking as PIC/PIE. What I understand now is that either way PIC or PIE needs to have addresses translated depending where it is placed in memory, so what is the advantage of PIE? |
PIE is a performance optimization over PIC. I think it basically puts all data (local or imported) at fixed offsets relative to the executable code, copying data from dylib dependencies and updating their GOT if necessary and avoids the GOT for non-imported functions, thus making them unoverridable by dependencies or |
Closing since #88820 has been merged, thank you all! |
Hi all,
AFAIK we always compile crates (
--crate-type=lib
) inrelocation-model=pic
as PIC (we callLLVMRustSetModulePICLevel
in https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/context.rs#L183). Only when we are building a binary crate we compile using PIE (https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/context.rs#L187).This is a reasonable default, PIC objects can be used for both executables and shared libraries. PIE objects can only be used for executables, but PIE code can be faster than PIC code.
We would like introduce a way to build crates as PIE in performance-critical scenarios where we know we won't need to produce shared libraries. Even further, cargo could detect that it's only building an executable and it could choose to build crates as PIE by default (but this is outside of the scope of this issue).
An obvious solution is to add a command line flag and check its value in https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/context.rs#L186. Would that be the best way to implement this? Would it be a welcomed change?
Thank you and have a lovely day!
The text was updated successfully, but these errors were encountered: