消除公共部分组
链接器可以检测节组的多个副本,并丢弃其他副本。
® Arm Compiler for Embedded 生成用于链接的完整对象。因此:
- 如果 C 和 C++ 源代码中存在内联函数,则每个对象都包含该对象所需的内联函数的外联副本。
- 如果在 C++ 源代码中使用模板,则每个对象都包含对象所需的模板函数。
在公共头文件中声明这些函数时,这些函数可能会在随后链接在一起的单独对象中多次定义。为了消除重复项,编译器将这些函数编译为公共节组的单独实例。
公共节组的单独实例可能不相同。例如,某些副本可能位于使用不同但兼容的构建选项、不同的优化或调试选项构建的库中。
如果副本不相同,则 armlink 会根据输入对象的属性保留每个公共节组的**可用变体。Armlink 丢弃其余部分。
如果副本相同,则 armlink 将保留位于的第一个部分组。
您可以使用以下链接器选项来控制此优化:
- 使用 -
-bestdebug选项使用最大的公共数据 (COMDAT) 组(可能提供**调试视图)。 - 使用 -
-no_bestdebug选项使用最小的 COMDAT 组(可能提供最小的代码大小)。这是默认设置。如果使用 -
g编译包含 COMDAT 组 A 的所有文件,即使使用 --no_bestdebug,映像也会更改。
消除未使用的部分
消除未使用的部分是链接器对图像大小执行的最重要优化。
未使用部分消除:
- 从最终映像中删除无法访问的代码和数据。
- 在可能导致删除所有部分的情况下被禁止显示。
要控制此优化,请使用 armlink 选项 --remove、--no_remove、--first、--last 和 --keep。
未使用的部分消除需要一个入口点。因此,如果未为映像指定入口点,请使用 armlink 选项 --entry 指定入口点。
使用 armlink 选项 --info unused 指示链接器生成它删除的未使用部分的列表。
注意
armlink报告错误:L6218E:未定义的符号 <symbol>,即使未使用的部分删除已删除此符号的要求。此行为与 GNU 链接器ld不同。
在以下情况下,输入部分将保留在最终图像中:
- 它包含一个入口点或一个外部可访问的符号。例如,Arm®v8-M 安全扩展的安全代码中的输入函数。
- 它是
SHT_INIT_ARRAY、SHT_FINI_ARRAY或SHT_PREINIT_ARRAY部分。 - 它被指定为第一个或最后一个输入部分,由 --
first或--last选项或分散加载等效项指定。 - 它被
--keep选项标记为不可删除。 - 它直接或间接地由图像中保留的输入部分的非弱引用引用。
- 其名称与输入截面符号所引用的名称匹配,并且该符号引用自图像中保留的截面。
注意
编译器通常将函数和数据收集在一起,并为每个类别发出一个部分。链接器只能删除完全未使用的部分。
您可以使用
__attribute__(used))属性标记源代码中的函数或变量。此属性使armclang为每个函数或变量生成符号__tagsym$$used.<num>,其中<num>是用于区分每个符号的计数器。消除未使用的部分不会删除包含__tagsym$$used.<num>的部分。您还可以使用
armclang选项 -ffunction-sections来指示编译器为源文件中的每个函数生成一个 ELF 部分。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/19054.html