我已经从 ARM 下载了官方 ARM linux gnueabihf 工具链的版本 13.2。
我检查了配置命令行:
$ /opt/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-g
nueabihf-gcc -v
Using built-in specs.
COLLECT_GCC=/opt/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/opt/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-linux-gnueabihf/bin/../libexec/gcc/arm-none-linux-gnueabihf/13.2.1/lto-wrapper
Target: arm-none-linux-gnueabihf
Configured with: /data/jenkins/workspace/GNU-toolchain/arm-13/src/gcc/configure --target=arm-none-linux-gnueabihf --prefix= --with-sysroot=/arm-none-linux-gnueabihf/libc --with-build-sysroot=/data/jenkins/workspace/GNU-toolchain/arm-13/build-arm-none-linux-gnueabihf/install//arm-none-linux-gnueabihf/libc --with-bugurl=https://bugs.linaro.org/ --enable-gnu-indirect-function --enable-shared --disable-libssp --disable-libmudflap --enable-checking=release --enable-languages=c,c++,fortran --with-gmp=/data/jenkins/workspace/GNU-toolchain/arm-13/build-arm-none-linux-gnueabihf/host-tools --with-mpfr=/data/jenkins/workspace/GNU-toolchain/arm-13/build-arm-none-linux-gnueabihf/host-tools --with-mpc=/data/jenkins/workspace/GNU-toolchain/arm-13/build-arm-none-linux-gnueabihf/host-tools --with-isl=/data/jenkins/workspace/GNU-toolchain/arm-13/build-arm-none-linux-gnueabihf/host-tools --with-arch=armv7-a --with-fpu=neon --with-float=hard --with-mode=thumb --with-arch=armv7-a --with-pkgversion='Arm GNU Toolchain 13.2.rel1 (Build arm-13.7)'
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 13.2.1 20231009 (Arm GNU Toolchain 13.2.rel1 (Build arm-13.7))
它显示了
--with-arch=armv7-a
,我的印象是这很重要。
但是当我为armv8编译测试二进制文件时,它似乎产生了正确的标签:
$ arm-linux-gnueabihf-gcc -march=armv7-a -shared -fPIC -o arm_raw_v7.so test.c
$ arm-linux-gnueabihf-gcc -march=armv8-a -shared -fPIC -o arm_raw_v8.so test.c
$ arm-linux-gnueabihf-readelf -A arm_raw_v?.so | grep Tag_CPU_arch:
Tag_CPU_arch: v7
Tag_CPU_arch: v8
当我使用 here 中的 RPi3+ 工具链进行相同的测试时,编译器会接受
-march=armv7-a
,但生成的二进制文件仍会打印标记 v8。
RPi 工具链的配置选项:
/opt/cross-pi-gcc-10.2.0-2/bin/arm-linux-gnueabihf-gcc -v
Using built-in specs.
COLLECT_GCC=/opt/cross-pi-gcc-10.2.0-2/bin/arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/opt/cross-pi-gcc-10.2.0-2/bin/../libexec/gcc/arm-linux-gnueabihf/10.2.0/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../configure --prefix= --target=arm-linux-gnueabihf --enable-languages=c,c++,fortran --with-sysroot=/arm-linux-gnueabihf/libc --with-build-sysroot=/tmp/cross-pi-gcc-10.2.0-2/arm-linux-gnueabihf/libc --with-arch=armv8-a --with-fpu=neon-fp-armv8 --with-float=hard --disable-multilib
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.2.0 (GCC)
有人可以解释为什么官方 ARM 工具链为 ISA 生成二进制文件,尽管配置为 armv7a?
arm-none-eabi-gcc --version
arm-none-eabi-gcc (GCC) 13.2.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
unsigned int fun ( unsigned int a )
{
return(a+1);
}
arm-none-eabi-gcc -O2 -c -march=armv7-a so.c -o so.o
arm-none-eabi-objdump -d so.o
so.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <fun>:
0: e2800001 add r0, r0, #1
4: e12fff1e bx lr
arm-none-eabi-readelf -A so.o | grep Tag_CPU_arch:
Tag_CPU_arch: v7
arm-none-eabi-gcc -O2 -c -march=armv8-a so.c -o so.o
arm-none-eabi-objdump -d so.o
so.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <fun>:
0: e2800001 add r0, r0, #1
4: e12fff1e bx lr
arm-none-eabi-readelf -A so.o | grep Tag_CPU_arch:
Tag_CPU_arch: v8
这两种情况都确实是armv7-a。
aarch64-none-elf-gcc --version
aarch64-none-elf-gcc (GCC) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
如果需要,我可以将其重建为 13.2.0。
aarch64-none-elf-gcc -O2 -c -march=armv8-a so.c -o so.o
aarch64-none-elf-objdump -d so.o
so.o: file format elf64-littleaarch64
Disassembly of section .text:
0000000000000000 <fun>:
0: 11000400 add w0, w0, #0x1
4: d65f03c0 ret
aarch64-none-elf-readelf -A so.o | grep Tag_CPU_arch:
(no output)
aarch64-none-elf-readelf -A so.o
(no output)
armv8-a是64位的,如果我没记错的话,(大多数?)产品都有armv7-a(32位)兼容模式。当然,arm-whatever-whatever-gnu 工具适用于 64 位之前的版本,有时称为 aarch32 或...armv7-a 用于高端,什么是 64 位部分的 32 位模式。对于完全不同且不兼容的 64 位指令集,您需要 aarch64-whatever-whatever gnu 工具。同样,您需要 mips-whatever-whatever 来实现与 32 位臂不同的架构(称为 mips)。