2012-12-25 8 views
7

mam crosscompiling C++ w Gentoo dla ARM Cortex M3 (Maple Mini), ale wydaje się, że uderzył w dach z zasobów pamięci podczas łączenia się elf plikZmniejszenie rozmiaru .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 

Ten post jest pytaniem o to, jak zmniejszyć rozmiar zawartości .rodata, aby móc zakończyć linkowanie pliku elfa.

Usunąłem załączony kod i kompiluję z następującymi właściwymi opcjami.

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

Nadal, .rodata w MAP-pliku (z których jestem całkiem obcy) zawiera, co wydaje się być pewnego rodzaju informacji o typie dla każdej z klas w programie. Niektóre fragmenty map-file (uwaga. MPU6050 jest SuperSensor <> który jest czujnikiem <> w C++ sens)

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) 

Więc lib_a-strerror.o i cp-demangle.o wydaje się być tym, co zajmuje najwięcej miejsca, choć wydaje mi się, że są one bardzo ważne.

Moje pytanie brzmi, jakie dalsze kroki mogę podjąć, aby zmniejszyć (lub zrestrukturyzować kod) sekcję .rodata i co dokładnie tam zapisano? Wszelkie sugestie są mile widziane! Jestem całkiem nowy w głębszym działaniu kompilacji i łączenia, ale w nauce.

+0

Są to ciągi komunikatów o błędach połączone z bibliotekami wykonawczymi C i C++. Informują użytkownika, dlaczego program się zawiesił. Pozbycie się ich wymagałoby przepisania bibliotek uruchomieniowych, co nie jest praktycznie praktyczne, ale zostało już zrobione. –

Odpowiedz

7

Myślę, że Twój problem nie musi koniecznie znajdować się w sekcji rodata - po prostu jest to facet, który nie usiadł na czas imprezy na fotelu muzycznym. Innymi słowy, rodata sama w sobie nie jest zbyt duża, ale CAŁKOWITA OBRAZ jest zbyt duża, by pasowała. Rozwiązaniem byłoby obejrzenie całego twojego kodu, danych i rodatek w twoim systemie i sprawdzenie, czy któryś z nich się wyróżnia.

Usunięcie niepotrzebnego kodu (lub ciągów znaków) w ogóle byłoby kluczowym punktem tutaj. Jeśli nie ma niczego, co można usunąć, musisz znaleźć inny sposób rozwiązania problemu. Jednym ze sposobów może być skompresowanie kodu i danych oraz rozpakowanie go do pamięci RAM (zakładając, że w systemie docelowym jest znacznie więcej pamięci RAM niż ROM). Nie jest to niesłychany problem, ale nigdy nie jest to łatwe do naprawienia - chyba że ktoś zrobił naprawdę złe kodowanie i dodał kilkaset kilobajtów kodu. Jeśli masz system kontroli wersji i znasz wersję, która pasuje, dobrze jest sprawdzić dokładnie, ile jest wolnego miejsca - jeśli nagle urosło, sprawdź, czy ktoś dodał masywne dane statyczne struktury lub niektóre takie.

+1

Dzięki, W dalszym oczyszczeniu znalazłem bezpańskie, bezpańskie stwierdzenie, które wydawało się być głównym źródłem części standardowej biblioteki, która zagracała .elf.Wydaje się, że najważniejszą kwestią jest zmniejszenie zależności do stdlib (w tym operatorów nowych i usuniętych) do absolutnego minimum. – templar

6

Podstawową kwestią nie jest to, że sekcja .rodata jest zbyt duża, koniecznie - w ogóle brakuje Ci przestrzeni ROM. (Łącznik właśnie dzieje się uderzając limitu, podczas gdy jest łączenie w tej sekcji).

Usuwanie żadnych wywołań funkcji, takich jak perror, strerror i spółki powinna zakończyć się upuszczenie zależność od strerror.o, które powinny zaoszczędzić kilobajtowy i pół po tobie. Mogą istnieć inne, łatwiejsze sposoby na dokonanie tych samych oszczędności - wszystko zależy od twojej aplikacji.