gcc 隐藏可执行文件中的符号

9ceoxa92  于 2023-06-30  发布在  其他
关注(0)|答案(1)|浏览(174)

我使用gcc 9.2.0arm编译c++程序。我使用boost 1.71.0(主要是asio)。我的最终可执行文件工作正常,但即使在剥离readelf -W prog --dyn-syms后,仍显示例如。这些条目:

904: 000dc518     1 OBJECT  UNIQUE DEFAULT   25 _ZN5boost4asio6detail30execution_context_service_baseINS1_16resolver_serviceINS0_2ip3tcpEEEE2idE
   912: 000dc498     1 OBJECT  UNIQUE DEFAULT   25 _ZN5boost4asio6detail30execution_context_service_baseINS1_18signal_set_serviceEE2idE
   943: 000dc46c     4 OBJECT  UNIQUE DEFAULT   25 _ZN5boost4asio6detail17posix_global_implINS0_14system_contextEE11static_ptr_E
   951: 000dc4b0     1 OBJECT  UNIQUE DEFAULT   25 _ZN5boost4asio6detail12service_baseINS1_14strand_serviceEE2idE
   990: 000dc48c     4 OBJECT  UNIQUE DEFAULT   25 _ZGVN5boost4asio6detail10call_stackINS1_14strand_service11strand_implEhE4top_E
  1005: 0009a484    38 OBJECT  WEAK   DEFAULT   15 _ZTSN5boost4asio22service_already_existsE
  1006: 000a3808    87 OBJECT  WEAK   DEFAULT   15 _ZTSN5boost16exception_detail10clone_implINS0_19error_info_injectorINS_12bad_any_castEEEEE
  1024: 0009ad9c    65 OBJECT  WEAK   DEFAULT   15 _ZTSN5boost16exception_detail19error_info_injectorISt11logic_errorEE
  1038: 0009ee34   128 OBJECT  WEAK   DEFAULT   15 _ZTSN5boost4asio6detail30execution_context_service_baseINS1_22deadline_timer_serviceINS0_11time_traitsINS_10posix_time5ptimeEEEEEEE
  1045: 0009ade0    84 OBJECT  WEAK   DEFAULT   15 _ZTSN5boost16exception_detail10clone_implINS0_19error_info_injectorISt11logic_errorEEEE

据我所知,这些符号是编译器/链接器已知的,因为它们的Ndx不是UND(因此未定义),这意味着它们不需要出现在符号表中。由于整个程序有690 kB和strings显示这些条目在符号表采取或多或少140 kB,我想删除它们。
目前我正在使用以下编译器/链接器选项进行编译:-fvisibility=hidden-fvisibility-inlines-hidden-flto-Wl,--exclude-libs,ALL-Wl,-r,--discard-all-Wl,-flto
如果没有这些选项,二进制是>1.3MB。
我有两个问题:
1.为什么这些符号很弱?这些符号不是外部库的形式(静态或动态),它们来自模板(因此来自包含文件),据我所知,没有必要将它们定义为WEAK。
1.如何将它们从符号表中删除?
注意:我既不想也不能手工定义可见性-为此修改boost是乏味的,而且如果我们升级它,我必须再做一次。所以这不是一个选择。
编辑:使用objcopy与任何选项(-x--localize-hidden--strip-unneeded)没有任何作用,因为符号表没有任何修改。我想所有这些功能/方法都是有用的。我猜它们必须通过链接器(在我的情况下是ld)进行不同的标记,否则什么也做不了,因为它们是严格要求的。

nsc4cvqm

nsc4cvqm1#

我使用objcopy从对象文件中删除符号:

objcopy --strip-unneeded --remove-section=.comment input.o output.o

同时删除保存编译器信息的.comment部分。
如果你的输出是可执行的,而不是库,strip也可以工作(我想)。
我不太熟悉boost,但是你可以在gcc中使用__attribute__((weak))定义弱符号。我猜弱符号允许符号覆盖,这可能被boost使用。

相关问题