musl libc ldso dynamic loading research notes: dynamic library search path

foreword

  • In the case of manually setting the storage path of the dynamic library, it is found that musl ldso can still load /libthe 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.cin load_librarythe function, I learned that the dynamic library of musl is libprefixed with by default, and the dynamic library name reserved by the system cannot be used, such aslibc.so

insert image description here

  • musl ldso obtains the name of the dependent dynamic library through the application's dynamic library dependency list, most of which have no path.

insert image description here

  • The following is the processing of the dynamic library path:

insert image description here
insert image description here

  • LDSO_ARCHThrough this, it is found that if the current platform is aarch64, if there is /etc/ld-musl-aarch64.patha 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.

insert image description here

environment variable

  • In the function ldso\dynlink.cin __dls3, it can be found that env_path and env_preload are also environment variables of the dynamic library search path. If the system sets LD_LIBRARY_PATHor through setenv LD_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_PRELOADthe 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 found ldso\dynlink.cin load_libraryare executed earlier than the system path.

  • None of the above is set, and with /etc/ld-musl-aarch64.paththe file, read /etc/ld-musl-aarch64.paththe path inside as the system dynamic library search path

  • If there is no /etc/ld-musl-aarch64.pathfile, it will search for the default one sys_path = "/lib:/usr/local/lib:/usr/lib", which means that even if it is not set, /libthe 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 here LD_LIBRARY_PATH, so that the path that can be searched is: /kernel-> /home/lib->/hello/app

  • Note LD_LIBRARY_PATHthat the setting of does not affect the system's dynamic library search path, that is, if it LD_LIBRARY_PATHcannot be found, it still searches under the system's dynamic library path

ld-musl-aarch64.path setting method

  • Note ld-musl-aarch64.pathIndicates 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 /hellothe 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:/helloadded/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 to setenv("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.paththe 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

Guess you like

Origin blog.csdn.net/tcjy1000/article/details/132460970
Recommended