Programmer's Self-cultivation Notes: Chapter 8

Chapter 8: Organization of Linux Shared Libraries

1. Different shared library versions may cause ABI changes, thus affecting the normal operation of the program. Therefore, each system will have its own set of shared library version naming rules. For Linux, it is
libname.so.xyz
x: major version number, y: minor version number, z: release version number.
Shared libraries differ greatly between different major versions and are incompatible with each other.
Only new symbols are added between minor versions and they are compatible with each other.
Interface bugs have been modified between released versions to make them compatible with each other.

2. The shared library that the program depends on is pointed out by the .dynamic section. If the name of the shared library of the complete version (both primary and secondary releases) is pointed out, the previous version must be saved every time the shared library is updated, which will cause the disk and memory to be loaded at the same time. Different versions of shared libraries) are under great pressure, so Linux has developed the SO-NAME naming rule.
libname.so.x
x is the major version number of the shared library.
The system will create a soft link with the same name as SO-NAME in the directory where each shared library is located, pointing to the latest version of the shared library (with the same major version number). It can be seen that if a shared library has multiple major versions installed, there will be Multiple corresponding soft connections.

There is a tool "ldconfig" in Linux. When the system installs or updates a shared library, it will traverse the default shared library directory and update or create the corresponding soft link.

gcc -lXXX means linking to the XXX shared library, and the system will look for the latest version of the XXX library (often specified by -L). It can be dynamic or static. Using -lc will select the appropriate version (static or dynamic) of the library according to the output file.

3. The minor version number intersection problem caused by SO-NAME and the solution of the symbol version mechanism

If an application relies on version 2.5 of lib.so and there is only version 2.3 in the system, the program will run normally because of the same SO-NAME, but if it references the symbols added in 2.5, it will exit abnormally. This is a minor version number intersection problem.

The symbolic version was introduced under this premise. The linking process of the shared library build can link the written symbol version script. There are some collections in the script. The collection has its own name such as VERS_1.1. The collection contains symbols defined by the shared library, so that the symbols of the shared library have their own versions (the collection names to which they belong). At the same time, there can be an inheritance relationship between collections. For example, VERS_1.2 inherits from VERS_1.1, so that the .so file after the shared library is built will contain the relevant content of the collection.
When an application links to the shared library lib.so, the lowest symbol set version of the shared library that the application depends on will be recorded in the final output file of the program (often an executable file). Note that the shared library is not owned by the system. The highest version.
When the program is running, the dynamic linker can determine whether the corresponding shared library installed by the system meets the requirements through the set versions of all shared library symbols it depends on recorded by the program. If not, it will prevent the program from running.
The symbolic version method is a complement to the SO-NAME mechanism.

----Linux symbol version
The symbol version mechanism under Linux is not widely used. It mainly uses some shared libraries under glibc.
There are two extensions to the Solaris symbol version under Linux.

In addition to specifying the version of the symbol in the symbol version script, you can add symbols to symbol tags in the c/c++ source code through
asm(".symver symbolInCode,symbolInScript@VERS_1.1") .

GCC allows the same symbol to exist in multiple versions of shared libraries, a symbol overloading mechanism at the link level.
The advantage of this overloading mechanism is that when the interfaces or meanings of a small number of existing interfaces are modified, there is no need to upgrade the main version to ensure that the functions of the old version are not affected.
asm(".symver newprintf,printf@VERS_1.1")
asm(".symver oldprintf,printf@VERS_1.1")
void oldprintf(){}
void newprintf(){}

4. The shared library system path
/usr/lib
/lib is generally the library required by the system itself;
/usr/local/lib is generally the shared library of third-party programs that are not required by the system.

5. Shared library search process
Shared library search is performed by the dynamic linker (/lib/ld-linux.so.x) based on the DT_NEED type item in the ".dynamic" section of any dynamically linked module.
If its value is an absolute path, it will be searched based on the absolute path. If it is a relative path, it will be searched in the directories specified in the /lib, /usr/lib and /etc/ld.so.conf configuration files. For the sake of portability of shared libraries, their paths are often relative.
If ld traverses these directories every time, it will be very time-consuming. Therefore, there is a program called ldconfig mentioned above. In addition to the SO-NAME soft links responsible for shared libraries mentioned above, it will also collect these SO-NAME special data structures and store them in /etc/ld.so.cache, thereby speeding up the process. Find speed. If ld is not found in the cache, it will traverse /lib and /usr/lib, otherwise it will fail.
Therefore, in theory, ldconfig should be run every time a shared library is added, deleted, or updated. Many software packages will call it after installing the shared library.

6.3 The environment variable
LD_LIBRARY_PATH related to dynamic linking
changes the process of ld searching for shared libraries. It will first query the path specified by this variable and then search by default. Facilitates open debugging and testing of shared libraries. Should not be abused. And it will affect the path of gcc compilation and search library, and the effect is equivalent to the -L parameter of gcc.
LD_LIBRARY_PATH=/home/mary:/home/ben /bin/ls

LD_PRELOAD
will load the specified shared library in advance, which has a higher priority than the previous variable. Due to the existence of the global symbol intervention mechanism, one or several functions of the standard C library can be easily rewritten without affecting other functions, which is useful for debugging and testing.
(/etc/ld.so.preload has the same effect as this variable)

Depending on the value of LD_DEBUG
, the dynamic linker will print out various useful information at runtime.
LD_DEBUG=files ./helloworld.out

7. Creation of shared libraries
When compiling with gcc, in addition to the -fPIC, -shared parameters, there are also -W1, -so-name, mysoname parameters passed to the linker to specify the SO-NAME of the output shared library.
If this parameter is not used, the shared library does not have SO-NAME by default. Even if you use ldconfig to update the SO-NAME soft link, it will have no effect on the shared library.

Note:
Do not remove the symbols and debugging information of the output shared library, and do not use gcc's "-fomit-frame-pointer" to remove the stack frame option, which will affect shared library debugging.
Test new shared libraries without affecting existing programs. In addition to using LD_LIBRARY_PATH, you can also use the "-rpath" option of ld to specify the shared library search path of the target program.
By default, in the executable file generated by the linker, only symbols referenced by other shared modules in the main module will be placed in the dynamic symbol table to reduce the size of the dynamic symbol table. This will cause a situation where when a program uses dlopen to dynamically load a shared module, and it needs to reference a symbol from the main module, the backreference fails because the symbol is not in the dynamic symbol table. The linker provides the "-export-dynamic" parameter to export all global symbols in the executable file (main module) to the dynamic symbol table to prevent the above problems.

For release versions, symbols have little effect. You can use the "strip" tool to clear all symbols and debugging information of shared libraries or executable files or the "-s" or "-S" parameter of ld.
striplibfoo.so

Methods that require system root permissions:
Copy the shared library to /lib, /usr/lib and other system directories, and run ldconfig.
Method that does not require root permissions:
Use ldconfig to create SO-NAME (for dynamic linker to find)
ldconfig -n shared_Library_directory
and you also need to specify the location of the shared library when compiling the program (-L and -l, or -rpath parameter (static link) device needs)

10. The constructor and destructor functions of the shared library in gcc are specified by
attribute ((constructorx))
attribute ((destructorx)), and x specifies the priority, which can be omitted. The smaller the x in the constructor, the higher the priority. The smaller the x in the destructor, the lower the priority. This is in line with the principle of resource application first and release later.
The construction of shared libraries in this way cannot use gcc's "-nostartfiles" or "-nostdlib" parameters because these constructors and destructors are run in the system's default standard runtime library or startup file. They will not run without these auxiliary results.

11. Shared library scripts
can combine several existing shared libraries to create a new shared library from the user's perspective.
The GROUP (/lib/libc.so.6 /lib/libm.so.2)
syntax command is no different from the link script, and its function is similar. It converts one or more input files in a certain format to form an output file. , so shared library scripts are also called dynamic link scripts, and the linking process is completed at runtime.

Guess you like

Origin blog.csdn.net/weixin_45719581/article/details/123207565
Recommended