【问题标题】:How to check which symbols on my shared library have non-position independent code (PIC)?如何检查我的共享库中的哪些符号具有非位置无关代码 (PIC)?
【发布时间】:2015-06-15 21:34:20
【问题描述】:

我正在尝试使用 debuild -i -us -uc -b 构建一个 .deb 包,最后我看到了:

Now running lintian...
warning: the authors of lintian do not recommend running it with root     privileges!
W: libluajit-5.1-2: hardening-no-relro usr/lib/powerpc64le-linux-gnu/libluajit-5.1.so.2.1.0
E: libluajit-5.1-2: shlib-with-non-pic-code usr/lib/powerpc64le-linux-gnu/libluajit-5.1.so.2.1.0
W: luajit: hardening-no-relro usr/bin/luajit-2.1.0-alpha
W: luajit: binary-without-manpage usr/bin/luajit-2.1.0-alpha
Finished running lintian.

我有一种预感,我没有定义一个“PIC代码设置”,它必须在每个外部函数的开头:

The following code might appear in a PIC code setup sequence to compute
the distance from a function entry point to the TOC base:
addis 2,12,.TOC.-func@ha
addi 2,2,.TOC.-func@l

ABI 指定,第 99 页。

但是我找不到非 PIC 的符号。或者可能是一些未使用-fPIC 编译的相关文件?

信息:

系统架构:ppc64le

编译.so库:gcc -shared -fPIC

【问题讨论】:

    标签: linux gcc debian powerpc


    【解决方案1】:

    要查找使您的精灵成为非 PIC/PIE(位置无关代码/可执行文件)的符号,请使用 pax-utils 包中的 scanelf(在 ubuntu 上,使用 sudo apt-get install pax-utils 安装它):

    $ scanelf -qT /usr/local/lib/libluajit-5.1.so.2.1.0 | head -n 3
      libluajit-5.1.so.2.1.0: buf_grow [0x7694] in (optimized out: previous lj_BC_MODVN) [0x7600]
      libluajit-5.1.so.2.1.0: buf_grow [0x769C] in (optimized out: previous lj_BC_MODVN) [0x7600]
      libluajit-5.1.so.2.1.0: buf_grow [0x76A0] in (optimized out: previous lj_BC_MODVN) [0x7600]
    $ objdump -Sa /usr/local/lib/libluajit-5.1.so.2.1.0 | grep -A5 \ 7694:
        7694:       00 00 80 39     li      r12,0
        7698:       c6 07 8c 79     rldicr  r12,r12,32,31
        769c:       00 00 8c 65     oris    r12,r12,0
        76a0:       00 00 8c 61     ori     r12,r12,0
        76a4:       a6 03 89 7d     mtctr   r12
        76a8:       21 04 80 4e     bctrl
    

    在我的情况下,绝对地址是要加载到r12,但这对于动态库是不可能的,因此链接器使用0 作为该参数(我必须使用@GOT 运算符,但仅此而已我的情况的特殊解决方案)。

    luajit 程序上,可以定义链接时间的地址,它看起来像这样:

        1003d0d4:   00 00 80 39     li      r12,0
        1003d0d8:   c6 07 8c 79     rldicr  r12,r12,32,31
        1003d0dc:   07 10 8c 65     oris    r12,r12,4103
        1003d0e0:   30 ca 8c 61     ori     r12,r12,51760
        1003d0e4:   a6 03 89 7d     mtctr   r12
    

    完全不同吧?

    可以在这个精彩的Gentoo wiki page上找到更详细的解释。

    【讨论】:

      【解决方案2】:

      失败的 lintian 检查是这样的:

              # Now that we're sure this is really a shared library, report on
              # non-PIC problems.
              if ($objdump->{$cur_file}->{TEXTREL}) {
                  tag 'shlib-with-non-pic-code', $cur_file;
              }
      

      因此,您可以通过查找包含 TEXTREL 动态部分(正在进入您的最终链接)的 .o 来找到有问题的文件。

      为此,您可以使用readelf --dyanamic,如下所示:

      find . -name '*.o' |
      while read obj
      do
          if readelf --dynamic "$obj" | grep -q TEXTREL
          then
              echo "$obj contains a TEXTREL section"
          fi
      done
      

      【讨论】:

      • 感谢@JeremyKerr 的提示,但实际上没有.o 文件有TEXTREL 部分,只有我的.so 文件。如果不是对象,我现在将检查导致添加此部分的原因。
      • @gut:啊,很高兴知道。那你也可以发布完整的最终链接命令吗?
      • gcc -shared -fPIC -Wl,-soname,libluajit-5.1.so.2 -o libluajit.so lj_vm_dyn.o ljamalg_dyn.o -lm -ldl
      • 顺便说一句,我在Gentoo Wiki 上找到了不错的技巧,但没有一个适合我的情况:$ scanelf -qT src/libluajit.so libluajit.so: floor [0x792C] in (optimized out: previous _init) [0x5B50] ... 在这个issue 上,问题仍然存在(错误仍然存​​在)
      • 这两个对象中的每一个都被编译为:gcc -fPIC -O2 -fomit-frame-pointer -Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U_FORTIFY_SOURCE -DLUA_ROOT=\"/usr\" -DLUA_MULTILIB=\"lib/powerpc64le-linux-gnu\" -fno-stack-protector -c -o ljamalg_dyn.o ljamalg.c @gcc -fPIC -O2 -fomit-frame-pointer -Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -U_FORTIFY_SOURCE -DLUA_ROOT="/usr" -DLUA_MULTILIB="lib/powerpc64le-linux-gnu" -fno-stack-protector -c -o ljamalg_dyn.o ljamalg.c
      猜你喜欢
      • 2011-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-09
      相关资源
      最近更新 更多