2012-07-21 14 views
9

Estoy trabajando en un córtex de metal puro-M3 en C++ por diversión y ganancias.Cómo depurar el proceso de enlace - GCC/ld - STL C++

Últimamente decidí probar y usar la biblioteca STL ya que necesitaba algunos contenedores. Pensé que simplemente proporcionando mi asignador no agregaría mucho código al binario final, ya que solo obtiene lo que usa. En realidad, ni siquiera esperaba ningún proceso de enlace con el STL (dando mi asignador), ya que pensé que era todo el código de la plantilla.

Estoy compilando con -fno-excepción por cierto.

Lamentablemente, alrededor de 600 KB o más se agregan a mi binario. Busqué los símbolos que están incluidos en el binario final con nm y me pareció una broma. La lista es tan larga No intentaré y la superaré. Aunque hay algunos símbolos débiles.

También se veía en el archivo MAP generado por el enlazador e incluso me encontré con los símbolos 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 

¿Cómo puedo depurar esto? Para empezar, quería entender qué es exactamente lo que GCC está utilizando para vincular (estoy vinculando a través de GCC). Sé que si se encuentra un símbolo en un segmento de texto, se usa el segmento completo , pero aún es demasiado.

Cualquier sugerencia sobre cómo abordar esto sería realmente apreciada.

Gracias, S.

Respuesta

3

El uso de las opciones -v y -Wl,-v de GCC le mostrará los comandos del vinculador (y la información de versión del vinculador) que se está utilizando.

¿Qué versión de GCC estás usando? Hice algunos cambios para GCC 4.6 (vea PR 44647 y PR 43863) para reducir el tamaño del código para ayudar a los sistemas integrados. Todavía hay una solicitud de mejora pendiente (PR 43852) para permitir la desactivación de la inclusión de los símbolos IO que está viendo, algunos de ellos provienen del controlador de finalización detallado, que imprime un mensaje cuando el proceso finaliza con una excepción activa. Si no está utilizando ejecuciones, parte de ese código es inútil para usted.

+0

Estoy usando la versión 4.6.3 de gcc de Code Sourcery. La opción -Wl, -v fue muy útil. A lo largo de las banderas que pasé al enlazador, también incluía el siguiente -lstdC++ -lm --start-group -lgcc -lgcc_eh -lc --end-group ahora tengo que entender por qué y cómo eliminarlos. Especialmente el gcc_eh que supongo representa el manejo de excepciones. ¿Alguna sugerencia o lectura sobre esto? – emitrax

+0

Si enlaza con 'gcc' en lugar de' g ++ ', entonces no pasará' -lstdC++ 'al enlazador, y eso también podría eliminar la necesidad de' -lgcc -lgcc_eh' (no lo recuerdo espontáneamente, tendría que comprobarlo) pero si no usa ningún código de esas libs, entonces no debería aumentar el tamaño del ejecutable de todos modos: el controlador de terminación verbosa en libstdC++ es probablemente lo que atrae el código no deseado –

+0

Si uso gcc, ganó No encuentra el símbolo _List_node_base :: _ M_hook.Passing -lstdC++ incluye todo lo demás. Para reducir el problema traté de vincular directamente con ld al agregar esos indicadores uno por uno. Falta __aeabi_unwind_cpp_pr0 en libstdC++. A (list.o): (..._ List_node_base7_M_hookE) que luego se vincula a libc (memcpy y otros), que luego vincula todo lo demás. Es una gran cadena y un PITA. Solo quería un contenedor. :-) También pensé que, dado que tengo un objeto global, necesita __static_initialization_and_destruction_0 que no esperaba. Gracias por tu ayuda. – emitrax

2

El problema no es sobre el TEL, se trata de la biblioteca estándar.

El STL en sí es pura (de forma), pero la biblioteca estándar también incluye todos esos paquetes arroyos y parece que también se las arregló para tirar en el libc así ...

El problema es que la Biblioteca estándar nunca se debe separar, por lo que puede no haber mucha preocupación en volver a utilizar las cosas de la Biblioteca estándar de C ...

Primero debe intentar identificar qué archivos se extraen cuando compila (usando stracefor example), de esta manera puede verificar que solo use solo encabezado archivos.

Luego puede intentar y eliminar la vinculación que se produce. Hay opciones para pasar a gcc y precisar que le gustaría una compilación libre de biblioteca estándar, algo como --nostdlib por ejemplo, sin embargo, no estoy lo suficientemente versado en las que le puedo indicar exactamente aquí.

+0

Ya estoy pasando -nostdlib al compilador, junto con -fno-exception, pero parece que no funciona. – emitrax