2012-07-21 8 views
9

Sto lavorando su una cortex-M3 bare-metal in C++ per divertimento e profitto.Come eseguire il debug del processo di collegamento - GCC/ld - STL C++

Ultimamente ho deciso di provare a utilizzare la libreria STL poiché avevo bisogno di alcuni contenitori. Ho pensato che semplicemente fornendo il mio allocatore non avrebbe aggiunto molto codice al binario finale , dal momento che si ottiene solo ciò che si utilizza. In realtà non mi aspettavo nemmeno alcun processo di collegamento con l'STL (assegnando il mio allocatore), poiché pensavo che fosse tutto il codice del modello.

Sto compilando con -fno-exception a proposito.

Sfortunatamente, circa 600 KB o più vengono aggiunti al mio binario. Ho visto quali simboli sono inclusi nel binario finale con nm e mi è sembrato uno scherzo. L'elenco è così lungo Non cercherò di superarlo. Sebbene ci siano alcuni simboli deboli.

ho anche guardato nel file .map generato dal linker e ho anche trovato i simboli scanf

.text   0x000158bc  0x30 /CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_GNU_Linux/bin/../arm-none-linux-gnueabi/libc/usr/lib/libc.a(sscanf.o)¶ 
      0x000158bc    __sscanf¶ 
      0x000158bc    sscanf¶ 
      0x000158bc    _IO_sscanf¶ 


$ arm-none-linux-gnueabi-nm binary | grep scanf 
000158bc T _IO_sscanf 
0003e5f4 T _IO_vfscanf 
0003e5f4 T _IO_vfscanf_internal 
000164a8 T _IO_vsscanf 
00046814 T ___vfscanf 
000158bc T __sscanf 
00046814 T __vfscanf 
000164a8 W __vsscanf 
000158bc T sscanf 
00046814 W vfscanf 
000164a8 W vsscanf 

Come posso eseguire il debug di questo? Innanzitutto volevo capire che cosa esattamente GCC sta usando per il collegamento (sto collegando tramite GCC). So che se il simbolo viene trovato in un segmento di testo, viene utilizzato l'intero segmento , ma è ancora troppo.

Qualsiasi suggerimento su come affrontare questo sarebbe davvero apprezzato.

Grazie, S.

risposta

3

L'utilizzo delle opzioni GCC -v e -Wl,-v consente di visualizzare i comandi del linker (e le informazioni sulla versione del linker) utilizzati.

Quale versione di GCC stai utilizzando? Ho apportato alcune modifiche a GCC 4.6 (vedere PR 44647 e PR 43863) per ridurre le dimensioni del codice per aiutare i sistemi incorporati. C'è ancora una richiesta di miglioramento eccezionale (PR 43852) per consentire la disabilitazione dell'inclusione dei simboli IO che stai vedendo, alcuni dei quali provengono dal gestore terminato verbose, che stampa un messaggio quando il processo viene terminato con un'eccezione attiva. Se non stai usando execptions, parte di quel codice è inutile per te.

+0

Sto usando gcc versione 4.6.3 da Code Sourcery. L'opzione -Wl, -v è stata molto utile. Lungo le bandiere passate al linker, includeva anche il seguente -lstdC++ -lm --start-group -lgcc -lgcc_eh -lc --end-group ora devo capire perché e come rimuoverli. Soprattutto il gcc_eh che suppongo rappresenta la gestione delle eccezioni. Qualche suggerimento o lettura di questo? – emitrax

+0

Se si collega con 'gcc' anziché' g ++', allora non passerà '-lstdC++' al linker, e questo potrebbe anche rimuovere la necessità di '-lgcc -lgcc_eh' (non mi ricordo in modo casuale, I dovrei controllare) ma se non usi alcun codice da quelle librerie allora non dovrebbe aumentare comunque la dimensione dell'eseguibile - il gestore terminato verbose in libstdC++ è probabilmente quello che tira nel codice indesiderato –

+0

Se uso gcc ha vinto trovare il simbolo _List_node_base :: _ M_hook.Passing -lstdC++ include tutto il resto. Per restringere il problema ho provato a collegare direttamente con ld aggiungendo quei flag uno per uno. Manca __aeabi_unwind_cpp_pr0 in libstdC++. A (list.o): (..._ List_node_base7_M_hookE) che poi si collega a libc (memcpy e altro), che quindi collega tutto il resto. È una grande catena e una PITA. Volevo solo un contenitore. :-) Ho anche pensato che, dal momento che ho un oggetto globale, ha bisogno di __static_initialization_and_destruction_0 che non mi aspettavo. Grazie per l'aiuto. – emitrax

2

Il problema non riguarda lo STL, si tratta della libreria standard.

Lo STL stesso è puro (in un certo senso), ma la libreria standard comprende anche tutti quei pacchetti ruscelli e sembra che anche tu sia riuscito a tirare in libc così ...

Il problema è che la libreria standard non è mai stata pensata per essere selezionata, quindi potrebbe non esserci stata molta preoccupazione nel riutilizzo della roba dalla libreria standard C ...

Si dovrebbe prima cercare di identificare quali file vengono estratti quando si compila (usando stracefor example), in questo modo è possibile verificare di utilizzare sempre lo solo intestazioni file.

Quindi è possibile provare e rimuovere il collegamento che si verifica. Ci sono opzioni da passare a gcc per precisare che ti piacerebbe una versione libera da libreria standard, ad esempio --nostdlib, tuttavia, non sono abbastanza esperto in coloro che ti istruiscono esattamente qui.

+0

Sto già passando -nostdlib al compilatore, insieme a -fno-exception, ma sembra non funzionare. – emitrax

Problemi correlati