Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is added to an executable when linking with a shared library?

Tags:

c++

linux

unix

If I want to create a C++ program that links with a static library, then the final executable will contain both the code from my program, and the code from the library (I think...!). But I'm not entirely sure as to what happens when I link with a shared library.

Suppose I link with a library called libfoo.so, by specifying in my CMakeLists.txt file the line target_link_libraries(${PROJECT_NAME} foo). I'm assuming that the final executable will contain some information about this library, but not the full code. What is this other information? And furthermore, does the library have to be called exactly libfoo.so on the user's system?

like image 540
Karnivaurus Avatar asked Aug 20 '15 23:08

Karnivaurus


1 Answers

When you link to a dynamic library, the linker will add a NEEDED entry in the dynamic section of the program. Then the dynamic loader will use these to locate the library and use the library to solve any undefined dynamic symbol.

Note that there is no connection between the undefined dynamic symbols and the dynamic libraries where they are expected to be found. Sometimes they are found in another library and interesting things may happen.

The particular name stored in the NEEDED entry depends on whether the library has a SONAME entry in its dynamic section:

  • If there is a SONAME, then its contents will be copied to the NEEDED of the program
  • If there is no SONAME, the the file name of the library as used in the linker command will be stored.

You can check the contents of the dynamic section of a library or program with:

$ objdump -p program

How is this used in practice? Well, most (all?) linux distributions use the following scheme, with the system libraries (take libfoo.so):

  • The library is installed as /usr/lib/libfoo.so.1.2 or whatever version it is.
  • The are symbolic links to that library named /usr/lib/libfoo.so.1 and /usr/lib/libfoo.so.
  • The SONAME of the library is libfoo.so.1.
  • The path /usr/lib is set as as dynamic library path.

That way, when you link with -lfoo it will find the symlink libfoo.so, but will record the SONAME as libfoo.so.1. And when the program is run it will find the other symlink and load the library.

This trick is used so that you can install an ABI compatible, improved libfoo.so.1.3 and an ABI incompatible newer libfoo.so.2.1, and old program will load the old library while new compilations will use the new library.

Also note that the environment variables LD_PRELOAD, LD_LIBRARY_PATH and others affect the runtime behaviour. For more details, you can read man ld.so

like image 100
rodrigo Avatar answered Nov 04 '22 13:11

rodrigo