From 9188b6818a3d1a6e6d89bf10fa4aea27a591494c Mon Sep 17 00:00:00 2001 From: Venkataramanan Kumar Date: Wed, 1 Jan 2014 17:47:14 +0000 Subject: [PATCH] [AArch64] Pointer mangling support for AArch64. --- ports/ChangeLog.aarch64 | 16 +++++++ ports/sysdeps/aarch64/__longjmp.S | 14 +++++-- ports/sysdeps/aarch64/jmpbuf-offsets.h | 18 +++++++- ports/sysdeps/aarch64/jmpbuf-unwind.h | 10 ----- ports/sysdeps/aarch64/setjmp.S | 12 ++++++ ports/sysdeps/aarch64/sysdep.h | 11 +++++ .../sysdeps/unix/sysv/linux/aarch64/sysdep.h | 42 +++++++++++++++++-- 7 files changed, 106 insertions(+), 17 deletions(-) diff --git a/ports/ChangeLog.aarch64 b/ports/ChangeLog.aarch64 index 279a2272c1..1dfd8f9388 100644 --- a/ports/ChangeLog.aarch64 +++ b/ports/ChangeLog.aarch64 @@ -1,3 +1,19 @@ +2014-01-01 Venkataramanan Kumar + + * sysdeps/aarch64/__longjmp.S (__longjmp): Demangle sp and lr when + restoring register values. + * sysdeps/aarch64/setjmp.S (__sigsetjmp): Mangle sp and lr + before storing register values. + * sysdeps/arm/jmpbuf-unwind.h (_jmpbuf_sp): Remove. + * sysdeps/aarch64/jmpbuf-offsets.h (_jmpbuf_sp): Add. + (JB_FRAME_ADDRESS): call _jmpbuf_sp. + * sysdeps/aarch64/sysdep.h (LDST_PCREL) : New macros. + (LDST_GLOBAL): Likewise. + * sysdeps/unix/sysv/linux/aarch64/sysdep.h (PTR_MANGLE): New macro. + (PTR_DEMANGLE): Likewise. + (PTR_MANGLE2): Likewise. + (PTR_DEMANGLE2): Likewise. + 2013-12-18 Marcus Shawcroft [BZ #15128] diff --git a/ports/sysdeps/aarch64/__longjmp.S b/ports/sysdeps/aarch64/__longjmp.S index 250f2afa4e..2d38bbf6a5 100644 --- a/ports/sysdeps/aarch64/__longjmp.S +++ b/ports/sysdeps/aarch64/__longjmp.S @@ -50,8 +50,12 @@ ENTRY (__longjmp) ldp x23, x24, [x0, #JB_X23<<3] ldp x25, x26, [x0, #JB_X25<<3] ldp x27, x28, [x0, #JB_X27<<3] +#ifdef PTR_DEMANGLE + ldp x29, x4, [x0, #JB_X29<<3] + PTR_DEMANGLE (x30, x4, x3, x2) +#else ldp x29, x30, [x0, #JB_X29<<3] - +#endif ldp d8, d9, [x0, #JB_D8<<3] ldp d10, d11, [x0, #JB_D10<<3] ldp d12, d13, [x0, #JB_D12<<3] @@ -87,8 +91,12 @@ ENTRY (__longjmp) cfi_same_value(d13) cfi_same_value(d14) cfi_same_value(d15) - - ldr x5, [x0, #JB_SP<<3] +#ifdef PTR_DEMANGLE + ldr x4, [x0, #JB_SP<<3] + PTR_DEMANGLE (x5, x4, x3, x2) +#else + ldr x5, [x0, #JB_SP<<3] +#endif mov sp, x5 cmp x1, #0 mov x0, #1 diff --git a/ports/sysdeps/aarch64/jmpbuf-offsets.h b/ports/sysdeps/aarch64/jmpbuf-offsets.h index 84c2cccaf4..bcf2afa555 100644 --- a/ports/sysdeps/aarch64/jmpbuf-offsets.h +++ b/ports/sysdeps/aarch64/jmpbuf-offsets.h @@ -39,6 +39,22 @@ #define JB_D14 20 #define JB_D15 21 +#ifndef __ASSEMBLER__ +#include +#include +#include + +static inline uintptr_t __attribute__ ((unused)) +_jmpbuf_sp (__jmp_buf jmpbuf) +{ + uintptr_t sp = jmpbuf[JB_SP]; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (sp); +#endif + return sp; +} +#endif + /* Helper for generic ____longjmp_chk(). */ #define JB_FRAME_ADDRESS(buf) \ - ((void *) (buf[JB_SP])) + ((void *) _jmpbuf_sp (buf)) diff --git a/ports/sysdeps/aarch64/jmpbuf-unwind.h b/ports/sysdeps/aarch64/jmpbuf-unwind.h index 22c6c2b758..39a5dc2c75 100644 --- a/ports/sysdeps/aarch64/jmpbuf-unwind.h +++ b/ports/sysdeps/aarch64/jmpbuf-unwind.h @@ -29,16 +29,6 @@ #define _JMPBUF_CFA_UNWINDS_ADJ(jmpbuf, context, adj) \ _JMPBUF_UNWINDS_ADJ (jmpbuf, (void *) _Unwind_GetCFA (context), adj) -static inline uintptr_t __attribute__ ((unused)) -_jmpbuf_sp (__jmp_buf jmpbuf) -{ - uintptr_t sp = jmpbuf[JB_SP]; -#ifdef PTR_DEMANGLE - PTR_DEMANGLE (sp); -#endif - return sp; -} - #define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ ((uintptr_t) (_address) - (_adj) < _jmpbuf_sp (_jmpbuf) - (_adj)) diff --git a/ports/sysdeps/aarch64/setjmp.S b/ports/sysdeps/aarch64/setjmp.S index cb94e01bbb..5822abd872 100644 --- a/ports/sysdeps/aarch64/setjmp.S +++ b/ports/sysdeps/aarch64/setjmp.S @@ -39,13 +39,25 @@ ENTRY (__sigsetjmp) stp x23, x24, [x0, #JB_X23<<3] stp x25, x26, [x0, #JB_X25<<3] stp x27, x28, [x0, #JB_X27<<3] + +#ifdef PTR_MANGLE + PTR_MANGLE (x4, x30, x3, x2) + stp x29, x4, [x0, #JB_X29<<3] +#else stp x29, x30, [x0, #JB_X29<<3] +#endif stp d8, d9, [x0, #JB_D8<<3] stp d10, d11, [x0, #JB_D10<<3] stp d12, d13, [x0, #JB_D12<<3] stp d14, d15, [x0, #JB_D14<<3] +#ifdef PTR_MANGLE + mov x4, sp + PTR_MANGLE (x5, x4, x3, x2) + str x5, [x0, #JB_SP<<3] +#else mov x2, sp str x2, [x0, #JB_SP<<3] +#endif #if defined NOT_IN_libc && defined IS_IN_rtld /* In ld.so we never save the signal mask */ mov w0, #0 diff --git a/ports/sysdeps/aarch64/sysdep.h b/ports/sysdeps/aarch64/sysdep.h index 0dd597acfc..7169ba716c 100644 --- a/ports/sysdeps/aarch64/sysdep.h +++ b/ports/sysdeps/aarch64/sysdep.h @@ -78,6 +78,17 @@ # define L(name) .L##name #endif +/* Load or store to/from a pc-relative EXPR into/from R, using T. */ +#define LDST_PCREL(OP, R, T, EXPR) \ + adrp T, EXPR; \ + OP R, [T, #:lo12:EXPR];\ + +/* Load or store to/from a got-relative EXPR into/from R, using T. */ +#define LDST_GLOBAL(OP, R, T, EXPR) \ + adrp T, :got:EXPR; \ + ldr T, [T, #:got_lo12:EXPR];\ + OP R, [T]; + /* Since C identifiers are not normally prefixed with an underscore on this system, the asm identifier `syscall_error' intrudes on the C name space. Make sure we use an innocuous name. */ diff --git a/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h b/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h index f3f0ada203..5ccf1da18b 100644 --- a/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h +++ b/ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h @@ -371,8 +371,44 @@ __local_syscall_error: \ #endif /* __ASSEMBLER__ */ -/* Pointer mangling is not yet supported for AArch64. */ -#define PTR_MANGLE(var) (void) (var) -#define PTR_DEMANGLE(var) (void) (var) +/* Pointer mangling is supported for AArch64. */ +#if (defined NOT_IN_libc && defined IS_IN_rtld) || \ + (!defined SHARED && (!defined NOT_IN_libc || defined IS_IN_libpthread)) +# ifdef __ASSEMBLER__ +# define PTR_MANGLE(dst, src, guard, tmp) \ + LDST_PCREL (ldr, guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard_local)); \ + PTR_MANGLE2 (dst, src, guard) +/* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ +# define PTR_MANGLE2(dst, src, guard)\ + eor dst, src, guard +# define PTR_DEMANGLE(dst, src, guard, tmp)\ + PTR_MANGLE (dst, src, guard, tmp) +# define PTR_DEMANGLE2(dst, src, guard)\ + PTR_MANGLE2 (dst, src, guard) +# else +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local) +# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# endif +#else +# ifdef __ASSEMBLER__ +# define PTR_MANGLE(dst, src, guard, tmp) \ + LDST_GLOBAL (ldr, guard, tmp, C_SYMBOL_NAME(__pointer_chk_guard)); \ + PTR_MANGLE2 (dst, src, guard) +/* Use PTR_MANGLE2 for efficiency if guard is already loaded. */ +# define PTR_MANGLE2(dst, src, guard)\ + eor dst, src, guard +# define PTR_DEMANGLE(dst, src, guard, tmp)\ + PTR_MANGLE (dst, src, guard, tmp) +# define PTR_DEMANGLE2(dst, src, guard)\ + PTR_MANGLE2 (dst, src, guard) +# else +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_MANGLE(var) \ + (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard) +# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# endif +#endif #endif /* linux/aarch64/sysdep.h */