aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYury Khrustalev <yury.khrustalev@arm.com>2025-04-16 19:08:47 +0100
committerYury Khrustalev <yury.khrustalev@arm.com>2025-06-18 09:37:13 +0100
commiteeedfc2f74463a06e8127dde42531913652371f8 (patch)
tree2e3bdb26725dd8665e61e1cad8b915a784e21110
parenteae5bb0f60205e6f709803cc6bba749daf5ece72 (diff)
downloadglibc-eeedfc2f74463a06e8127dde42531913652371f8.zip
glibc-eeedfc2f74463a06e8127dde42531913652371f8.tar.gz
glibc-eeedfc2f74463a06e8127dde42531913652371f8.tar.bz2
aarch64: GCS: use internal struct in __alloc_gcs
No functional change here, just a small refactoring to simplify using __alloc_gcs() for allocating shadow stacks. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
-rw-r--r--sysdeps/aarch64/__alloc_gcs.c15
-rw-r--r--sysdeps/aarch64/aarch64-gcs.h17
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/makecontext.c4
3 files changed, 28 insertions, 8 deletions
diff --git a/sysdeps/aarch64/__alloc_gcs.c b/sysdeps/aarch64/__alloc_gcs.c
index e70b459..b98e5fc 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 162ef18..8e253ed 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 a2eab9e..4485723 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 ();