Beginner's Guide to Linkers (2010)
lurklurk.org
lurklurk.org
Pretty cool to watch it happen. The call lookup code in the dynamic linker involves a bunch of strcmp calls, which makes sense, but I still found surprising for some reason.
You can set the environment variable LD_BIND_NOW to make it do all these lookups at startup time.
http://eli.thegreenplace.net/2011/11/03/position-independent...
Usually security-sensitive binaries are compiled with this so that the GOT can be made read-only (although this isn't necessarily required -- PaX described a way to do this by mprotect()ing before and after each update to the GOT).
Ubuntu 16.10+ compile every binary like this, which is fine except it breaks ltrace and co, as I described here: https://stackoverflow.com/a/44295494
As well as for security, sometimes setting LD_BIND_NOW is good for performance, for example see AFL: https://github.com/mirrorer/afl/blob/a08fadf3cb0b0beffc0e4f9... (but normally it's not and you end up do a bunch of wasted loading work).
Solaris has the opposite LD_BIND_LAZY but this doesn't appear to be implemented on linux.
$ LD_DEBUG=statistics nmap -V
32564: total startup time in dynamic loader: 8917260 cycles
32564: final number of relocations: 2449
$ LD_BIND_NOW=1 LD_DEBUG=statistics nmap -V
32565: total startup time in dynamic loader: 12511900 cycles
32565: final number of relocations: 4730
Another difference between lazy and now is that if there is some symbol resolution problem, but the application never actually references that symbol, then the process can still run. This is either an advantage or a disadvantage depending on how you look at it.How does one acquire (and retain) this depth of knowledge. I work on low-level system software (C programming). Having good understanding of build system (make, cmake), dependencies and shared library knowledge is highly desired in my field.
But this is very hard core. Really interested in the path leading up to this.
If you want to learn, it is not hard at all. All it takes is curiosity. Of course, hitting a bug in ld.so or having to debug a kinky issue at the instruction level can feed such curiosity.
Apart from that, being in the right place helps. That could be a mailing list or some other channel where these tools are talked about.
Out of curiosity, what software do you work on? I have a very difficult time finding a C job, let alone one where this type of information would be valued.
I work in networking industry (as software dev). Think Juniper, Cisco, Brocade etc. This industry needs only C devs.
Passing commands directly to the linker requires
that you know what you are doing.
I added this to my makefiles. It doesn't make the linker work any better. But it does make me think a little harder about what the linker is doing with my incantations.Linker scripts [1] are a particular pain to get write and if you want to do something complicated on Linux or BSD, you'll be using linker scripts. These are a gnu linker thing. The OSX linker doesn't have the same. Indeed, linkers are different or duplicated on each platform.
gnu ld
osx ld
gold ld (Google)
lld (llvm)
whatever Windows uses because I don't know
...
I'm not embarrassed to admit this: I get my linker command lines and scripts working and that's about it. But linkers should be easier to understand and use. There is even a security bug that relies on our not understanding them [2].I can't sugar coat this: linkers are a pain. Taylor is right when he says Passing commands directly to the linker requires that you know what you are doing.
The idea was pretty cool - you could write and test ladder logic in a Window's GUI and then click a button to generate an .exe file and upload it to the PLC. The PLC's RTOS would then call my linker code which would link up the symbol tables for the DLLs with the embedded code in the PLC and do some other minor relocations. By putting all the ladder logic code in the loaded .exe they were able to optimize for size/speed (using gcc and heuristics of the ladder logic diagram) instead of running a ladder logic interpreter in the PLC.
If you ever get a change to play around with a linker I'd suggest you do. It's one of those "aha" moments in CS about the userland/OS boundary.
Beware that the content is not related to the original Turbo Pascal.
Or Oberon's dynamic linker based on strong typed packages, chapter 6 on http://www.inf.ethz.ch/personal/wirth/ProjectOberon/PO.Syste...