[PATCH] RISC-V: Fix the asm code for large code model
Kito Cheng
kito.cheng@sifive.com
Tue Apr 1 14:04:21 GMT 2025
The large code model assume the data may far away from the code, so we
must put the address of the target data wihin the `.text` section,
normally we will just put within the function or nearby the function to
prevent it out-of-range.
Report from riscv-gnu-toolchain:
https://github.com/riscv-collab/riscv-gnu-toolchain/issues/1699
Verified with riscv-gnu-toolchain with rv64gc.
---
libgloss/riscv/crt0.S | 39 ++++++++++++++++++++++++++++++
newlib/libc/machine/riscv/strcmp.S | 9 ++++++-
2 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/libgloss/riscv/crt0.S b/libgloss/riscv/crt0.S
index 54443e412..aa5ac3684 100644
--- a/libgloss/riscv/crt0.S
+++ b/libgloss/riscv/crt0.S
@@ -27,8 +27,13 @@ _start:
.option pop
/* Initialize jvt CSR (reg addr: 0x0017) */
+#ifndef __riscv_cmodel_large
.weak __jvt_base$
lla a0, __jvt_base$
+#else
+ la a0, .Laddr_jvt_base
+ ld a0, 0(a0)
+#endif
beqz a0, .Ljvt_init_end
.option push
.option norelax
@@ -38,21 +43,38 @@ _start:
.Ljvt_init_end:
# Clear the bss segment
+#ifndef __riscv_cmodel_large
la a0, __bss_start
la a2, _end
+#else
+ la a0, .Laddr_bss_start
+ ld a0, 0(a0)
+ la a2, .Laddr_end
+ ld a2, 0(a2)
+#endif
sub a2, a2, a0
li a1, 0
call memset
#ifdef _LITE_EXIT
# Make reference to atexit weak to avoid unconditionally pulling in
# support code. Refer to comments in __atexit.c for more details.
+#ifndef __riscv_cmodel_large
.weak atexit
la a0, atexit
+#else
+ la a0, .Laddr_atexit
+ ld a0, 0(a0)
+#endif
beqz a0, .Lweak_atexit
.weak __libc_fini_array
#endif
+#ifndef __riscv_cmodel_large
la a0, __libc_fini_array # Register global termination functions
+#else
+ la a0, .Laddr_libc_fini_array
+ ld a0, 0(a0)
+#endif
call atexit # to be called upon exit
#ifdef _LITE_EXIT
.Lweak_atexit:
@@ -66,4 +88,21 @@ _start:
add a2, a2, a1 # a2 = envp
call main
tail exit
+#ifdef __riscv_cmodel_large
+.Laddr_gp:
+ .dword __global_pointer$
+.Laddr_jvt_base:
+ .weak __jvt_base$
+ .dword __jvt_base$
+.Laddr_bss_start:
+ .dword __bss_start
+.Laddr_end:
+ .dword _end
+.Laddr_atexit:
+ .weak atexit
+ .dword atexit
+.Laddr_libc_fini_array:
+ .weak __libc_fini_array
+ .dword __libc_fini_array
+#endif
.size _start, .-_start
diff --git a/newlib/libc/machine/riscv/strcmp.S b/newlib/libc/machine/riscv/strcmp.S
index 12c39db94..cc29b7b8b 100644
--- a/newlib/libc/machine/riscv/strcmp.S
+++ b/newlib/libc/machine/riscv/strcmp.S
@@ -188,9 +188,16 @@ strcmp:
foundnull 1 3
foundnull 2 3
#endif
+#ifdef __riscv_cmodel_large
+ # Put the data within the funciton for large code model to prevent
+ # the data put too far.
+.align 3
+mask:
+.dword 0x7f7f7f7f7f7f7f7f
+#endif
.size strcmp, .-strcmp
-#if SZREG == 8
+#if SZREG == 8 && !defined(__riscv_cmodel_large)
.section .srodata.cst8,"aM",@progbits,8
.align 3
mask:
--
2.34.1
More information about the Newlib
mailing list