ARM编译错误,可执行文件使用的VFP寄存器,而不是目标文件
Posted
技术标签:
【中文标题】ARM编译错误,可执行文件使用的VFP寄存器,而不是目标文件【英文标题】:ARM compilation error, VFP registers used by executable, not object file 【发布时间】:2012-04-02 23:15:28 【问题描述】:过去几天我一直遇到这个问题,我无法理解这里到底发生了什么,或者问题是什么。
我有一个带有这些标志的生成文件:
CC = arm-linux-gnueabihf-gcc-4.6
FLAGS = -O3 -march=armv7-a -mtune=cortex-a9 -mfpu=neon -ftree-vectorize -mfloat-abi=softfp -std=gnu99
我在 .a 文件中有一个库,其中包含一些目标文件,我需要做的就是将它们与我的可执行文件链接起来。我知道原型和所有这些,唯一抱怨的是:
/usr/bin/ld: error: *EXECUTABLE* uses VFP register arguments, *OBJECTFILE* does not
/usr/bin/ld: failed to merge target specific data of file *OBJECTFILE*
当我不使用 -mfloat-abi=softfp 时,我收到另一个与浮点寄存器有关的错误。
有没有人知道是什么原因造成的,以及我可以做些什么来解决这个问题,例如让我的可执行文件不使用虚拟浮点寄存器参数?
x@x:~/Desktop/perf_test$ make
arm-linux-gnueabihf-gcc-4.6 -c -O3 -march=armv7-a -mtune=cortex-a9 -mfpu=neon -ftree-vectorize -std=gnu99 -mfloat-abi=softfp perf_test.c ../baseline/util.c
arm-linux-gnueabihf-gcc-4.6 -o perf_test perf_test.o util.o ../baseline/lib.a
/usr/bin/ld: error: perf_test uses VFP register arguments, perf_test.o does not
/usr/bin/ld: failed to merge target specific data of file perf_test.o
/usr/bin/ld: error: perf_test uses VFP register arguments, util.o does not
/usr/bin/ld: failed to merge target specific data of file util.o
/usr/bin/ld: error: perf_test uses VFP register arguments, ../baseline/lib.a(a.o) does not
/usr/bin/ld: failed to merge target specific data of file ../baseline/lib.a(a.o)
/usr/bin/ld: error: perf_test uses VFP register arguments, ../baseline/lib.a(b.o) does not
/usr/bin/ld: failed to merge target specific data of file ../baseline/lib.a(b.o)
/usr/bin/ld: error: perf_test uses VFP register arguments, ../baseline/lib.a(c.o) does not
/usr/bin/ld: failed to merge target specific data of file ../baseline/lib.a(c.o)
/usr/bin/ld: error: perf_test uses VFP register arguments, ../baseline/lib.a(d.o) does not
/usr/bin/ld: failed to merge target specific data of file ../baseline/lib.a(d.o)
/usr/bin/ld: error: perf_test uses VFP register arguments, ../baseline/lib.a(e.o) does not
/usr/bin/ld: failed to merge target specific data of file ../baseline/lib.a(e.o)
/usr/bin/ld: error: perf_test uses VFP register arguments, ../baseline/lib.a(f.o) does not
/usr/bin/ld: failed to merge target specific data of file ../baseline/lib.a(f.o)
collect2: ld returned 1 exit status
make: *** [perf_test] Error 1
【问题讨论】:
【参考方案1】:这是猜测,但您可能还需要为链接阶段提供部分或全部浮点相关开关。
【讨论】:
【参考方案2】:您的目标三元组表明您的编译器已针对 hard-float ABI 进行了配置。这意味着 libgcc 库也将是 hardfp。该错误消息表明您的系统至少有一部分正在使用 soft-float ABI。
如果编译器启用了 multilib(你可以用 -print-multi-lib
告诉你),那么你可以使用 -mfloat-abi=softfp
,但如果没有,那么这个选项对你没有多大帮助:gcc 会很高兴地生成 softfp 代码,但是有'将没有兼容的 libgcc 链接。
基本上,hardfp 和 softfp 只是不兼容。您需要以一种或另一种方式配置整个系统。
编辑:一些发行版是或将是“多架构”。如果您有其中之一,则可以同时安装两个 ABI,但这是通过将所有内容加倍来完成的——兼容性问题仍然存在。
【讨论】:
当我使用 -hard 编译时,它会删除我编写的可执行文件和代码,但库仍然出错。我的问题基本上是假装我什么都不知道。这里发生了什么,为什么? 您的库和/或可执行文件不兼容,因为它们使用不同的过程调用约定:一个在 VFP 寄存器中传递浮点值,另一个在核心寄存器中传递它们。 这个修复对我有用。但是,请确保将-mfloat-abi=softfp
标志添加到编译器和链接器中,否则错误将持续存在【参考方案3】:
也可以通过添加几个标志来解决该错误,例如-marm -mthumb-interwork
。避免同样的错误对我很有帮助。
【讨论】:
【参考方案4】:我发现在 glibc binutils 和 gcc 交叉编译的 arm hardfloat 系统上,使用 gcc 会出现相同的错误。
通过将-mfloat-abi=hard
导出到flags来解决,然后gcc编译没有错误。
【讨论】:
【参考方案5】:也使用相同的编译器选项进行链接。
例子:
gcc -mfloat-abi=hard fpu=neon -c -o test.cpp test.o
gcc -mfloat-abi=hard fpu=neon -c test1.cpp test1.o
gcc test.o test1.o mfloat-abi=hard fpu=neon HardTest
【讨论】:
我有相同的 mfloat-abi 选项,但错过了链接器的 mcpu。这导致了 VFP 错误。【参考方案6】:就我而言,CFLAGS = -O0 -g -Wall -I. -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=soft
提供了帮助。如您所见,我将它用于我的 stm32f407。
【讨论】:
【参考方案7】:在我的特殊情况下,-g -march=armv7-a -mfloat-abi=hard -mfpu=neon -marm -mthumb-interwork
有效。
【讨论】:
【参考方案8】:我在 STM32F4 上使用 Atollic for ARM 时遇到了这个问题(我猜它适用于所有带 FPU 的 STM32)。
使用 SW 浮点对我来说效果不佳(因此编译正确)。
当 STM32cubeMX 为 TrueStudio (Atollic) 生成代码时,它不会在 C/C++ 构建设置中设置 FPU 单元(不确定为其他 IDE 生成的代码)。
在 "Target" 中为(在项目属性构建设置下)设置 FPU:
汇编器 C 编译器 C 链接器然后您可以选择混合硬件/软件 fp 或使用硬件。
为预期目标添加生成的命令行:
-mfloat-abi=hard -mfpu=fpv4-sp-d16
armatollic
【讨论】:
【参考方案9】:这个答案表面上可能看起来不相关,但这个错误信息有一个间接原因。
首先,“使用 VFP 寄存器...”错误消息是由在您的构建中混合使用 mfloat-abi=soft 和 mfloat-abi=hard 选项直接引起的。对于要链接的所有对象,此设置必须一致。这个问题的其他答案很好地涵盖了这一事实。
此错误的间接原因可能是由于 Eclipse 编辑器被项目的“.cproject”文件中的自我造成的错误弄糊涂了。 Eclipse 编辑器经常重新调整文件链接,有时它会在您更改目录结构或文件位置时自行中断。这也可能会影响 gcc 编译器的路径设置 - 并且仅适用于项目文件的子集。虽然我还不确定导致此故障的确切原因,但用备份副本替换 .cproject 文件为我解决了这个问题。就我而言,我在添加包含目录路径后注意到 .java.null.pointer 错误并开始突然收到“VFP 注册错误”消息。在构建日志中,我注意到 gcc 编译器的不同路径被用于工作区本地的一些源,但不是全部!?由于未知原因,两个 gcc 编译器使用不同的浮点设置 - 因此出现 VFP 寄存器错误。
我将 .cproject 设置与旧副本进行了比较,并观察到导致问题的源条目的差异 - 即使项目设置的覆盖被禁用。通过用旧版本替换 .cproject 文件,问题就消失了,我留下这个答案以提醒发生了什么。
【讨论】:
【参考方案10】:我也面临同样的问题。我正在尝试为 Cyclone V FPGA-SoC 构建 linux 应用程序。我遇到了如下问题:
错误: 使用 VFP 寄存器参数,main.o 不使用我使用的是altera的嵌入式软件设计工具提供的工具链arm-linux-gnueabihf-g++
。
通过导出解决:
mfloat-abi=hard
到标志,然后arm-linux-gnueabihf-g++
编译没有错误。还包括CC
和LD
中的标志。
【讨论】:
【参考方案11】:“请注意,硬浮点和软浮点 ABI 不是链接兼容的;您必须使用相同的 ABI 编译整个程序,并与一组兼容的库链接。” https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html arm-none-eabi-gcc.exe
Silicon Labs “kjostera” “Employee” 对 EFR32 Flex Gecko(交叉引用 Cortex-M4F)的回应:“因此,使用 softfp ABI 编译的代码与使用 hardfp ABI 编译的代码的链接时间不兼容。因此,由于我们目前仅支持 RAIL使用 softfp ABI 编译的库,这意味着您还必须使用 softfp ABI 构建应用程序。”
“注意,使用softfp ABI并不意味着你的代码不能使用FPU指令。任何做浮点运算的代码都会在编译器认为有意义的时候使用FPU。”
“kjostera”然后继续证明 GCC 7 为-mfloat-abi=softfp
和-mfloat-abi=hard
的情况生成了程序集,调用了vmul.f32
指令,指令计数为10 用于softfp
,9 用于hard
.
https://www.silabs.com/community/mcu/32-bit/forum.topic.html/enable_fpu_in_rail-p-SEYrhttps://www.silabs.com/documents/public/data-sheets/efr32fg1-datasheet.pdfhttps://www.silabs.com/documents/public/reference-manuals/efr32xg12-rm.pdfhttps://www.silabs.com/documents/public/reference-manuals/efr32xg13-rm.pdfhttps://www.silabs.com/documents/public/reference-manuals/efr32xg14-rm.pdf
【讨论】:
【参考方案12】:这个问题的另一个原因是你省略了最终二进制目标的 cpu 架构规范。
例如,即使您的-mfloat-abi
和-mfpu
开关在所有模块和最终二进制文件之间都一致,您仍然可能在-mcpu
上被绊倒。
在我的例子中,在最终二进制文件中省略 -mcpu=cortex-m4
会导致链接器默认使用其他一些 cpu 架构。这也产生了关于 VFP 寄存器的相同消息。
【讨论】:
【参考方案13】:通过将我的项目与 Raspberry 的一些外部库静态链接,我遇到了类似的问题。任何提到的编译器选项都可以提供帮助。通过比较我的目标文件和我正在链接的静态库的目标文件的 readelf 输出,我开始使用另一个交叉编译器。使用与以前相同的编译器选项,问题不再出现。所以,也许您只需要使用正确的交叉编译器,支持正确的 ABI 版本。
作为提示,ABI 版本编码在您主机上的编译器名称中。
【讨论】:
以上是关于ARM编译错误,可执行文件使用的VFP寄存器,而不是目标文件的主要内容,如果未能解决你的问题,请参考以下文章