2016-12-08 3 views
3

Я компилирую код для встроенного микроконтроллера ARM, и я пытаюсь оптимизировать двоичный размер. Для этого я использую arm-none-eabi-g++ с опциями -Os -ffunction-sections -fdata-sections -Wl,--gc-sections. Похоже, что это удаляет некоторые (но не все) неиспользуемые функции, особенно некоторые тяжелые.Удалить неиспользуемые функции из двоичного кода

arm-none-eabi-nm --print-size --size-sort --radix=d дает мне:

[...] 
00008412 00000084 T _raise_r 
00004888 00000088 t restore_non_core_regs 
00000172 00000092 t _ZN5USART5writeENS_4PortEc.constprop.22 
00005276 00000094 T __gnu_Unwind_RaiseException 
00001644 00000094 t _ZN4GPIO16enablePeripheralERKNS_3PinE 
536871016 00000096 d impure_data 
00004592 00000096 t search_EIT_table 
00000624 00000100 t _ZN5Flash9writePageEiPh 
00005648 00000112 T __gnu_Unwind_Backtrace 
536874336 00000128 b _ZN3USB8_bankEP0E 
00000264 00000128 t _ZN5USART9availableENS_4PortE.constprop.20 
00002500 00000140 t _Z17usbControlHandlerRN3USB11SetupPacketEPhRi 
00004728 00000160 t get_eit_entry 
00000464 00000160 t _ZN3USB15ep0SETUPHandlerEv 
00005060 00000212 t unwind_phase2_forced 
536871424 00000256 b _ZN3USB17_epRAMDescriptorsE 
536871688 00000384 b _ZN3USB10_endpointsE 
536874496 00000384 b _ZN4Core9isrVectorE 
00001972 00000528 t _ZN3USB12ep0INHandlerEv 
00006504 00000590 T _Unwind_VRS_Pop 
00007612 00000674 T __gnu_unwind_execute 
00005760 00000732 t __gnu_unwind_pr_common 
00000752 00000892 t _ZN3USB16interruptHandlerEv 
00002640 00001848 T main 
536872096 00002144 b _ZN5USART5portsE 

Как вы можете видеть, есть довольно много места, принятое «развернутые» функции. Кажется, что они связаны с исключениями C++, но я их не использую. Я посмотрел на ELF с objdump -d, и похоже, что никакая функция «разматывания» не вызывается из любой из моих функций, поэтому это будет эффективно мертвый код.

Есть ли способ удалить его из ELF? Или они по какой-то причине являются обязательными? Я мог бы сэкономить не менее 1/4 от общего двоичного размера.

+3

Вы попробовали '-fno-exceptions'? –

+2

Я подозреваю, что адреса в режиме разматывания регистрируются в специальной таблице, поэтому вы не видите прямых вызовов. Если вам не нужны исключения, почему вы не компилируете с '-fno-exceptions' в первую очередь? – gudok

+0

@DarkFalcon @ gudok Спасибо, я не знал этого варианта, и он работает очень хорошо! Все функции раскрутки исчезли, и я сохранил 27% двоичного размера. Я где-то читал, что C++ не налагает накладные расходы, если он явно не используется, знаете ли вы, почему мне приходится вручную отключать исключения, если я их не использую? – Foaly

ответ

1

Благодаря @DarkFalcon, @gudok и @jaggedSpire для ответа: решение заключалось в том, чтобы добавить -fno-exceptions, чтобы удалить все функции, связанные с размоткой. Теперь весь код, добавленный в двоичный файл, эффективно используется.

Смежные вопросы