2012-07-21 49 views
9

我正在使用C++中的裸机cortex-M3来获得乐趣和利润。如何调试链接过程 - GCC/ld - STL C++

最近我决定尝试使用STL库,因为我需要一些容器。 我认为通过简单地提供我的分配器,它不会向 最终二进制文件添加太多的代码,因为您只能得到您使用的内容。 我实际上甚至没有期望STL (给出我的分配器)的任何链接过程,因为我认为它是全部模板代码。

我正在用-fno-exception进行编译。

不幸的是,我的二进制文件中增加了约600KB或更多。我用nm查找包含在最终二进制文件中的什么符号 ,这对我来说似乎是个玩笑。名单很长 我不会试着去过去。虽然有一些微弱的符号。

我也看了在链接器生成的.map文件,我甚至发现scanf函数符号

.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 

如何调试呢?首先,我想了解GCC正在使用什么来链接(我通过GCC链接)。我知道如果在文本段中找到符号,则使用整个段,但仍然太多。

任何有关如何解决这个问题的建议真的很感谢。

感谢, S.

回答

3

使用GCC的-v-Wl,-v选项将显示正在使用的链接器命令(和链接器的版本信息)。

您使用的是哪个版本的GCC?我对GCC 4.6进行了一些更改(请参阅PR 44647PR 43863)以减少代码大小以帮助嵌入式系统。还有一个出色的增强请求(PR 43852)允许禁止包含您看到的IO符号 - 其中一些来自详细终止处理程序,当进程以活动异常终止时,它会输出消息。如果你不使用执行选项,那么一些代码对你来说就没用了。

+0

我使用Code Sourcery的gcc版本4.6.3。 -Wl,-v选项非常有用。除了我传递给链接的标志,它也包含以下 -lstdC++ -lm --start组-lgcc -lgcc_eh -lc --end组 现在我明白为什么,以及如何删除它们。特别是我认为gcc_eh代表异常处理。任何建议或阅读关于此? – emitrax 2012-07-22 08:29:08

+0

如果你用'gcc',而不是'G ++链接'那么它不会通过-lstdc''++的链接,而且还可能消除对'-lgcc -lgcc_eh'需要(我不记得的副手,我倒是要检查),但如果不从这些库使用任何代码,那么它不应该增加可执行文件的大小无论如何 - 冗长终止处理程序中的libstdC++可能是不需要的代码 – 2012-07-22 11:31:30

+0

什么拉如果我用gcc它赢得找不到_List_node_base :: _ M_hook符号。通过-lstdC++包含其他所有内容。 为了缩小这个问题,我试着直接连接ld,然后逐个添加这些标志。它缺少的libstdC++ __aeabi_unwind_cpp_pr0一(list.o):(..._ List_node_base7_M_hookE) 然后指向libc,就是(memcpy和其他),然后链接一切。这是一个大型连锁店和PITA。我只是想要一个容器。 :-) 我也认为,因为我有一个全局对象,它需要__static_initialization_and_destruction_0,我没有想到。谢谢你的帮助。 – emitrax 2012-07-22 12:21:59

2

的问题不是关于STL,它是关于标准库。

的STL本身是(在某种程度上),但标准库还包括所有这些流包,似乎还设法在libc以及拉...

问题是标准库从来没有打算分开,所以可能没有太多的关注重新使用从C标准库的东西...

你应该首先尝试确定哪些文件被拉入当你编译(使用stracefor example),这样你可以验证你只使用标头专用文件。

然后,您可以尝试删除发生的链接。有一些选项可以传递给gcc,以确保你想要一个标准库免费版本,比如--nostdlib,但是我不太了解那些在这里完全指导你的东西。

+0

我已经传递到-nostdlib编译器,用-fno-例外一起,但它似乎没有工作。 – emitrax 2012-07-22 08:35:00