我知道可以用来readelf -d <elf> | grep RPATH
从外壳检查给定的二进制文件,但是有可能在一个进程中执行此操作吗?
类似于(我完全组成了系统调用):
/* get a copy of current rpath into buffer */
sys_get_current_rpath(&buffer);
我正在尝试在我们的代码库中诊断一些可疑的SO链接问题,并希望在可能的情况下以这种方式检查RPATH(我宁愿不必生成外部脚本)。
Answers:
#include <stdio.h>
#include <elf.h>
#include <link.h>
int main()
{
const ElfW(Dyn) *dyn = _DYNAMIC;
const ElfW(Dyn) *rpath = NULL;
const char *strtab = NULL;
for (; dyn->d_tag != DT_NULL; ++dyn) {
if (dyn->d_tag == DT_RPATH) {
rpath = dyn;
} else if (dyn->d_tag == DT_STRTAB) {
strtab = (const char *)dyn->d_un.d_val;
}
}
if (strtab != NULL && rpath != NULL) {
printf("RPATH: %s\n", strtab + rpath->d_un.d_val);
}
return 0;
}
/proc
已安装环境中执行,则扩展$ORIGIN
就像readlink("/proc/self/exe", ...)
在最后一个斜杠处NUL终止一样简单。
RPATH
,但我想指出的是,检查DT_RUNPATH
标签是否希望知道二进制文件可能从其加载共享库的路径也同样重要。
作为记录,这里有几个命令将显示rpath
标题。
objdump -x binary-or-library |grep RPATH
也许更好的方法如下:
readelf -d binary-or-library |head -20
第二个命令还列出了对其他库的直接依赖关系,后跟rpath
。
这是我为方便起见使用的shell函数:
function getrpath {
eu-readelf -d "${1:?}" | sed -e '/RUNPATH/{s~.*\[\(.*\)\]~\1~;n};d'
}
这消耗eu-readelf
了elfutils
类似的输出:
Type Value
NEEDED Shared library: [libpq.so.5]
NEEDED Shared library: [libc.so.6]
RUNPATH Library runpath: [/some/path/to/lib]
....
并发出
/some/path/to/lib
它也应该与binutilsreadelf
而不是elfutils一起工作eu-readelf
。
grep PATH
改为。是否使用RPATH或RUNPATH取决于链接器,两者之间有细微但重要的区别:stackoverflow.com/a/52020177