foreword
-
In the case of manually setting the storage path of the dynamic library, it is found that musl ldso can still load
/lib
the dynamic shared library located in the directory -
Can the storage path or search path of the dynamic library be manually configured? For example, there is a configuration file on Linux that can be configured to change the search order of dynamic libraries. Can musl ldso also do this?
search path
- By looking at the code of musl: implemented
ldso\dynlink.c
inload_library
the function, I learned that the dynamic library of musl islib
prefixed with by default, and the dynamic library name reserved by the system cannot be used, such aslibc.so
- musl ldso obtains the name of the dependent dynamic library through the application's dynamic library dependency list, most of which have no path.
- The following is the processing of the dynamic library path:
-
LDSO_ARCH
Through this, it is found that if the current platform isaarch64
, if there is/etc/ld-musl-aarch64.path
a file, read this file and get sys_path, which is the search path of the dynamic library -
There is not only one search path for the dynamic library, and
:
multiple paths can be separated by colons. The sys_path paths are in order, and the previous ones are searched first.
environment variable
- In the function
ldso\dynlink.c
in__dls3
, it can be found that env_path and env_preload are also environment variables of the dynamic library search path. If the system setsLD_LIBRARY_PATH
or through setenvLD_PRELOAD
, it will also change the order of the search path of musl ldso
env_path = getenv("LD_LIBRARY_PATH");
env_preload = getenv("LD_PRELOAD");
-
Currently, I understand that
LD_PRELOAD
the dynamic library is set, and the dynamic library here is also:
separated by a colon, and it is loaded first -
If it is set
LD_LIBRARY_PATH
, it is the search path of the dynamic library, which can be multiple,:
separated by colons, and the functions foundldso\dynlink.c
inload_library
are executed earlier than the system path. -
None of the above is set, and with
/etc/ld-musl-aarch64.path
the file, read/etc/ld-musl-aarch64.path
the path inside as the system dynamic library search path -
If there is no
/etc/ld-musl-aarch64.path
file, it will search for the default onesys_path = "/lib:/usr/local/lib:/usr/lib"
, which means that even if it is not set,/lib
the dynamic library under the directory can be searched by musl ldso. -
"/lib:/usr/local/lib:/usr/lib"
The path search order is:/lib
->/usr/local/lib
->/usr/lib
LD_LIBRARY_PATH setting method
-
setenv("LD_LIBRARY_PATH", "/kernel:/home/lib:/hello/app", 1);
, set the environment variable hereLD_LIBRARY_PATH
, so that the path that can be searched is:/kernel
->/home/lib
->/hello/app
-
Note
LD_LIBRARY_PATH
that the setting of does not affect the system's dynamic library search path, that is, if itLD_LIBRARY_PATH
cannot be found, it still searches under the system's dynamic library path
ld-musl-aarch64.path setting method
-
Note
ld-musl-aarch64.path
Indicates that under the aarch64 platform, different platforms, pay attention to the name"/etc/ld-musl-" LDSO_ARCH ".path"
-
Test method: Move the shared library libt0.so to another location, such as
/hello
the directory, and run the application (depending on the shared library libt0.so) at this time, prompting that the dependent shared library cannot be found -
Create a new /etc directory, create a new one under the /etc directory
ld-musl-aarch64.path
, content: , which is the path/lib:/usr/local/lib:/usr/lib:/hello
added/hello
-
At this time, run the application again, run normally, and find the location of the loaded shared library:
/hello/libt0.so
msh />./t0_test_s.elf
msh />Error loading shared library libt0.so: No such file or directory (needed by ./t0_test_s.elf)
librtthread.so : load map : 0x212000
Error relocating ./t0_test_s.elf: t0_data_set: symbol not found
Error relocating ./t0_test_s.elf: t0_data_get: symbol not found
msh />mkdir /etc
msh />cd /etc/
msh /etc>echo /lib:/usr/local/lib:/usr/lib:/hello /etc/ld-musl-aarch64.path
msh /etc>cat ld-musl-aarch64.path
/lib:/usr/local/lib:/usr/lib:/hello
msh />./t0_test_s.elf
msh />libt0.so : load map : 0x212000
librtthread.so : load map : 0x233000
/lib/librtthread.so : init_array : 0x235a60
/hello/libt0.so : init_array : 0x212750
./t0_test_s.elf : init_array : 0x2015d0
main : test start
main : -----------dlopen enter -----------
dl_test : ------------get-----------
dl_test : [get] ts.name = rt-smart_t0_lib_default
dl_test : [get] ts.cmd = 0xaabbccdd
dl_test : [get] ts.data = 0x8999eeff
main : -----------dlopen exit -----------
main : ------------get-----------
main : [get] ts.name = rt-smart_t0_lib_default
main : [get] ts.cmd = 0xaabbccdd
main : [get] ts.data = 0x8999eeff
main : ------------set->get-----------
main : [set-get] ts.name = t2_name_is_ok
main : [set-get] ts.cmd = 0x33559977
main : [set-get] ts.data = 0x4499aabb
main : test end
Preload library LD_PRELOAD
- Currently musl ldso supports
"LD_PRELOAD"
environment variables, which can be used tosetenv("LD_PRELOAD", "/lib/aa.so:/lib/bb.so", 1);
set shared libraries that need to be loaded in advance.
summary
-
If the library shared by the application has priority, you can put the higher priority in front of the search path, you can configure
/etc/ld-musl-aarch64.path
the file or set the environment variable:setenv("LD_LIBRARY_PATH", "/kernel:/home/lib:/hello/app", 1);
-
If several dynamic libraries need to be loaded and initialized in advance, you can set
"LD_PRELOAD"
environment variables so that the shared libraries loaded in advance are loaded first