前言?
? ? ? ? 在Linux程序的执行时,通过读取ELF文件中的rpath和interpreter字段,加载程序需要的依赖库。
rpath
????????rpath全名run-time search path,是elf文件中一个字段,它指定了可执行文件执行时搜索so文件的第一优先位置,一般编译器默认将该字段设为空。elf文件中还有一个类似的字段runpath,其作用与rpath类似,但搜索优先级低,搜索优先级如下:
rpath > LD_LIBRARY_PATH > runpath > ldconfig缓存 > 默认的/lib,/usr/lib等
如果需要使用相对路径指定程序的rpath lib目录,可以使用ORIGIN变量,ld(加载器)会将ORIGIN理解成可执行文件所在的路径。如:
gcc -Wl,-rpath='$ORIGIN/../lib' // 依赖库在程序的上一级,lib目录下
查看rpath命令:
readelf -d picToText // picToText 为被查看rpath的程序名称
结果:
interpreter
????interpreter是elf文件中的一个字段(全名:Requesting program interpreter),它指定了动态库加载器的位置。程序启动时操作系统会先把控制权转交给ld-linux-x86-64.so.2,该so负责加载所有程序依赖的so,这个库在程序链接时自动设置。64bit程序一般为/lib64/ld-linux-x86-64.so.2。这个库的加载不受动态库搜索路径(RPATH,LD_LIBRARY_PATH等)约束,是因为在程序编译时,将这个加载器的路径写到二进制文件中了,而在二进制文件中标记的字段就是interpreter。如果要指定其它加载器,就要修改这个字段。
设置interpreter字段:
gcc -Wl,-rpath='/my/lib',-dynamic-linker='/my/lib/ld-linux.so.2' // 设置lib/ld-linux.so.2 库的绝对路径到dynamic-linker
查看interpreter命令:
readelf -l picToText // picToText 是被查看的程序名称
结果:
patchelf命令
功能
修改已经生成的elf程序rpath和interpreter值。
修改rpath
patchelf --set-rpath libDir app
// 1 libDir: 要设置到程序app中rpath的依赖库路径
// 2 app: 被设置的程序文件
# 也可以使用相对程序app的路径
patchelf --set-rpath `pwd`/path/libDir app
修改interpreter
patchelf --set-interpreter /usr/lib64/ld-linux.so.2 app
// 1 /usr/lib64/ld-linux.so.2 程序app要使用加载器的绝对路径
// 2 要设置的程序名称
# 也可以使用相对程序app的路径
patchelf --set-interpreter `pwd`/path/lib64/ld-linux-x86-64.so.2 app
|