Is there a programmatic way to inspect the current rpath on Linux?
I'm aware that it is possible to use readelf -d <elf> | grep RPATH
to inspect a given binary from the shell, but is it possible to do this within a process?
Something like (my completely made up system call):
/* get a copy of current rpath into buffer */
sys_get_current_rpath(&buffer);
I'm trying to diagnose some suspect SO linking issues in our codebase, and would like to inspect the RPATH this way if possible (I'd rather not have 开发者_开发知识库to spawn an external script).
For the record, here are a couple of commands that will show the rpath
/ runpath
header.
objdump -x binary-or-library |grep 'R.*PATH'
Maybe an even better way to do it is the following:
readelf -d binary-or-library |head -20
The second command also lists the direct dependencies on other libraries followed by rpath
.
#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;
}
You can also use:
chrpath -l binary-or-library
Here's what I use for convenience, as a shell function:
function getrpath {
eu-readelf -d "${1:?}" | sed -e '/RUNPATH/{s~.*\[\(.*\)\]~\1~;n};d'
}
This consumes eu-readelf
output from elfutils
like:
Type Value
NEEDED Shared library: [libpq.so.5]
NEEDED Shared library: [libc.so.6]
RUNPATH Library runpath: [/some/path/to/lib]
....
and emits
/some/path/to/lib
It should work fine with binutils readelf
instead of elfutils eu-readelf
too.
There is a way. Follow the example code in man dlinfo
[1], but use NULL
as the first parameter of dlopen()
.
[1] https://man7.org/linux/man-pages/man3/dlinfo.3.html
精彩评论