I am trying to build a simple hello world program I have written for the riscv64 architecture and run it with qemu. That works as long as I compile specific files as .c files in the main gcc invocation. The specific error is:
main.o: in function `main':
main.c:(.text+0x8): relocation truncated to fit: R_RISCV_HI20 against `hello'
test.o: in function `test':
test.c:(.text+0x8): relocation truncated to fit: R_RISCV_HI20 against `hello'
collect2.exe: error: ld returned 1 exit status
Basically if I compile with:
gcc -march=rv64gc -mabi=lp64d -nostartfiles --machine-cmodel=medany -T linker.ld crt0.o main.c putchar.a test.c -o main.elf
everything works fine. But if I compile main.c and test.c first with
gcc -march=rv64gc -mabi=lp64d -nostartfiles --machine-cmodel=medany -T linker.ld -c main.c test.c
and then
gcc -march=rv64gc -mabi=lp64d -nostartfiles --machine-cmodel=medany -T linker.ld crt0.o main.o putchar.a test.o -o main.elf
I get the relocation errors. I wonder what is the reason for that? I tried compiling the object files as position independent code but with no success. It is worth noting that with the former way with .c files I had the relocation problem before I used the -machine-cmodel=medany option
The code:
main.c:
#include "putchar.h"
// #include "test.h"
static const char *hello = "Hello, World!\n";
void main(){
// test();
putchars(hello);
putchars("Hello, World!\n");
while(1);
}
test.c
#include "putchar.h"
static const char *hello = "Hello, World!\n";
void test(){
putchars(hello);
}
putchar.c
volatile char * const UART = (char*)0x10000000;
void putchars(char *str){
for(char *i = str; *i != 0; i++) *UART = *i;
}
linker.ld
/* Template linker definition script for riscv64 virtIO machine */
OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv")
OUTPUT_ARCH(riscv)
/* Define the entry point */
ENTRY(_start)
/* Define the memory regions */
MEMORY
{
/* The flash memory region */
FLASH (rwx) : ORIGIN = 0x20000000, LENGTH = 0x2000000
/* The RAM memory region */
RAM (rw) : ORIGIN = 0x80000000, LENGTH = 0x1000000
}
/* Define the output sections */
SECTIONS
{
/* The text section contains the executable code */
.text :
{
/* Align to page boundary */
. = ALIGN(0x1000);
/* Record the start address of this section */
_stext = .;
/* Include all input files with .text sections */
*(.text)
/* Record the end address of this section */
_etext = .;
/* Align to page boundary */
. = ALIGN(0x1000);
} > FLASH
/* The rodata section contains read-only data */
.rodata :
{
/* Align to page boundary */
. = ALIGN(0x1000);
/* Record the start address of this section */
_srodata = .;
/* Include all input files with .rodata sections */
*(.rodata)
*(.srodata)
/* Record the end address of this section */
_erodata = .;
/* Align to page boundary */
. = ALIGN(0x1000);
} > FLASH
/* The data section contains initialized data */
.data :
{
/* Align to page boundary */
. = ALIGN(0x1000);
/* Record the start address of this section */
_sdata = .;
/* Include all input files with .data sections */
*(.data)
*(.sdata)
/* Record the end address of this section */
_edata = .;
/* Align to page boundary */
. = ALIGN(0x1000);
} > RAM AT > FLASH
.fill :
{
FILL(0xFFFF);
. = ORIGIN(FLASH) + LENGTH(FLASH) - 1;
BYTE(0xAA);
} > FLASH
_sdata_load = LOADADDR(.data);
/* The bss section contains uninitialized data */
.bss (NOLOAD):
{
/* Align to page boundary */
. = ALIGN(0x1000);
/* Record the start address of this section */
_sbss = .;
/* Include all input files with .bss sections */
*(.bss)
/* Record the end address of this section */
_ebss = .;
/* Align to page boundary */
. = ALIGN(0x1000);
} > RAM
}
Relevant part of the Makefile
CC = riscv64-unknown-elf-gcc
AR = riscv64-unknown-elf-ar
*.o:
$(CC) -march=rv64gc -mabi=lp64d -nostartfiles --machine-cmodel=medany -misa-spec=20191213 -T linker.ld -c %.c
crt0.o: crt0.s
$(CC) -march=rv64gc -mabi=lp64d -nostartfiles --machine-cmodel=medany -misa-spec=20191213 -T linker.ld -c crt0.s
putchar.a: putchar.o
$(AR) r putchar.a putchar.o
main.elf: putchar.a main.o crt0.o test.o
$(CC) -march=rv64gc -mabi=lp64d -nostartfiles --machine-cmodel=medany -misa-spec=20191213 -T linker.ld crt0.o main.o putchar.a test.o -o main.elf
You should compile
main.candtest.cfirst withbefore linking, so
main.oandtest.ocontain relocation entries thatldgets to fill during linking.