I have build the GCC4.7.1 cross-toolchain for ARM (cortex-m3). Now I'm linking an executable from C/C++ code that surely doesn't use some certain STL classes (e.g. std::string
). Furthermore exceptions and RTTI are turned off.
Though when I'm looking to the target ELF (e.g. using nm), there's a lot of symbols (apparantly from the libstdc++) linked in I wouldn't expect to find there (e.g. std::exception
, std::ios_base
, etc.).
Why is this there, and how can I get rid of this stuff to reduce the .text
section size of my target?
A coworker gave me a tip to override some GCC specific stub function:
namespace __gnu_cxx
{
void __verbose_terminate_handler()
{
for (;;)
;
}
}
This alone reduced the code size about 20KB.
Are there more such stubs I can override?
UPDATE:
OK, I found one really stupid error that removed most of the stuff I was wondering about, when fixing it:
There was an #include <iostream>
statement left (though nothing called from there) in one of the source files. This will of course link in the static std::cin
, std::cout
and std::cerr
instances and all the stuff that comes along with these.
Removing the #include <iostream>
statement reduced the .text
segment about another > 100KB portion.
Nevertheless:
There's still the std::exception
and std::basic_string
stuff I'm wondering about:
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> >'
There isn't really much code size used, just about several 100 bytes, so I could live with neglecting it, but would appreciate, if I can get rid of this also.
Since I'm explicitly using no exceptions I wonder why these are still instantiated when linking. Usage of exceptions or not can't be really determined at runtime?!?
The only remaining thing from the __gnu_cxx
namespace I have left now is
Type Size Class
T 58 '__gnu_cxx::recursive_init_error'
It's another exception class.
FINALLY:
I used some additional flags to configure the GCC4.7 cross build:
--enable-gold=yes
--enable-lto
--enable-cxx-flags='-fno-exceptions -ffunction-sections -fno-omit-frame-pointer'
The latter flags are used to compile the libstdc++ and are essentially the same as used for building the target code (which is a reasonable action anyway). Exception references where gone afterwards (including the __gnu_cxx::recursive_init_error
).
Last thing was, I found an unexpected use of std::string
in our codebase. After fixing that, the reference to std::basic_string<char, std::char_traits<char>, std::allocator<char> >
also disappeared.
So I'm happy with the result now, no more unnecessary, unexpected overhead from libstdc++, no reason not to use C++ in preference over C.
You can never know what using one of library functions will pull in. Well, actually you probably can by creating call graph with one of the tools. So what part of c++ std library are you using?
Other than that, I have had success in removing unneeded function from executable by using two methods (none of this on ARM, but methods are not ARM specific):
You are already using -Os, right?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With