ARM,.COMMON部分和-fno-common标志

时间:2015-02-12 10:11:26

标签: gcc linker arm ld

我试图诊断问题。问题是如果我在程序开头放置printf(特别是printf),我的程序工作正常,如果我不这样做,它就没有了。这个问题非常特定于一个循环,它读取我在systick_handler中递增的systick变量。

如果我用-fno-common编译,那么一切正常。为什么会这样?

另外,我已经从我的链接器脚本中删除了.COMMON部分,因为它们使程序几乎增加了两倍。无论如何,一切都在没有它们的情况下运行良好,但是当我使用默认(-fcommon)标志进行编译时,我怀疑他们的缺席是以某种方式导致无限循环。我仍然看不到我文件中的.COMMON部分的引用。它必须来自libc。

有谁可以解释发生了什么?

1 个答案:

答案 0 :(得分:6)

当您使用-fno-common时,未初始化的全局变量将被放置在GCC中的.bss部分(哦,虽然手册中说明了数据)。如果您不使用该选项,则将它们放在名为COMMON的特殊部分中。

如果从链接描述文件中省略此部分,链接器只会将其放入RAM,可能与其他数据重叠。您可以在地图文件中查看它。我只是尝试使用我的链接器脚本,发现COMMON的内容与我的情况下的堆放在同一个内存区域。这意味着全局变量和使用例如malloc分配的任何内容都将相互覆盖。不要那样做。糟糕的事情会发生。

关于使用-fno-common和忽略COMMON的安全性:我假设库也可以包含COMMON。即使您的代码不包含此部分,因为您使用-fno-common并不意味着链接器不需要处理它。只需在*(。bss)旁边添加*(COMMON)就可以了。如果由此增加内存消耗,则有充分的理由。

进一步阅读:

相关问题