[v4,13/17] riscv/cfi: Add internal sigset_t union and use it for both ucontext/jmpbuf

Message ID 20260526061703.2188042-14-jesse.huang@sifive.com (mailing list archive)
State New
Headers
Series Support RISC-V Control Flow Integrifty (CFI) |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent
linaro-tcwg-bot/tcwg_glibc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_glibc_check--master-arm success Test passed

Commit Message

Jesse Huang May 26, 2026, 6:16 a.m. UTC
  Co-authored-by: Jerry Zhang Jian <jerry.zhangjian@sifive.com>
---
 .../sysv/linux/riscv/bits/types/__sigset_t.h  | 43 +++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/setjmpP.h       | 31 +------------
 sysdeps/unix/sysv/linux/riscv/sys/ucontext.h  | 14 +++++-
 3 files changed, 57 insertions(+), 31 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/riscv/bits/types/__sigset_t.h
  

Patch

diff --git a/sysdeps/unix/sysv/linux/riscv/bits/types/__sigset_t.h b/sysdeps/unix/sysv/linux/riscv/bits/types/__sigset_t.h
new file mode 100644
index 0000000000..d83c76876d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/bits/types/__sigset_t.h
@@ -0,0 +1,43 @@ 
+/* Architecture-specific __sigset_t definition.  RISC-V version.  */
+#ifndef ____sigset_t_defined
+#define ____sigset_t_defined
+
+#define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int)))
+typedef struct
+{
+  unsigned long int __val[_SIGSET_NWORDS];
+} __sigset_t;
+
+#define __ALIGN_DOWN(base, size)	((base) & -((__typeof__ (base)) (size)))
+#define __ALIGN_UP(base, size)	__ALIGN_DOWN ((base) + (size) - 1, (size))
+
+/* Number of bits per long.  */
+#define _SSP_SIGSET_BITS_PER_WORD (8 * sizeof (unsigned long int))
+/* This holds the number of signals, 512 should be sufficient for future.
+   expansion  */
+#define _SSP_SIGSET_NSIG	512
+/* Number of longs to hold all signals.  */
+#define _SSP_SIGSET_NWORDS \
+  (__ALIGN_UP (_SSP_SIGSET_NSIG, _SSP_SIGSET_BITS_PER_WORD) \
+   / _SSP_SIGSET_BITS_PER_WORD)
+
+typedef struct
+  {
+    unsigned long int __val[_SSP_SIGSET_NWORDS];
+  } __ssp_sigset_t;
+
+typedef union
+  {
+    __sigset_t __saved_mask_compat;
+    struct
+      {
+	__ssp_sigset_t __saved_mask;
+	/* Used for shadow stack pointer.  NB: Shadow stack pointer
+	   must have the same alignment as __saved_mask.  Otherwise
+	   offset of __saved_mask will be changed.  */
+	unsigned long int __ssp;
+	unsigned long int __ssp_base;
+      } __saved;
+  } __ssp_sigset_arch_t;
+
+#endif
diff --git a/sysdeps/unix/sysv/linux/riscv/setjmpP.h b/sysdeps/unix/sysv/linux/riscv/setjmpP.h
index 43cb28e2d1..b237f7baf4 100644
--- a/sysdeps/unix/sysv/linux/riscv/setjmpP.h
+++ b/sysdeps/unix/sysv/linux/riscv/setjmpP.h
@@ -23,42 +23,13 @@ 
 #include <libc-pointer-arith.h>
 #include <sigsetops.h>
 
-/* Number of bits per long.  */
-#define _JUMP_BUF_SIGSET_BITS_PER_WORD (8 * sizeof (unsigned long int))
-/* This holds the number of signals, 512 should be sufficient for future.
-   expansion  */
-#define _JUMP_BUF_SIGSET_NSIG	512
-/* Number of longs to hold all signals.  */
-#define _JUMP_BUF_SIGSET_NWORDS \
-  (ALIGN_UP (_JUMP_BUF_SIGSET_NSIG, _JUMP_BUF_SIGSET_BITS_PER_WORD) \
-   / _JUMP_BUF_SIGSET_BITS_PER_WORD)
-
-typedef struct
-  {
-    unsigned long int __val[_JUMP_BUF_SIGSET_NWORDS];
-  } __jmp_buf_sigset_t;
-
-typedef union
-  {
-    __sigset_t __saved_mask_compat;
-    struct
-      {
-	__jmp_buf_sigset_t __saved_mask;
-	/* Used for shadow stack pointer.  NB: Shadow stack pointer
-	   must have the same alignment as __saved_mask.  Otherwise
-	   offset of __saved_mask will be changed.  */
-	unsigned long int __ssp;
-	unsigned long int __ssp_base;
-      } __saved;
-  } __jmpbuf_arch_t;
-
 /* <setjmp/setjmp.h> has
 
    NB: We use setjmp in thread cancellation and this saves the shadow
    stack register, but __libc_unwind_longjmp doesn't restore the shadow
    stack register since cancellation never returns after longjmp.  */
 #undef __sigset_t
-#define __sigset_t __jmpbuf_arch_t
+#define __sigset_t __ssp_sigset_arch_t
 #include <setjmp.h>
 #undef __saved_mask
 #define __saved_mask __saved_mask.__saved.__saved_mask
diff --git a/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h b/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h
index 312be3cfc3..37cfc41fb6 100644
--- a/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h
+++ b/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h
@@ -23,6 +23,7 @@ 
 
 #include <features.h>
 
+#include <bits/types/__sigset_t.h>
 #include <bits/types/sigset_t.h>
 #include <bits/types/stack_t.h>
 
@@ -90,7 +91,18 @@  typedef struct ucontext_t
     unsigned long int  __uc_flags;
     struct ucontext_t *uc_link;
     stack_t            uc_stack;
-    sigset_t           uc_sigmask;
+    /* Internal overlay for uc_sigmask to store CFI shadow stack state while
+       keeping the public API type as sigset_t.  */
+    union
+      {
+        sigset_t uc_sigmask; /* Public view.  */
+        struct
+          {
+            __ssp_sigset_t __saved_mask;
+            unsigned long int __ssp;
+            unsigned long int __ssp_base;
+          } __saved; /* Internal view.  */
+      };
     /* There's some padding here to allow sigset_t to be expanded in the
        future.  Though this is unlikely, other architectures put uc_sigmask
        at the end of this structure and explicitly state it can be