Another fairly straight forward setjmp cookie implementation, applying them to gp, sp, and ra.
Passes regress/lib/libc/*setjmp* on the loongson. ok? Philip Guenther Index: arch/mips64/gen/_setjmp.S =================================================================== RCS file: /data/src/openbsd/src/lib/libc/arch/mips64/gen/_setjmp.S,v retrieving revision 1.6 diff -u -p -r1.6 _setjmp.S --- arch/mips64/gen/_setjmp.S 23 May 2016 00:18:57 -0000 1.6 +++ arch/mips64/gen/_setjmp.S 29 May 2016 05:38:56 -0000 @@ -33,6 +33,8 @@ #include <machine/regnum.h> #include <machine/signal.h> + .globl __jmpxor + /* * _setjmp, _longjmp (not restoring signal state) * @@ -48,11 +50,7 @@ LEAF(_setjmp, FRAMESZ) PTR_SUBU sp, FRAMESZ SETUP_GP64(GPOFF, _setjmp) .set noreorder -#if defined(__mips64) - dli v0, 0xACEDBADE # sigcontext magic number -#else - li v0, 0xACEDBADE # sigcontext magic number -#endif + LI v0, 0xACEDBADE # sigcontext magic number REG_S v0, SC_REGS+ZERO*REGSZ(a0) REG_S s0, SC_REGS+S0*REGSZ(a0) REG_S s1, SC_REGS+S1*REGSZ(a0) @@ -63,12 +61,19 @@ LEAF(_setjmp, FRAMESZ) REG_S s6, SC_REGS+S6*REGSZ(a0) REG_S s7, SC_REGS+S7*REGSZ(a0) REG_S s8, SC_REGS+S8*REGSZ(a0) - REG_L v0, GPOFF(sp) + LA t0, __jmpxor # load cookie addr + REG_L v0, 0(t0) # load gp cookie + REG_L v1, GPOFF(sp) + xor v0, v0, v1 REG_S v0, SC_REGS+GP*REGSZ(a0) - PTR_ADDU v0, sp, FRAMESZ + REG_L v0, REGSZ(t0) # load sp cookie over gp cookie + PTR_ADDU v1, sp, FRAMESZ + xor v0, v0, v1 REG_S v0, SC_REGS+SP*REGSZ(a0) - REG_S ra, SC_PC(a0) - cfc1 v0, $31 + REG_L t0, 2*REGSZ(t0) # load ra cookie over addr + xor t0, ra, t0 + REG_S t0, SC_PC(a0) + cfc1 t0, $31 # overwrite ra cookie #if _MIPS_FPSET == 32 sdc1 $f20, SC_FPREGS+((F20-F0)*REGSZ)(a0) sdc1 $f21, SC_FPREGS+((F21-F0)*REGSZ)(a0) @@ -96,7 +101,7 @@ LEAF(_setjmp, FRAMESZ) swc1 $f30, SC_FPREGS+((F30-F0)*REGSZ)(a0) swc1 $f31, SC_FPREGS+((F31-F0)*REGSZ)(a0) #endif - REG_S v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0) + REG_S t0, SC_FPREGS+((FSR-F0)*REGSZ)(a0) RESTORE_GP64 PTR_ADDU sp, FRAMESZ j ra @@ -109,8 +114,10 @@ LEAF(_longjmp, FRAMESZ) .set noreorder REG_L v0, SC_REGS+ZERO*REGSZ(a0) bne v0, 0xACEDBADE, botch # jump if error + LA v0, __jmpxor # load cookie addr + REG_L v1, 2*REGSZ(v0) # load ra cookie REG_L ra, SC_PC(a0) - REG_L v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0) + xor ra, ra, v1 REG_L s0, SC_REGS+S0*REGSZ(a0) REG_L s1, SC_REGS+S1*REGSZ(a0) REG_L s2, SC_REGS+S2*REGSZ(a0) @@ -120,9 +127,14 @@ LEAF(_longjmp, FRAMESZ) REG_L s6, SC_REGS+S6*REGSZ(a0) REG_L s7, SC_REGS+S7*REGSZ(a0) REG_L s8, SC_REGS+S8*REGSZ(a0) + REG_L v1, 0(v0) # load gp cookie over ra cookie REG_L gp, SC_REGS+GP*REGSZ(a0) + xor gp, gp, v1 + REG_L v1, REGSZ(v0) # load sp cookie over gp cookie REG_L sp, SC_REGS+SP*REGSZ(a0) - ctc1 v0, $31 + xor sp, sp, v1 + REG_L v1, SC_FPREGS+((FSR-F0)*REGSZ)(a0) # overwrite sp cookie + ctc1 v1, $31 #if _MIPS_FPSET == 32 ldc1 $f20, SC_FPREGS+((F20-F0)*REGSZ)(a0) ldc1 $f21, SC_FPREGS+((F21-F0)*REGSZ)(a0) Index: arch/mips64/gen/setjmp.S =================================================================== RCS file: /data/src/openbsd/src/lib/libc/arch/mips64/gen/setjmp.S,v retrieving revision 1.10 diff -u -p -r1.10 setjmp.S --- arch/mips64/gen/setjmp.S 23 May 2016 00:18:57 -0000 1.10 +++ arch/mips64/gen/setjmp.S 29 May 2016 05:53:16 -0000 @@ -33,6 +33,16 @@ #include <machine/regnum.h> #include <machine/signal.h> + .section .openbsd.randomdata,"aw",@progbits + .balign 8 + .globl __jmpxor + .hidden __jmpxor +__jmpxor: + .space 3*REGSZ # (28/gp, 29/sp, 31/ra) + .size __jmpxor, . - __jmpxor + .type __jmpxor,@object + .text + /* * setjmp, longjmp implementation for libc. this code depends * on the layout of the struct sigcontext in machine/signal.h. @@ -54,11 +64,7 @@ LEAF(setjmp, FRAMESZ) bne a3, zero, botch REG_S v0, SC_MASK(a2) # save sc_mask -#if defined(__mips64) - dli v0, 0xACEDBADE # sigcontext magic number -#else - li v0, 0xACEDBADE # sigcontext magic number -#endif + LI v0, 0xACEDBADE # sigcontext magic number REG_S v0, SC_REGS+ZERO*REGSZ(a2) REG_S s0, SC_REGS+S0*REGSZ(a2) REG_S s1, SC_REGS+S1*REGSZ(a2) @@ -69,12 +75,19 @@ LEAF(setjmp, FRAMESZ) REG_S s6, SC_REGS+S6*REGSZ(a2) REG_S s7, SC_REGS+S7*REGSZ(a2) REG_S s8, SC_REGS+S8*REGSZ(a2) - REG_L v0, GPOFF(sp) + LA t0, __jmpxor # load cookie addr + REG_L v0, 0(t0) # load gp cookie + REG_L v1, GPOFF(sp) + xor v0, v0, v1 REG_S v0, SC_REGS+GP*REGSZ(a2) - PTR_ADDU v0, sp, FRAMESZ + REG_L v0, REGSZ(t0) # load sp cookie over gp cookie + PTR_ADDU v1, sp, FRAMESZ + xor v0, v0, v1 REG_S v0, SC_REGS+SP*REGSZ(a2) - REG_S ra, SC_PC(a2) - cfc1 v0, $31 + REG_L t0, 2*REGSZ(t0) # load ra cookie over addr + xor t0, ra, t0 + REG_S t0, SC_PC(a2) + cfc1 t0, $31 # overwrite ra cookie #if _MIPS_FPSET == 32 sdc1 $f20, SC_FPREGS+((F20-F0)*REGSZ)(a2) sdc1 $f21, SC_FPREGS+((F21-F0)*REGSZ)(a2) @@ -102,7 +115,7 @@ LEAF(setjmp, FRAMESZ) swc1 $f30, SC_FPREGS+((F30-F0)*REGSZ)(a2) swc1 $f31, SC_FPREGS+((F31-F0)*REGSZ)(a2) #endif - REG_S v0, SC_FPREGS+((FSR-F0)*REGSZ)(a2) + REG_S t0, SC_FPREGS+((FSR-F0)*REGSZ)(a2) RESTORE_GP64 PTR_ADDU sp, FRAMESZ j ra @@ -124,8 +137,10 @@ LEAF(longjmp, FRAMESZ) REG_L v0, SC_REGS+ZERO*REGSZ(a2) bne v0, 0xACEDBADE, botch # jump if error + LA v0, __jmpxor # load cookie addr + REG_L v1, 2*REGSZ(v0) # load ra cookie REG_L ra, SC_PC(a2) - REG_L v0, SC_FPREGS+((FSR-F0)*REGSZ)(a2) + xor ra, ra, v1 REG_L s0, SC_REGS+S0*REGSZ(a2) REG_L s1, SC_REGS+S1*REGSZ(a2) REG_L s2, SC_REGS+S2*REGSZ(a2) @@ -135,9 +150,14 @@ LEAF(longjmp, FRAMESZ) REG_L s6, SC_REGS+S6*REGSZ(a2) REG_L s7, SC_REGS+S7*REGSZ(a2) REG_L s8, SC_REGS+S8*REGSZ(a2) + REG_L v1, 0(v0) # load gp cookie over ra cookie REG_L gp, SC_REGS+GP*REGSZ(a2) + xor gp, gp, v1 + REG_L v1, REGSZ(v0) # load sp cookie over gp cookie REG_L sp, SC_REGS+SP*REGSZ(a2) - ctc1 v0, $31 + xor sp, sp, v1 + REG_L v1, SC_FPREGS+((FSR-F0)*REGSZ)(a2) # overwrite sp cookie + ctc1 v1, $31 #if _MIPS_FPSET == 32 ldc1 $f20, SC_FPREGS+((F20-F0)*REGSZ)(a2) ldc1 $f21, SC_FPREGS+((F21-F0)*REGSZ)(a2)