diff options
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/alpha/__longjmp.S | 5 | ||||
-rw-r--r-- | sysdeps/alpha/setjmp.S | 51 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/alpha/sysdep.h | 39 |
3 files changed, 83 insertions, 12 deletions
diff --git a/sysdeps/alpha/__longjmp.S b/sysdeps/alpha/__longjmp.S index 40d50312a3..43ab7ba004 100644 --- a/sysdeps/alpha/__longjmp.S +++ b/sysdeps/alpha/__longjmp.S @@ -54,6 +54,11 @@ ENTRY(__longjmp) ldt $f7, JB_F7*8(a0) ldt $f8, JB_F8*8(a0) ldt $f9, JB_F9*8(a0) +#ifdef PTR_DEMANGLE + PTR_DEMANGLE(ra, t1) + PTR_DEMANGLE2(t0, t1) + PTR_DEMANGLE2(fp, t1) +#endif cmoveq v0, 1, v0 mov t0, sp ret diff --git a/sysdeps/alpha/setjmp.S b/sysdeps/alpha/setjmp.S index 14a0320cd3..1b352f346d 100644 --- a/sysdeps/alpha/setjmp.S +++ b/sysdeps/alpha/setjmp.S @@ -23,16 +23,22 @@ #define _SETJMP_H #include <bits/setjmp.h> - .ent __sigsetjmp - .global __sigsetjmp + .ent __sigsetjmp + .global __sigsetjmp __sigsetjmp: - ldgp gp, 0(pv) + ldgp gp, 0(pv) $sigsetjmp_local: - subq sp, 16, sp - .frame sp, 16, ra, 0 - stq ra, 0(sp) - .mask 0x04000000, -16 +#ifndef PIC +#define FRAME 16 + subq sp, FRAME, sp + .frame sp, FRAME, ra, 0 + stq ra, 0(sp) + .mask 0x04000000, -FRAME +#else +#define FRAME 0 + .frame sp, FRAME, ra, 0 +#endif #ifdef PROF .set noat lda AT, _mcount @@ -47,10 +53,27 @@ $sigsetjmp_local: stq s3, JB_S3*8(a0) stq s4, JB_S4*8(a0) stq s5, JB_S5*8(a0) +#ifdef PTR_MANGLE + PTR_MANGLE(t1, ra, t0) + stq t1, JB_PC*8(a0) +#else stq ra, JB_PC*8(a0) - addq sp, 16, t0 +#endif +#if defined(PTR_MANGLE) && FRAME == 0 + PTR_MANGLE2(t1, sp, t0) +#else + addq sp, FRAME, t1 +# ifdef PTR_MANGLE + PTR_MANGLE2(t1, t1, t0) +# endif +#endif + stq t1, JB_SP*8(a0) +#ifdef PTR_MANGLE + PTR_MANGLE2(t1, fp, t0) + stq t1, JB_FP*8(a0) +#else stq fp, JB_FP*8(a0) - stq t0, JB_SP*8(a0) +#endif stt $f2, JB_F2*8(a0) stt $f3, JB_F3*8(a0) stt $f4, JB_F4*8(a0) @@ -60,12 +83,20 @@ $sigsetjmp_local: stt $f8, JB_F8*8(a0) stt $f9, JB_F9*8(a0) +#ifndef PIC /* Call to C to (potentially) save our signal mask. */ jsr ra, __sigjmp_save - ldq ra, 0(sp) addq sp, 16, sp ret +#elif defined NOT_IN_libc && defined IS_IN_rtld + /* In ld.so we never save the signal mask. */ + mov 0, v0 + ret +#else + /* Tailcall to save the signal mask. */ + br $31, __sigjmp_save !samegp +#endif END(__sigsetjmp) diff --git a/sysdeps/unix/sysv/linux/alpha/sysdep.h b/sysdeps/unix/sysv/linux/alpha/sysdep.h index c3de78f4bb..ccbce81f0d 100644 --- a/sysdeps/unix/sysv/linux/alpha/sysdep.h +++ b/sysdeps/unix/sysv/linux/alpha/sysdep.h @@ -22,10 +22,10 @@ #define _LINUX_ALPHA_SYSDEP_H 1 #ifdef __ASSEMBLER__ - #include <asm/pal.h> #include <alpha/regdef.h> - +#else +#include <stdint.h> #endif /* There is some commonality. */ @@ -98,4 +98,39 @@ INTERNAL_SYSCALL1(name, err_out, nr, args); \ }) +/* Pointer mangling support. Note that tls access is slow enough that + we don't deoptimize things by placing the pointer check value there. */ +#if defined NOT_IN_libc && defined IS_IN_rtld +# ifdef __ASSEMBLER__ +# define PTR_MANGLE(dst, src, tmp) \ + ldah tmp, __pointer_chk_guard_local($29) !gprelhigh; \ + ldq tmp, __pointer_chk_guard_local(tmp) !gprellow; \ + xor src, tmp, dst +# define PTR_MANGLE2(dst, src, tmp) \ + xor src, tmp, dst +# define PTR_DEMANGLE(dst, tmp) PTR_MANGLE(dst, dst, tmp) +# define PTR_DEMANGLE2(dst, tmp) PTR_MANGLE2(dst, dst, tmp) +# else +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_MANGLE(var) \ + (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard_local) +# define PTR_DEMANGLE(var) PTR_MANGLE(var) +# endif +#elif defined PIC +# ifdef __ASSEMBLER__ +# define PTR_MANGLE(dst, src, tmp) \ + ldq tmp, __pointer_chk_guard; \ + xor src, tmp, dst +# define PTR_MANGLE2(dst, src, tmp) \ + xor src, tmp, dst +# define PTR_DEMANGLE(dst, tmp) PTR_MANGLE(dst, dst, tmp) +# define PTR_DEMANGLE2(dst, tmp) PTR_MANGLE2(dst, dst, tmp) +# else +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_MANGLE(var) \ + (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard) +# define PTR_DEMANGLE(var) PTR_MANGLE(var) +# endif +#endif + #endif /* _LINUX_ALPHA_SYSDEP_H */ |