Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bare-metal C Program compilation fails #5

Open
apivovarov opened this issue Jan 4, 2021 · 3 comments
Open

Bare-metal C Program compilation fails #5

apivovarov opened this issue Jan 4, 2021 · 3 comments

Comments

@apivovarov
Copy link

apivovarov commented Jan 4, 2021

I'm trying to follow the instructions described in Bare-metal C Program in README

I got the following errors (OS: Ubuntu 20.10 x86_64)

root@292c6ad9bfc1:~/workplace/riscv# riscv64-unknown-elf-gcc -S -nostdlib foo.c
root@292c6ad9bfc1:~/workplace/riscv# riscv64-unknown-elf-gcc -Wl,-Ttext=0x80000000 -nostdlib -o foo foo.s
/opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000080000000
/tmp/ccfhLgt3.o: in function `main':
foo.c:(.text+0x8): relocation truncated to fit: R_RISCV_HI20 against `.LC0'
collect2: error: ld returned 1 exit status

foo.c

#include <stdio.h>

int main() {
  puts("Hello World!");
  return 0;
}

foo.s

	.file	"foo.c"
	.option nopic
	.attribute arch, "rv64i2p0_m2p0_a2p0_f2p0_d2p0_c2p0"
	.attribute unaligned_access, 0
	.attribute stack_align, 16
	.text
	.section	.rodata
	.align	3
.LC0:
	.string	"Hello World!"
	.text
	.align	1
	.globl	main
	.type	main, @function
main:
	addi	sp,sp,-16
	sd	ra,8(sp)
	sd	s0,0(sp)
	addi	s0,sp,16
	lui	a5,%hi(.LC0)
	addi	a0,a5,%lo(.LC0)
	call	puts
	li	a5,0
	mv	a0,a5
	ld	ra,8(sp)
	ld	s0,0(sp)
	addi	sp,sp,16
	jr	ra
	.size	main, .-main
	.ident	"GCC: (GNU) 10.2.0"
@d0iasm
Copy link
Owner

d0iasm commented Jan 5, 2021

Thank you for trying to use this emulator!

You can't use #include <stdio.h> in foo.c because we use -nostdlib flag at riscv64-unknown-elf-gcc, which means we can't depend on the standard library.

bin/raw/simple.c is one of the simplest sample C code. We can compile it with the instructions described in Bare-metal C Program in README. Once simple.c is executed in this emulator, we'll see the value of 42 at x10 (a0) register. The x10 register stores a return value of the main function.

@apivovarov
Copy link
Author

apivovarov commented Jan 5, 2021

I was able to generate simple.text myself, but the content and size of my file is different from the official simple.text

I did the following to generate simple.text (BTW, I got ld warning)

$ riscv64-unknown-elf-gcc -S -nostdlib simple.c 
$ riscv64-unknown-elf-gcc -Wl,-Ttext=0x80000000 -nostdlib -o simple simple.s
/opt/riscv/lib/gcc/riscv64-unknown-elf/10.2.0/../../../../riscv64-unknown-elf/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000080000000
$ riscv64-unknown-elf-objcopy -O binary simple simple.text

The content of my simple.text is hexdump -C simple.text

00000000  41 11 22 e4 00 08 93 07  a0 02 3e 85 22 64 41 01  |A.".......>."dA.|
00000010  82 80                                             |..|
00000012

Official simple.text has different content and size

00000000  13 01 01 ff 23 34 81 00  13 04 01 01 93 07 a0 02  |....#4..........|
00000010  13 85 07 00 03 34 81 00  13 01 01 01 67 80 00 00  |.....4......g...|
00000020

As a result if I run my simple.text in rvemu.app it does not set x10= 0x2a

What I'm doing wrong?

My OS is Ubuntu 20.10.

riscv64-unknown-elf-gcc (GCC) 10.2.0

my simple.c is the same as the official simple.c

int main() {
    return 42;
}

my simple.s is almost the same as the official simple.s

	.file	"simple.c"
	.option nopic
	.attribute arch, "rv64i2p0_m2p0_a2p0_f2p0_d2p0_c2p0"
	.attribute unaligned_access, 0
	.attribute stack_align, 16
	.text
	.align	1
	.globl	main
	.type	main, @function
main:
	addi	sp,sp,-16
	sd	s0,8(sp)
	addi	s0,sp,16
	li	a5,42
	mv	a0,a5
	ld	s0,8(sp)
	addi	sp,sp,16
	jr	ra
	.size	main, .-main
	.ident	"GCC: (GNU) 10.2.0"

@d0iasm
Copy link
Owner

d0iasm commented Jan 23, 2021

Sorry for my late response. I've been busy these days.

I think your compiler is using compressed instructions (RV64C). Each length of compressed instructions is 2 bytes and the original simple.text binary is composed of non-compressed instructions, each length of them is 4 bytes. That's why the length of your binary differs.

The app rvemu.app didn't support compressed instructions so that you coludn't see the result x10= 0x2a. It, however, is updated to support compressed instructions now. I think you can see x10= 0x2a with your binary.

FYI: If you want to compile code into RV64G (without compressed) instructions, you need to compile RISC-V toolchain with --with-arch=rv64g option.

$ git clone --recursive [email protected]:riscv/riscv-gnu-toolchain.git
$ cd riscv-gnu-toolchain
$ ./configure --prefix=/opt/riscv --with-arch=rv64g
$ make
$ make linux

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants