RISC-V: Fix the asm code for large code model
Commit Message
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(-)
Comments
Patch merged. Thanks.
-- Jeff J.
On Tue, Apr 1, 2025 at 10:11 AM Kito Cheng <kito.cheng@sifive.com> wrote:
> 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
>
>
@@ -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
@@ -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: