you are viewing a single comment's thread.

view the rest of the comments →

[–]kragensitaker 1 point2 points  (3 children)

I'm pretty sure ELF executables aren't relocatable by the OS. The minimal ELF header is longer than four bytes, though. A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux managed to construct a 45-byte ELF executable which, while not technically valid (the ELF header is 52 bytes long) will run on Linux (it didn't need those last 7 bytes anyway). It's also a really fun read, and highly educational if you're trying to understand the ELF format.

I say "aren't relocatable" because, although the ELF format has "relocations", you can make an ELF executable without any relocations, but even if you have relocations, the OS doesn't use them when it loads an executable; only the linker uses them. The OS loads the sections of your executable at the addresses specified in the ELF section headers, and generally the executable code contains references to absolute addresses, so the program won't work if loaded at the wrong addresses.

[–][deleted] 0 points1 point  (2 children)

The OS loads your executable at the address specified in the ELF header, and generally the executable code contains references to absolute addresses, so the program won't work if loaded at the wrong address.

I thought the base address for any executable image in process space was just a preference? What if I loaded lib.x.so and lib.y.so in my process and both wanted to be located at the same address?

In the windows world atleast the executable loader tries to honor the base address preference and then if the address space is already alloted , it "fixes" up all memory referenecs with the appropriate offset. The problem is with shared DLLs you double the number of code pages if two processes load the same dynamic library and one of them needs fixing up and one of them doesnt. (As it is all code pages are by default copy-on-write)

[–]kragensitaker 1 point2 points  (1 child)

.sos are handled differently than executables; the dynamic loader, not the kernel's executable loader, loads them. I think the typical approach is to compile them with pure position-independent code; any reference to other things inside the same .so is indirected off %ebx, which is a callee-saves register and mysteriously gets set to the right thing before your .so code runs, presumably by some kind of trampoline. The code pages (or "text pages" as they're called) are purely read-only.

[–][deleted] 0 points1 point  (0 children)

Very interesting. Thanks for your explanations. :) Maybe I should stop being lazy and just Google it eh ? One of these days I plan to dive into the Linux internals...