You are misreading the map file. None of the occurrences of .text.port_lock
,
for example, represents a definition of the ChibiOS function void port_lock(void)
.
All the occurrences of .text.port_lock
refer to input linker sections.
The first 4 occurrences, lying within the section of the map file titled
Discarded input sections
, refer to input linker sections that the linker
discarded. For example:
.text.port_lock
0x00000000 0x1c /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chmempools.o)
means that the linker found a section .text.port_lock
of size 28 bytes
in input file /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chmempools.o)
and threw it away.
The next 6 occurrences, lying within the the section of the map file titled
Linker script and memory map
all refer to input linker sections that were
mapped into the output .text
section. For example the first one:
.text.port_lock
0x000012a8 0x1c /tmp/ccaossic.ltrans0.ltrans.o
means that the linker found a section .text.port_lock
of size 28 bytes
in input file /tmp/ccaossic.ltrans0.ltrans.o
and mapped it at address 0x000012a8 in the output .text
section. Likewise the
second occurrence:
.text.port_lock
0x00001f70 0x1c /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chsys.o)
means that an input section of the same name and size also was found in input
file /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chsys.o)
and was mapped at address 0x00001f70 in the output .text
section.
Altogether there are .text.port_lock
input sections, all of them 28 bytes,
mapped in your output .text
section from these input files:
/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)
In all 6 of these cases, the input section contains no symbols, and in particular
no functions. For contrast, here is an example of an input section that does contain symbols:
.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
This is the input .text
section from /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chcoreasm_v7m.o)
.
The map file contains no indication that the port_lock
function is linked multiple times. It contains no
indication that this function is linked at all. If it were linked multiple times then there
would have been a multiple-definition linkage error (except in the event that it had
been annotated as a weak symbol).
Why these six 28-byte input sections containing no symbols are all linked, or if they
need to be, is a matter about which I have no adequate evidence or ChibiOS expertise. I notice
that all but one of the object files from which these input sections come are
archive members of libChibios
. In that light, it is worth remembering that if your linkage
requires an archive member for any reason then by default you will link the whole
archive member, even it contains more stuff than you need. On the other hand, the fact
that some port_lock
input sections are discarded and some are kept suggests that there
is a need to keep the ones that are kept. If for my own cunning reasons I write a source file
essentially like:
static int __attribute__((section(".text.foo"))) __attribute__((used))
boo(int i)
{
return i * 2;
}
int bar(int i)
{
return boo(i);
}
then in my map file you will see an empty input section called .text.foo
. This
doesn't tell you anything about the symbols I'm linking.
How can I tell the toolchain to only link once each function?
The linker will not link any symbol definition more than once, except in the special
case of weak symbols. Your map file contains no evidence of any function being linked more than once.
How can I reduce the final file size?
Compile with -Os
for your release, of course. And to minimize linkage redundancy,
see this question.
Reading a linker map file is usually a clunky way of investigating the symbols and sections
in your binaries. Prefer objdump
, readelf
and nm