Al compilar un archivo C trivial con las banderas que proporcionó, entre gcc-4.5 y gcc-4.6 y usando objdump -h para examinar la salida, parece que el .eh_frame la sección se introduce en gcc-4.6 .
Los ld El script que proporcionó no se ocupa de esa sección, y probablemente debería hacerlo. Puedes usar strip -R .eh_frame -R .eh_frame_hdr para eliminar esa sección y otras de los archivos de objeto antes de vincular.
De todos modos, dado que el enlazador es el mismo para ambas versiones de gcc, objdump -h en los archivos de objetos indicará la diferencia que causa este problema.
¿Hay algún argumento en la línea de comandos que desactive una función que pueda producir secciones más grandes?
Sí:si te importa el tamaño, debes construir con -Os . El -O3 habilita explícitamente optimizaciones que podrían conducir a un tamaño de código más grande. Dado que el gestor de arranque se ejecuta una vez , usando -O3 porque es casi seguro que está mal.
Editar:
"La optimización en el montaje no tiene sentido...
... y otros objetos aquí..."
es todo de su código en ensamblador? Si es así, el nivel de optimización no tiene sentido, pero entonces debería poder comparar simplemente la salida de readelf -S vga_pm.S.o construido con ambos compiladores, y vea exactamente cuál las secciones son diferentes.
Pero parece más probable que algunos de sus objetos no en ensamblaje, en cuyo caso la diferencia entre -O3 y -Os será bastante significativo.
GCC agrega algunas secciones de depuración no deseadas a su salida binaria (use objdump -h <file> para verlos), suelo poner los que no quiero en un /DISCARD/ regla en mis scripts ld para deshacerme de ellos:
/DISCARD/ : {
*(.debug_*)
*(.note*)
*(.indent)
*(.comment)
*(.stab)
*(.stabstr)
*(.eh_frame)
}