Linux dynamic Library related knowledge collation

Source: Internet
Author: User
Tags locale naming convention

Dynamic libraries and static libraries are common in C + + development, where the dynamic library run-time load makes the executable program smaller, and updates the dynamic library without recompiling the executable program, as opposed to the static library being compiled directly into the executable program. The author is a Linux background development, this knowledge is often used, so to collate this knowledge. The static library is relatively simple, this article only cares about the dynamic library under the Linux platform.


Create a dynamic library


Here I compile a short but useful hash function into a dynamic library as an example, Elfhash is used to hash the string and return an unsigned integer.


Elfhash.h

#include <stdio.h>

unsigned long elfhash (const char* key);


Http://www.qixoo.qixoo.com/elfhash.c

#include "elfhash.h"

unsigned long elfhash (const char* key)

{

unsigned long h = 0, G;

while (*key) {

h = (H << 4) + *key++;

if ((g = h & 0xf0000000)! = 0)

H ^= G >> 24;

H &= ~g;

}

return h;

}


Next, compile the above code with GCC and link the compiled target file into a dynamic library with LD


Gcc-fpic-c-wall elfhash.c

ld-shared Elfhash.o-o libelfhash.so


Where-fpic means generating location-independent code (Position independent codes) for dynamic libraries that share the same code of dynamic libraries in multiple processes. The-shared option for LD tells the linker to create a dynamic library. GCC can also indirectly invoke LD to generate a dynamic library


Gcc-fpic-shared-wall-o libelfhash.so elfhash.c


Working with Dynamic libraries


There are two ways to use a dynamic library, one for implicit use and the second for explicit use. The implicit use of the method is simple.


#include "elfhash.h"

int main ()

{

printf ("%ld\n", Elfhash ("Key-for-test"));

return 0;

}

Using dynamic libraries explicitly requires the use of several functions


#include <dlfcn.h>

void *dlopen (const char *filename, int flag); Flag can be rtld_lazy, the undefined symbol is resolved when executing code in the shared library, and Rtld_now is resolved before the Dlopen returns.

Char *dlerror (void); When an error occurs, an error message is returned

void *dlsym (void *handle, const char *symbol); Get symbols

int dlclose (void *handle); Shut down


Using the above functions, calling Elfhash implements the same function as implicit invocation


#include "elfhash.h"

#include <stdlib.h>

#include <dlfcn.h>


int main () {

void *handle;

unsigned long (*hash) (const char*);

Char *error;

Handle = Dlopen ("./libelfhash.so", Rtld_lazy);

if (!handle) {

Fputs (Dlerror (), stderr);

Exit (1);

}

hash = Dlsym (handle, "Elfhash");

if (Error = Dlerror ()) = NULL) {

Fputs (Error, stderr);

Exit (1);

}

printf ("%ld\n", (*hash) ("Key-for-test"));

Dlclose (handle);

}


Now that you know the knowledge above, you can create and use a dynamic library. We may still encounter some problems in the actual application.


Loading of dynamic libraries


Dynamic library creation that section, I show how to implicitly use the dynamic library, then compile and run this code to try.


GCC main.c-l./-lelfhash

./a.out//Execute executable program

Here are the output results

./a.out:error while loading shared libraries:libelfhash.so:cannot open Shared object file:no such file or directory


Results run times error, executable program cannot find the dynamic library. There are some statements on the web is the compile-time set-l option, but it proves that it is not possible on Linux (SunOS), this option is only valid when compiling links, allowing you to use the-L as above-lelfhash. Use readelf-d a.out to see the dynamic library information that the executable file relies on.


0x0000000000000001 (NEEDED) Shared library: [libelfhash.so]


You can see that the polygon does not contain the path information for the dynamic library. Check the documentation for the dynamic linker man ld-linux.so can find such a word (some no, version problem)


If a slash is found, then the dependency string was interpreted as a (relative or absolute) pathname, and the library is Lo Aded using that pathname


This paragraph is too long, I only intercept part, roughly speaking, when the dependency on the/symbol, then it will be parsed into the dynamic library loading path, implicitly use the example of a compilation method.


GCC main.c./libelfhash.so

./a.out

23621492//Output Normal


Re-use readelf-d a.out The view will find that there is a path in the dependency information.


0x0000000000000001 (NEEDED) Shared Library: [./libelfhash.so]


This approach solves the problem, but the path in the dependency is hard-coded and not very flexible. The dynamic linker is how to find the dynamic libraries that need further review documents. The order of the lookups is a bit long, it is not directly quoted here, basically:


1. (elf files only) use the properties of the Dt_rpath locale in the executable file, if Dt_runpath is set, then ignore Dt_rpath (RPATH and Runpath in my Linux).

2, using the environment variable Ld_library_path, if there is set-user-id/set-group-id in the executable file, it will be ignored.

3. (elf files only) use the properties of the Dt_runpath locale in the executable file

4. Find from the/etc/ld.so.cache cache file

5, from the default path/lib,/usr/lib file directory to find


We need to set rpath or Runpath, so we can do this.


GCC main.c-wl,-rpath,/home/xxx,--enable-new-dtags-l./-lelfhash


The-WL option here tells the linker LD How to handle the next pass of the-rpath (or use-R) to tell the LD Dynamic Library of the path information (note that there is no space between the-WL and the following options). If there is no--enable-new-dtags then only set rpath, conversely, rpath and Runpath will be set at the same time. View results using readelf-d a.out:


0X000000000000000F (RPATH) Library RPATH: [/home/xxx]

0x000000000000001d (Runpath) Library runpath: [/home/xxx]


If you use the environment variable Ld_library_path, you generally use export


Export ld_library_path=/home/xxx; $LD _library_path


Rpath and Runpath Specify the path of the dynamic library, which is simple to use, but also lacks flexibility, ldlibrarypath is also useful for temporary testing, but in a formal environment, it is not a good practice to use it directly, because environment variables are more relevant to the user's environment. Dynamic libraries need to be considered not only for their own use, but also for distribution to other users.


A more general approach is to use ldconfig, there are several ways to create a file in the/etc/ld.so.conf.d/directory, and then write your dynamic library path in. Or put your dynamic library into/lib,/lib64 (64-bit),/USR/LIB,/USR/LIB64 (64-bit) and then run sudo ldconfig to rebuild the/etc/ld.so.cache file.


Dynamic Library version


Usually in the use of third-party dynamic libraries, all with version (file name), you can see a lot of such dynamic library under/USR/LIB64. Now I recompile the dynamic library, this time with the version information.


Gcc-fpic-shared-wall-wl,-soname,libelfhash.so.0-o libelfhash.so.0.0.0 elfhash.c


Each dynamic library has a name, such as the libelfhash.so.0.0.0 here, called real name, the naming convention is simple, usually libxxx.so.MAJOR.MINOR.VERSION (sometimes VERSION is omitted), If the dynamic library on the interface compatibility, such as the removal of the interface or modify the interface parameters, major increase, if the interface is compatible, only made updates or bug fixes so minor and version increase. That is to say, major the same library interface is compatible, and vice versa, if using incompatible dynamic libraries requires recompiling the executable program.


When compiling a dynamic library, you can specify a soname by passing the connection option-soname to the LD, where libelfhash.so.0 is only reserved for major, and the library that specifies the name is loaded when the executable program runs the load dynamic library.


The dynamic library also has a name of link name, which, when compiling executable programs, passes the dynamic library name of the linker ld, usually a file name that has no version number ending with. So. The general practice is to create a soft chain on soname.


The dynamic library named after this rule can be ldconfig recognized, we put libelfhash.so.0.0.0 in the/usr/lib64 folder, execute the following command


$sudo Ldconfig-v | grep libelfhash.so

libelfhash.so.0-libelfhash.so.0.0.0


You can find that ldconfig, based on the information of libelfhash.so.0.0.0, creates a soft chain soname to real name, when dynamic library updates (minor,version increases), copies the new library to the appropriate location, and then executes sudo Ldconfig automatically updates the soft link to the latest dynamic library, and the dynamic Library update is complete.


Summarize


OK, about the Linux dynamic Library knowledge collation is here, although these are some of the basics, there are few principles involved in the internal dynamic library, but it is very common. In the process I took questions to read the LD and ld-linux.so documents, the harvest quite abundant. Again, I hope this article will help you explain some of the problems or doubts you have encountered.

Linux dynamic Library related knowledge collation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.