Ho notato che mentre giocava con GDB di rbreak .
, e poi ha fatto un esempio minimo:Perché _init da csu/init-first.c di glibc viene chiamato prima di _start anche se _start è il punto di ingresso ELF?
(gdb) file hello_world.out
Reading symbols from hello_world.out...done.
(gdb) b _init
Breakpoint 1 at 0x4003e0
(gdb) b _start
Breakpoint 2 at 0x400440
(gdb) run
Starting program: /home/ciro/bak/git/cpp/cheat/gdb/hello_world.out
Breakpoint 1, _init (argc=1, argv=0x7fffffffd698, envp=0x7fffffffd6a8) at ../csu/init-first.c:52
52 ../csu/init-first.c: No such file or directory.
(gdb) continue
Continuing.
Breakpoint 2, 0x0000000000400440 in _start()
(gdb) continue
Continuing.
Breakpoint 1, 0x00000000004003e0 in _init()
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y <MULTIPLE>
breakpoint already hit 2 times
1.1 y 0x00000000004003e0 <_init>
1.2 y 0x00007ffff7a36c20 in _init at ../csu/init-first.c:52
2 breakpoint keep y 0x0000000000400440 <_start>
breakpoint already hit 1 time
noti che ci sono 2 _init
: uno in csu/init-first.c
, e l'altro sembra provenire da sysdeps/x86_64/crti.S
. Sto parlando dello csu
.
Non è _start
il punto di ingresso impostato dal linker e memorizzato nell'intestazione ELF? Quale meccanismo esegue prima _init
? Qual è il suo scopo?
Testato su GCC 4.8, glibc 2.19, GDB 7.7.1 e Ubuntu 14.04.
davvero. C'è una sezione init definita in ELF. Dai un'occhiata a [QUESTO] (http://l4u-00.jinr.ru/usoft/WWW/www_debian.org/Documentation/elf/node3.html) Potresti anche provare 'readelf -d selfelf' per controllare INIT e Sezioni FINI. Ad ogni modo se si compila con -nostdlib quelle parti vengono evitate. – LPs