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?

Reply via email to