4 ms·
I don't have much experience with the Windows model, but if I'm understanding you correctly . . . ELF does support load-time relocation, as appears to be done
by yew 12y ago
I don't have much experience with the Windows model, but if I'm understanding you correctly . . .
ELF does support load-time relocation, as appears to be done under Windows if two base addresses conflict. That just isn't the standard way of doing things, for several reasons.
First, load-time relocation imposes a cost at startup (whereas PIC imposes a smaller cost throughout the lifetime of the process). I'm given to understand that, back in the day, the startup delay for programs using large shared libraries could be quite noticeable.
Second, load-time relocation reduces in-memory text section sharing in the case where relocation is performed. If your goal in using shared libraries is saving RAM, this is a problem.
Third, it's a matter of inertia. Originally, UNIX shared libraries (a.out format) were built with a static, non-relocatable base address. Library authors had to coordinate via a central authority to ensure compatibility. PIC seemed like a good way to get as far away from that problem as possible - or so I understand.
Indirection through the GOT/PLT also serves another purpose, even in load-time relocation code - it enables replacing a symbol in one shared library with a symbol from another (eg via LD_PRELOAD). Though that's more of a side benefit than a justification.
- deleted 12y ago[deleted]
- quotemstr 12y agoKeep in mind that you don't need text relocations for code sequences that are naturally PC-relative, like jumps on x86, or pretty much anything on ARM and amd64. Windows DLLs don't need text relocations for references to other modules: the IAT (Import Address Table) does pretty much the same thing as the GOT and in pretty much the same way.
- yew 12y agoSure. Much of what I wrote is very x86 specific! Though I believe that a degree of indirection is preserved on AMD64 to enable symbol interposition?
- quotemstr 12y ago> Though I believe that a degree of indirection is preserved on AMD64 to enable symbol interposition? You really don't want symbol interdiction. You don't use it most of the time, and the rest of the time, you're just changing a call that looks like: foo(1, 2); to (*g_foo)(1, 2); Which do you think is faster? There's a reason everything on Android compiles with -Bsymbolic (which kills interdiction for calls between functions in the same module). You really should be compiling all your code with -Bsymbolic -fvisibility=hidden; explicitly export the symbols you want other modules to call.
- yew 12y agoThe first is faster, of course. Whether or not I want the second depends entirely on what I'm doing :) It certainly shouldn't be the default - it isn't very useful during normal work - but I've been glad to have it before. I wouldn't recommend -Bsymbolic by default unless you know it's safe for your environment, though. There is software that uses symbol interposition to 'productive' ends in production (not much of it, thank heavens). Mobile platforms are something of a special case.
- quotemstr 12y agoC++ exceptions exempted (see -Bsymbolic-functions), anything broken with -Bsymbolic is inherently broken and ought to be fixed. The same goes for symbol interposition. There are ways of providing extension points that are saner than allowing any shared library that happens to be loaded into your process the ability to override one of your functions.
- yew 12y agoOught to be fixed doesn't mean will be fixed, unfortunately. Especially when the people doing the fixing wouldn't be the developers. Fortunately there aren't too many applications that rely on interposition to function. As for myself: I've only ever used symbol interposition for debugging, instrumentation, etc . . . for which it was quite useful (as I've said). I pay attention to what my libraries export, so accidental interposition has never been a problem for me. (Making that easier by default is something that I would support.) I'll happily discuss the matter further, but I'm not interested in arguing it.
- brigade 12y agoUm, ARM by default is very not PIC; loads have only a 4k offset so references to the data section are stored as absolute addresses in the text section, unless you explicitly specify PIC which adds another 'add rN, pc' instruction to each reference. (and actually I believe Windows doesn't even support these PIC references in ARM code)
- deleted 12y ago[deleted]
- weinzierl 12y ago"back in the day, the startup delay for programs using large shared libraries could be quite noticeable. The start up delay for programs caused by relocation of shared libraries is a problem big enough today that the Google Chrome team jumps through several hoops to mitigate it. They collect DLL startup addresses from the systems where Chrome is installed and calculate an optimal address for chrome.dll so that the likelihood of relocation is minimized. Or maybe I dreamt all of this, because I couldn't find the original article where I read it.