2012-07-21 9 views
9

Pracuję na bare-metal cortex-M3 w C++ dla zabawy i zysku.Jak debugować proces łączenia - GCC/ld - STL C++

Ostatnio postanowiłem spróbować użyć biblioteki STL, ponieważ potrzebowałem niektórych pojemników. Myślałem, że po prostu dostarczając mój alokator, nie doda wiele kodu do ostatecznego pliku binarnego , ponieważ otrzymasz tylko to, czego używasz. Właściwie nie oczekiwałem nawet żadnego procesu łączenia ze STL (dając mój przydział), ponieważ myślałem, że to cały kod szablonu.

Podczas kompilacji kompiluję się przy użyciu opcji -nosekcja wyjątku.

Niestety, do mojego pliku binarnego dodano około 600 KB lub więcej. Sprawdziłem, jakie symbole są zawarte w końcowym pliku binarnym za pomocą nm i wydawało mi się to żartem. Lista jest tak długa. Nie będę próbowała i przeszłam. Chociaż istnieją pewne słabe symbole.

Spojrzałem także w pliku .map generowanego przez łącznik i ja nawet znaleźć symbole scanf

.text   0x000158bc  0x30 /CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_GNU_Linux/bin/../arm-none-linux-gnueabi/libc/usr/lib/libc.a(sscanf.o)¶ 
      0x000158bc    __sscanf¶ 
      0x000158bc    sscanf¶ 
      0x000158bc    _IO_sscanf¶ 


$ arm-none-linux-gnueabi-nm binary | grep scanf 
000158bc T _IO_sscanf 
0003e5f4 T _IO_vfscanf 
0003e5f4 T _IO_vfscanf_internal 
000164a8 T _IO_vsscanf 
00046814 T ___vfscanf 
000158bc T __sscanf 
00046814 T __vfscanf 
000164a8 W __vsscanf 
000158bc T sscanf 
00046814 W vfscanf 
000164a8 W vsscanf 

Jak mogę debugowania to? Najpierw chciałem zrozumieć, co dokładnie GCC używa do łączenia (łączę się przez GCC). Wiem, że jeśli w segmencie tekstowym zostanie znaleziony symbol, zostanie użyty cały segment , ale nadal to za dużo.

Wszelkie sugestie, jak rozwiązać ten problem, byłyby naprawdę docenione.

Dzięki S.

Odpowiedz

3

Użycie opcji GCC w postaci -v i -Wl,-v spowoduje wyświetlenie poleceń łącznika (i informacji o wersji łącznika).

Z której wersji GCC korzystasz? Wprowadziłem pewne zmiany w GCC 4.6 (patrz PR 44647 i PR 43863), aby zmniejszyć rozmiar kodu, aby pomóc systemom wbudowanym. Nadal istnieje wyjątkowe żądanie ulepszenia (PR 43852), aby umożliwić wyłączenie uwzględnienia symboli IO, które widzisz - niektóre z nich pochodzą z pełnej procedury obsługi zakończeń, która drukuje komunikat po zakończeniu procesu z aktywnym wyjątkiem. Jeśli nie używasz komend, to część tego kodu jest dla ciebie bezużyteczna.

+0

Używam gcc wersji 4.6.3 z Code Sourcery. Opcja -Wl, -v była bardzo przydatna. Wzdłuż flag podałem linkerowi, zawierał on także następujący -lstdC++ -lm --start-group -lgcc -lgcc_eh -lc --end-group teraz muszę zrozumieć, dlaczego i jak je usunąć. Zwłaszcza argument gcc_eh, który jak sądzę, oznacza obsługę wyjątku. Wszelkie sugestie lub czytanie o tym? – emitrax

+0

Jeśli połączysz się z 'gcc' zamiast' g ++ ', to nie przekażesz' -lstdC++ 'do linkera, a to może również usunąć potrzebę' -lgcc -lgcc_eh' (nie pamiętam od ręki, I trzeba to sprawdzić), ale jeśli nie użyjesz żadnego kodu z tych bibliotek, to i tak nie powinieneś zwiększać rozmiaru pliku wykonywalnego - pełny kod obsługi kończy się w libstdC++ prawdopodobnie jest tym, co wciąga niechciany kod –

+0

Jeśli użyję gcc to wygrałem nie znajduje symbolu _List_node_base :: _ M_hook.Passing -lstdC++ zawiera wszystko inne. Aby zawęzić problem, spróbowałem połączyć bezpośrednio z Ld, dodając te flagi jeden po drugim. Brakuje __aeabi_unwind_cpp_pr0 w libstdC++. A (list.o): (..._ List_node_base7_M_hookE) który następnie łączy się z libc (memcpy i inne), które następnie łączy wszystko inne. To wielki łańcuch i PITA. Chciałem tylko pojemnika. :-) Pomyślałem również, że ponieważ mam obiekt globalny, potrzebuje __static_initialization_and_destruction_0, czego się nie spodziewałem. Dzięki za pomoc. – emitrax

2

Problem nie polega na STL, chodzi o biblioteki standardowej.

Sam STL jest czysty (w pewnym sensie), ale biblioteka standardowa zawiera również wszystkie te pakiety strumieni i wydaje się, że udało się również wyciągnąć w libc oraz ...

Problem jest to, że Biblioteka Standardowa nigdy nie była przeznaczona do oddzielania, więc nie było większego problemu z ponownym użyciem rzeczy z Biblioteki Standardowej C ...

Najpierw należy spróbować określić, które pliki są wciągnięte kiedy kompilujesz (używając stracefor example), w ten sposób możesz sprawdzić, czy używasz tylko tylko nagłówkowe pliki.

Następnie można spróbować usunąć występujące połączenie. Istnieją opcje przekazania do gcc, aby dokładnie określić, czy chcesz mieć standardową, wolną od biblioteki kompilację, na przykład na przykład --nostdlib, jednak nie jestem wystarczająco zaznajomiony z tymi, którzy polecili ci dokładnie tutaj.

+0

Już przekazuję -nostdlib do kompilatora wraz z -noserem, ale wygląda na to, że nie działa. – emitrax