GCC --gc-sections和查找符号依赖项

时间:2014-07-09 09:06:27

标签: c++ gcc embedded thumb

我正在尝试减少我的elf可执行文件的大小。我正在使用-ffunction-sections -fdata-sections进行编译并与-gc-sections进行关联,但似乎我认为未使用的某些符号不会被丢弃。

GNU工具链中是否有一些命令我可以运行以找出正在使用的符号以及在哪里?

  • 工具链:GNU arm-none-eabi
  • 平台:Cortex-M4
  • 语言:C ++

以下是我的典型构建标志:

编译:{{1​​}}

链接:arm-none-eabi-g++.exe -Wall -O3 -mthumb -std=c++11 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -fsingle-precision-constant -ffunction-sections -fdata-sections

感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

我无法找到显示符号依赖关系的命令。但是,我能够通过使用以下技术获得所需的信息:

  • 将相关符号添加到链接描述文件的/DISCARD/部分。这将输出一条错误消息,显示哪个符号正在使用它。它看起来像这样:<symbol0>' referenced in section '<symbol1>' of <lib0.a file path>(<object0 file path>): defined in discarded section '<symbol0>' of <lib1.a file path>(object1 file path>)
  • 继续将这些消息中的符号从调用堆栈添加到/DISCARD/部分,直到找到问题的根源。

问题的根源在于我有一个从另一个继承的类。这创建了一个虚拟表,编译器无法删除虚拟表中引用的死代码。

获得的经验:如果您想减少代码大小并仍然使用C ++,请不要使用继承。 GNU工具链曾经有一个-fvtable-gc开关来帮助解决这个问题,但是它已经被删除了。我将重构我的代码以解决我的具体问题。

答案 1 :(得分:3)

您可以尝试使用链接器选项-Wl,--trace-symbol=<symbol_name>。它将在输出中显示符号,以及符号的使用位置。

答案 2 :(得分:2)

使用交叉引用输出创建链接器映射文件:

-Wl,-Map=output.map -Wl,--cref