[PATCH v2 04/14] riscv: Adjust assembly routines to support landing pad

Jesse Huang jesse.huang@sifive.com
Wed Jul 23 07:23:00 GMT 2025


Do you have any concern that we are going to change something as about
unlabel scheme in the future?

2025年7月23日(水) 4:28 Deepak Gupta <debug@rivosinc.com>:

> On Fri, Jul 11, 2025 at 06:52:45AM -0700, Jesse Huang wrote:
> >Landing pads, instructions for setting the label value as well as
> >alignment directives are inserted at where they should be.
> >
> >Frame offsets for floating point registers in _dl_runtime_resolve
> >are also adjusted because now t2 has to be saved onto the stack.
> >
> >Co-authored-by: Hau Hsu <hau.hsu@sifive.com>
> >Co-authored-by: Kito Cheng <kito.cheng@sifive.com>
> >---
> > sysdeps/riscv/__longjmp.S                    |  1 +
> > sysdeps/riscv/crti.S                         |  4 ++
> > sysdeps/riscv/crtn.S                         |  4 ++
> > sysdeps/riscv/dl-machine.h                   |  8 +++
> > sysdeps/riscv/dl-trampoline.S                | 61 +++++++++++------
> > sysdeps/riscv/multiarch/memcpy_noalignment.S |  4 ++
> > sysdeps/riscv/setjmp.S                       |  3 +
> > sysdeps/riscv/start.S                        | 10 +++
> > sysdeps/unix/sysv/linux/riscv/clone.S        |  2 +
> > sysdeps/unix/sysv/linux/riscv/sysdep.S       |  1 +
> > sysdeps/unix/sysv/linux/riscv/sysdep.h       | 71 ++++++++++++++++++++
> > sysdeps/unix/sysv/linux/riscv/vfork.S        |  1 +
> > 12 files changed, 150 insertions(+), 20 deletions(-)
> > create mode 100644 sysdeps/riscv/crti.S
> > create mode 100644 sysdeps/riscv/crtn.S
> >
> >diff --git a/sysdeps/riscv/__longjmp.S b/sysdeps/riscv/__longjmp.S
> >index 7228b457a6..47ff3aa09e 100644
> >--- a/sysdeps/riscv/__longjmp.S
> >+++ b/sysdeps/riscv/__longjmp.S
> >@@ -20,6 +20,7 @@
> > #include <sys/asm.h>
> >
> > ENTRY (__longjmp)
> >+      LPAD
> >       REG_L ra,  0*SZREG(a0)
> >       REG_L s0,  1*SZREG(a0)
> >       REG_L s1,  2*SZREG(a0)
> >diff --git a/sysdeps/riscv/crti.S b/sysdeps/riscv/crti.S
> >new file mode 100644
> >index 0000000000..fb1097c5ca
> >--- /dev/null
> >+++ b/sysdeps/riscv/crti.S
> >@@ -0,0 +1,4 @@
> >+/* crti.S is empty because .init_array/.fini_array are used exclusively.
> >+   Include sysdep.h to define gnu property if necessary. */
> >+
> >+#include <sysdep.h>
> >diff --git a/sysdeps/riscv/crtn.S b/sysdeps/riscv/crtn.S
> >new file mode 100644
> >index 0000000000..b2e7cb692e
> >--- /dev/null
> >+++ b/sysdeps/riscv/crtn.S
> >@@ -0,0 +1,4 @@
> >+/* crtn.S is empty because .init_array/.fini_array are used exclusively.
> >+   Include sysdep.h to define gnu property if necessary. */
> >+
> >+#include <sysdep.h>
> >diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h
> >index dcc3e0883b..76f43a242b 100644
> >--- a/sysdeps/riscv/dl-machine.h
> >+++ b/sysdeps/riscv/dl-machine.h
> >@@ -28,6 +28,13 @@
> > #include <dl-irel.h>
> > #include <dl-static-tls.h>
> > #include <dl-machine-rel.h>
> >+/* This is a marker to remind us to add real expansion to setup the label
> >+   for the function signature label scheme in the future  */
> >+#ifdef __riscv_landing_pad_unlabeled
> >+# define SET_LPAD
> >+#else
> >+# define SET_LPAD
> >+#endif
> >
> > #ifndef _RTLD_PROLOGUE
> > # define _RTLD_PROLOGUE(entry)
>       \
> >@@ -126,6 +133,7 @@ elf_machine_dynamic (void)
> >       # Pass our finalizer function to _start.\n\
> >       lla a0, _dl_fini\n\
> >       # Jump to the user entry point.\n\
> >+        " STRINGXV (SET_LPAD) "\n\
> >       jr s0\n\
> >       " _RTLD_EPILOGUE (ENTRY_POINT) \
> >         _RTLD_EPILOGUE (_dl_start_user) "\
> >diff --git a/sysdeps/riscv/dl-trampoline.S b/sysdeps/riscv/dl-trampoline.S
> >index 93d04af326..2b25f64a3b 100644
> >--- a/sysdeps/riscv/dl-trampoline.S
> >+++ b/sysdeps/riscv/dl-trampoline.S
> >@@ -25,13 +25,27 @@
> > /* Assembler veneer called from the PLT header code for lazy loading.
> >    The PLT header passes its own args in t0-t2.  */
> >
> >-#ifdef __riscv_float_abi_soft
> >-# define FRAME_SIZE (-((-10 * SZREG) & ALMASK))
> >-#else
> >-# define FRAME_SIZE (-((-10 * SZREG - 8 * SZFREG) & ALMASK))
> >+#ifdef __riscv_landing_pad
> >+
> >+# ifdef __riscv_float_abi_soft
> >+#  define FRAME_SIZE (-((-11 * SZREG) & ALMASK))
> >+# else
> >+#  define FRAME_SIZE (-((-11 * SZREG - 8 * SZFREG) & ALMASK))
> >+#  define FREG_BASE_OFFSET (11*SZREG)
> >+# endif
> >+
> >+# else
> >+
> >+# ifdef __riscv_float_abi_soft
> >+#  define FRAME_SIZE (-((-10 * SZREG) & ALMASK))
> >+# else
> >+#  define FRAME_SIZE (-((-10 * SZREG - 8 * SZFREG) & ALMASK))
> >+#  define FREG_BASE_OFFSET (10*SZREG)
> >+# endif
> > #endif
> >
> > ENTRY (_dl_runtime_resolve)
> >+  LPAD
> >   # Save arguments to stack.
> >   addi sp, sp, -FRAME_SIZE
> >   REG_S ra, 9*SZREG(sp)
> >@@ -43,16 +57,19 @@ ENTRY (_dl_runtime_resolve)
> >   REG_S a5, 6*SZREG(sp)
> >   REG_S a6, 7*SZREG(sp)
> >   REG_S a7, 8*SZREG(sp)
> >+#ifdef __riscv_landing_pad
> >+  REG_S t2, 10*SZREG(sp)
> >+#endif
> >
> > #ifndef __riscv_float_abi_soft
> >-  FREG_S fa0, (10*SZREG + 0*SZFREG)(sp)
> >-  FREG_S fa1, (10*SZREG + 1*SZFREG)(sp)
> >-  FREG_S fa2, (10*SZREG + 2*SZFREG)(sp)
> >-  FREG_S fa3, (10*SZREG + 3*SZFREG)(sp)
> >-  FREG_S fa4, (10*SZREG + 4*SZFREG)(sp)
> >-  FREG_S fa5, (10*SZREG + 5*SZFREG)(sp)
> >-  FREG_S fa6, (10*SZREG + 6*SZFREG)(sp)
> >-  FREG_S fa7, (10*SZREG + 7*SZFREG)(sp)
> >+  FREG_S fa0, (FREG_BASE_OFFSET + 0*SZFREG)(sp)
> >+  FREG_S fa1, (FREG_BASE_OFFSET + 1*SZFREG)(sp)
> >+  FREG_S fa2, (FREG_BASE_OFFSET + 2*SZFREG)(sp)
> >+  FREG_S fa3, (FREG_BASE_OFFSET + 3*SZFREG)(sp)
> >+  FREG_S fa4, (FREG_BASE_OFFSET + 4*SZFREG)(sp)
> >+  FREG_S fa5, (FREG_BASE_OFFSET + 5*SZFREG)(sp)
> >+  FREG_S fa6, (FREG_BASE_OFFSET + 6*SZFREG)(sp)
> >+  FREG_S fa7, (FREG_BASE_OFFSET + 7*SZFREG)(sp)
> > #endif
> >
> >   # Update .got.plt and obtain runtime address of callee.
> >@@ -60,6 +77,7 @@ ENTRY (_dl_runtime_resolve)
> >   mv a0, t0       # link map
> >   add a1, a1, t1  # reloc offset (== thrice the .got.plt offset)
> >   la a2, _dl_fixup
> >+  SET_LPAD
> >   jalr a2
> >   mv t1, a0
> >
> >@@ -73,16 +91,19 @@ ENTRY (_dl_runtime_resolve)
> >   REG_L a5, 6*SZREG(sp)
> >   REG_L a6, 7*SZREG(sp)
> >   REG_L a7, 8*SZREG(sp)
> >+#ifdef __riscv_landing_pad
> >+  REG_L t2, 10*SZREG(sp)
> >+#endif
> >
> > #ifndef __riscv_float_abi_soft
> >-  FREG_L fa0, (10*SZREG + 0*SZFREG)(sp)
> >-  FREG_L fa1, (10*SZREG + 1*SZFREG)(sp)
> >-  FREG_L fa2, (10*SZREG + 2*SZFREG)(sp)
> >-  FREG_L fa3, (10*SZREG + 3*SZFREG)(sp)
> >-  FREG_L fa4, (10*SZREG + 4*SZFREG)(sp)
> >-  FREG_L fa5, (10*SZREG + 5*SZFREG)(sp)
> >-  FREG_L fa6, (10*SZREG + 6*SZFREG)(sp)
> >-  FREG_L fa7, (10*SZREG + 7*SZFREG)(sp)
> >+  FREG_L fa0, (FREG_BASE_OFFSET + 0*SZFREG)(sp)
> >+  FREG_L fa1, (FREG_BASE_OFFSET + 1*SZFREG)(sp)
> >+  FREG_L fa2, (FREG_BASE_OFFSET + 2*SZFREG)(sp)
> >+  FREG_L fa3, (FREG_BASE_OFFSET + 3*SZFREG)(sp)
> >+  FREG_L fa4, (FREG_BASE_OFFSET + 4*SZFREG)(sp)
> >+  FREG_L fa5, (FREG_BASE_OFFSET + 5*SZFREG)(sp)
> >+  FREG_L fa6, (FREG_BASE_OFFSET + 6*SZFREG)(sp)
> >+  FREG_L fa7, (FREG_BASE_OFFSET + 7*SZFREG)(sp)
> > #endif
> >
> >   addi sp, sp, FRAME_SIZE
> >diff --git a/sysdeps/riscv/multiarch/memcpy_noalignment.S
> b/sysdeps/riscv/multiarch/memcpy_noalignment.S
> >index dd135f4a4d..e97748e82b 100644
> >--- a/sysdeps/riscv/multiarch/memcpy_noalignment.S
> >+++ b/sysdeps/riscv/multiarch/memcpy_noalignment.S
> >@@ -34,7 +34,11 @@
> > #define BLOCK_SIZE (16 * SZREG)
> >
> >       .attribute unaligned_access, 1
> >+#ifdef __riscv_landing_pad
> >+        .align  2
> >+#endif
> > ENTRY (__memcpy_noalignment)
> >+        LPAD
> >       beq     a2, zero, L(ret)
> >
> >       /* if LEN < SZREG jump to tail handling.  */
> >diff --git a/sysdeps/riscv/setjmp.S b/sysdeps/riscv/setjmp.S
> >index 600ea84db6..df048cb544 100644
> >--- a/sysdeps/riscv/setjmp.S
> >+++ b/sysdeps/riscv/setjmp.S
> >@@ -20,14 +20,17 @@
> > #include <sys/asm.h>
> >
> > ENTRY (_setjmp)
> >+  LPAD
> >   li  a1, 0
> >   j   HIDDEN_JUMPTARGET (__sigsetjmp)
> > END (_setjmp)
> > ENTRY (setjmp)
> >+  LPAD
> >   li  a1, 1
> >   /* Fallthrough */
> > END (setjmp)
> > ENTRY (__sigsetjmp)
> >+      LPAD
> >       REG_S ra,  0*SZREG(a0)
> >       REG_S s0,  1*SZREG(a0)
> >       REG_S s1,  2*SZREG(a0)
> >diff --git a/sysdeps/riscv/start.S b/sysdeps/riscv/start.S
> >index 2db79c0ae6..ff083b13a4 100644
> >--- a/sysdeps/riscv/start.S
> >+++ b/sysdeps/riscv/start.S
> >@@ -47,12 +47,14 @@ ENTRY (ENTRY_POINT)
> >          .cfi_label to force starting the FDE.  */
> >       .cfi_label .Ldummy
> >       cfi_undefined (ra)
> >+      LPAD
> >       call  load_gp
> >       mv    a5, a0  /* rtld_fini.  */
> >       /* main may be in a shared library.  */
> > #if defined PIC && !defined SHARED
> >       /* Avoid relocation in static PIE since _start is called before it
> >          is relocated.  */
> >+      SET_LPAD
> >       lla   a0, __wrap_main
> > #else
> >       la   a0, main
> >@@ -69,7 +71,11 @@ ENTRY (ENTRY_POINT)
> > END (ENTRY_POINT)
> >
> > #if defined PIC && !defined SHARED
> >+#ifdef __riscv_landing_pad
> >+      .align 2
> >+#endif /* __riscv_landing_pad  */
> > __wrap_main:
> >+      LPAD
> >       tail  main@plt
> > #endif
> >
> >@@ -79,9 +85,13 @@ __wrap_main:
> >    needs to be initialized before calling __libc_start_main in that case.
> >    So we redundantly initialize it at the beginning of _start.  */
> >
> >+#ifdef __riscv_landing_pad
> >+      .align 2
> >+#endif /* __riscv_landing_pad  */
> > load_gp:
> > .option push
> > .option norelax
> >+      LPAD
> >       lla   gp, __global_pointer$
> > .option pop
> >       ret
> >diff --git a/sysdeps/unix/sysv/linux/riscv/clone.S
> b/sysdeps/unix/sysv/linux/riscv/clone.S
> >index 1362dd9c22..d6a0996ec8 100644
> >--- a/sysdeps/unix/sysv/linux/riscv/clone.S
> >+++ b/sysdeps/unix/sysv/linux/riscv/clone.S
> >@@ -31,6 +31,7 @@
> >
> >       .text
> > LEAF (__clone)
> >+      LPAD
> >
> >       /* Align stack to a 128-bit boundary as per RISC-V ABI.  */
> >       andi            a1,a1,ALMASK
> >@@ -82,6 +83,7 @@ L (thread_start):
> >       REG_L           a0,SZREG(sp)    /* Argument pointer.  */
> >
> >       /* Call the user's function.  */
> >+      SET_LPAD
> >       jalr            a1
> >
> >       /* Call exit with the function's return value.  */
> >diff --git a/sysdeps/unix/sysv/linux/riscv/sysdep.S
> b/sysdeps/unix/sysv/linux/riscv/sysdep.S
> >index b50671b9b7..e7ea424e45 100644
> >--- a/sysdeps/unix/sysv/linux/riscv/sysdep.S
> >+++ b/sysdeps/unix/sysv/linux/riscv/sysdep.S
> >@@ -23,6 +23,7 @@
> > #endif
> >
> > ENTRY (__syscall_error)
> >+      LPAD
> >       mv t0, ra
> >       /* Fall through to __syscall_set_errno.  */
> > END (__syscall_error)
> >diff --git a/sysdeps/unix/sysv/linux/riscv/sysdep.h
> b/sysdeps/unix/sysv/linux/riscv/sysdep.h
> >index ee015dfeb6..14a1f3a647 100644
> >--- a/sysdeps/unix/sysv/linux/riscv/sysdep.h
> >+++ b/sysdeps/unix/sysv/linux/riscv/sysdep.h
> >@@ -53,6 +53,75 @@
> >
> > # include <sys/asm.h>
> >
> >+/* GNU_PROPERTY_RISCV_* macros from elf.h for use in asm code.  */
> >+#define FEATURE_1_AND 0xc0000000
> >+
> >+/* Add a NT_GNU_PROPERTY_TYPE_0 note.  */
> >+#if __riscv_xlen == 32
> >+# define GNU_PROPERTY(type, value)    \
> >+   .section .note.gnu.property, "a";  \
> >+   .p2align 2;                                \
> >+   .word 4;                           \
> >+   .word 12;                          \
> >+   .word 5;                           \
> >+   .asciz "GNU";                      \
> >+   .word type;                                \
> >+   .word 4;                           \
> >+   .word value;                               \
> >+   .text
> >+#else
> >+# define GNU_PROPERTY(type, value)    \
> >+   .section .note.gnu.property, "a";  \
> >+   .p2align 3;                                \
> >+   .word 4;                           \
> >+   .word 16;                          \
> >+   .word 5;                           \
> >+   .asciz "GNU";                      \
> >+   .word type;                                \
> >+   .word 4;                           \
> >+   .word value;                               \
> >+   .word 0;                           \
> >+   .text
> >+#endif
>
> + Heinrich
>
> Do we need a version field for unlabeled landing pad scheme?
> I have raised it with Kito, for labeled one's we need version for sure.
> Although if we start with unlabaled gnu property, it will look
> canonical.
>
> >+
> >+/* Add GNU property note with the supported features to all asm code
> >+   where sysdep.h is included.  */
> >+#undef __VALUE_FOR_FEATURE_1_AND
> >+#if defined (__riscv_landing_pad) || defined (__riscv_shadow_stack)
> >+#  if defined (__riscv_landing_pad_unlabeled)
> >+#    if defined (__riscv_shadow_stack)
> >+#      define __VALUE_FOR_FEATURE_1_AND 0x3
> >+#    else
> >+#      define __VALUE_FOR_FEATURE_1_AND 0x1
> >+#    endif
> >+#  elif defined (__riscv_landing_pad_func_sig)
> >+#    if defined (__riscv_shadow_stack)
> >+#      define __VALUE_FOR_FEATURE_1_AND 0x6
> >+#    else
> >+#      define __VALUE_FOR_FEATURE_1_AND 0x4
> >+#    endif
> >+#  else
> >+#    if defined (__riscv_shadow_stack)
> >+#      define __VALUE_FOR_FEATURE_1_AND 0x2
> >+#    else
> >+#      error "What?"
> >+#    endif
> >+#  endif
> >+#endif
> >+
> >+#if defined (__VALUE_FOR_FEATURE_1_AND)
> >+GNU_PROPERTY (FEATURE_1_AND, __VALUE_FOR_FEATURE_1_AND)
> >+#endif
> >+#undef __VALUE_FOR_FEATURE_1_AND
> >+
> >+#ifdef __riscv_landing_pad_unlabeled
> >+# define SET_LPAD
> >+# define LPAD       lpad 0
> >+#else
> >+# define SET_LPAD
> >+# define LPAD
> >+#endif
> >+
> > # define ENTRY(name) LEAF(name)
> >
> > # define L(label) .L ## label
> >@@ -64,6 +133,7 @@
> >   .text;                                                      \
> >   .align 2;                                                   \
> >   ENTRY (name);                                                       \
> >+  LPAD;                                                       \
> >   li a7, SYS_ify (syscall_name);                              \
> >   scall;                                                      \
> >   li a7, -4096;                                                       \
> >@@ -111,6 +181,7 @@
> > # define PSEUDO_NOERRNO(name, syscall_name, args)     \
> >   .align 2;                                           \
> >   ENTRY (name);                                               \
> >+  LPAD;                                               \
> >   li a7, SYS_ify (syscall_name);                      \
> >   scall;
> >
> >diff --git a/sysdeps/unix/sysv/linux/riscv/vfork.S
> b/sysdeps/unix/sysv/linux/riscv/vfork.S
> >index 1e39b7a057..4cf7b5a9d8 100644
> >--- a/sysdeps/unix/sysv/linux/riscv/vfork.S
> >+++ b/sysdeps/unix/sysv/linux/riscv/vfork.S
> >@@ -29,6 +29,7 @@
> >
> >       .text
> > LEAF (__libc_vfork)
> >+      LPAD
> >
> >       li      a0, (CLONE_VFORK | CLONE_VM | SIGCHLD)
> >       mv      a1, sp
> >--
> >2.39.3
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://sourceware.org/pipermail/libc-alpha/attachments/20250723/7451f6a7/attachment-0001.htm>


More information about the Libc-alpha mailing list