Link failed using riscv clang for rv64imac arch

Hello,

I am using clang + newlib + libgcc to compile and link simple helloworld, but got the following errors, did anyone meet with this issue before.

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-mprec.o):(function _Balloc: .text._Balloc+0x1e): relocation R_RISCV_HI20 out of range: 589825 is not in [-524288, 524287]; references .LC0
>>> referenced by mprec.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-mprec.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-nano-vfprintf_float.o):(function _printf_float: .text._printf_float+0x60): relocation R_RISCV_HI20 out of range: 589824 is not in [-524288, 524287]; references .LC4
>>> referenced by nano-vfprintf_float.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-nano-vfprintf_float.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-mprec.o):(function __pow5mult: .text.__pow5mult+0x1a): relocation R_RISCV_HI20 out of range: 589825 is not in [-524288, 524287]; references p05.0
>>> referenced by mprec.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-mprec.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-nano-freer.o):(function _free_r: .text._free_r+0x1c): relocation R_RISCV_HI20 out of range: 589825 is not in [-524288, 524287]; references __malloc_free_list
>>> referenced by nano-mallocr.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-nano-mallocr.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-__atexit.o):(function __register_exitproc: .text.__register_exitproc+0x0): relocation R_RISCV_HI20 out of range: 589825 is not in [-524288, 524287]; references _global_atexit
>>> referenced by __atexit.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-__call_atexit.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-mprec.o):(function __multiply: .text.__multiply+0x3a): relocation R_RISCV_HI20 out of range: 589825 is not in [-524288, 524287]; references .LC2
>>> referenced by mprec.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-mprec.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-findfp.o):(function __sinit: .text.__sinit+0x6): relocation R_RISCV_HI20 out of range: 524293 is not in [-524288, 524287]; references _cleanup_r
>>> referenced by findfp.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-findfp.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-wbuf.o):(function __swbuf_r: .text.__swbuf_r+0x1c): relocation R_RISCV_HI20 out of range: 589825 is not in [-524288, 524287]; references __sf_fake_stdin
>>> referenced by wbuf.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-findfp.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-makebuf.o):(function __smakebuf_r: .text.__smakebuf_r+0x5e): relocation R_RISCV_HI20 out of range: 524293 is not in [-524288, 524287]; references _cleanup_r
>>> referenced by makebuf.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-findfp.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-mprec.o):(function __lshift: .text.__lshift+0x40): relocation R_RISCV_HI20 out of range: 589825 is not in [-524288, 524287]; references .LC2
>>> referenced by mprec.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-mprec.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-mprec.o):(function _Balloc: .text._Balloc+0x22): relocation R_RISCV_HI20 out of range: 589825 is not in [-524288, 524287]; references .LC1
>>> referenced by mprec.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-mprec.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-dtoa.o):(function _dtoa_r: .text._dtoa_r+0x3e): relocation R_RISCV_HI20 out of range: 589825 is not in [-524288, 524287]; references .LC3
>>> referenced by dtoa.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-dtoa.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-mprec.o):(function __i2b: .text.__i2b+0x10): relocation R_RISCV_HI20 out of range: 589825 is not in [-524288, 524287]; references .LC2
>>> referenced by mprec.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-mprec.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-wbuf.o):(function __swbuf_r: .text.__swbuf_r+0x56): relocation R_RISCV_HI20 out of range: 589825 is not in [-524288, 524287]; references __sf_fake_stdout
>>> referenced by wbuf.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-findfp.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-nano-mallocr.o):(function _malloc_r: .text._malloc_r+0x4a): relocation R_RISCV_HI20 out of range: 589825 is not in [-524288, 524287]; references __malloc_free_list
>>> referenced by nano-mallocr.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-nano-mallocr.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-mprec.o):(function __mdiff: .text.__mdiff+0x26): relocation R_RISCV_HI20 out of range: 589825 is not in [-524288, 524287]; references .LC2
>>> referenced by mprec.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-mprec.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-malloc.o):(function malloc: .text.malloc+0x0): relocation R_RISCV_HI20 out of range: 589824 is not in [-524288, 524287]; references _impure_ptr
>>> referenced by malloc.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-impure.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-fprintf.o):(function fprintf: .text.fprintf+0x4): relocation R_RISCV_HI20 out of range: 589824 is not in [-524288, 524287]; references _impure_ptr
>>> referenced by fprintf.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-impure.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-nano-mallocr.o):(function _malloc_r: .text._malloc_r+0x56): relocation R_RISCV_HI20 out of range: 589825 is not in [-524288, 524287]; references __malloc_sbrk_start
>>> referenced by nano-mallocr.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-nano-mallocr.o)

ld.lld: error: rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-assert.o):(function __assert_func: .text.__assert_func+0x0): relocation R_RISCV_HI20 out of range: 589824 is not in [-524288, 524287]; references _impure_ptr
>>> referenced by assert.c
>>> defined in rvgnutoolchainv6/bin/../lib/gcc/riscv64-unknown-elf/12.2.0/../../../../riscv64-unknown-elf/lib/rv64imac/lp64/libc_nano.a(lib_a-impure.o)

ld.lld: error: too many errors emitted, stopping now (use --error-limit=0 to see all errors)

I tried to turn off link relax, -mno-relax, but it still not work.

The newlibc + libgcc are generated via riscv-gnu-toolchain project.

Thanks

Hello,

Those errors mean the linker is unable to put the symbol location in the 20bits available, because it’s too far away.

I would try and compile with -mcmodel=medany, which should tell the compiler to use auipc/jalr pair when jumping, which gives you a larger range of ± 2GB

Thanks, I am compiling with medany already, and it still show issue below.

Here is the link options I used.

clang -Ofast  -g -fno-common -mno-relax -march=rv64imac -mabi=lp64 -mcmodel=medany   -ffunction-sections -fdata-sections   -fuse-ld=lld gcc_ilm.ld -nostartfiles   -Wl,--gc-sections -Wl,--check-sections -u _printf_float  -Wl,--start-group -lc_nano -Wl,--end-group

But the libraries you’re linking in weren’t. You need to either recompile them with -mcmodel=medany or change what address you link everything at to be within the lower (or upper) 2GiB.

Thanks for the information, I check the configure script riscv-gnu-toolchain/configure.ac at master · riscv-collab/riscv-gnu-toolchain · GitHub, indeed it use medlow by default, I need to configure to medany, I will take a try to recompile the library.

Thanks

Thanks. It works now with libraries rebuilt using medany.

Question:: Does LLVM have a model where the target address is bigger than ±4GB ???
{Where target may be from a CALL, JMP, or appropriate to a LD, or ST}

The address can be any value, so long as it is within 2 GiB of the current one.

There is no large code model specified in the ABI that allows for more than a 2 GiB relative offset.