ILD

ipq5018 toolchain编译出的可执行程序出现illegal instruction的问题
作者:Yuan Jianpeng 邮箱:yuanjp89@163.com
发布时间:2022-6-6 站点:Inside Linux Development

使用crosstool-ng编译的toolchain,开启了vfp:

CT_ARCH_FPU="neon-vfpv4"

CT_ARCH_FLOAT="hard"


编译进入rootfs后,概率性出现illegal instruction,也不知道是啥指令。今天在使用bare metal的时候,也出现了illegal instruction。这很好,因为uboot打印除了PC的地址。

IPQ5018# go 44000000

## Starting application at 0x44000000 ...

undefined instruction

pc : [<44000148>]          lr : [<440002e0>]

reloc pc : [<44000148>]    lr : [<440002e0>]

sp : 4a822934  ip : 00000000     fp : 4a822934

r10: 00000000  r9 : 4a822ea0     r8 : 4a97b1a0

r7 : 4a928b61  r6 : 00000002     r5 : 44000000  r4 : 4a82a84c

r3 : 44000318  r2 : 44000318     r1 : 4a82a84c  r0 : 00000001

Flags: nzCv  IRQs off  FIQs off  Mode SVC_32

Resetting CPU ...



反汇编:

ipq_timer.timer_load_val = 0x00FFFFFFFFFFFFFF;

4400013c: e3003318 movw r3, #792 ; 0x318

44000140: e3443400 movt r3, #17408 ; 0x4400

44000144: f2c70e3f vmov.i64 d16, #0x00ffffffffffffff

44000148: edc30b04 vstr d16, [r3, #16]


定位vstr原来是浮点数指令。尝试使用soft。第一次修改为softfp,产生的指令不变,修改为soft即可。

hard/softfp/soft 3种,soft才完全是软件soft。


然后在openwrt的toolchain中还发现了一个选项:

Configured with: /work/ax3000/build_dir/toolchain-arm_cortex-a7_gcc-5.5.0_musl_eabi/gcc-5.5.0/configure 

--with-bugurl=http://www.lede-project.org/bugs/ 

--with-pkgversion='OpenWrt GCC 5.5.0 unknown' 

--prefix=/work/ax3000/staging_dir/toolchain-arm_cortex-a7_gcc-5.5.0_musl_eabi 

--build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu 

--target=arm-openwrt-linux-muslgnueabi 

--with-gnu-ld 

--enable-target-optspace 

--disable-libgomp 

--disable-libmudflap --disable-multilib --disable-libmpx --disable-nls --without-isl --without-cloog --with-host-libstdcxx=-lstdc++ 

--with-float=soft 

--with-gmp=/work/ax3000/staging_dir/host --with-mpfr=/work/ax3000/staging_dir/host --with-mpc=/work/ax3000/staging_dir/host --disable-decimal-float --with-diagnostics-color=auto-if-env --disable-libssp --enable-__cxa_atexit 

--with-arch=armv7-a

--with-headers=/work/ax3000/staging_dir/toolchain-arm_cortex-a7_gcc-5.5.0_musl_eabi/include --disable-libsanitizer --enable-languages=c,c++ --enable-shared --enable-threads --with-slibdir=/work/ax3000/staging_dir/toolchain-arm_cortex-a7_gcc-5.5.0_musl_eabi/lib --enable-lto --with-libelf=/work/ax3000/staging_dir/host


代码里面根本没有浮点数运算,应该是整数也使用了浮点数了。disable-decimal-float可能也可以解决这个问题。


使用soft后,反汇编正常了:

ipq_timer.timer_load_val = 0x00FFFFFFFFFFFFFF;

4400013c: e3003318 movw r3, #792 ; 0x318

44000140: e3443400 movt r3, #17408 ; 0x4400

44000144: e3e00000 mvn r0, #0

44000148: e3e014ff mvn r1, #-16777216 ; 0xff000000

4400014c: e1c301f0 strd r0, [r3, #16]



IPQ5018是支持硬件浮点运算的。但是可能uboot并没有初始化fpu,导致uboot不支持fpu。有一个编译选项可以不适用fpu寄存器:

-mgeneral-regs-only

Generate code which uses only the general-purpose registers. This will prevent

the compiler from using floating-point and Advanced SIMD registers but will

not impose any restrictions on the assembler.


使用这个编译选项后,产生的汇编代码如下:

125         ipq_timer.timer_load_val = 0x00FFFFFFFFFFFFFF;

126 4400013c:       e3003398        movw    r3, #920        ; 0x398

127 44000140:       e3443400        movt    r3, #17408      ; 0x4400

128 44000144:       e3e00000        mvn     r0, #0

129 44000148:       e3e014ff        mvn     r1, #-16777216  ; 0xff000000

130 4400014c:       e1c301f0        strd    r0, [r3, #16]


Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.