diff options
-rw-r--r-- | sysdeps/aarch64/jmpbuf-offsets.h | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/sysdeps/aarch64/jmpbuf-offsets.h b/sysdeps/aarch64/jmpbuf-offsets.h index 632328c7e2..ec047cf6b1 100644 --- a/sysdeps/aarch64/jmpbuf-offsets.h +++ b/sysdeps/aarch64/jmpbuf-offsets.h @@ -39,6 +39,69 @@ #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> |