Hide symbols from executable

234 Views Asked by At

I use gcc 9.2.0 to compile c++ program for arm. I use boost 1.71.0 (mainly asio). My final executable works fine, but even after stripping readelf -W prog --dyn-syms shows e.g. these entries:

   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

As far as I can tell, these symbols are known to the compiler/linker, as their Ndx is not UND (so undefined), which means their presence in symbol table is not necessary. Since whole program has 690kB and as strings shows these entries in symbol table take more or less 140kB, I'd like to remove them.

Currently I am compiling using the following compiler/linker options: -fvisibility=hidden -fvisibility-inlines-hidden -flto -Wl,--exclude-libs,ALL -Wl,-r,--discard-all -Wl,-flto

Without these options binary is >1.3MB.

I have two questions:

  1. Why are these symbols WEAK? These symbols are not form external library (static or dynamic), they come from templates (so from include files) and there is no need for them to be defined as WEAK as far as I can tell.
  2. How can I removed them from symbols table?

Note: I neither want nor can defined visibility by hand - modifying boost to this end is tedious, also if we ever upgrade it I'd have to do it again. So it is not an option.

EDIT: Using objcopy with any option (-x, --localize-hidden, --strip-unneeded) does nothing, as symbol table is not modified whatsoever. I guess all these functions/methods are is use. I guess they must be marked differently by linker (ld in my case), otherwise nothing can be done as they are strictly required.

1

There are 1 best solutions below

2
Ziming Song On

I use objcopy to remove symbols from object file:

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

Also remove .comment section, which holds compiler information.

If your output is executable, not library, strip would work too (i think).

I'm not familiar with boost, but you can define weak symbol in gcc using __attribute__((weak)). I guess weak symbol allows symbol override, which might by used by boost.