Saturday 7 November 2015

Linking & Loading C++

I came across a nice article that quickly revisits you through the linking & loading process.

http://ref.web.cern.ch/ref/CERN/CNL/2001/003/shared-lib/Pr/

Hence the post is summarized into following sections:

1) Compiling your program - using gcc or g++
2) Seeing the machine instructions of your object file - using 'nm' command.
3) Static & Dynamic Binding -
  • making a static library
  • making a dynamic library
4) Compiling the source code with static library
5) Compiling the source code with shared/dynamic library.
6) Seeing the symbols in object file - using objdump (linux) or dump (solaris) command.
7) Seeing the binding information when you execute your program - 
  • You need to set environment variable i.e.;
    • LD_DEBUG=bindings
    • after this execute your program; you will see the binding info; for eg:
$ LD_DEBUG=bindings  merrysh 
27534: binding file /lib/libc.so.6 to /lib/libc.so.6: symbol `_nl_current_LC_CTYPE' [GLIBC_2.0]
27534: binding file /lib/libc.so.6 to /lib/libc.so.6: symbol `_nl_current_LC_COLLATE' [GLIBC_2.0]
27534: ...
27534: calling fini: /lib/libm.so.6
27534: 
27534: binding file /lib/libm.so.6 to /usr/lib/libstdc++-libc6.1-1.so.2: symbol `__deregister_frame_info' [GLIBC_2.0]
27534: 
27534: calling fini: /lib/libc.so.6
27534: 
27534: binding file /lib/libc.so.6 to /usr/lib/libstdc++-libc6.1-1.so.2: symbol `__deregister_frame_info' [GLIBC_2.0]
27534: binding file /usr/lib/libstdc++-libc6.1-1.so.2 to /lib/libc.so.6: symbol `_IO_file_setbuf' [GLIBC_2.1]
27534: binding file /lib/libc.so.6 to /lib/libc.so.6: symbol `_exit' [GLIBC_2.0]

8) Dynamic library -> it is the responsibility of the dynamic linker i.e. 'ld.so' to load the shared libraries required for the program execution.
  • But remember it is the dynamic linker who firsts loads its required dependencies & once done it than shifts the control to the program in execution.
  • To know the way a dynamic linker loads the libs & shifts the control, you can set an env variable i.e. LD_DEBUG=libs. Once done execute the pgm & see the magic.
Note: Remember the way you link the libraries in your compile line, it defines the order for their loading as well.
  • For eg: $bash> g++ mytest.cpp -o test -lmy1 -lmy2
    • In this link line we have defined that first my1.so will be loaded & than my2.so. 
  • So basically, at link time when we specify the libraries to be linked, with this at linking phase the externals are resolved by matching the symbols in the defined libraries in the same order they are specified.
    • By this we ensure that all the symbols are resolved, although their definition will be presented at the time when the pgm is executed.
9) Understanding why -fPIC is required while creating shared library: