为armv5交叉编译,但生成的是v7二进制文件。

3

我成功地为arm926ej-s创建了一个目标文件。
我正在使用在qemu上运行的debian arm。

arm-linux-gnueabi-gcc-4.4 -static -O -c -mcpu=arm926ej-s  hello.c -o hello
root@at0012-ubuntu:/qemu-deb-squeeze/mnt/package# readelf -A hello
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "ARM926EJ-S"
  Tag_CPU_arch: v5TEJ
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-1
  Tag_FP_arch: VFPv3-D16
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align_needed: 8-byte
  Tag_ABI_align_preserved: 8-byte, except leaf SP
  Tag_ABI_enum_size: int
  Tag_ABI_HardFP_use: SP and DP
  Tag_ABI_optimization_goals: Prefer Speed
  Tag_DIV_use: Not allowed

但是在Ubuntu中,如果我不带-c编译选项,它会为armv7创建可执行文件而不是这个:
那么如何编译适用于正确CPU的代码?
我尝试了以下命令:$ arm-linux-gnueabi-gcc-4.4 -static -mcpu=arm926ej-s hello.c -o hello
它会生成:
Tag_CPU_name: "7-A"
Tag_CPU_arch: v7


编译时,这些库是如何被链接的? - Michael Burr
你需要找到正确的工具链,这是最简单的。 - auselen
2
这实际上是 https://dev59.com/FmnWa4cB1Zd3GeqP38jR 的副本,由 @auselen 回答。 - unixsmurf
2个回答

3
GCC的ld会尽力找到正确的库进行链接。据我所知,它会考虑-mcpu-mthumb-mfpu-mfloat-abi(见下面的示例)。这个列表可能不完整,-mthumb-interwork也可能被考虑在内。如果指定了-mcpu,则从该值中推导出架构。
因此,应将这些选项传递给ld,并确保ld确实选择了正确的多库。
对于每个选项,都有内置的默认值,这些默认值可能不会指向正确的方向。
如果ld找不到匹配的库,则回退到默认库。没有错误消息。
因此,在您的情况下 - 假设您已将-mcpu传递给ld并且您的工具链安装正确 - 可能没有匹配的多库,ld使用默认的多库。链接过程在技术上成功,但您得不到想要的结果。

一些示例(arm-none-eabi-gcc 4.6.2)

可用的多库:

$ arm-none-eabi-gcc -print-multi-lib
.;
thumb/arm7tdmi-s;@mthumb@mcpu=arm7tdmi-s
thumb/cortex-m0;@mthumb@mcpu=cortex-m0
thumb/cortex-m3;@mthumb@mcpu=cortex-m3
thumb/cortex-m4;@mthumb@mcpu=cortex-m4
thumb/cortex-m4/float-abi-hard/fpuv4-sp-d16;@mthumb@mcpu=cortex-m4@mfloat-abi=hard@mfpu=fpv4-sp-d16

默认

$ arm-none-eabi-gcc -print-multi-directory
.

如果给定 CPU 的 multilib 未找到,则它也使用默认值 - 不会出现错误消息。
$ arm-none-eabi-gcc -print-multi-directory -mcpu=arm926ej-s 
.

即使-mcpu明显错误(也就是CPU不在已知的ARM CPU列表中,您可以通过arm-none-eabi-gcc --target-help查看),也没有错误消息:

$ arm-none-eabi-gcc -print-multi-directory -mcpu=xxx
.

即使使用了-mcpu=cortex-m4,仍然选择了无效的多库。cm4仅支持thumb,因此该值可以从-mcpu中推导出来,但是内置默认值胜出:
$ arm-none-eabi-gcc -print-multi-directory -mcpu=cortex-m4
.

为了获取适用于cm4的正确的多库文件,同样需要使用-mthumb>,这是为了覆盖指令集的默认值。
$ arm-none-eabi-gcc -print-multi-directory -mcpu=cortex-m4 -mthumb
thumb/cortex-m4

为了获得正确的支持浮点运算硬件的cm4多库,仅使用-mfpu可能不足够:
$ arm-none-eabi-gcc -print-multi-directory -mcpu=cortex-m4 -mthumb -mfloat-abi=hard
.

它需要

$ arm-none-eabi-gcc -print-multi-directory -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
thumb/cortex-m4/float-abi-hard/fpuv4-sp-d16

更多有关multilib的细节可以在这里找到,以及在auselen的回答中。


正如auselen所评论的那样,解决这个问题最简单的方法是找到正确的工具链,因为构建ARM工具链是另一回事。


这是不正确的。每个mcpu标志非常明确地描述了该CPU支持的架构版本。这就是为什么使用-c编译时,对象最终会针对正确的架构版本。汇编器也是如此。没有任何工具链默认值可以更改这一点。我不知道GNU LD可以配置为通过指定-march自动支持几个版本的C库 - 您能否提供有关如何实现此目的的参考资料? - unixsmurf
@unixsmurf:你说得对。抱歉,各位,是我的错。我会更新我的答案,只需要给我一些时间来整理事情。 - Beryllium
1
@unixsmurf:我已经重写了我的答案。至于你关于-march的问题:似乎在gcc/ld搜索多库时会忽略-march。 - Beryllium
遗憾,如果它支持的话,我会非常高兴 :) - unixsmurf

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接