As far my understanding, when I compile my C source code GCC/LD does the address binding at compile time. Typically this address starts at zero. When I call a function from shared library how the compiler knows the address of shared library in advance? I know shared libraries gets their address at load time. Please correct me if I am wrong.

  • Searching for "dynamic linking" (which you already appear to know since you selected that tag) yields loads of information already. What specific questions do you have? (Covering the whole process is quite a task.) – Mat Oct 27 '15 at 10:53
  • suppose I called the printf() function. How the compiler will know the memory location of printf() function at compile time? – Saber Oct 27 '15 at 12:03
  • 3
    It doesn't, that's why it's called dynamic linking. – Mat Oct 27 '15 at 12:05

You can do a few things to help yourself understand this.

ldd /usr/bin/cat

On my laptop, that gives this output:

1771 % ldd /usr/bin/cat 
        linux-vdso.so.1 (0x00007ffc37fba000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007f1ea7018000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f1ea73bc000)

You'll notice that linux-vdso.so.1 and libc.so.6 don't have a fully qualified path, and that ldd shows you what the actual path that would be used to dynamically link in libc.so.6 is.

You can check that (and learn a bit) by doing the ldd again, with a little variation:

1790 % export LD_LIBRARY_PATH=/lib
1791 % ldd /usr/bin/cat 
        linux-vdso.so.1 (0x00007fff0a5a0000)
        libc.so.6 => /lib/libc.so.6 (0x00007fa257535000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fa2578d9000)

Looking closely, you can see that the dynamic linker (/lib64/ld-linux-x86-64.so.2 in this case) will now choose /lib/libc.so.6 as the C library. So the enironment variable LD_LIBRARY_PATH is important to deciding which files actually get used in dynamic linking.

The other thing you can do is strace:

strace -o cat.trace /usr/bin/cat /etc/motd

The file cat.trace will have a record of what system calls your subject process performs. Some of them will be mmap() of the files shown by ldd as getting dynamically linked in. Follow up by googlling for mmap.

Further reading: man ld.so.

See if you have the readelf command installed, or if you can install it, or compile it. Run readelf -a /usr/bin/cat. The actual ELF specification is impenetrable in my opinion, but there is some good ELF format information out there. Try to find it.

If you have the musl libc installed, or can install it, doing the same experiments as above on a simple executable compiled with musl libc can be very informative. Even something as complex as dynamic linking can have two different, working implementations on the same operating system.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.