RISC-V: Fix the asm code for large code model

Message ID 20250401140421.537428-1-kito.cheng@sifive.com
State New
Headers
Series RISC-V: Fix the asm code for large code model |

Commit Message

Kito Cheng April 1, 2025, 2:04 p.m. UTC
  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

Jeff Johnston April 1, 2025, 8:10 p.m. UTC | #1
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
>
>
  

Patch

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: