I am currently working trying to develop software for a SAM7X256 microcontroller in C. The device is running contiki OS and I am using the yagarto toolchain.
While studying the map file (to try to figure out why the .text region had grown so much) I discovered that several kb of the .text region where assigned to unwind support (see below)
.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
I have tried finding looking for some information on unwinding and found 1 and 2. However the following is still unclear to me:
In case it is necessary I am including a link to the complete map file
Thanks in advance for your help
Edit 1: Adding Linker commands
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
Several parts to this answer:
the unwinding library functions are pulled in from exception "personality routines" (__aeabi_unwind_cpp_pr0 etc.) that are mentioned in exception tables in some of the GCC library function modules.
your map file shows that bpapi.o (a module which contains integer division functions) pulls in this exception code. I don't see this in the latest YAGARTO, but I do it in _divdi3.o which is another integer division helper module. I can reproduce the effect of the unwinding code being pulled in by writing a trivial main() that does a 64-bit division.
the general reason for C code having (non-trivial) exception tables is so that C++ exceptions can be thrown "through" the C code when you arbitrarily mix C and C++ code in your application.
functions which can't throw or call throwing functions, should, if they have exception tables at all, only need trivial ones marked as CANTUNWIND, so that the unwinding library isn't pulled in. You'd expect division helpers to be in this category and in fact in CodeSourcery's distribution, _divdi3.o is marked CANTUNWIND.
so the root cause is that YAGARTO's GCC library (libgcc.a) is built inappropriately. Not quite incorrectly, as it should still work, but it's code bloat that you wouldn't expect in an embedded toolchain.
Can you do anything about this? There seems to be no simple way to get the GNU linker to ignore ARM exception sections, even with a /DISCARD/ script - the link to the text section overrides that. But what you can do is add a stub definition for the exception personality routine:
void __aeabi_unwind_cpp_pr0(void) {}
int main(void) { return *(unsigned long long *)0x1000 / 3; }
compiles to 4K using YAGARTO, compared to 14K without the stub. But you might want to investigate alternative GNU tools distributions too.
GCC has an option that eliminates exception handling.
-fno-exceptions
While I'm not familiar with yagarto to say for sure, it may have a similar option. On GCC, this option eliminates this overhead at the expense of support for standard exceptions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With