9

Ho appreso da this recent answer che gcc e clang includono il nome file di origine da qualche parte nel binario come metadati, anche quando il debug non è abilitato.Perché i compilatori C comuni includono il nome file di origine nell'output?

Non riesco davvero a capire perché questa dovrebbe essere una buona idea. Oltre ai piccoli rischi per la privacy, questo accade anche quando si ottimizza la dimensione del file binario risultante (-Os), che appare inefficiente.

Perché i compilatori includono queste informazioni?

+2

Non è solo GCC, Clang lo fa (e qualsiasi toolchain del compilatore che crea binari ELF che seguono la [specifica] (http://flint.cs.yale.edu/cs422/doc/ELF_Format.pdf)). – cyphar

+1

@cyphar Devo ammettere che mi sono semplicemente immerso in esso anziché leggere tutte le 60 pagine, ma ho trovato FILE menzionato solo a pagina 25 di quel documento, e non dice che è obbligatorio ("Convenzionalmente, il nome del simbolo dà il nome di il file sorgente associato al file oggetto "). –

+0

Non ho letto neanche tutte le 60 pagine. Ma quando si tratta di standard "convenzionalmente" significa "probabilmente dovresti farlo perché la gente potrebbe fare affidamento su di esso". Alla fine della giornata, se ti viene data una specifica è più facile seguirla alla lettera (dato che i tuoi utenti potrebbero decidere di utilizzare le caratteristiche più esoteriche espresse nello standard) piuttosto che provare a uscire furtivamente da implementando cose che non devi. dopotutto GNU è la terra di quantità estreme di funzionalità extra. – cyphar

risposta

6

Il motivo per cui GCC include il nome del file è principalmente per scopi di debug, perché permette ai programmatori di identificare da quale sorgente il file di un determinato simbolo viene da come (laconicamente) delineato nel ELF spec p1-17 e ulteriormente approfondito nel some Oracle docs on linking.

Un esempio di utilizzo della sezione STT_FILE è dato da this SO question.

Sono ancora confuso perché sia ​​GCC che Clang lo includono anche se si specifica -g0, ma è possibile impedirlo includendo STT_FILE con -s. Non sono riuscito a trovare alcuna spiegazione per questo, né ho potuto trovare un "motivo ufficiale" perché STT_FILE è incluso nelle specifiche ELF (che è molto terse).

5

che ho imparato da questa recente risposta che gcc include il nome del file di origine da qualche parte nel binario come metadati, anche quando debug non è attivo.

Non proprio. Nella moderna oggetto ELF file il nome del file in effetti è un simbolo di tipo FILE:

$ readelf bignum.o # Source bignum.c 
[...] 
Symbol table (.symtab) contains 36 entries: 
    Num: Value   Size Type Bind Vis  Ndx Name 
    0: 0000000000000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 0000000000000000  0 FILE LOCAL DEFAULT ABS bignum.c 
    2: 0000000000000000  0 SECTION LOCAL DEFAULT 1 
    3: 0000000000000000  0 SECTION LOCAL DEFAULT 3 
    4: 0000000000000000  0 SECTION LOCAL DEFAULT 4 
    5: 0000000000000000  0 SECTION LOCAL DEFAULT 5 
    6: 0000000000000000  0 SECTION LOCAL DEFAULT 6 
    7: 0000000000000000  0 SECTION LOCAL DEFAULT 7 
    8: 0000000000000000  0 SECTION LOCAL DEFAULT 8 
    9: 00000000000003f0 172 FUNC GLOBAL DEFAULT 1 add 
    10: 00000000000004a0 104 FUNC GLOBAL DEFAULT 1 copy 

Tuttavia, una volta messo a nudo, il simbolo è andato:

$ strip bignum.o 
$ readelf -all bignum.o | grep bignum.c 
$ 

Quindi, per mantenere la vostra privacy, spellare l'eseguibile, o compilare/collegare con -s.

+1

Perché "non proprio"?Conosco ancora questo come "incluso nel file binario", sebbene tu correttamente indichi che è incorporato in un modo che lo rende facile da rimuovere. La mia domanda riguardava la motivazione, comunque. –

+1

@FedericoPoloni Solo un motivo molto sottile per "non proprio": è un metadati della tabella dei simboli? È * richiesto * per un collegamento riuscito. Tuttavia, i dati di debug non sono disponibili, hanno una propria sezione ELF e possono essere rimossi. Non è davvero un grosso problema e non dovrebbe ostacolare la comprensione. – Jens

+1

Sebbene la tabella dei simboli in generale sia necessaria per il collegamento, questo particolare simbolo non lo è. Quindi è essenzialmente usare la tabella dei simboli come luogo per contenere alcuni dei metadati. – Barmar