Использование памяти для поддержки поддержки (по архитектуре ARM)

В настоящее время я работаю над созданием программного обеспечения для микроконтроллера SAM7X256 в C. На устройстве работает ОС contiki, и я использую toolchain yagarto.

При изучении файла карты (чтобы выяснить, почему область .text выросла настолько), я обнаружил, что несколько kb области .text, где назначено для поддержки поддержки (см. ниже)

.text           0x00116824      0xee4 c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2\libgcc.a(unwind-arm.o)
                0x00116c4c                _Unwind_VRS_Get
                ......   
                0x0011763c                __gnu_Unwind_Backtrace

.text           0x00117708      0x1b0 c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2\libgcc.a(libunwind.o)
                0x00117708                __restore_core_regs
                0x00117708                restore_core_regs
                ....
                0x00117894                _Unwind_Backtrace

.text           0x001178b8      0x558 c:/toolchains/yagarto/bin/../lib/gcc/arm-none-eabi/4.6.2\libgcc.a(pr-support.o)
                0x00117958                __gnu_unwind_execute
                ...
                0x00117e08                _Unwind_GetTextRelBase

Я попытался найти информацию о разматывании и нашел 1 и 2. Однако мне все еще не ясно следующее:

  • Когда/зачем мне нужна поддержка для размотки?
  • Какая часть моего кода вызывает связь pr-support.o, unwind-arm.o и libunwind.o?
  • Если это применимо, как мне избежать ссылки на элементы ниже.

В случае необходимости я включаю ссылку на полный файл .

Заранее благодарим за помощь

Изменить 1: Добавление команд компоновщика

CC       = arm-none-eabi-gcc
CFLAGSNO = -I. -I$(CONTIKI)/core -I$(CONTIKI_CPU) -I$(CONTIKI_CPU)/loader \
       -I$(CONTIKI_CPU)/dbg-io \
           -I$(CONTIKI)/platform/$(TARGET) \
           ${addprefix -I,$(APPDIRS)} \
           -DWITH_UIP -DWITH_ASCII -DMCK=$(MCK) \
           -Wall $(ARCH_FLAGS) -g -D SUBTARGET=$(SUBTARGET)

CFLAGS  += $(CFLAGSNO) -O -DRUN_AS_SYSTEM -DROM_RUN  -ffunction-sections

LDFLAGS += -L $(CONTIKI_CPU) --verbose -T $(LINKERSCRIPT) -nostartfiles  -Wl,-Map,$(TARGET).map

$(CC) $(LDFLAGS) $(CFLAGS) -nostartfiles -o project.elf -lc Project.a

Ответ 1

Несколько частей этого ответа:

  • функции разворачивания библиотеки вытягиваются из исключения "подпрограммы личности" (__aeabi_unwind_cpp_pr0 и т.д.), которые упоминаются в таблицах исключений в некоторых функциональных модулях библиотеки GCC.

  • ваш файл карты показывает, что bpapi.o(модуль, который содержит функции с целым делением) втягивает этот код исключения. Я не вижу этого в последнем YAGARTO, но я делаю это в _divdi3.o, который является еще одним вспомогательным модулем целочисленного подразделения. Я могу воспроизвести эффект отвлечения кода разматывания, написав тривиальный main(), который выполняет 64-битное деление.

  • общая причина для кода C, имеющего (нетривиальные) таблицы исключений, заключается в том, что исключения С++ могут быть переданы "через" код C, когда вы произвольно смешиваете код C и С++ в своем приложении.

  • функции, которые не могут бросать или вызывать функции бросания, должны, если у них вообще есть таблицы исключений, нужны только тривиальные, отмеченные как CANTUNWIND, так что библиотека разматывания не втягивается. помощники разделения, которые будут в этой категории, а на самом деле в дистрибутиве CodeSourcery, _divdi3.o отмечен CANTUNWIND.

  • поэтому основная причина в том, что библиотека YAGARTO GCC (libgcc.a) построена некорректно. Не совсем некорректно, так как он все равно должен работать, но он код раздувается, что вы не ожидаете во встроенной инструментальной цепочке.

Вы можете что-нибудь сделать? Кажется, нет простого способа заставить GNU-компоновщик игнорировать разделы исключений ARM, даже с помощью /DISCARD/ script - ссылка на текстовый раздел переопределяет это. Но то, что вы можете сделать, это добавить определение заглушки для индивидуальной процедуры исключения:

void __aeabi_unwind_cpp_pr0(void) {}
int main(void) { return *(unsigned long long *)0x1000 / 3; }

компилируется до 4K с использованием YAGARTO, по сравнению с 14K без заглушки. Но вы можете также изучить альтернативные дистрибутивы инструментов GNU.

Ответ 2

GCC имеет опцию, исключающую обработку исключений.

-fno-exceptions

Пока я не знаком с yagarto, чтобы сказать наверняка, у него может быть аналогичный вариант. В GCC эта опция устраняет эти накладные расходы за счет поддержки стандартных исключений.