[PATCH] aarch64: GCS: use internal struct in __alloc_gcs

Yury Khrustalev yury.khrustalev@arm.com
Mon Jun 16 12:23:17 GMT 2025


No functional change here, just a small refactoring to simplify
using __alloc_gcs() for allocating shadow stacks.

---

base commit: 5b7c8d1cd4

Passes tests on AArch64. OK for trunk?

---
 sysdeps/aarch64/__alloc_gcs.c                 | 15 +++++++++++----
 sysdeps/aarch64/aarch64-gcs.h                 | 17 ++++++++++++++++-
 sysdeps/unix/sysv/linux/aarch64/makecontext.c |  4 +---
 3 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/sysdeps/aarch64/__alloc_gcs.c b/sysdeps/aarch64/__alloc_gcs.c
index e70b4594a2..b98e5fcdba 100644
--- a/sysdeps/aarch64/__alloc_gcs.c
+++ b/sysdeps/aarch64/__alloc_gcs.c
@@ -15,6 +15,8 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include "aarch64-gcs.h"
+
 #include <sysdep.h>
 #include <unistd.h>
 #include <sys/mman.h>
@@ -34,7 +36,7 @@ map_shadow_stack (void *addr, size_t size, unsigned long flags)
 #define GCS_ALTSTACK_RESERVE 160
 
 void *
-__alloc_gcs (size_t stack_size, void **ss_base, size_t *ss_size)
+__alloc_gcs (size_t stack_size, struct gcs_record *gcs)
 {
   size_t size = (stack_size / 2 + GCS_ALTSTACK_RESERVE) & -8UL;
   if (size > GCS_MAX_SIZE)
@@ -45,9 +47,6 @@ __alloc_gcs (size_t stack_size, void **ss_base, size_t *ss_size)
   if (base == MAP_FAILED)
     return NULL;
 
-  *ss_base = base;
-  *ss_size = size;
-
   uint64_t *gcsp = (uint64_t *) ((char *) base + size);
   /* Skip end of GCS token.  */
   gcsp--;
@@ -58,6 +57,14 @@ __alloc_gcs (size_t stack_size, void **ss_base, size_t *ss_size)
       __munmap (base, size);
       return NULL;
     }
+
+  if (gcs != NULL)
+    {
+      gcs->gcs_base = base;
+      gcs->gcs_token = gcsp;
+      gcs->gcs_size = size;
+    }
+
   /* Return the target GCS pointer for context switch.  */
   return gcsp + 1;
 }
diff --git a/sysdeps/aarch64/aarch64-gcs.h b/sysdeps/aarch64/aarch64-gcs.h
index 162ef18726..8e253ed32f 100644
--- a/sysdeps/aarch64/aarch64-gcs.h
+++ b/sysdeps/aarch64/aarch64-gcs.h
@@ -23,6 +23,21 @@
 #include <stddef.h>
 #include <stdbool.h>
 
-void *__alloc_gcs (size_t, void **, size_t *) attribute_hidden;
+struct gcs_record
+{
+  void *gcs_base;
+  void *gcs_token;
+  size_t gcs_size;
+};
+
+void *__alloc_gcs (size_t, struct gcs_record *) attribute_hidden;
+
+static inline bool
+has_gcs (void)
+{
+  register unsigned long x16 asm ("x16") = 1;
+  asm ("hint	40" /* chkfeat x16 */ : "+r" (x16));
+  return x16 == 0;
+}
 
 #endif
diff --git a/sysdeps/unix/sysv/linux/aarch64/makecontext.c b/sysdeps/unix/sysv/linux/aarch64/makecontext.c
index a2eab9efc6..4485723cfb 100644
--- a/sysdeps/unix/sysv/linux/aarch64/makecontext.c
+++ b/sysdeps/unix/sysv/linux/aarch64/makecontext.c
@@ -36,9 +36,7 @@ static struct _aarch64_ctx *extension (void *p)
 static void *
 alloc_makecontext_gcs (size_t stack_size)
 {
-  void *base;
-  size_t size;
-  void *gcsp = __alloc_gcs (stack_size, &base, &size);
+  void *gcsp = __alloc_gcs (stack_size, NULL);
   if (gcsp == NULL)
     /* ENOSYS, bad size or OOM.  */
     abort ();
-- 
2.39.5



More information about the Libc-alpha mailing list