GCC's __attribute__ compiler attribute has many subkeys that change the behavior of the object. The role of the Section subkey is discussed here.
The section subkeys of the __attribute__ are used in the following ways:
?
| 1 |
__attribute__((section("section_name"))) |
Its role is to put the function or data of the function into the specified section named "Section_name".
See the following program snippet:
?
| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 |
#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(".myown")))#define func_init(func) myown_call _fn_##func _init = funcstatic 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(".myown"))) = mspec1;static myown_call mc2 __attribute__((unused, section(".myown"))) = mspec2;static myown_call mc3 __attribute__((unused, section(".myown"))) = mspec3;*/void do_initcalls(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_initcalls(); return 0;} |
In the Custom. Myown segment, fill in the MSPEC1/MSPEC2/MSPEC3 function pointer in turn and call it in order in Do_initcalls to construct and invoke the initialization function list.
Two extern variables:
?
| 12 |
externmyown_call _myown_start;externmyown_call _myown_end; |
Link scripts from LD, which can be used:
?
Get the built-in LDS script, and in:
?
Add the following before:
?
| 1234 |
_myown_start = .; .myown : { *(.myown) } = 0x90000000 _myown_end = .; code_segment : { *(code_segment) } |
Defines the. Myown segment and the _myown_start/_myown_end variable (0x90000000 This value may need to be adjusted).
Save the modified linker script, assuming that the program is S.C, the linker script is saved as S.lds and compiled with the following command:
?
Execution Result:
?
| 1234567 |
[[email protected] ]# ./a.out call_ptr: 0x8049768aha!call_ptr: 0x804976caloha!call_ptr: 0x8049770hello! |
Have fun!
Reprint: http://my.oschina.net/senmole/blog/50710
GCC attribute initialization function list