dlopen(3) Library Functions Manual dlopen(3) dlclose, dlopen, dlmopen - LIBRARY Dynamic linking library (libdl, -ldl) #include void *dlopen(const char *filename, int flags); int dlclose(void *handle); #define _GNU_SOURCE #include void *dlmopen(Lmid_t lmid, const char *filename, int flags); dlopen() dlopen() ( ) , filename ( null) . dlopen, dlsym(3), dladdr(3), dlinfo(3) dlclose(). filename NULL, . filename (<>), ( ). ( ld.so(8)): o (ELF only) If the calling object (i.e., the shared library or executable from which dlopen() is called) contains a DT_RPATH tag, and does not contain a DT_RUNPATH tag, then the directories listed in the DT_RPATH tag are searched. o LD_LIBRARY_PATH, , ( set-user-ID set-group-ID). o (ELF only) If the calling object contains a DT_RUNPATH tag, then the directories listed in that tag are searched. o /etc/ld.so.cache ( ldconfig(8)) filename. o /lib /usr/lib ( ). , filename, , ( , , , , ). flags : RTLD_LAZY (lazy binding). , . , ( ; ). libc 2.1.1, LD_BIND_NOW. RTLD_NOW LD_BIND_NOW , dlopen(). , . flags , : RTLD_GLOBAL , , , , . RTLD_LOCAL RTLD_GLOBAL, , . , , , . RTLD_NODELETE ( glibc 2.2) dlclose(). , dlopen(). RTLD_NOLOAD ( glibc 2.2) . , (dlopen() NULL, , ). . , , RTLD_LOCAL, RTLD_NOLOAD | RTLD_GLOBAL. RTLD_DEEPBIND ( glibc 2.3.4) , . , , , . If filename is NULL, then the returned handle is for the main program. When given to dlsym(3), this handle causes a search for a symbol in the main program, followed by all shared objects loaded at program startup, and then all shared objects loaded by dlopen() with the flag RTLD_GLOBAL. ( ): , ; ( ), dlopen() RTLD_GLOBAL; ( , ). , ld(1), . - , <<-rdynamic>> ( <<--export-dynamic>>), , - , ld(1) . dlopen() , . , dlclose() , dlopen(). ( ) (. ., 1). dlopen(), RTLD_NOW, RTLD_LAZY. , RTLD_LOCAL, dlopen() RTLD_GLOBAL. - dlopen() , NULL. dlmopen() This function performs the same task as dlopen()--the filename and flags arguments, as well as the return value, are the same, except for the differences noted below. dlmopen() dlopen(), , lmid, (link-map list, ), (dlopen() , , dlopen()). Lmid_t , . lmid ID ( dlinfo(3) RTLD_DI_LMID) : LM_ID_BASE (. ., ). LM_ID_NEWLM . , , . filename NULL, lmid LM_ID_BASE. dlclose() dlclose() , handle. , , ( - , RTLD_GLOBAL ). , dlopen() , handle, . dlclose() , , handle . , - dlopen(), ( ), . . dlopen() dlmopen() NULL. ( , , ) NULL. dlclose() 0; . , , dlerror(3). attributes(7). +----------------------------+----------------------------------------------------------+--------------------------+ | | | | +----------------------------+----------------------------------------------------------+--------------------------+ |dlopen(), dlmopen(), | | MT-Safe | |dlclose() | | | +----------------------------+----------------------------------------------------------+--------------------------+ dlopen() dlclose() POSIX.1-2008. dlmopen() RTLD_NOLOAD RTLD_NODELETE GNU. RTLD_DEEPBIND Solaris. dlopen() dlclose() glibc 2.0. POSIX.1-2001. dlmopen() glibc 2.3.4. dlmopen() . , , , ( ) . The dlmopen() function permits object-load isolation--the ability to load a shared object in a new namespace without exposing the rest of the application to the symbols made available by the new object. Note that the use of the RTLD_LOCAL flag is not sufficient for this purpose, since it prevents a shared object's symbols from being available to any other shared object. In some cases, we may want to make the symbols provided by a dynamically loaded shared object available to (a subset of) other shared objects without exposing those symbols to the entire application. This can be achieved by using a separate namespace and the RTLD_GLOBAL flag. dlmopen() , RTLD_LOCAL. , , RTLD_LOCAL, RTLD_GLOBAL, , RTLD_GLOBAL. , RTLD_LOCAL , (), . dlmopen() -- , , . -- . dlmopen() . dlmopen() . glibc 16 . __attribute__((constructor)) __attribute__((destructor)). - dlopen(), - dlclose(). , , . info- gcc ( << >>). () , : _init _fini. _init(), , dlopen(). _fini(), . , ; gcc(1) -nostartfiles. _init _fini , , , , . glibc 2.2.3, atexit(3) , . dlopen, SunOS. glibc 2.24 RTLD_GLOBAL dlmopen() . , RTLD_GLOBAL dlopen() (SIGSEGV), , , . , , math (glibc), cos(3) 2.0. : $ cc dlopen_demo.c -ldl $ ./a.out -0.416147 #include #include #include #include /* Defines LIBM_SO (which will be a string such as "libm.so.6") */ int main(void) { void *handle; double (*cosine)(double); char *error; handle = dlopen(LIBM_SO, RTLD_LAZY); if (!handle) { fprintf(stderr, "%s\n", dlerror()); exit(EXIT_FAILURE); } dlerror(); /* Clear any existing error */ cosine = (double (*)(double)) dlsym(handle, "cos"); /* According to the ISO C standard, casting between function pointers and 'void *', as done above, produces undefined results. POSIX.1-2001 and POSIX.1-2008 accepted this state of affairs and proposed the following workaround: *(void **) (&cosine) = dlsym(handle, "cos"); This (clumsy) cast conforms with the ISO C standard and will avoid any compiler warnings. The 2013 Technical Corrigendum 1 to POSIX.1-2008 improved matters by requiring that conforming implementations support casting 'void *' to a function pointer. Nevertheless, some compilers (e.g., gcc with the '-pedantic' option) may complain about the cast used in this program. */ error = dlerror(); if (error != NULL) { fprintf(stderr, "%s\n", error); exit(EXIT_FAILURE); } printf("%f\n", (*cosine)(2.0)); dlclose(handle); exit(EXIT_SUCCESS); } . ld(1), ldd(1), pldd(1), dl_iterate_phdr(3), dladdr(3), dlerror(3), dlinfo(3), dlsym(3), rtld-audit(7), ld.so(8), ldconfig(8) Info gcc ld Yuri Kozlov ; GNU 3 , . . , , . Linux man-pages 6.06 31 2023 . dlopen(3)