【问题标题】:GCC 7.1.1 RISCV compilation (link) failures, incompatible ABIGCC 7.1.1 RISCV 编译(链接)失败,ABI 不兼容
【发布时间】:2018-03-25 18:08:46
【问题描述】:

我在 Windows 7-64 位平台上的最新 GCC for RISCV 上为 RISCV 进行基本编译和链接时遇到了困难。

安装的工具:7.1.1-2-20170912-2255 来自https://github.com/gnu-mcu-eclipse/riscv-none-gcc/releases/

平台:Windows 7,64 位,无 cygwin

程序:

#include <stdint.h>

int32_t iBlahblah;
int main (void)
{
    while(1)
        iBlahblah++;
    return 0;
}

命令行:

"c:\Program Files\GNU MCU Eclipse\RISC-V Embedded GCC\7.1.1-2-20170912-2255\bin\riscv64-unknown-elf-gcc.exe" -c hello.c -o hello  -march=rv32imac -mabi=ilp32  -Os 
"c:\Program Files\GNU MCU Eclipse\RISC-V Embedded GCC\7.1.1-2-20170912-2255\bin\riscv64-unknown-elf-gcc.exe" -o hello.elf  -march=rv32imac -mabi=ilp32  -Os -Wl,-Map=hello.lst hello.o

输出:

c:/program files/gnu mcu eclipse/risc-v embedded gcc/7.1.1-2-20170912-2255/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/../../../../riscv64-unknown-elf/bin/ld.exe: hello.o: ABI is incompatible with that of the selected emulation:  target emulation `elf64-littleriscv' does not match `elf32-littleriscv'
c:/program files/gnu mcu eclipse/risc-v embedded gcc/7.1.1-2-20170912-2255/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/../../../../riscv64-unknown-elf/bin/ld.exe: failed to merge target specific data of file hello.o
c:/program files/gnu mcu eclipse/risc-v embedded gcc/7.1.1-2-20170912-2255/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/../../../../riscv64-unknown-elf/lib/rv32imac/ilp32\libg.a(lib_a-exit.o): In function `.L0 ':  exit.c:(.text.exit+0x1e): undefined reference to `_exit'
c:/program files/gnu mcu eclipse/risc-v embedded gcc/7.1.1-2-20170912-2255/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/../../../../riscv64-unknown-elf/bin/ld.exe: hello.elf(.text): relocation "iBlahblah+0x0 (type R_RISCV_HI20)" goes out of range
c:/program files/gnu mcu eclipse/risc-v embedded gcc/7.1.1-2-20170912-2255/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/../../../../riscv64-unknown-elf/bin/ld.exe: hello.o: file class ELFCLASS64 incompatible with ELFCLASS32
c:/program files/gnu mcu eclipse/risc-v embedded gcc/7.1.1-2-20170912-2255/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/../../../../riscv64-unknown-elf/bin/ld.exe: final link failed: File in wrong format
collect2.exe: error: ld returned 1 exit status

最大的问题是如何解决“ABI 与所选仿真的不兼容”?我们可以忽略有关重定位、退出等的其他问题,因为我更大的构建环境会处理这些问题(它可以为许多平台构建,但目前还不是 RISCV)。

【问题讨论】:

  • 您将 gcc 用于 riscv64 并希望它以 32 位模式编译。但是这个 gcc 会将 64 位模式的 c 运行时库添加到链接阶段(将 -v 选项添加到 gcc 以查看 gcc 添加的其他 crt 文件)这是错误的(32 位 elf 和 64 位 elf 对象无法链接一起)。您应该将 gcc 用于具有 64 位模式的 64 位目标;和 gcc 用于具有 32 位模式的 32 位目标(实际上您需要 32 位 crt;它可能包含在您的 gcc 中,但它使用了错误的版本)
  • @osgx gnu-mcu-eclipse.github.io/toolchain/riscv/install 的文档指出 riscv64-unknown-elf-gcc.exe 可以针对 32 位和 64 位。如何提示它执行 32 位库?
  • 使用 riscv32-unknown-elf-gcc.exe 将使用正确的 32 位 CRT 路径。比较 riscv64-unknown-elf-gcc.exe -v ...riscv32-unknown-elf-gcc.exe -v ... 的输出以使用 CRT 找到确切的目录。
  • 您的 gcc 声明支持 multilib 以便能够从 riscv64-gcc:gnu-mcu-eclipse.github.io/toolchain/riscv/#multiple-libraries 搜索 32 位 crt 库,但出现问题,它没有选择正确的 multilib 目录。检查实际的gcc/config/riscv/t-elf-multilib github.com/riscv/riscv-gcc/blob/… 会很有用。 gnu-mcu-eclipse.github.io/blog/2017/09/13/… 说“支持 March/mabi 的组合......并非所有组合都有库。”
  • @osgx 我认为该工具有轻微损坏。如果我通过 riscv-unknown-elf-ld.exe 使用适当的-melf32lriscv 调用它就没有问题。我认为 gcc.exe 没有将正确的东西传递给 ld.exe 来告诉它“这是带有 rv32imac 指令集的 ilp32 abi”

标签: gcc cross-compiling toolchain riscv


【解决方案1】:

riscv64-unknown-elf-gcc.exe -c hello.c -o hello -march=rv32imac -mabi=ilp32 -Os

这部分是错误的。你的 gcc tolchain 文档说 https://gnu-mcu-eclipse.github.io/toolchain/riscv/

riscv64-unknown-elf-gcc 与 riscv32-unknown-elf-gcc 由于支持许多架构和系统,GCC 建议在二进制文件前加上一个唯一的元组:

<arch>-<vendor>-<os>-<libc/abi>-

裸机工具链的当前 RISC-V 前缀是 riscv64-unknown-elf- 和 riscv32-unknown-elf-。

好吧,不要被这些不幸的名字所迷惑。附加到体系结构的 64 或 32 ... 这并不意味着编译器生成 64 位或 32 位 RISC-V 二进制文件。实际上,编译器基于 -march 和 -mabi 生成 32/64 位二进制文​​件。唯一的区别是默认值,即在没有在命令行上显式设置 -march 和 -mabi 的情况下调用编译器。

尝试使用 riscv32-unknown-elf-gcc.exe 为 32 位 riscv 平台编译程序(arch & abi 的名称中有 r3232 部分),它应该使用正确的 32 位CRT 文件。

当 riscv64 将搜索 32 位库(https://gnu-mcu-eclipse.github.io/toolchain/riscv/#multiple-librarieshttps://gnu-mcu-eclipse.github.io/blog/2017/09/13/riscv-none-gcc-v7-1-1-2-20170912-released/https://gcc.gnu.org/onlinedocs/gccint/Target-Fragment.htmlMULTILIB_OPTIONS)时,有一些对 multilib 的支持,但出现了问题。请发布gcc -v .... -o your_program.bin riscv32 编译器、riscv64 编译器和几个 March/mabi 组合的结果。

【讨论】:

  • 我在任何地方都找不到预构建的 riscv32-unknown-elf 工具链(而且真的没有时间自己去构建它)。这些库在标准安装中,似乎 gcc.exe 没有正确调用 ld.exe……或者我没有说正确的魔法词来让它正确调用 ld.exe
猜你喜欢
  • 2021-11-26
  • 2015-06-27
  • 2018-01-07
  • 2015-11-28
  • 2016-06-30
  • 2011-04-09
  • 1970-01-01
相关资源
最近更新 更多