aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sysdeps/aarch64/jmpbuf-offsets.h62
1 files changed, 62 insertions, 0 deletions
diff --git a/sysdeps/aarch64/jmpbuf-offsets.h b/sysdeps/aarch64/jmpbuf-offsets.h
index 73d51ba..2720526 100644
--- a/sysdeps/aarch64/jmpbuf-offsets.h
+++ b/sysdeps/aarch64/jmpbuf-offsets.h
@@ -39,6 +39,68 @@
#define JB_D14 20
#define JB_D15 21
+/* The target specific part of jmp_buf has no space for expansion but
+ the public jmp_buf ABI type has. Unfortunately there is another type
+ that is used with setjmp APIs and exposed by thread cancellation (in
+ binaries built with -fno-exceptions) which complicates the situation.
+
+ // Internal layout of the public jmp_buf type on AArch64.
+ // This is passed to setjmp, longjmp, sigsetjmp, siglongjmp.
+ struct
+ {
+ uint64_t jmpbuf[22]; // Target specific part.
+ uint32_t mask_was_saved; // savemask bool used by sigsetjmp/siglongjmp.
+ uint32_t pad;
+ uint64_t saved_mask; // sigset_t bits used on linux.
+ uint64_t unused[15]; // sigset_t bits not used on linux.
+ };
+
+ // Internal layout of the public __pthread_unwind_buf_t type.
+ // This is passed to sigsetjmp with !savemask and to the internal
+ // __libc_longjmp (currently alias of longjmp on AArch64).
+ struct
+ {
+ uint64_t jmpbuf[22]; // Must match jmp_buf.
+ uint32_t mask_was_saved; // Must match jmp_buf, always 0.
+ uint32_t pad;
+ void *prev; // List for unwinding.
+ void *cleanup; // Cleanup handlers.
+ uint32_t canceltype; // 1 bit cancellation type.
+ uint32_t pad2;
+ void *pad3;
+ };
+
+ Ideally only the target specific part of jmp_buf (A) is accessed by
+ __setjmp and __longjmp. But that is always embedded into one of the
+ two types above so the bits that are unused in those types (B) may be
+ reused for target specific purposes. Setjmp can't distinguish between
+ jmp_buf and __pthread_unwind_buf_t, but longjmp can: only an internal
+ longjmp call uses the latter, so state that is not needed for cancel
+ cleanups can go to fields (C). If generic code is refactored then the
+ usage of additional fields can be optimized (D). And some fields are
+ only accessible in the savedmask case (E). Reusability of jmp_buf
+ fields on AArch64 for target purposes:
+
+ struct
+ {
+ uint64_t A[22]; // 0 .. 176
+ uint32_t D; // 176 .. 180
+ uint32_t B; // 180 .. 184
+ uint64_t D; // 184 .. 192
+ uint64_t C; // 192 .. 200
+ uint32_t C; // 200 .. 204
+ uint32_t B; // 204 .. 208
+ uint64_t B; // 208 .. 216
+ uint64_t E[12]; // 216 .. 312
+ }
+
+ The B fields can be used with minimal glibc code changes. We need a
+ 64 bit field for the Guarded Control Stack pointer (GCSPR_EL0) which
+ can use a C field too as cancellation cleanup does not execute RET
+ for a previous BL of the cancelled thread, but that would require a
+ custom __libc_longjmp. This layout can change in the future. */
+#define JB_GCSPR 208
+
#ifndef __ASSEMBLER__
#include <setjmp.h>
#include <stdint.h>