2012-12-25 3 views
7

Ich crosscompiling C++ in Gentoo für einen ARM Cortex M3 (Maple Mini), scheinen aber mit den Speicherressourcen traf ein Dach zu haben, als die Verknüpfung der Elf-DateiReduzierung der Größe von .rodata

/usr/libexec/gcc/arm-none-eabi/ld: build/maple_mini.elf section `.rodata' will not fit in region `rom' 
/usr/libexec/gcc/arm-none-eabi/ld: region `rom' overflowed by 1508 bytes 

Dieser Post ist eine Frage darüber, wie man die Größe des Inhalts von .rodata reduzieren kann, um die Verknüpfung der Elf-Datei zu vervollständigen.

Ich habe den mitgelieferten Code entfernt und kompiliere mit den folgenden relevanten Optionen.

CXXFLAGS = -fno-rtti -fno-exceptions -Os -fdata-sections -ffunction-sections -Wl,-gc-sections ... 
LDFLAGS = -Wl,-gc-sections -fno-exceptions -fno-rtti ... 

Doch die .rodata in der Karte-Datei (mit der ich bin ganz ungewohnt) enthält, was für jede der Klassen in dem Programm eine Art von Typinformationen zu sein scheint. Einige map-Datei Auszüge (Anm. MPU6050 ist ein Supersonde <>, die ein Sensor ist <>, in einem C++ Sinn)

0x000000000801d6c0  0x28 .../libsyrup.a(MPU6050.o) 
    0x000000000801d6c0 _ZTVN5syrup6SensorILi6EEE 
.rodata._ZTVN5syrup11SuperSensorILi6EEE 0x000000000801d6e8  0x28 .../libsyrup.a(MPU6050.o) 
    0x000000000801d6e8    _ZTVN5syrup11SuperSensorILi6EEE 
.rodata._ZTVN5syrup7MPU6050E 0x000000000801d710  0x28 .../libsyrup.a(MPU6050.o) 
    0x000000000801d710    _ZTVN5syrup7MPU6050E 
.rodata._ZTVN5syrup6SensorILi1EEE 
    0x000000000801d738     0x28 .../libsyrup.a(MS5611.o) 
    0x000000000801d738    _ZTVN5syrup6SensorILi1EEE 
.rodata._ZTVN5syrup11SuperSensorILi1EEE 
      0x000000000801d760   0x28 .../libsyrup.a(MS5611.o) 
      0x000000000801d760    _ZTVN5syrup11SuperSensorILi1EEE 
... 
      0x000000000801ee24   0x6f3 .../libstdc++.a(cp-demangle.o) 
             0x730 (size before relaxing) 
*fill*   0x000000000801f517  0x1 
.rodata  0x000000000801f518  0x14 .../libgcc.a(unwind-arm.o) 
.rodata  0x000000000801f52c  0x23c .../libc.a(lib_a-strerror.o) 
.rodata.str1.4 0x000000000801f768 0x635 .../libc.a(lib_a-strerror.o) 
             0x63c (size before relaxing) 

So lib_a-strerror.o und cp-demangle.o scheint, was den meisten Platz einnimmt, obwohl ich denke, dass diese ziemlich lebenswichtig sind.

Also meine Frage ist, welche weiteren Schritte kann ich ergreifen, um den .rodata Abschnitt zu reduzieren (oder den Code neu zu strukturieren), und was genau ist dort gespeichert? Irgendwelche Vorschläge sind willkommen! Ich bin ziemlich neu in den tieferen Arbeiten des Kompilierens und Verknüpfens, aber lernen.

+0

Dies sind Fehlermeldungen, die aus den C- und C++ - Laufzeitbibliotheken stammen. Sie teilen dem Benutzer mit, warum Ihr Programm abgestürzt ist. Um sie loszuwerden, müssten die Laufzeitbibliotheken neu geschrieben werden, was nicht gerade praktisch ist, aber es wurde getan. –

Antwort

7

Ich denke, dass dein Problem nicht unbedingt in der Rodata-Sektion als solche sein muss - es ist nur, dass das der Typ ist, der sich nicht rechtzeitig bei den Muskelstuhl-Events gesetzt hat. Mit anderen Worten, Rodata an sich ist nicht, was zu groß ist, aber das GANZE BILD ist zu groß, um zu passen. Die Lösung wäre, Ihren gesamten Code, Daten und Rodata in Ihrem System zu betrachten und zu sehen, ob etwas davon herausragt.

Das Entfernen von unnötigem Code (oder Strings) im Allgemeinen wäre hier der Schlüsselpunkt. Wenn nichts entfernt werden kann, müssen Sie einen anderen Weg finden, um das Problem zu lösen. Eine Möglichkeit besteht darin, den Code und die Daten zu komprimieren und sie in den RAM zu dekomprimieren (unter der Annahme, dass auf dem Zielsystem wesentlich mehr RAM als ROM vorhanden ist). Das ist kein unbekanntes Problem, aber es ist nie wirklich so einfach zu beheben - es sei denn, jemand hat einige wirklich schlechte Programmierung gemacht und einige hundert Kilobyte Code hinzugefügt. Wenn Sie ein Versionskontrollsystem haben und eine Version kennen, die passt, kann es gut sein, genau zu prüfen, wie viel Speicherplatz vorhanden ist. Wenn es plötzlich stark anwächst, überprüfen Sie, ob jemand einige massive statische Daten hinzugefügt hat Strukturen oder einige solcher.

+1

Dank, Bei der weiteren Aufräumarbeiten fand ich eine streunende, fehlerhafte Asser-Include-Datei, die ein Hauptgrund dafür zu sein schien, Teile der Standardbibliothek einzuschließen, die die .elf überfüllte.Der Hauptpunkt hier scheint zu sein, die Abhängigkeit von der stdlib (einschließlich neuer und löschender Operatoren) auf ein absolutes Minimum zu reduzieren. – templar

6

Das zugrunde liegende Problem ist nicht, dass die .rodata Abschnitt zu groß ist, unbedingt - Sie haben nur im Allgemeinen ROM-Speicherplatz im Allgemeinen. (Der Linker gerade geschieht, die Grenze zu schlagen, während es in diesem Abschnitt ist die Verknüpfung.)

alle Aufrufe von Funktionen aus- wie perror, strerror und Unternehmen soll die Abhängigkeit von strerror.o fallen am Ende, mit dem Sie die Kilobyte speichern soll und eine Hälfte bist du vorbei. Es kann andere, einfachere Wege geben, wie Sie die gleichen Einsparungen erzielen können - alles hängt von Ihrer Anwendung ab.