当前位置: 首页 > article >正文

解决编译问题:undefined reference to `__aeabi_uidivmod‘

1、编译存在问题 

在编译韦老师课程提供的裸机源码时(比如004_erase_write_016_005),弹出以下几种错误:

init.o:(.ARM.exidx+0x0): undefined reference to `__aeabi_unwind_cpp_pr0'
init.o:(.ARM.exidx+0x8): undefined reference to `__aeabi_unwind_cpp_pr1'
my_printf.c:(.text+0x11c): undefined reference to `__aeabi_uidivmod'
my_printf.c:(.text+0x14c): undefined reference to `__aeabi_uidiv'

2、解决问题的过程

2.1 猜想问题所在

根据“undefined reference to”,应该是未定义某些函数或者缺失某些内容。但这些裸机程序在韦老师的课程中是可以编译成功的,应该不缺东西的。那问题出在哪里呢?

我猜想,问题出在我使用的与韦老师当时使用的交叉编译工具链的版本不一样。

2.2 查看交叉编译工具链

韦老师的交叉编译工具链版本是gcc-3.4.5(由书P27可知)。

我使用的交叉编译工具链版本是gcc-4.4.1,如下所示。

xjh@ubuntu:~/iot$ arm-linux-gcc -v
Using built-in specs.
Target: arm-none-linux-gnueabi
Configured with: //这里省略一大堆的配置选项,直观形式见下面内容。
Thread model: posix
gcc version 4.4.1 (Sourcery G++ Lite 2009q3-67)
xjh@ubuntu:~/iot$

为了方便查看配置选项,这里单独把它挑出来,罗列成直观的形式。其中有一个配置选项--with-arch=armv5te ,我觉得应该是有问题的,因为S3C2440是ARMv4版本的ARM指令集。

/scratch/julian/2009q3-respin-linux-lite/src/gcc-4.4/configure 
--build=i686-pc-linux-gnu 
--host=i686-pc-linux-gnu 
--target=arm-none-linux-gnueabi 
--enable-threads 
--disable-libmudflap 
--disable-libssp 
--disable-libstdcxx-pch 
--enable-extra-sgxxlite-multilibs 
--with-arch=armv5te 
--with-gnu-as 
--with-gnu-ld 
--with-specs='%{funwind-tables|fno-unwind-tables|mabi=*|ffreestanding|nostdlib:;:-funwind-tables} %{O2:%{!fno-remove-local-statics: -fremove-local-statics}} %{O*:%{O|O0|O1|O2|Os:;:%{!fno-remove-local-statics: -fremove-local-statics}}}' 
--enable-languages=c,c++ 
--enable-shared 
--disable-lto 
--enable-symvers=gnu 
--enable-__cxa_atexit 
--with-pkgversion='Sourcery G++ Lite 2009q3-67' 
--with-bugurl=https://support.codesourcery.com/GNUToolchain/ 
--disable-nls 
--prefix=/opt/codesourcery 
--with-sysroot=/opt/codesourcery/arm-none-linux-gnueabi/libc 
--with-build-sysroot=/scratch/julian/2009q3-respin-linux-lite/install/arm-none-linux-gnueabi/libc 
--with-gmp=/scratch/julian/2009q3-respin-linux-lite/obj/host-libs-2009q3-67-arm-none-linux-gnueabi-i686-pc-linux-gnu/usr 
--with-mpfr=/scratch/julian/2009q3-respin-linux-lite/obj/host-libs-2009q3-67-arm-none-linux-gnueabi-i686-pc-linux-gnu/usr 
--with-ppl=/scratch/julian/2009q3-respin-linux-lite/obj/host-libs-2009q3-67-arm-none-linux-gnueabi-i686-pc-linux-gnu/usr 
--with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' 
--with-cloog=/scratch/julian/2009q3-respin-linux-lite/obj/host-libs-2009q3-67-arm-none-linux-gnueabi-i686-pc-linux-gnu/usr 
--disable-libgomp 
--enable-poison-system-directories 
--with-build-time-tools=/scratch/julian/2009q3-respin-linux-lite/install/arm-none-linux-gnueabi/bin 
--with-build-time-tools=/scratch/julian/2009q3-respin-linux-lite/install/arm-none-linux-gnueabi/bin

2.3 更改交叉编译工具链 

从上面可知,我使用的与韦老师当时所使用的交叉编译工具链,两者的版本的确不同。那么如果我换成韦老师所用的版本而编译成功,则说明问题出在交叉编译工具链的版本上面。

那如何更换或者说安装交叉编译工具链?

书籍配套光盘提供有 arm-linux-gcc-3.4.5-glibc-2.3.6.tar.bz2,我们可以参考书P25~26进行安装与设置(其实解压之后就算完成了安装,但还需要对环境变量PATH进行设置):

(1)环境变量PATH是在/etc/environment文件中定义的,是最原始的值。这里直接在它后面补充新安装的交叉编译工具链的路径。

#将
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
#改为
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/arm/gcc-3.4.5-glibc-2.3.6/bin"

(2)在各个用户目录下有个.bashrc文件,即~/.bashrc文件。以前它里面使用export语句修改了PATH的值,即添加了交叉编译工具链的路径。为了避免对现在要安装的版本造成影响,先把export语句注释掉,然后"source ~/.bashrc"让修改生效。

#注释掉这个内容
export PATH=/usr/local/arm/arm-2009q3/bin:$PATH

(3)查看/etc/profile文件内容,看看有没有使用export导出以前交叉编译工具链的路径,有的话就先注释掉,以免对现在要安装的版本造成影响。然后“source /etc/profile”让修改生效。

#这里没有导出以前安装的交叉编译工具链,所以不注释也行
export PATH="/opt/hisi-linux/x86-arm/arm-hisiv300-linux/target/bin:$PATH"

(4)执行“arm-linux-gcc -v”,如果显示如下则说明安装成功。后续如果要恢复成原来版本,撤销上面的操作即可。

ot@ubuntu:/# arm-linux-gcc -v
Reading specs from /usr/local/arm/gcc-3.4.5-glibc-2.3.6/bin/../lib/gcc/arm-linux/3.4.5/specs
Configured with: //直观内容见下面
Thread model: posix
gcc version 3.4.5
root@ubuntu:/# 

/work/tools/create_crosstools/crosstool-0.43/build/arm-linux/gcc-3.4.5-glibc-2.3.6/gcc-3.4.5/configure 
--target=arm-linux 
--host=i686-host_pc-linux-gnu 
--prefix=/work/tools/gcc-3.4.5-glibc-2.3.6 
--with-float=soft 
--with-headers=/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/include 
--with-local-prefix=/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux 
--disable-nls 
--enable-threads=posix 
--enable-symvers=gnu 
--enable-__cxa_atexit 
--enable-languages=c,c++ 
--enable-shared 
--enable-c99 
--enable-long-long

2.4 测试是否已解决问题

更改交叉编译工具链之后,发现可以编译了:

xjh@ubuntu:~/iot/embedded_basic/jz2440/armBareMachine/004_erase_write_016_005$ make
arm-linux-gcc -march=armv4 -c -o start.o start.S
arm-linux-gcc -march=armv4 -c -o init.o init.c
init.c: In function `copy2sdram':
init.c:140: warning: passing arg 1 of `nand_read' makes integer from pointer without a cast
init.c:140: warning: passing arg 2 of `nand_read' from incompatible pointer type
arm-linux-gcc -march=armv4 -c -o interrupt.o interrupt.c
arm-linux-gcc -march=armv4 -c -o nand_flash.o nand_flash.c
arm-linux-gcc -march=armv4 -c -o led.o led.c
arm-linux-gcc -march=armv4 -c -o uart.o uart.c
arm-linux-gcc -march=armv4 -c -o main.o main.c
arm-linux-gcc -march=armv4 -c -o exception.o exception.c
arm-linux-gcc -march=armv4 -c -o timer.o timer.c
arm-linux-gcc -march=armv4 -c -o my_printf.o my_printf.c
arm-linux-gcc -march=armv4 -c -o string_utils.o string_utils.c
arm-linux-gcc -march=armv4 -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 init.o interrupt.o nand_flash.o led.o uart.o main.o exception.o timer.o my_printf.o string_utils.o lib1funcs.o -o sdram.elf
arm-linux-objcopy -O binary -S sdram.elf sdram.bin
arm-linux-objdump -D sdram.elf > sdram.dis
xjh@ubuntu:~/iot/embedded_basic/jz2440/armBareMachine/004_erase_write_016_005$

2.5 其他解决方法

通过查询,网上似乎有解决这些问题的其他方法(不是更换版本的方法),不知道有没有真解决问题,有空测试一下。

(1)undefined reference to `__aeabi_uidivmod' 的解决方法

(2)编译报undefined reference to `__aeabi_uldivmod'错误

(3)__aeabi_uldivmod 解决办法

3、分析受版本影响的原因

为什么交叉编译工具链的版本会影响编译过程?按理说,我使用的版本比韦老师当时使用的版本更高,应该可以向下兼容。 

待查明。

(1)解决uboot编译问题__aeabi_uidivmod'和o `__aeabi_uidiv'没定义的错误

(2)解决undefined reference to `__aeabi_uidivmod\'和undefined reference to `__aeabi_uidiv\'错误


http://www.kler.cn/news/323461.html

相关文章:

  • 20240924 行列式为1的矩阵不一定是正交矩阵
  • 昇思MindSpore进阶教程--数据处理管道支持Python对象
  • 基于Hive和Hadoop的用电量分析系统
  • 三节课发布首张AIGC学习地图,全员学习AI真的必要吗?
  • Java Web —— 第十天(SpringBoot原理)
  • ML 系列:机器学习和深度学习的深层次总结(06)— 提升数据质量
  • 数通。。。
  • uniapp js向json中增加另一个json的全部数据,并获取json长度
  • 【分布式微服务云原生】Dockerfile命令详解
  • 一站式家装服务管理系统
  • day01——通过git进行管理项目
  • HarmonyOS鸿蒙系统开发应用程序,免费开源DevEco Studio开发工具
  • 【中间件——基于消息中间件的分布式系统的架构】
  • C语言开发基础新手快速入门及精通系列学习教程(系统性完整C语言学习笔记整理)
  • Android常用C++特性之std::unique
  • 接口报错500InvalidPropertyException: Invalid property ‘xxx[256]‘,@InitBinder的使用
  • Python编程:08- pycharm使用技巧
  • OpenSource - 开源WAF_SamWaf
  • 详解Ajax与axios的区别
  • 增强现实中的物体识别与跟踪
  • rocketmq 学习文档
  • Vue3(五) 组件通信大汇总
  • 学习记录:js算法(四十八):另一棵树的子树
  • 【C++】Eclipse技巧汇总
  • Codeforces Round 975 (Div. 2) A. Max Plus Size
  • 使用JLINK合并boot和app两个hex文件,使用Keil烧写到单片机
  • AI Agent如何落地?来看看在教育行业大厂的落地实践
  • 使用 lstm + crf 实现NER
  • 防伪溯源查询系统V1.0.5
  • 虚幻引擎UE5如何云渲染,教程来了