Unexpected behavior regarding linking sections

Felix von Leitner felix-binutils@fefe.de
Tue Dec 11 15:27:00 GMT 2018

This is about my libc handling code for ctors and dtors.
In the startup code, I do this:

  .section .ctors,"aw"
  .global __CTOR_LIST__

  .section .dtors,"aw"
  .global __DTOR_LIST__

Then, after all the other code, I do this:

  .section .ctors,"aw"
  .global __CTOR_END__

  .section .dtors,"aw"
  .global __DTOR_END__

And the handling code looks like this:

  funcptr* f;
  funcptr* m=__CTOR_END__<__DTOR_LIST__ ? __CTOR_END__ : __DTOR_LIST__;
  for (f=__CTOR_LIST__; f<m; ++f) (*f)();

Note the surprising declaration of m here.

I was expecting, since ctors go into section .ctors and dtors go into
section .dtors, that if I have code like this:

  __attribute__((destructor)) void dtor(void) { puts("dtor"); }
  __attribute__((constructor)) void ctor(void) { puts("ctor"); }

that __CTOR_END__ - __CTOR_LIST__ would be sizeof(void*) and the same
for __DTOR_END__ - __DTOR_LIST__. In reality, the values are like this
(on x86_64):

__CTOR_LIST__ is 0x404fe0
__DTOR_LIST__ is 0x404ff0

__CTOR_END__ == __DTOR_END__ == 0x405000

Uh ... wat? Why is __DTOR_END__ not 0x404ff0?
Is this a bug in ld or am I missing something?
I'm using gcc 8.2 and binutils


More information about the Binutils mailing list