有没有办法在Linux上检查当前的rpath?


82

我知道可以用来readelf -d <elf> | grep RPATH从外壳检查给定的二进制文件,但是有可能在一个进程中执行此操作吗?

类似于(我完全组成了系统调用):

  /* get a copy of current rpath into buffer */
  sys_get_current_rpath(&buffer);

我正在尝试在我们的代码库中诊断一些可疑的SO链接问题,并希望在可能的情况下以这种方式检查RPATH(我宁愿不必生成外部脚本)。


1
请记住,在诊断共享库问题时,还应该检查RUNPATH标记。因此,您应该grep PATH改为。是否使用RPATH或RUNPATH取决于链接器,两者之间有细微但重要的区别:stackoverflow.com/a/52020177
Nicolas Capens

Answers:


54
#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;
}

1
它很棒,但是不能与$ ORIGIN一起使用。$ ORIGIN不会被解释,并由函数按原样返回。有没有一种方法可以添加$ ORIGIN解释?
杰罗姆

5
@Jérôme如果要在/proc已安装环境中执行,则扩展$ORIGIN就像readlink("/proc/self/exe", ...)在最后一个斜杠处NUL终止一样简单。
2014年

尽管问题是关于的RPATH,但我想指出的是,检查DT_RUNPATH标签是否希望知道二进制文件可能从其加载共享库的路径也同样重要。
Nicolas Capens

154

作为记录,这里有几个命令将显示rpath标题。

objdump -x binary-or-library |grep RPATH

也许更好的方法如下:

readelf -d binary-or-library |head -20

第二个命令还列出了对其他库的直接依赖关系,后跟rpath


7
在ubuntu 15.04上,我必须使用:objdump -x binary-or-library | grep RUNPATH
Andreas Roth,


11
该答案与提出的问题无关(并包含在问题本身中)。
俄罗斯


1

这是我为方便起见使用的shell函数:

function getrpath {
    eu-readelf -d "${1:?}" | sed -e '/RUNPATH/{s~.*\[\(.*\)\]~\1~;n};d'
}

这消耗eu-readelfelfutils类似的输出:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.