Sie lesen die Map-Datei falsch. Keines der Vorkommen von .text.port_lock
, zum Beispiel stellt eine Definition der ChibiOS-Funktion void port_lock(void)
dar.
Alle Vorkommen von .text.port_lock
beziehen sich auf Eingabe-Linkerabschnitte.
Die ersten 4 Vorkommen innerhalb des Abschnitts der Kartendatei Discarded input sections
siehe Abschnitte Eingang Linker betitelte liegen, die der Linker verworfen. Zum Beispiel:
.text.port_lock
0x00000000 0x1c /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chmempools.o)
bedeutet, dass der Linker einen Abschnitt .text.port_lock
der Größe 28 Bytes in Eingabedatei /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chmempools.o)
und warf es weg gefunden.
die nächsten 6 Vorkommen, im dem Abschnitt der Kartendatei Linker script and memory map
alle Titel liegenden siehe Eingangslinkerabschnitte, die in den Ausgabe .text
Abschnitt kartiert waren.Zum Beispiel kann die ersten:
.text.port_lock
0x000012a8 0x1c /tmp/ccaossic.ltrans0.ltrans.o
bedeutet, dass der Linker einen Abschnitt .text.port_lock
der Größe 28 Bytes in Eingabedatei /tmp/ccaossic.ltrans0.ltrans.o
und kartiert sie bei der Adresse 0x000012a8 im Ausgabe .text
Abschnitt. Ebenso ist die zweite Vorkommen:
.text.port_lock
0x00001f70 0x1c /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chsys.o)
bedeutet, dass ein Eingangsabschnitt des gleichen Namens und Größe auch in der Eingabedatei /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chsys.o)
und wurde bei der Adresse 0x00001f70 im Ausgabe .text
Abschnitt kartiert wurde gefunden.
Insgesamt gibt es .text.port_lock
Eingangsabschnitte, alle von ihnen 28 Bytes, in Ihrer Ausgabe .text
Abschnitt aus diesen Eingabedateien zugeordnet:
/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 allen sechs dieser Fälle der Eingabeabschnitt enthält keine Symbole und insbesondere keine Funktionen. Für Kontrast, hier ist ein Beispiel für einen Eingangsabschnitt, dass tun Symbole enthalten:
.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
Dies ist der Eingang .text
Abschnitt von /home/fotis/Documents/Resources/Chibios/Chibios/Debug/libChibios.a(chcoreasm_v7m.o)
.
Die Map-Datei enthält keinen Hinweis darauf, dass die Funktion port_lock
mehrfach verknüpft ist. Es enthält keine Anzeige, dass diese Funktion überhaupt verknüpft ist. Wenn es mehrfach verknüpft wäre, dann wäre ein Mehrfachauflösungs-Verknüpfungsfehler gewesen (außer in dem Fall, dass es als weak symbol annotiert wurde).
Warum diese sechs 28-Byte-Eingabeabschnitte, die keine Symbole enthalten, alle verknüpft sind, oder ob sie sein müssen, ist eine Angelegenheit, über die ich keine ausreichenden Beweise oder ChibiOS-Kenntnisse habe. Ich bemerke , dass alle außer einer der Objektdateien, aus denen diese Eingabeabschnitte stammen, Archivmitglieder von libChibios
sind. In diesem Licht lohnt es sich zu erinnern, dass, wenn Ihre Verknüpfung ein Archiv-Mitglied aus irgendeinem Grund erfordert, dann standardmäßig verknüpfen Sie die ganze Archiv-Mitglied, auch es enthält mehr Zeug als Sie brauchen. Auf der anderen Seite, die Tatsache , dass einige port_lock
Eingabeabschnitte verworfen werden und einige beibehalten werden schlägt vor, dass es ist ein Bedarf, diejenigen zu halten, die gehalten werden. Wenn für meine eigenen listig Gründe, warum ich eine Quelldatei schreiben im Wesentlichen wie:
static int __attribute__((section(".text.foo"))) __attribute__((used))
boo(int i)
{
return i * 2;
}
int bar(int i)
{
return boo(i);
}
dann in meiner Map-Datei finden Sie einen leeren Eingabeabschnitt .text.foo
genannt sehen. Diese sagt nichts über die Symbole, die ich verlinke.
Wie kann ich der Toolchain mitteilen, nur einmal jede Funktion zu verknüpfen?
Der Linker wird nicht Link Symboldefinition mehr als einmal, außer in dem speziellen bei schwachen Symbolen.Ihre Map-Datei enthält keine Hinweise darauf, dass eine Funktion mehr als einmal verknüpft ist.
Wie kann ich die endgültige Dateigröße reduzieren?
Kompilieren Sie mit -Os
für Ihre Freigabe, natürlich. Um die Kopplungsredundanz zu minimieren, siehe , siehe this question.
Das Lesen einer Linker-Map-Datei ist normalerweise eine kluge Art, die Symbole und Abschnitte in Ihren Binärdateien zu untersuchen. Bevorzugen objdump
, readelf
und nm
So klar zu sein, Sie sagen, dass Sie die kompilierten Größen von zwei völlig getrennten und unabhängigen Programmen vergleichen, die die gleiche (einfache) Funktion ausführen? –
GCC hat die Option '-Os', um für kleine ausführbare Dateien zu optimieren. Sie könnten darüber nachdenken, das einzuschalten. Oder sogar "-O1" könnte besser in der Größe sein als überhaupt keine Optimierung. Wie für mehrere Kopien der gleichen Funktion in dem ausführbaren Bild - wenn das tatsächlich das ist, was Sie sehen - haben Sie uns nicht viel gegeben, um weiterzumachen. Kannst du ein [mcve] produzieren, das das Problem zeigt? –
Bewusst wurden die Optimierungen ausgeschaltet. Ich teste nicht die Fähigkeit des Compilers, Code zu optimieren. Ich untersuche, wie ich den Code optimieren kann. Die beiden Programme unterscheiden sich nicht. Sie sind die gleichen, mit einigen sehr kleinen Änderungen. Die Frage besteht darin, die Map-Datei zu verstehen und die gleiche Funktion mehrmals zu sehen. –