Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What functions does gcc add to the linux ELF?

When linking a hello-world-like program in c (or asm) with gcc it will add some stuff into the result executable object file. I know only about runtime dynamic linker and _start entry point but what is the kind of these added functions?

00000000004003f0 t deregister_tm_clones 0000000000400430 t register_tm_clones 0000000000400470 t __do_global_dtors_aux 0000000000400490 t frame_dummy 00000000004004e0 T __libc_csu_init 0000000000400550 T __libc_csu_fini 0000000000400554 T _fini 0000000000600668 t __frame_dummy_init_array_entry 0000000000600668 t __init_array_start 0000000000600670 t __do_global_dtors_aux_fini_array_entry 0000000000600670 t __init_array_end 

What are they and what for? Is it described somewhere? Googling does not help.

like image 841
Victor Polevoy Avatar asked Jan 23 '16 16:01

Victor Polevoy


1 Answers

Most of these are various methods to execute code before or after the "main" program itself and most live in crtstuff.c ( https://github.com/gcc-mirror/gcc/blob/master/libgcc/crtstuff.c ). They exist to support features of various C-like programming languages, but they can be accessed in C as well. It perhaps seems over complicated because some of these represent legacy baggage and some the variation needed to support the various different architectures that GCC runs on.

 

From your list, one by one (or two by two):

00000000004003f0 t deregister_tm_clones 0000000000400430 t register_tm_clones 

Transactional memory is intended to make programming with threads simpler. It is an alternative to lock-based synchronization. These routines tear down and setup, respectively, a table used by the library (libitm) which supports these functions. More info on TM here https://gcc.gnu.org/wiki/TransactionalMemory and here http://pmarlier.free.fr/gcc-tm-tut.html

 

0000000000400470 t __do_global_dtors_aux 

Runs all the global destructors on exit from the program on systems where .fini_array is not available.

 

0000000000400490 t frame_dummy 

This function lives in the .init section. It is defined as void frame_dummy ( void ) and its whole point in life is to call __register_frame_info_bases which has arguments. Apparently calls to functions with arguments from the .init section can be unreliable, hence this function so __register_frame_info_bases doesn't get called directly from the .init section. The .eh_frame info bases are used for exception handling and similar features (e.g. functions declared with __attribute__((cleanup(..)))).

 

00000000004004e0 T __libc_csu_init 0000000000400550 T __libc_csu_fini 

These run any program-level initializers and finalizers (kind of like constructors/destructors for your whole program). If you define functions like:

void __attribute__ ((constructor)) mefirst () {     /* ... do something here ... */ }  void __attribute__ ((destructor)) melast () {     /* ... do something here ... */ } 

they will be called before and after main() respectively by these routines. See also https://gcc.gnu.org/onlinedocs/gccint/Initialization.html

 

0000000000400554 T _fini 

This is a now-deprecated way to run a program-level (object file-level actually) destructor (a little info on this can be found in man dlclose). The corresponding obsolete function for constructors is __init.

 

0000000000600668 t __frame_dummy_init_array_entry 0000000000600668 t __init_array_start 

These mark the end and start of the .init_array section, which contains pointers to all the program-level initializers (see __libc_csu_init above).

 

0000000000600670 t __do_global_dtors_aux_fini_array_entry 0000000000600670 t __init_array_end 

These mark the end and start of the .fini_array section, which contains pointers to all the program-level finalizers (see __libc_csu_fini above).

 

[EDIT] Some Additional Notes:

  • The link http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html (wayback machine) from Jester's question comment contains a nice diagram and a small sample program illustrating the overall order these things run as well as how to access some of these features from C.

  • The terms 'ctors' and 'dtors' are abbreviations for 'constructors' and 'destructors' respectively.

  • The difference between global constructors/destructors and object-file constructors/destructors is most apparent when your program is constructed from multiple object files.

  • The symbols marked 'T' (__libc_csu_init, __libc_csu_fini, _fini) are "global" (externally visible), the remainer (marked 't') are not.

like image 124
John Hascall Avatar answered Oct 11 '22 14:10

John Hascall