我目前正在尝试用C开发SAM7X256微控制器的软件。该设备运行的是contiki OS,我正在使用yagarto工具链。
在研究地图文件时(为了弄清楚为什么.text区域增长了这么多)我发现了.text区域的几个kb被分配到展开支持(见下文)
.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。但是,我仍然不清楚以下内容:
如果有必要,我会提供指向完整map file
的链接提前感谢您的帮助
编辑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
答案 0 :(得分:13)
这个答案的几个部分:
展开的库函数是从异常"个性例程"中提取出来的。 (__aeabi_unwind_cpp_pr0等)在某些GCC库函数模块的异常表中提到。
您的地图文件显示bpapi.o(包含整数除法函数的模块)会引入此异常代码。我在最新的YAGARTO中没有看到这个,但我在_divdi3.o中这样做,这是另一个整数除法辅助模块。我可以通过编写一个执行64位除法的普通main()来重现放卷代码的效果。
C代码具有(非平凡的)异常表的一般原因是可以抛出C ++异常"通过"在应用程序中任意混合C和C ++代码时的C代码。
不能抛出或调用抛出函数的函数,如果它们有异常表,只需要标记为CANTUNWIND的简单函数,这样放卷库就不会被拉入。你希望分工助手属于这一类,事实上在CodeSourcery的发行版中,_divdi3.o被标记为CANTUNWIND。
因此根本原因是YAGARTO的GCC库(libgcc.a)构建不当。不完全错误,因为它仍然可以工作,但它在嵌入式工具链中不会期望它的代码臃肿。
你能对此做些什么吗?似乎没有简单的方法可以让GNU链接器忽略ARM异常部分,即使使用/ DISCARD /脚本 - 文本部分的链接会覆盖它。但是你可以做的是为异常个性例程添加一个存根定义:
void __aeabi_unwind_cpp_pr0(void) {}
int main(void) { return *(unsigned long long *)0x1000 / 3; }
使用YAGARTO编译为4K,而没有存根则编译为14K。但您也可能想要研究其他GNU工具分发。
答案 1 :(得分:1)
GCC有一个选项可以消除异常处理。
-fno-exceptions
虽然我不熟悉yagarto肯定地说,但它可能有类似的选择。在GCC上,此选项以支持标准异常为代价消除了这种开销。