Take the 2-minute tour ×

I'm working on a bare-metal cortex-M3 in C++ for fun and profit.

Lately I decided to try and use the STL library as I needed some containers. I thought that by simply providing my allocator it wouldn't add much code to the final binary, since you get only what you use. I actually didn't even expect any linking process at all with the STL (giving my allocator), as I thought it was all template code.

I am compiling with -fno-exception by the way.

Unfortunately, about 600KB or more are added to my binary. I looked up what symbols are included in the final binary with nm and it seemed a joke to me. The list is so long I won't try and past it. Although there are some weak symbols.

I also looked in the .map file generated by the linker and I even found the scanf symbols

.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

How can I debug this? For first I wanted to understand what exactly GCC is using for linking (I'm linking through GCC). I know that if symbol is found in a text segment, the whole segment is used, but still that's too much.

Any suggestion on how to tackle this would really be appreciated.

Thanks, S.

share|improve this question
add comment

2 Answers

up vote 2 down vote accepted

Using GCC's -v and -Wl,-v options will show you the linker commands (and version info of the linker) being used.

Which version of GCC are you using? I made some changes for GCC 4.6 (see PR 44647 and PR 43863) to reduce code size to help embedded systems. There's still an outstanding enhancement request (PR 43852) to allow disabling the inclusion of the IO symbols you're seeing - some of them come from the verbose terminate handler, which prints a message when the process is terminated with an active exception. If you're not using execptions then some of that code is useless to you.

share|improve this answer
I'm using gcc version 4.6.3 from Code Sourcery. The -Wl,-v option was very useful. Along the flags I passed to the linker, it also included the following -lstdc++ -lm --start-group -lgcc -lgcc_eh -lc --end-group now I have to understand why, and how to remove them. Especially the gcc_eh which I suppose stands for exception handling. Any suggestions or reading about this? –  emitrax Jul 22 '12 at 8:29
If you link with gcc instead of g++ then it won't pass -lstdc++ to the linker, and that might also remove the need for -lgcc -lgcc_eh (I don't remember offhand, I'd have to check) but if you don't use any code from those libs then it shouldn't increase the executable size anyway - the verbose terminate handler in libstdc++ is probably what pulls in the unwanted code –  Jonathan Wakely Jul 22 '12 at 11:31
If I use gcc it won't find the _List_node_base::_M_hook symbol.Passing -lstdc++ includes everything else. To narrow down the problem I tried linking directly with ld adding those flags one by one. It's missing __aeabi_unwind_cpp_pr0 in libstdc++.a(list.o):(..._List_node_base7_M_hookE) which then links to libc (memcpy and other), which then links everything else. It's a big chain and a PITA. I just wanted a container. :-) I also figured that,since I have a global object, it needs __static_initialization_and_destruction_0 which I didn't expect. Thanks for your help. –  emitrax Jul 22 '12 at 12:21
Ah yes, std::__detail::_List_node_base::_M_hook is not inline, it's defined in libstdc++.a, but the file it's in (list.cc) is pretty small and I'm surprised it requires the unwind support if you've disabled exceptions ... strange. –  Jonathan Wakely Jul 23 '12 at 8:14
add comment

The problem is not about the STL, it is about the Standard library.

The STL itself is pure (in a way), but the Standard Library also includes all those streams packages and it seems that you also managed to pull in the libc as well...

The problem is that the Standard Library has never been meant to be picked apart, so there might not have been much concern into re-using stuff from the C Standard Library...

You should first try to identify which files are pulled in when you compile (using strace for example), this way you can verify that you only ever use header-only files.

Then you can try and remove the linking that occurs. There are options to pass to gcc to precise that you would like a standard library-free build, something like --nostdlib for example, however I am not well versed enough in those to instruct you exactly here.

share|improve this answer
I am already passing -nostdlib to the compiler, along with -fno-exception, but it seems not to work. –  emitrax Jul 22 '12 at 8:35
add comment

Your Answer


