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>
#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)
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--;
__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;
}
#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
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 ();