6

我正在尝试减小我的 elf 可执行文件的大小。我正在编译-ffunction-sections -fdata-sections和链接-gc-sections,但似乎一些我认为未使用的符号没有被丢弃。

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

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

这是我典型的构建标志:

汇编: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

关联:arm-none-eabi-g++.exe -static -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -Wl,-gc-sections -Wl,-T"LinkerScript.ld

谢谢您的帮助。

4

3 回答 3

6

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

于 2015-04-01T19:53:09.520 回答
5

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

  • 将有问题的符号添加到/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开关来帮助解决这个问题,但它在前一段时间被删除了。我将重构我的代码以解决我的具体问题。

于 2014-07-11T01:20:34.183 回答
4

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

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

于 2014-07-09T14:56:17.993 回答