dlopen in libc and libdl

15,519

libdl is only exposing the private dl functions that already exist in libc as well as some wrappers to make the use of the libraries a bit easier. You can see some of this behaviour by looking at the symbol table of libdl.

If you use readelf on libdl, limiting to PRIVATE symbols:

readelf -s /usr/lib/x86_64-linux-gnu/libdl.so | grep PRIVATE
    13: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  UND _rtld_global_ro@GLIBC_PRIVATE (7)
    14: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _dl_vsym@GLIBC_PRIVATE (8)
    16: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _dl_addr@GLIBC_PRIVATE (8)
    18: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _dl_sym@GLIBC_PRIVATE (8)
    20: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND _dl_rtld_di_serinfo@GLIBC_PRIVATE (7)
    25: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  UND _rtld_global@GLIBC_PRIVATE (7)
    34: 00000000002030c0     8 OBJECT  GLOBAL DEFAULT   27 _dlfcn_hook@@GLIBC_PRIVATE
    39: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  ABS GLIBC_PRIVATE

You see all the entries that are UND, listing from GLIBC_PRIVATE? those are all referencing the implementations within libc.

The defined API of libc itself is not declared as implementing the dl functions as an exposed API, however in glibc libdl is tightly bound to libc, and it exposes the known API. glibc can use the private routines within itself to accomplish the run-time opening and using of the relevant .so files for nss routines in this case.

Share:
15,519
badnack
Author by

badnack

I'm a computer engineer graduated in Pisa. My main programming languages are c/c++ and java.

Updated on June 13, 2022

Comments

  • badnack
    badnack almost 2 years

    If a gcc-compiled program is calling dlopen, it has to be compiled with the -ldl option enabled. This means that such a program relies at run time on the library libdl.so. In fact by doing ldd on it we see the line:

    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2
    

    libc.so in turn uses dlopen (e.g., to deal with libnss.so), but doing ldd on libldl.so doesn't appear:

    /lib64/ld-linux-x86-64.so.2 (0x00007f5a488e4000)
    linux-vdso.so.1 =>  (0x00007fff7bdfe000)
    

    Why this difference?