This article is translated:
Http://gcc.gnu.org/onlinedocs/gccint/Initialization.html
As we know, in GCC, We append _ attribute _ (constructor) and _ attribute _ (destructor) to the code )) to append the initial function and terminate the function,
This article describes how GCC implements the above processing internally.
In short, in most cases, the initial function will be appended to the. ctor section, and. init will call the corresponding functions to process these initial functions. The termination is similar.
----------------------------------------------------------
How is the initialization function processed? The compiled code in some languages contains the constructor (also known as the initialization routine)-This function is used to initialize program data when the program starts. These functions must be called before the program starts-that is, they must be called before the main function.
At the same time, when compiling some languages, the Destructor (also known as the termination routine) will be generated. It should be called at the end of the program.
To support initial and termination functions, the compiler must generate something in the assembly code so that these functions can be called at an appropriate time point. When you port the compiler to a new system, you need to specify how to do it.
Currently, GCC supports the execution of initial and termination functions in two ways. Each method has two variants. Most of these four variants share the same structure.
The linker must create two lists for these functions-a list of initialization functions, called _ ctor_list __, and a list of termination functions, called _ dtor_list __.
Each list always starts with a ignored function pointer (this function pointer may be 0,-1, or the number of function pointers in different environments ). This function pointer is followed by a series of 0 or many other Constructor (destructor) function pointers and ends with a function pointer containing 0.
Crtstuff. C or libgcc2.c will traverse these lists at startup and exit based on different operating systems and their executable file formats. The constructor is called in reverse order of the list, and the constructor is called in order.
The best way to process static constructor is to only provide the target file format of the random naming section. A section is used to construct the body list, and a section is used to analyze the body list. They are often called '. ctors' and '. dtors '. Each target file defining an initial function places a word in the section of the constructor to point to the initial function. The linker accumulates all the words to a continuous '. ctors' section. The termination function is also processed in a similar way.
Assuming that target_asm_named_section is defined, this method is set to the default method by the target-def.h. Assume that a target board does not support section naming at will. However, it also supports Special customizable constructor and destructor, and can achieve the same effect by defining ctors_section_asm_op and dtors_section_asm_op.
When a section can be named randomly, there are two variants that differ in the call of the crtstuff. C code. On systems that support. init section (run when the program starts), part of crtstuff. C is compiled into this section. The program is linked like this:
LD-O output_file crti. O crtbegin. O...-lgcc crtend. O crtn. o
The prologue (_ init) of a function is now crti. o's. in the init section; epilogue is now crtn. o. function _ fini is in. the same is true for Fini section. normally, these files are provided by the OS or GNU C library, but some target boards are provided by GCC.
The target file crtbegin. O and crtend. O (in most cases) is caused by crtstuff. C compiled. they include, except ,. init and. the code snippet in fini sections to jump. function in text section. The linker will put all the parts of a section together to generate a complete _ init function to call the function that we need to call at the startup stage.
To use this variant, you must correctly define the init_section_asm_op macro.
Assume that the init Section cannot be used. When GCC compiles a function named main (more precise, no matter which function is specified as the program entry point by expand_main_function ), it inserts a function call _ main as the first code to run the prologue function. the _ main function is defined in libgcc2.c and runs the global constructor.
The file format of Arbitrary Section is not supported. There are also two variants. The GNU linker (gnu ld) and 'a. out' formats must be used in the simplest variants. In this case, target_asm_constructor is defined to generate a type of 'n' _ sett. stabs entry, ctor_list __,. the stabs entry points to the void function address of the initialization function code as its value. The GNU linker thinks this is a request to add values to the set. These values accumulate and are finally placed in the runable file as a vector. The format is as described above, there is a leading (ignored) and a zero element at the end. The target_asm_destructor process is similar. Since no init section is available, the default init_section_asm_op enables the main compilation process to call the above _ main function and start initialization.
The final variant neither uses arbitrary sections nor the GNU linker. This is recommended when you want Dynamic Links and the file format is not supported by the GNU linker (such as ecoff. In this case, target_have_ctors_dtors is incorrect. The initial and termination functions are identified by their names. This requires that an additional program called collect2 be used in the Link stage. This program will pretend to be used by GCC as a linker. It runs normally as a linker and manages the vectors for appending and terminating functions, these functions are called through the above _ main. To use this method, you must define use_collect2 in target in config. GCC.
How is the initialization function processed in GCC?