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

GCC --gc-sections and finding symbol dependencies

本文关键字:符号 依赖 查找 gc-sections GCC      更新时间:2023-10-16

我正在尝试减少我的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

谢谢你的帮助

我找不到显示符号依赖关系的命令。然而,我能够通过使用以下技术获得我需要的信息:

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

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

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

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