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.
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
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 –
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