编译出现“__aeabi_uidivmod”和“__aeabi_uidiv”未定义(除法实现的问题)的解决方法

引言

第十五课(2)Nor FLash编程_识别
在裸机上运行uart的printf函数,
所以引入了lib1funcs.S 文件

编译出错:

book@www.100ask.org:/work/uart/test$ make
arm-linux-gcc -c -o nor_flash.o nor_flash.c
arm-linux-gcc -c -o my_printf.o my_printf.c
arm-linux-gcc -c -o string_utils.o string_utils.c
arm-linux-gcc -c -o lib1funcs.o lib1funcs.S
#arm-linux-ld -Ttext 0 -Tdata 0x30000000  start.o led.o uart.o init.o main.o -o sdram.elf
arm-linux-ld -T sdram.lds start.o led.o uart.o init.o main.o exception.o interrupt.o timer.o nor_flash.o my_printf.o string_utils.o lib1funcs.o -o sdram.elf
my_printf.o: In function `out_num':
my_printf.c:(.text+0x120): undefined reference to `__aeabi_uidivmod'
my_printf.c:(.text+0x158): undefined reference to `__aeabi_uidiv'
Makefile:2: recipe for target 'all' failed
make: *** [all] Error 1

查找到的解决步骤:
http://bbs.elecfans.com/jishu_1743669_1_1.html

我整理一下别人的解决思路:

从百问网查找到的解决方案为,将4.3.2 交叉编译工具替换为3.4.5版本的版本。
4.3.2 版本交叉编译的解决思路:
1、这个错误提示说明是一个未定义引用的错误,根据__aeabi_uidivmod,和__aeabi_uidiv猜想应该是除法实现的问题(为什么就能得出是除法实现的问题?根据英文名吗?可是我查了下,没有这个英文。)。
2、这里用到了lib1funcs.S这个除法库文件,于是在里面搜索__aeabi_uidiv和__aeabi_uidivmod,找不到这两个关键字的定义。
说明应该是4.3.2版本的编译工具需要找这两个关键字的定义,但是找不到。
3、猜测应该是这个lib1funcs.S是比较老版本的库文件,可是这个较新版本的去哪找呢,除法运算在u-boot和Linux内核里肯定实现了,就到这两个里面去找这个文件。
4、4.3.2编译通过的两个项目版本分别是u-boot-2012.04.01以及linux-3.4.2,就到这两个项目中找,你会发现u-boot里面没有这个文件,u-boot肯定实现了,但是不是用这个来实现的,我们到linux内核里找:
find /work/projects/linux-3.4.2 -name "lib1funcs.S"
搜索结果:

./arch/arm/lib/lib1funcs.S
./arch/arm/boot/compressed/lib1funcs.S

5、/work/system/linux-3.4.2/arch/arm/lib/lib1funcs.S,这个文件应该就是我们找的库文件。
把他copy到项目里,然后make。
编译结果:

arm-linux-gcc -c -o lib1funcs.o lib1funcs.S
lib1funcs.S:36:27: error: linux/linkage.h: No such file or directory
lib1funcs.S:37:27: error: asm/assembler.h: No such file or directory
lib1funcs.S:38:24: error: asm/unwind.h: No such file or directory
Makefile:11: recipe for target 'lib1funcs.o' failed
make: *** [lib1funcs.o] Error 1

提示我们找不到这些头文件,对比以前的lib1funcs.S不需要这些头文件。
所以我们把头文件注释掉:

 35 /*
 36 #include <linux/linkage.h>
 37 #include <asm/assembler.h>
 38 #include <asm/unwind.h>
 39 */

6、再次编译,出现如下错误:

arm-linux-gcc -c -o lib1funcs.o lib1funcs.S
lib1funcs.S: Assembler messages:
lib1funcs.S:181: Error: bad instruction `entry(__udivsi3)'
lib1funcs.S:182: Error: bad instruction `entry(__aeabi_uidiv)'
lib1funcs.S:183: Error: bad instruction `unwind(.fnstart)'
lib1funcs.S:207: Error: bad instruction `unwind(.fnend)'
lib1funcs.S:208: Error: bad instruction `endproc(__udivsi3)'
lib1funcs.S:209: Error: bad instruction `endproc(__aeabi_uidiv)'
lib1funcs.S:211: Error: bad instruction `entry(__umodsi3)'
lib1funcs.S:212: Error: bad instruction `unwind(.fnstart)'
lib1funcs.S:226: Error: bad instruction `unwind(.fnend)'
lib1funcs.S:227: Error: bad instruction `endproc(__umodsi3)'
lib1funcs.S:229: Error: bad instruction `entry(__divsi3)'
lib1funcs.S:230: Error: bad instruction `entry(__aeabi_idiv)'
lib1funcs.S:231: Error: bad instruction `unwind(.fnstart)'
lib1funcs.S:268: Error: bad instruction `unwind(.fnend)'
lib1funcs.S:269: Error: bad instruction `endproc(__divsi3)'
lib1funcs.S:270: Error: bad instruction `endproc(__aeabi_idiv)'
lib1funcs.S:272: Error: bad instruction `entry(__modsi3)'
lib1funcs.S:273: Error: bad instruction `unwind(.fnstart)'
lib1funcs.S:293: Error: bad instruction `unwind(.fnend)'
lib1funcs.S:294: Error: bad instruction `endproc(__modsi3)'
lib1funcs.S:356: Error: bad instruction `unwind(.fnstart)'
lib1funcs.S:357: Error: bad instruction `unwind(.pad #4)'
lib1funcs.S:358: Error: bad instruction `unwind(.save {lr})'
lib1funcs.S:363: Error: bad instruction `unwind(.fnend)'
lib1funcs.S:364: Error: bad instruction `endproc(Ldiv0)'
Makefile:11: recipe for target 'lib1funcs.o' failed
make: *** [lib1funcs.o] Error 1

应该是去掉头文件引起的编译器对定义不理解。
对比老版本的lib1funcs开头有一些宏定义我们先加上:

#define ALIGN		.align 4,0x90
#define __LINUX_ARM_ARCH__  1

#define ENTRY(name) \
  .globl name; \
  ALIGN; \
  name:

其中有entry的宏定义,我们可以猜想这些都是在头文件里的宏定义,其实你去linux内核里找这个头文件#include <linux/linkage.h>在这里就可以找到entry的宏定义。

7、再次编译,出现错误:

book@www.100ask.org:/work/test$ make
arm-linux-gcc -c -o lib1funcs.o lib1funcs.S
lib1funcs.S: Assembler messages:
lib1funcs.S:192: Error: bad instruction `unwind(.fnstart)'
lib1funcs.S:216: Error: bad instruction `unwind(.fnend)'
lib1funcs.S:217: Error: bad instruction `endproc(__udivsi3)'
lib1funcs.S:218: Error: bad instruction `endproc(__aeabi_uidiv)'
lib1funcs.S:221: Error: bad instruction `unwind(.fnstart)'
lib1funcs.S:235: Error: bad instruction `unwind(.fnend)'
lib1funcs.S:236: Error: bad instruction `endproc(__umodsi3)'
lib1funcs.S:240: Error: bad instruction `unwind(.fnstart)'
lib1funcs.S:277: Error: bad instruction `unwind(.fnend)'
lib1funcs.S:278: Error: bad instruction `endproc(__divsi3)'
lib1funcs.S:279: Error: bad instruction `endproc(__aeabi_idiv)'
lib1funcs.S:282: Error: bad instruction `unwind(.fnstart)'
lib1funcs.S:302: Error: bad instruction `unwind(.fnend)'
lib1funcs.S:303: Error: bad instruction `endproc(__modsi3)'
lib1funcs.S:365: Error: bad instruction `unwind(.fnstart)'
lib1funcs.S:366: Error: bad instruction `unwind(.pad #4)'
lib1funcs.S:367: Error: bad instruction `unwind(.save {lr})'
lib1funcs.S:372: Error: bad instruction `unwind(.fnend)'
lib1funcs.S:373: Error: bad instruction `endproc(Ldiv0)'
Makefile:11: recipe for target 'lib1funcs.o' failed
make: *** [lib1funcs.o] Error 1

unwind()unwind()的宏定义老版本里没有,怎么办呢?
全部注释掉:

#UNWIND(.fnend)
#ENDPROC(__modsi3)

8、再次编译,出现错误:

book@www.100ask.org:/work/test$ make
arm-linux-gcc -c -o lib1funcs.o lib1funcs.S
#arm-linux-ld -Ttext 0 -Tdata 0x30000000  start.o led.o uart.o init.o main.o -o sdram.elf
arm-linux-ld -T sdram.lds start.o led.o uart.o init.o main.o exception.o interrupt.o timer.o nor_flash.o my_printf.o string_utils.o lib1funcs.o -o sdram.elf
my_printf.o: In function `out_num':
my_printf.c:(.text+0x120): undefined reference to `__aeabi_uidivmod'
lib1funcs.o: In function `Ldiv0':
(.text+0x3a8): undefined reference to `__div0'
Makefile:2: recipe for target 'all' failed
make: *** [all] Error 1

在新的lib1funcs.S搜索这个定义,找到如下:

#ifdef CONFIG_AEABI

我们在开头加一句 #define CONFIG_AEABI ,然后保存make

9、再次编译,出现错误:

book@www.100ask.org:/work/test$ make
arm-linux-gcc -c -o lib1funcs.o lib1funcs.S
#arm-linux-ld -Ttext 0 -Tdata 0x30000000  start.o led.o uart.o init.o main.o -o sdram.elf
arm-linux-ld -T sdram.lds start.o led.o uart.o init.o main.o exception.o interrupt.o timer.o nor_flash.o my_printf.o string_utils.o lib1funcs.o -o sdram.elf
lib1funcs.o: In function `Ldiv0':
(.text+0x3ec): undefined reference to `__div0'
Makefile:2: recipe for target 'all' failed
make: *** [all] Error 1

还有一个未定义,在ib1funcs.S里搜索“__div0”,是在最后相对跳转到一个c函数里面执行,我们对比老的lib1funcs.S发现这里注释掉了,我们也注释掉,然后保存make

Ldiv0:
#UNWIND(.fnstart)
#UNWIND(.pad #4)
#UNWIND(.save {lr})
	str	lr, [sp, #-8]!
	/*bl	__div0*/
	mov	r0, #0			@ About as wrong as it could be.
	ldr	pc, [sp], #8
#UNWIND(.fnend)
#ENDPROC(Ldiv0)

10、再次make,通过编译。
作者make还是不通过,出现的错误是:

arm-linux-gcc -c -o led.o led.c
arm-linux-gcc -c -o uart.o uart.c
arm-linux-gcc -c -o lib1funcs.o lib1funcs.S
arm-linux-gcc -c -o my_printf.o my_printf.c
arm-linux-gcc -c -o main.o main.c
arm-linux-gcc -c -o start.o start.S
arm-linux-ld -Ttext 0  -Tdata 0xe80 start.o led.o uart.o lib1funcs.o my_printf.o main.o -o uart.elf
arm-linux-ld: section .data [00000e80 -> 00000e8f] overlaps section .rodata [00000d74 -> 00000e9b]
arm-linux-ld: uart.elf: section .data lma 0xe80 overlaps previous sections
Makefile:2: recipe for target 'all' failed
make: *** [all] Error 1,

因为我没有指定数据段的地址,作者指定了数据段和代码段的地址。
代码段太长了,超过了定义的数据段的位置,可以自己适当延长代码段,,我试了一下用0xea0就可以。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值