据我所知,真正需要的可执行二进制文件中只有一种符号,即动态符号。这些符号用于重定位操作,因为它们是动态链接的。另一方面,不需要静态链接函数/变量,因此可以剥离它。
然而,当我检查剥离的 ffmpeg
二进制文件时,这就是我所得到的:
>nm -D ffmpeg
...
U __vfprintf_chk
U __vsnprintf_chk
U write
00000000018fa880 B x264_cabac_contexts
0000000001052a40 R x264_cabac_range_lps
0000000001052940 R x264_cabac_transition
0000000001970580 B x264_cabac_transition_unary
0000000001056820 R x264_last_coeff_flag_offset
0000000001056860 R x264_significant_coeff_flag_offset
0000000001056900 R x264_significant_coeff_flag_offset_8x8
U __xpg_strerror_r
U __xstat64
...
我可以验证libx264是静态链接到ffmpeg:
> ldd ffmpeg
linux-vdso.so.1 => (0x00007fff26d61000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f7c707e7000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f7c704e1000)
liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f7c702be000)
libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007f7c700ae000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f7c6fe95000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f7c6fc76000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7c6f8b0000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7c70b0a000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f7c6f69a000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f7c6f495000)
所以,我不明白为什么像x264_cabac_contexts
这样的符号没有被删除。 (它在libx264 /.../ cabac.c中定义):
uint8_t x264_cabac_contexts[4][QP_MAX_SPEC+1][1024];
困扰了我几个小时,我在谷歌上找不到任何东西......希望有人能解释一下......提前致谢!
答案 0 :(得分:1)
据我所知,真正需要的可执行二进制文件中只有一种符号,即动态符号。
正确。
所以,我不明白为什么像x264_cabac_contexts这样的符号没有被剥离。
因为它们是动态符号(这正是nm -D
正在打印的内容)。
您应该问的问题不是为什么动态符号没有被剥离,而是为什么x264_cabac_contexts
是动态符号。
有两种可能的答案:
ffmpeg
二进制文件与--export-dynamic
或等效标志或查看ldd
输出中的共享库列表,答案#2似乎不太可能。所以回答#1可能是正确的。
不,我不是用-rdynamic
编译它
编译与此无关。重要的是链接。你没有显示你的链接命令,但它可能有一些标志,这意味着“导出所有符号”(即相当于-rdynamic
)。或者您使用执行相同操作的链接描述文件。
答案 1 :(得分:0)
什么?
如果您的代码中有实际的常量只读数据,例如
const char *serialNumber = "451722-145252";
然后当然必须住在某个地方,如果你剥离它就会破坏程序,以免被删除。
如果serialNumber
此处不是static
,则无法删除。