2016-01-23 13 views
20

Quando si collega un programma simile a un ciao-mondo in c (o asm) con gcc si aggiungeranno alcune cose nel file dell'oggetto eseguibile risultato. Conosco solo il linker dinamico di runtime e il punto di ingresso _start ma qual è il tipo di queste funzioni aggiunte?Quali funzioni aggiunge gcc all'ELF di Linux?

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 

Cosa sono e cosa? È descritto da qualche parte? Googling non aiuta.

+6

Sede [Linux x86 programma Start Up da Patrick Horgan] (http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html) Si noti che il codice asm puro senza libc non aggiunge questi, perché vengono dalla libc. – Jester

+0

@Jester sembra molto carino, grazie! Se contiene qualcosa che ti ho chiesto puoi rispondere con queste informazioni (con alcune informazioni da lì, ovviamente). –

risposta

20

La maggior parte di questi sono vari metodi per eseguire il codice prima o dopo il programma "principale" stesso e la maggior parte dal vivo in crtstuff.c (https://github.com/gcc-mirror/gcc/blob/master/libgcc/crtstuff.c). Esistono per supportare funzionalità di vari linguaggi di programmazione C-like, ma sono accessibili anche in C. Sembra forse troppo complicato perché alcuni di questi rappresentano il bagaglio precedente e alcune delle variazioni necessarie per supportare le varie architetture su cui GCC gira.

 

Dalla tua lista, uno per uno (o due a due):

00000000004003f0 t deregister_tm_clones 
0000000000400430 t register_tm_clones 

memoria transazionale è destinato a fare la programmazione con i thread più semplice. È un'alternativa alla sincronizzazione basata su lock. Queste routine abbattono e impostano, rispettivamente, una tabella utilizzata dalla libreria (libitm) che supporta queste funzioni. Maggiori informazioni su TM qui https://gcc.gnu.org/wiki/TransactionalMemory e qui http://pmarlier.free.fr/gcc-tm-tut.html

 

0000000000400470 t __do_global_dtors_aux 

esegue tutti i distruttori globali, in uscita dal programma su sistemi in cui .fini_array non è disponibile.

 

0000000000400490 t frame_dummy 

Questa funzione vive nella sezione .init. È definito come void frame_dummy (void) e il suo intero punto nella vita è chiamare __register_frame_info_bases che ha argomenti. Apparentemente chiamate alle funzioni con argomenti dalla sezione .init possono essere inaffidabili, quindi questa funzione è così che __register_frame_info_bases non viene richiamato direttamente dallo .init section. Le basi di informazioni .eh_frame vengono utilizzate per la gestione delle eccezioni e funzionalità simili (ad esempio funzioni dichiarate con __attribute__((cleanup(..)))).

 

00000000004004e0 T __libc_csu_init 
0000000000400550 T __libc_csu_fini 

Questi eseguire qualsiasi initializers a livello di programma e finalizzatori (un po 'come costruttori/distruttori per tutto il vostro programma). Se si definiscono funzioni come:

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

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

saranno chiamati prima e dopo main() rispettivamente di queste routine. Vedere anche https://gcc.gnu.org/onlinedocs/gccint/Initialization.html

 

0000000000400554 T _fini 

Questo è un modo ormai deprecato per eseguire un-livello di programma (oggetto file-level in realtà) distruttore (un po 'di informazioni su questo può essere trovato in man dlclose). La funzione obsoleta corrispondente per i costruttori è __init.

 

0000000000600668 t __frame_dummy_init_array_entry 
0000000000600668 t __init_array_start 

Questi Mark alla fine e inizio della sezione .init_array, che contiene i puntatori a tutti gli inizializzatori a livello di programma (vedi sopra __libc_csu_init).

 

0000000000600670 t __do_global_dtors_aux_fini_array_entry 
0000000000600670 t __init_array_end 

Questi Mark alla fine e inizio della sezione .fini_array, che contiene i puntatori a tutti i finalizzatori a livello di programma (vedi __libc_csu_fini sopra).

 

[EDIT] Alcune note aggiuntive:

  • Il collegamento http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html dal commentare la domanda del Giullare contiene un bel diagramma e un piccolo programma di esempio illustrando l'ordine globale questi le cose funzionano così come accedere ad alcune di queste funzionalità da C.

  • Le espressioni 'ctors' e 'dtors' sono abbreviazioni per 'costruttori' e 'distruttori' rispettivamente.

  • La differenza tra i costruttori/distruttori globali e file oggetto costruttori/distruttori è più evidente quando il programma è costruito da più file oggetto.

  • I simboli contrassegnati 'T' (__libc_csu_init, __libc_csu_fini, _fini) sono "globale" (visibile esternamente), il remainer (segnata 't') non sono.

+0

Potresti fare alcune aggiunte per chiarire quali sono gli inizializzatori e i finalizzatori di 'program destructors' globali?, Per favore? Ciò renderebbe la risposta più rifinita secondo me. –

+1

Per * shared * file oggetto, non per file oggetto. – o11c

Problemi correlati