对 'malloc' 等的未定义引用

Undefined reference to 'malloc' and more

当我尝试编译 dhrystone 基准测试时,它显示以下错误:

xilinx@pynq:~/dhrystone$ riscv32-unknown-elf-gcc -Os -ffreestanding -nostdlib -o out.elf -Wl,-Bstatic,-T,picorv32.ld dhry_1.o dhry_2.o init.o -lgcc -march=rv32im

/opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/bin/ld: dhry_1.o: in function `Proc_1':
dhry_1.c:(.text+0x84): undefined reference to `memcpy'
/opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/bin/ld: dhry_1.c:(.text+0x100): undefined reference to `memcpy'
/opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/bin/ld: dhry_1.o: in function `main':
dhry_1.c:(.text.startup+0x3c): undefined reference to `malloc'
/opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/bin/ld: dhry_1.c:(.text.startup+0x4c): undefined reference to `malloc'
/opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/bin/ld: dhry_1.c:(.text.startup+0x84): undefined reference to `strcpy'
/opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/bin/ld: dhry_1.c:(.text.startup+0x98): undefined reference to `strcpy'
/opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/bin/ld: dhry_1.c:(.text.startup+0xb8): undefined reference to `time'
/opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/bin/ld: dhry_1.c:(.text.startup+0xf0): undefined reference to `strcpy'
/opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/bin/ld: dhry_1.c:(.text.startup+0x184): undefined reference to `time'
/opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/bin/ld: dhry_1.c:(.text.startup+0x254): undefined reference to `strcpy'
/opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/bin/ld: dhry_2.o: in function `.L15':
dhry_2.c:(.text+0x118): undefined reference to `strcmp'
collect2: error: ld returned 1 exit status

似乎所有缺失的功能都来自stdih.h。但是我不知道怎么解决。

这是我用来编译基准测试的命令。

riscv32-unknown-elf-gcc -c -Qn -DSTKPTR=32768 -march=rv32im -o init.o -Os --std=c99 init.S 
riscv32-unknown-elf-gcc -c -Qn -march=rv32im -o dhry_1.o -Os --std=c99 dhry_1.c
riscv32-unknown-elf-gcc -c -Qn -march=rv32im -o dhry_2.o -Os --std=c99 dhry_2.c

riscv32-unknown-elf-gcc -Os -ffreestanding -nostdlib -o out.elf -Wl,-Bstatic,-T,picorv32.ld init.o dhry_1.o dhry_2.o -lgcc -march=rv32im
riscv32-unknown-elf-objcopy -O binary out.elf out.bin

谁能帮帮我。感谢您的帮助。

在@yflelion 的帮助下,我将第五行更改为以下内容,

riscv32-unknown-elf-gcc -Os -ffreestanding -nostdlib -o out.elf -Wl,-Bstatic,-T,picorv32.ld init.o dhry_1.o dhry_2.o -lgcc -lc -lgloss -march=rv32im

并显示以下错误,

/opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/bin/ld: /opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/lib/libgloss.a(sys_gettimeofday.o): in function `.L5':
sys_gettimeofday.c:(.text+0x48): undefined reference to `__errno'
/opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/bin/ld: /opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/lib/libgloss.a(sys_sbrk.o): in function `.L7':
sys_sbrk.c:(.text+0x84): undefined reference to `__errno'
collect2: error: ld returned 1 exit status

使用以下命令,

riscv32-unknown-elf-gcc -Os -ffreestanding -nostdlib -o out.elf -Wl,-Bstatic,-T,picorv32.ld init.o dhry_1.o dhry_2.o -lgcc -lc -march=rv32im

它显示以下错误,

/opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/bin/ld: /opt/riscv32im/lib/gcc/riscv32-unknown-elf/10.1.0/../../../../riscv32-unknown-elf/lib/libc.a(lib_a-sbrkr.o): in function `_sbrk_r':
sbrkr.c:(.text+0x20): undefined reference to `_sbrk'

当您使用 nostdlib 时,编译器在链接时不使用标准系统启动文件或库。
https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
您使用命令行链接的唯一库是 libgcc,但您使用的是 libc 中的函数。您需要添加 -lc 并且最有可能添加 -lgloss。小心循环依赖(--start-group--end-group)。
您可以添加 -v 选项并使用默认选项编译一个极简示例,以查看默认情况下它是如何完成的。
如果没有理由不能默认使用 libc 和 libgloss,最好去掉 nostdlib 选项。

要编译您的示例,请尝试:

riscv32-unknown-elf-gcc -Os -ffreestanding -nostdlib -o out.elf -Wl,-Bstatic,-T,picorv32.ld init.o dhry_1.o dhry_2.o -lgcc -lc -lgloss -lc -march=rv32im

但是避免循环依赖的最佳解决方案是:

riscv32-unknown-elf-gcc -Os -ffreestanding -nostdlib -o out.elf -Wl,-Bstatic,-T,picorv32.ld init.o dhry_1.o dhry_2.o -lgcc --start-group -lc -lgloss --end-group -lgcc -march=rv32im