Nicht verwendete Runtime-Funktionen entfernen, die die ausführbare Datei aufblähen (GCC)

Ich habe die GCC4.7.1-Cross-Toolchain für ARM (cortex-m3) erstellt. Jetzt verknüpfe ich eine ausführbare Datei aus C / C ++ - Code, die sicherlich einige bestimmte STL-Klassen nicht verwendet (z.std::string). Außerdem sind Ausnahmen und RTTI deaktiviert.

Wenn ich zum Ziel-ELF schaue (z. B. unter Verwendung von nm), sind viele Symbole (anscheinend aus der libstdc ++) verknüpft, die ich dort nicht erwarten würde (z. B.std::exception, std::ios_base, usw.).

Warum ist das da und wie kann ich dieses Zeug loswerden, um das zu reduzieren?.text Abschnittsgröße meines Ziels?

Ein Kollege gab mir einen Tipp, wie ich einige GCC-spezifische Stub-Funktionen überschreiben kann:

namespace __gnu_cxx
{
    void __verbose_terminate_handler()
    {
        for (;;)
            ;
    }
}

Dies allein reduzierte die Codegröße um etwa 20 KB.
Gibt es mehr solcher Stubs, die ich überschreiben kann?

AKTUALISIEREN:
OK, ich habe einen wirklich dummen Fehler gefunden, der die meisten Dinge, über die ich mich gewundert habe, beseitigt hat, als ich das Problem behoben habe:
Da war ein#include <iostream> Anweisung links (obwohl nichts von dort aufgerufen) in einer der Quelldateien. Dies wird natürlich in der Statik verlinkenstd::cin, std::cout undstd::cerr Instanzen und all das Zeug, das damit einhergeht.
Entferne den#include <iostream> Aussage reduziert die.text Segment um einen anderen> 100KB Teil.

Dennoch:
Es gibt immer noch diestd::exception undstd::basic_string Sachen, über die ich mich wundere:

Namespace summaries:
==============================================================================
Type         Size Namespace 
T             774 'std'
W             184 'std::string::_Rep'
W             268 'std'
W             472 'std::string'
Class summaries:
==============================================================================
Type         Size Class 
T              50 'std::error_category'
T              52 'std::type_info'
T              54 'std::bad_exception'
T              54 'std::exception'
T              68 'std::bad_alloc'
T              98 'std::length_error'
T             214 'std::logic_error'
W             268 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >'

Es wird nicht wirklich viel Code-Größe verwendet, nur einige 100 Bytes, so dass ich damit leben könnte, es zu vernachlässigen, aber ich würde es begrüßen, wenn ich dies auch loswerden könnte.

Da ich ausdrücklich keine Ausnahmen verwende, frage ich mich, warum diese beim Verlinken immer noch instanziiert werden. Verwendung von Ausnahmen oder nicht kann zur Laufzeit nicht wirklich festgestellt werden?!?
Das einzig verbleibende Ding von der__gnu_cxx Namespace, den ich jetzt verlassen habe, ist

Type         Size Class 
T              58 '__gnu_cxx::recursive_init_error'

Es ist eine weitere Ausnahmeklasse.

ENDLICH:
Ich habe einige zusätzliche Flags verwendet, um das GCC4.7-Crossbuild zu konfigurieren:

--enable-gold=yes 
--enable-lto 
--enable-cxx-flags='-fno-exceptions -ffunction-sections -fno-omit-frame-pointer'

Die letzteren Flags werden zum Kompilieren von libstdc ++ verwendet und entsprechen im Wesentlichen dem Erstellen des Zielcodes (was ohnehin eine vernünftige Aktion ist). Ausnahmereferenzen wurden danach entfernt (einschließlich der__gnu_cxx::recursive_init_error).

Das Letzte war, ich fand eine unerwartete Verwendung vonstd::string in unserer Codebasis. Nachdem das behoben wurde, wird der Verweis aufstd::basic_string<char, std::char_traits<char>, std::allocator<char> > auch verschwunden.

So bin ich jetzt mit dem Ergebnis zufrieden, kein unnötiger, unerwarteter Overhead von libstdc ++ mehr, kein Grund, C ++ nicht gegenüber C vorzuziehen.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage