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
Rust Building PIE without relocations #110270
Comments
Try the unstable |
Still no luck I'm afraid:
|
Right, if the relocation model is set to PIC or PIE, rustc will tell the linker to produce PIE executables. As I understand it PIE executables use relative relocations when it isn't known at link time that the symbol will always come from the executable itself as opposed to a dynamic library. You can do |
Even with the helloworld example, there are tens of such relocations including the following types:
I can't see any real pattern in them to explain why they are relocated. So I figured I'd try to build a static library so that I can then manually call the linker to build a fully statically linked binary (e.g. no DT_NEEDED) so the linker will know exactly where every symbol is at link time (since I don't think rust/cargo supports building a static binary?). Anyway, I've discovered that even if I build a Thanks for your continued help with this, it's really baffling! |
Indeed.
All relative relocations within the same executable will be resolved by the linker, but absolute relocations can only be resolved at runtime once the final memory location of the executable is known and GOT relocations can only be resolved once the target of the respective symbols has been determined and (if it is from a dynamic library) loaded into memory. By the way why do you want to avoid all relocations? |
I am trying to build a powerpc However, if I perform the link using |
Also, if I build with |
When creating a statically linked position independent executable, Scrt.o is linked in. This object file defines the |
Also, if I build with |
Sorry, a little more detail. I'm not using cargo/rust to perform my linking since I use it to build my crate as a static lib as I wanted total control of my linker step. I am passing my crate (.a) as an input to the linker along with As a test harness, I am loading the binary using a simple Linux loader process which |
If you build an ET_EXEC binary, the linker will resolve all absolute relocations using a fixed base address. You need an ET_DYN position independent executable to keep the absolute relocations in metadata for Scrt.o to resolve at runtime. To produce a position independent executable which doesn't need to perform any relocations at runtime, you need to make sure that the data section doesn't contain any relocations, that you compile with |
Even with |
Is that after linking? |
Yes. It looks like the relocations are applied to the |
If there is a |
Looking at the link map, it seems the vast majority of the Looking at the One of the sources of entries in the |
Are you passing |
Sorry for the delay. I got distracted with a few other things. I decided to create a minimal reproducer here to help demonstrate things. Just running It's essentially just a #[no_mangle]
extern "C" fn unsafe_main(_argc: i32, _argv: *const *const i8) -> i32 {
unsafe {
let bytes = b"HELLO\n\0";
write(STDOUT_FILENO, bytes.as_ptr() as *const c_void, bytes.len());
// libc::_exit(0);
0xdeadface_u32 as i32
}
} Grateful if you have any more suggestions. |
I tried compiling the minimal reproducer for x86_64 and I didn't find any GOT references. Based on https://maskray.me/blog/2023-02-26-linker-notes-on-power-isa |
Should this be refered to someone on the rust compiler team? Is it an inherent limitation of the architecture? Or perhaps of the LLVM backend for PPC? I apprecaite it may not be the most common problem people face and hence may not be prioritised for a fix, but it would be good at least to determine a definitive cause and confirm there isn't a simple workaround if possible. |
You could try asking someone who works on the PPC backend of LLVM. |
@WorksButNotTested Do you still have a copy of https://github.com/WorksButNotTested/pie/ somewhere? |
I'm afraid not. I abandoned the approach in the end if I recall. The rust portion used a linker script to merge all the sections into a single executable segment (being sure to put the entry point in its own section at the start). This was then extracted using objcopy to give a flat binary. Then a C loader would just |
How did you do that sanely? |
Use an |
I am trying to build a rust executable without any relocations. Looking at the documentation for codegen options, it seems to say that the
relocation-model
controls the generation of position independent code and that it should be set topic
for most targets. However, when I build a simple test application, I can see it still contains relocations? Is it possible to prevent this?The text was updated successfully, but these errors were encountered: