Use the _ attribute _ of gcc to compile the attribute section sub-item to construct the initialization function table. The gcc _ attribute _
This article forwarded from: https://my.oschina.net/u/180497/blog/177206
It solves song Baohua's previousC language object-oriented (for larger software) ppt sharing and ppt annotationsMulti-module software initialization
Gcc's _ attribute _ compilation attribute has many sub-items, which are used to change the characteristics of the target object. The role of the section subitem is discussed here.
Use the section subitem of _ attribute _ as follows:
_ Attribute _ (section ("section_name ")))
The function is to put the function or data to a segment named "section_name.
Take a look at the following program snippets:
# Include <unistd. h>
# Include <stdint. h>
# Include <stdio. h>
Typedef void (* myown_call) (void );
Extern myown_call _ myown_start;
Extern myown_call _ myown_end;
# Define _ init _ attribute _ (unused, section (". mywn ")))
# Define func_init (func) myown_call _ fn _ # func _ init = func
Static void mspec1 (void)
{
Write (1, "aha! \ N ", 5 );
}
Static void mspec2 (void)
{
Write (1, "aloha! \ N ", 7 );
}
Static void mspec3 (void)
{
Write (1, "hello! \ N ", 7 );
}
Func_init (mspec1 );
Func_init (mspec2 );
Func_init (mspec3 );
/* Exactly like below:
Static myown_call mc1 _ attribute _ (unused, section (". mywn") = mspec1;
Static myown_call mc2 _ attribute _ (unused, section (". mywn") = mspec2;
Static myown_call mc3 _ attribute _ (unused, section (". mywn") = mspec3;
*/
Void do_initcils (void)
{
Myown_call * call_ptr = & _ myown_start;
Do {
Fprintf (stderr, "call_ptr: % p \ n", call_ptr );
(* Call_ptr )();
++ Call_ptr;
} While (call_ptr <& _ myown_end );
}
Int main (void)
{
Do_initcils ();
Return 0;
}
Fill in the UDF pointer of mspec1/mspec2/mspec3 in sequence in the custom. mywn segment, and call it in do_initcils to construct and call the initialization function list.
Two extern variables:
Extern myown_call _ myown_start;
Extern myown_call _ myown_end;
From the ld link script, you can use:
Ld -- verbose
Obtain the built-in lds script and go:
_ Bss_start = .;
Add the following content before:
_ Myown_start = .;
. Mywn: {* (. mywn)} = 0x90000000
_ Myown_end = .;
Code_segment: {* (code_segment )}
The. mywn segment and the _ myown_start/_ myown_end variable are defined (the value 0x90000000 may need to be adjusted ).
Save the modified linker script. If the program is s. c and the linker script is saved as s. lds, run the following command to compile the script:
Gcc s. c-Wl,-Ts. lds
Execution result:
[Root @ localhost] #./a. out
Call_ptr: 0x8049768
Aha!
Call_ptr: 0x804976c
Aloha!
Call_ptr: 0x8049770
Hello!
Have Fun!