I'd like to improve address space randomization (ASLR) by randomizing the offset between .text, .data and .bss segments (or more generalized, any program segments). With large code generation model (-mcmodel=large) on AMD64, the offset could be very large, but even with the default model, the segments could be randomized within range of RIP-relative accesses (+/-2GB). Currently the dynamic loader can't randomize the segments (nothing also tells it if this would be OK) so it maps them next to each other, which is predictable and boring.
For this to happen, I think the compiler would have to emit relocations for all cross-segment accesses and probably flagging the shared object somehow. Then, when detecting the flag, the dynamic loader could load the segments at random offsets within 2GB, or if the large model was used in compilation (another flag), anywhere in the available virtual address space (let OS map the segment anywhere by using mmap(NULL,...)).
Perhaps if GOT would be kept within 2GB range, other data segments could still be placed anywhere.
There would be some slowdown because of additional relocations (and the OS would not be happy due to increased VM fragmentation) but I think otherwise nothing should change (the code should be identical). This would be of course an opt-in feature mainly for hardened systems.
So, I wonder how to implement the compiler part. Is this something that could be done easily with LLVM/Clang?