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

Ver*_*rax 5 c++ embedded gcc thumb

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

谢谢您的帮助.

Ver*_*rax 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开关可以帮助解决此问题,但是它在一段时间前已被删除。我将重构代码以解决我的特定问题。


sdi*_*ive 5

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