Documentation for initialization-related linker sections in GCC

Viewed 139

I'm using the Gnu Arm Embedded Toolchain and I'm writing a custom linker file for a project. I'm writing custom startup/initialization code too. The project uses lots of C++ code, in addition to C and some assembler.

I'm looking for documentation related to the linker sections that handles initialization:

  • .preinit_array
  • .init
  • .init_array
  • .ctors
  • ...

Mostly, I've found blogs and various posts on the web. But it still leaves me with lots of open questions.

I have made global initialization work (at least the cases I can come up with) by using only the .init_array section but there are many details I'd like to get on top of in order to know that I've covered everything.

For example (see the snippet below):

  • What exactly is each section used for? When are they output by the compiler?
  • I've read the source code for __libc_init_array (for inspiration) and that one calls a function called _init() in between handling the .preinit_array and the .init_array sections. Where does this _init() function come from?
  • What's the purpose of the .ctors section? I must admit I don't understand the comment.
  • What's the purpose of the crtbegin.o and similar files?
  • What's does CONSTRUCTORS mean in the .data section?
  • ...

Everything related to tear-down can be skipped for now. It's not relevant for this project.

Here are the relevant sections from the default linker script of my GCC installation, if that helps the discussion:

  .preinit_array    :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  }
  .init_array    :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
    KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
    PROVIDE_HIDDEN (__init_array_end = .);
  }
  .ctors          :
  {
    /* gcc uses crtbegin.o to find the start of
       the constructors, so we make sure it is
       first.  Because this is a wildcard, it
       doesn't matter if the user does not
       actually link against crtbegin.o; the
       linker won't look for a file to match a
       wildcard.  The wildcard also means that it
       doesn't matter which directory crtbegin.o
       is in.  */
    KEEP (*crtbegin.o(.ctors))
    KEEP (*crtbegin?.o(.ctors))
    /* We don't want to include the .ctor section from
       the crtend.o file until after the sorted ctors.
       The .ctor section from the crtend file contains the
       end of ctors marker and it must be last */
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
  }
  .data           :
  {
    __data_start = .;
    *(.data .data.* .gnu.linkonce.d.*)
    SORT(CONSTRUCTORS)
  }

Any input is welcome! Thanks in advance.

0 Answers
Related