【问题标题】:Discard unused symbos from dlopen()'ed .so从 dlopen()'ed .so 中丢弃未使用的符号
【发布时间】:2017-11-10 07:37:22
【问题描述】:

我有一组仅以二进制形式分发的共享库 (Intel MKL)。一个顶级“运行时”库libmkl_rt.so,链接到我的可执行文件,并通过ldd 可见:

...
libmkl_rt.so => /var/task/lib/libmkl_rt.so (0x00007f8049a1f000)
...

但是,其他的,比如libmkl_avx.so,我假设是用dlopen()动态加载的,因为可执行文件会抛出一个错误,说如果找不到库就丢失了,但是用ldd看不到。

这些库很大(> 100MB),这是我的容器中唯一使用它们的可执行文件。我假设可执行文件没有调用这些库中的每个函数,所以我想精简它们,首先确定正在调用哪些函数,然后只保留这些函数。

我该怎么做:

  1. 确定实际使用了动态加载的共享库中的哪些符号?
  2. 仅将这些符号提取到库的“精简”副本中?

有什么工具可以解决这个问题吗?

【问题讨论】:

    标签: reverse-engineering dlopen objdump objcopy sprof


    【解决方案1】:

    确定动态加载的共享库中实际使用了哪些符号?

    您可以在LD_DEBUG=bindings LD_BIND_NOW=1 下运行您的程序,并查看libmkl_avx.so 中的哪些符号被绑定。

    仅将这些符号提取到库的“精简”副本中?

    不幸的是,这是不可能的,原因与您无法在可执行文件中重新排列函数的原因相同。链接代码后,所有内部 goto 和全局变量位置都是固定的,无法更改。即使正确反汇编链接代码(以确定函数边界和调用图)也是一个无法解决的问题(IDA 等工具使用启发式方法来缓解它,但问题仍然存在)。

    这应该不是一个大问题,因为操作系统只会加载您的应用程序实际使用的代码页。

    【讨论】:

      猜你喜欢
      • 2013-01-15
      • 2018-03-19
      • 2022-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-25
      • 2012-10-10
      相关资源
      最近更新 更多