GCC 7.1.1 编译 RISCV (链接) 失败,ABI 不兼容。

3
我在最新的RISCV GCC上遇到了编译和链接基础问题,我的操作系统是Windows 7 64位。我已经安装了工具集7.1.1-2-20170912-2255,该工具集可从https://github.com/gnu-mcu-eclipse/riscv-none-gcc/releases/获取。我的开发平台是Windows 7 64位,没有安装cygwin。下面是需要翻译的程序内容:

Program:

#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与所选仿真的ABI不兼容”的问题?我们可以忽略关于重定位、退出等方面的其他问题,因为我的更大的构建环境会处理这些问题(它可以在许多平台上构建,目前只是不支持RISCV)。

你使用gcc来编译riscv64,并希望以32位模式进行编译。但是这个gcc会在链接阶段添加64位模式的c运行时库(使用-v选项可以查看gcc添加的额外crt文件),这是错误的(32位elf和64位elf对象不能链接在一起)。你应该使用64位目标的gcc来进行64位模式的编译;而使用32位目标的gcc来进行32位模式的编译(实际上你需要32位的crt,它可能已经包含在你的gcc中,但是使用了错误的版本)。 - undefined
@osgx 在 https://gnu-mcu-eclipse.github.io/toolchain/riscv/install/ 的文档中提到 riscv64-unknown-elf-gcc.exe 可以同时支持32位和64位。我应该如何提示它使用32位库呢? - undefined
使用riscv32-unknown-elf-gcc.exe,它将使用正确的路径来定位32位CRT。比较riscv64-unknown-elf-gcc.exe -v ...riscv32-unknown-elf-gcc.exe -v ...的输出,以找到具体的CRT目录。 - undefined
您的gcc声明支持multilib,可以从riscv64-gcc中搜索32位crt库:https://gnu-mcu-eclipse.github.io/toolchain/riscv/#multiple-libraries 但是出现了一些问题,它没有选择正确的multilib目录。检查实际的 gcc/config/riscv/t-elf-multilib 可能会有帮助 https://github.com/riscv/riscv-gcc/blob/c95cdcae21de8dbb8a8ceb9c58b5f9560f0628ff/gcc/config/riscv/t-elf-multilib。https://gnu-mcu-eclipse.github.io/blog/2017/09/13/riscv-none-gcc-v7-1-1-2-20170912-released/ 提到,“march/mabi的组合是受支持的..并非所有组合都有库”。 - undefined
2
@osgx 我认为该工具存在轻微故障。如果我使用适当的 -melf32lriscv 通过 riscv-unknown-elf-ld.exe 进行调用,就不会出现这个问题。我认为 gcc.exe 没有将正确的信息传递给 ld.exe,告诉它“这是带有 rv32imac 指令集的 ilp32 abi”。 - undefined
请Russ,发布-v输出和hello.o。 - undefined
1个回答

0
riscv64-unknown-elf-gcc.exe -c hello.c -o hello -march=rv32imac -mabi=ilp32 -Os
这部分是错误的。你的gcc工具链文档说https://gnu-mcu-eclipse.github.io/toolchain/riscv/

riscv64-unknown-elf-gcc vs riscv32-unknown-elf-gcc With lots of architectures and systems supported, GCC recommends prefixing the binaries with a unique tuple:

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

The current RISC-V prefixes for the bare metal toolchains are riscv64-unknown-elf- and riscv32-unknown-elf-.

Well, don’t be confused by this unfortunate names. The 64 or 32 attached to the architecture ... It does not mean either that the compiler produces 64-bits or 32-bits RISC-V binaries. Actually, the compilers produce both 32/64-bits binaries, based on -march and -mabi. The only difference are defaults, when the compiler are invoked without the -march and -mabi explicitly set on the command line.

尝试使用riscv32-unknown-elf-gcc.exe编译32位riscv平台上的程序(其arch和abi名称中包含“r32”和“32”部分),它应该使用正确的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.html MULTILIB_OPTIONS)时,有一些对multilib的支持,但是出现了一些问题。请发布riscv32编译器、riscv64编译器和几个march/mabi组合的gcc -v .... -o your_program.bin结果。


我找不到任何现成的riscv32-unknown-elf工具链(而且真的没有时间去自己构建它)。标准安装中有库,只是gcc.exe似乎没有正确调用ld.exe...或者我没有说出正确的咒语来使其正确调用ld.exe。 - undefined

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