Usuwaj nieużywane funkcje środowiska wykonawczego, które rozszerzają plik wykonywalny (GCC)

Zbudowałem cross-toolchain GCC4.7.1 dla ARM (cortex-m3). Teraz łączę plik wykonywalny z kodu C / C ++, który z pewnością nie używa niektórych klas STL (np.std::string). Ponadto wyjątki i RTTI są wyłączone.

Chociaż gdy szukam docelowego ELF (np. Przy użyciu nm), istnieje wiele symboli (widocznych z libstdc ++), z którymi się nie łączę, nie spodziewałbym się tam znaleźć (np.std::exception, std::ios_baseitd.).

Dlaczego tak się dzieje i jak mogę pozbyć się tych rzeczy, aby zmniejszyć.text rozmiar sekcji mojego celu?

Współpracownik dał mi wskazówkę, aby zastąpić niektóre funkcje GCC:

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

Samo to zmniejszyło rozmiar kodu o około 20 KB.
Czy jest więcej takich skrótów, które mogę zastąpić?

AKTUALIZACJA:
OK, znalazłem jeden naprawdę głupi błąd, który usunął większość rzeczy, nad którymi się zastanawiałem, gdy go naprawiałem:
Tam był#include <iostream> pozostawione oświadczenie (choć nic z tego nie zostało wywołane) w jednym z plików źródłowych. Będzie to oczywiście link statycznystd::cin, std::cout istd::cerr instancje i wszystkie te rzeczy, które im towarzyszą.
Usuwanie#include <iostream> oświadczenie zmniejszyło.text segment o innej części> 100 KB.

Niemniej jednak:
Nadal jeststd::exception istd::basic_string rzeczy, nad którymi się zastanawiam:

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> >'

Nie ma tak naprawdę zbyt dużego rozmiaru kodu, tylko kilka 100 bajtów, więc mógłbym żyć zaniedbując go, ale byłbym wdzięczny, jeśli mogę się tego pozbyć.

Ponieważ wyraźnie nie używam żadnych wyjątków, zastanawiam się, dlaczego są one nadal tworzone podczas łączenia. Korzystanie z wyjątków lub nie może być naprawdę ustalone w czasie wykonywania?!?
Jedyna pozostała rzecz z__gnu_cxx Przestrzeń nazw, którą mi teraz pozostało

Type         Size Class 
T              58 '__gnu_cxx::recursive_init_error'

To kolejna klasa wyjątków.

WRESZCIE:
Użyłem kilku dodatkowych flag do skonfigurowania kompilacji GCC4.7:

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

Te ostatnie flagi są używane do kompilacji libstdc ++ i są zasadniczo takie same jak używane do budowania kodu docelowego (co i tak jest rozsądnym działaniem). Odniesienia do wyjątków, gdzie później (w tym__gnu_cxx::recursive_init_error).

Ostatnią rzeczą było to, że znalazłem nieoczekiwane użyciestd::string w naszym kodzie źródłowym. Po ustaleniu tego, odniesienie dostd::basic_string<char, std::char_traits<char>, std::allocator<char> > także zniknął.

Jestem więc zadowolony z rezultatu teraz, bez zbędnych, nieoczekiwanych problemów z libstdc ++, bez powodu, aby nie używać C ++ zamiast C.

questionAnswers(4)

yourAnswerToTheQuestion