https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117630
--- Comment #5 from R. Diez <rdiez-2006 at rd10 dot de> ---
I am trying to figure out why generic_category_instance and
system_category_instance land in my ELF file even though nobody is apparently
using them. Other similar objects, like io_category_instance, do not.
So I did an "objdump --disassemble" on the ELF file and tried to manually
follow all references to those 2 instances.
generic_category_instance is being used by something related to
__throw_system_error() and by system_error_category::default_error_condition,
which then gets complicated.
However, system_category_instance is apparently only being used by something
related to __throw_system_error(). That is the disassembly of that function:
0008a280 <_GLOBAL__sub_I__ZSt20__throw_system_errori>:
8a280: b580 push {r7, lr}
8a282: 4a07 ldr r2, [pc, #28] @ (8a2a0
<_GLOBAL__sub_I__ZSt20__throw_system_errori+0x20>)
8a284: af00 add r7, sp, #0
8a286: 4907 ldr r1, [pc, #28] @ (8a2a4
<_GLOBAL__sub_I__ZSt20__throw_system_errori+0x24>)
8a288: 4807 ldr r0, [pc, #28] @ (8a2a8
<_GLOBAL__sub_I__ZSt20__throw_system_errori+0x28>)
8a28a: f004 f8e5 bl 8e458 <__aeabi_atexit>
8a28e: 4a04 ldr r2, [pc, #16] @ (8a2a0
<_GLOBAL__sub_I__ZSt20__throw_system_errori+0x20>)
8a290: 4906 ldr r1, [pc, #24] @ (8a2ac
<_GLOBAL__sub_I__ZSt20__throw_system_errori+0x2c>)
8a292: 4807 ldr r0, [pc, #28] @ (8a2b0
<_GLOBAL__sub_I__ZSt20__throw_system_errori+0x30>)
8a294: 46bd mov sp, r7
8a296: e8bd 4080 ldmia.w sp!, {r7, lr}
8a29a: f004 b8dd b.w 8e458 <__aeabi_atexit>
8a29e: bf00 nop
8a2a0: 20071120 .word 0x20071120
8a2a4: 0008e3cf .word 0x0008e3cf
8a2a8: 20071270 .word 0x20071270 <-- this is generic_category_instance
8a2ac: 0008e3d5 .word 0x0008e3d5
8a2b0: 2007126c .word 0x2007126c <-- this is system_category_instance
I do not now much ARM assembly, but this looks like it is just registering the
(empty) destructors with atexit().
I couldn't find any references to __throw_system_error() anywhere.
I would venture that just the existence of generic_category_instance and
system_category_instance is enough to pull in that generated code which calls
atexit for the associated destructors. But then the same would probably happen
with io_category_instance and others, unless the object files they live in do
not get pulled at all.
There is one thing I would like to understand. If nothing is calling
__throw_system_error(), so that it does not get pulled into the ELF, and
nothing else is using system_category_instance, shouldn't GCC and/or the linker
be smart enough to discard the whole system_category_instance, including
constructor and destructor code and/or data for it? Or does GCC believe that
the atexit() call has side-effects (other than effectively destroying the
object) and it does not eliminate that call then?