aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVenkataramanan Kumar <venkataramanan.kumar@linaro.org>2014-01-01 17:47:14 +0000
committerMarcus Shawcroft <marcus.shawcroft@linaro.org>2014-01-01 17:58:46 +0000
commit9188b6818a3d1a6e6d89bf10fa4aea27a591494c (patch)
treea39527a08f172d51a8e69fce1b969b0dcf5589a4
parentb06ece6aec66e5ea973bc3c7f835ff3258dd4bb5 (diff)
downloadglibc-9188b6818a3d1a6e6d89bf10fa4aea27a591494c.tar
glibc-9188b6818a3d1a6e6d89bf10fa4aea27a591494c.tar.gz
glibc-9188b6818a3d1a6e6d89bf10fa4aea27a591494c.tar.bz2
glibc-9188b6818a3d1a6e6d89bf10fa4aea27a591494c.zip
[AArch64] Pointer mangling support for AArch64.
-rw-r--r--ports/ChangeLog.aarch6416
-rw-r--r--ports/sysdeps/aarch64/__longjmp.S14
-rw-r--r--ports/sysdeps/aarch64/jmpbuf-offsets.h18
-rw-r--r--ports/sysdeps/aarch64/jmpbuf-unwind.h10
-rw-r--r--ports/sysdeps/aarch64/setjmp.S12
-rw-r--r--ports/sysdeps/aarch64/sysdep.h11
-rw-r--r--ports/sysdeps/unix/sysv/linux/aarch64/sysdep.h42
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 <venkataramanan.kumar@linaro.org>
+
+ * 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 <marcus.shawcroft@linaro.org>
[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 <setjmp.h>
+#include <stdint.h>
+#include <sysdep.h>
+
+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 */