您误读了地图文件。没有出现.text.port_lock,
例如,表示ChibiOS函数void port_lock(void)的定义。
所有出现的.text.port_lock 指的是输入链接器部分。
前 4 次出现,位于地图文件标题为的部分中
Discarded input sections,请参阅链接器的输入链接器部分
丢弃。例如:
.text.port_lock
0x00000000 0x1c /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chmempools.o)
表示链接器找到了一个大小为 28 字节的部分 .text.port_lock
在输入文件/home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chmempools.o)
然后扔掉了。
接下来的 6 次出现,位于地图文件标题为的部分中
Linker script and memory map 都指的是输入链接器部分
映射到输出.text 部分。比如第一个:
.text.port_lock
0x000012a8 0x1c /tmp/ccaossic.ltrans0.ltrans.o
表示链接器找到了一个大小为 28 字节的部分 .text.port_lock
在输入文件/tmp/ccaossic.ltrans0.ltrans.o
并将其映射到输出.text 部分的地址0x000012a8。同样的
第二次出现:
.text.port_lock
0x00001f70 0x1c /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chsys.o)
表示在输入中也找到了相同名称和大小的输入部分
文件/home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chsys.o)
并在输出.text 部分中映射到地址 0x00001f70。
总共有.text.port_lock输入段,都是28字节,
从这些输入文件映射到您的输出.text 部分:
/tmp/ccaossic.ltrans0.ltrans.o
/home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chsys.o)
/home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chthreads.o)
/home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chcore_v7m.o)
/home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chmemcore.o)
/home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chschd.o)
在所有这 6 种情况下,输入部分不包含符号,尤其是
没有功能。相比之下,下面是一个确实包含符号的输入部分的示例:
.text 0x000002f0 0x28 /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chcoreasm_v7m.o)
0x000002f0 _port_switch
0x00000300 _port_thread_start
0x00000310 _port_switch_from_isr
0x00000314 _port_exit_from_isr
这是来自/home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chcoreasm_v7m.o) 的输入.text 部分。
映射文件不包含port_lock 函数被多次链接的迹象。它不包含
表明这个函数是完全链接的。如果它被链接多次,那么那里
将是一个多定义链接错误(除非它有
被注释为weak symbol)。
为什么这六个不包含符号的 28 字节输入段都被链接了,或者如果它们
需要,这是我没有足够证据或 ChibiOS 专业知识的问题。我注意到
除了这些输入部分来自的一个目标文件之外的所有目标文件都是
libChibios 的存档成员。鉴于此,值得记住的是,如果您的链接
出于任何原因需要存档成员,然后默认情况下您将链接整个
存档成员,即使它包含的内容比您需要的还要多。另一方面,事实
一些port_lock 输入部分被丢弃,一些被保留表明存在
是需要保留那些被保留的。如果出于我自己狡猾的原因我写了一个源文件
基本上像:
static int __attribute__((section(".text.foo"))) __attribute__((used))
boo(int i)
{
return i * 2;
}
int bar(int i)
{
return boo(i);
}
然后在我的地图文件中,您将看到一个名为.text.foo 的空输入部分。这
没有告诉您有关我正在链接的符号的任何信息。
如何告诉工具链每个函数只链接一次?
链接器不会多次链接任何符号定义,除非在特殊情况下
弱符号的情况。您的地图文件不包含任何函数被多次链接的证据。
如何减小最终文件大小?
当然,使用 -Os 编译您的版本。为了最大限度地减少链接冗余,
见this question。
读取链接器映射文件通常是研究符号和部分的笨拙方法
在你的二进制文件中。首选objdump,readelf
和nm