如何检查我的共享库中的哪些符号具有非位置无关代码 (PIC)?
How to check which symbols on my shared library have non-position independent code (PIC)?
我正在尝试用 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 code setup",它必须在每个外部函数的开头:
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
如第 99 页 ABI 所述。
但是我找不到非 PIC 的符号。或者可能是一些未使用 -fPIC
?
编译的相关文件
信息:
系统架构:ppc64le
使用以下命令编译 .so 库:gcc -shared -fPIC
失败的 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
动态部分(正在进入最终 link 的 .o
的 .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
要查找哪些符号使您的精灵 non-PIC/PIE(与位置无关 Code/Executable),请使用 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.
上可以找到更详细的解释
我正在尝试用 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 code setup",它必须在每个外部函数的开头:
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
如第 99 页 ABI 所述。
但是我找不到非 PIC 的符号。或者可能是一些未使用 -fPIC
?
信息:
系统架构:ppc64le
使用以下命令编译 .so 库:gcc -shared -fPIC
失败的 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
动态部分(正在进入最终 link 的 .o
的 .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
要查找哪些符号使您的精灵 non-PIC/PIE(与位置无关 Code/Executable),请使用 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.
上可以找到更详细的解释