Implement setjmp cookies on AArch64.

Bug: http://b/23942752
Change-Id: I81408ef0dd53010140b51e3083d357d3f2961112
This commit is contained in:
Josh Gao 2015-09-11 15:23:32 -07:00
parent 7fda8d2aa4
commit 54db0df8d6

View File

@ -52,6 +52,29 @@
#define _JB_D10_D11 (_JB_D12_D13 + 2) #define _JB_D10_D11 (_JB_D12_D13 + 2)
#define _JB_D8_D9 (_JB_D10_D11 + 2) #define _JB_D8_D9 (_JB_D10_D11 + 2)
#define MANGLE_REGISTERS 1
.macro m_mangle_registers reg, sp_reg
#if MANGLE_REGISTERS
eor x19, x19, \reg
eor x20, x20, \reg
eor x21, x21, \reg
eor x22, x22, \reg
eor x23, x23, \reg
eor x24, x24, \reg
eor x25, x25, \reg
eor x26, x26, \reg
eor x27, x27, \reg
eor x28, x28, \reg
eor x29, x29, \reg
eor x30, x30, \reg
eor \sp_reg, \sp_reg, \reg
#endif
.endm
.macro m_unmangle_registers reg, sp_reg
m_mangle_registers \reg, sp_reg=\sp_reg
.endm
ENTRY(setjmp) ENTRY(setjmp)
mov w1, #1 mov w1, #1
b sigsetjmp b sigsetjmp
@ -64,23 +87,47 @@ END(_setjmp)
// int sigsetjmp(sigjmp_buf env, int save_signal_mask); // int sigsetjmp(sigjmp_buf env, int save_signal_mask);
ENTRY(sigsetjmp) ENTRY(sigsetjmp)
// Record whether or not we're saving the signal mask. stp x0, x30, [sp, #-16]!
str w1, [x0, #(_JB_SIGFLAG * 8)] .cfi_def_cfa_offset 16
.cfi_rel_offset x0, 0
.cfi_rel_offset x30, 8
// Get the cookie and store it along with the signal flag.
mov x0, x1
bl __bionic_setjmp_cookie_get
mov x1, x0
ldr x0, [sp, #0]
str x1, [x0, #(_JB_SIGFLAG * 8)]
// Do we need to save the signal mask? // Do we need to save the signal mask?
cbz w1, 1f tbz w1, #0, 1f
// Save the cookie for later.
stp x1, xzr, [sp, #-16]!
.cfi_adjust_cfa_offset 16
// Save current signal mask. // Save current signal mask.
stp x0, x30, [sp, #-16]!
// The 'how' argument is ignored if new_mask is NULL. // The 'how' argument is ignored if new_mask is NULL.
mov x1, #0 // NULL. mov x1, #0 // NULL.
add x2, x0, #(_JB_SIGMASK * 8) // old_mask. add x2, x0, #(_JB_SIGMASK * 8) // old_mask.
bl sigprocmask bl sigprocmask
ldp x0, x30, [sp], #16
ldp x1, xzr, [sp], #16
.cfi_adjust_cfa_offset -16
1: 1:
// Restore original x0 and lr.
ldp x0, x30, [sp], #16
.cfi_adjust_cfa_offset -16
.cfi_restore x0
.cfi_restore x30
// Mask off the signal flag bit.
bic x1, x1, #1
// Save core registers. // Save core registers.
mov x10, sp mov x10, sp
m_mangle_registers x1, sp_reg=x10
stp x30, x10, [x0, #(_JB_X30_SP * 8)] stp x30, x10, [x0, #(_JB_X30_SP * 8)]
stp x28, x29, [x0, #(_JB_X28_X29 * 8)] stp x28, x29, [x0, #(_JB_X28_X29 * 8)]
stp x26, x27, [x0, #(_JB_X26_X27 * 8)] stp x26, x27, [x0, #(_JB_X26_X27 * 8)]
@ -88,6 +135,7 @@ ENTRY(sigsetjmp)
stp x22, x23, [x0, #(_JB_X22_X23 * 8)] stp x22, x23, [x0, #(_JB_X22_X23 * 8)]
stp x20, x21, [x0, #(_JB_X20_X21 * 8)] stp x20, x21, [x0, #(_JB_X20_X21 * 8)]
str x19, [x0, #(_JB_X19 * 8)] str x19, [x0, #(_JB_X19 * 8)]
m_unmangle_registers x1, sp_reg=x10
// Save floating point registers. // Save floating point registers.
stp d14, d15, [x0, #(_JB_D14_D15 * 8)] stp d14, d15, [x0, #(_JB_D14_D15 * 8)]
@ -102,30 +150,60 @@ END(sigsetjmp)
// void siglongjmp(sigjmp_buf env, int value); // void siglongjmp(sigjmp_buf env, int value);
ENTRY(siglongjmp) ENTRY(siglongjmp)
// Do we need to restore the signal mask? // Do we need to restore the signal mask?
ldr w9, [x0, #(_JB_SIGFLAG * 8)] ldr x2, [x0, #(_JB_SIGFLAG * 8)]
cbz w9, 1f tbz w2, #0, 1f
stp x0, x30, [sp, #-16]!
.cfi_adjust_cfa_offset 16
.cfi_rel_offset x0, 0
.cfi_rel_offset x30, 8
// Restore signal mask. // Restore signal mask.
stp x0, x30, [sp, #-16]!
mov x19, x1 // Save 'value'. mov x19, x1 // Save 'value'.
mov x2, x0 mov x2, x0
mov x0, #2 // SIG_SETMASK mov x0, #2 // SIG_SETMASK
add x1, x2, #(_JB_SIGMASK * 8) // new_mask. add x1, x2, #(_JB_SIGMASK * 8) // new_mask.
mov x2, #0 // NULL. mov x2, #0 // NULL.
bl sigprocmask bl sigprocmask
mov x1, x19 // Restore 'value'. mov x1, x19 // Restore 'value'.
ldp x0, x30, [sp], #16
// Restore original x0 and lr.
ldp x0, x30, [sp], #16
.cfi_adjust_cfa_offset -16
.cfi_restore x0
.cfi_restore x30
ldr x2, [x0, #(_JB_SIGFLAG * 8)]
1: 1:
// Restore core registers. // Restore core registers.
bic x2, x2, #1
ldp x30, x10, [x0, #(_JB_X30_SP * 8)] ldp x30, x10, [x0, #(_JB_X30_SP * 8)]
mov sp, x10
ldp x28, x29, [x0, #(_JB_X28_X29 * 8)] ldp x28, x29, [x0, #(_JB_X28_X29 * 8)]
ldp x26, x27, [x0, #(_JB_X26_X27 * 8)] ldp x26, x27, [x0, #(_JB_X26_X27 * 8)]
ldp x24, x25, [x0, #(_JB_X24_X25 * 8)] ldp x24, x25, [x0, #(_JB_X24_X25 * 8)]
ldp x22, x23, [x0, #(_JB_X22_X23 * 8)] ldp x22, x23, [x0, #(_JB_X22_X23 * 8)]
ldp x20, x21, [x0, #(_JB_X20_X21 * 8)] ldp x20, x21, [x0, #(_JB_X20_X21 * 8)]
ldr x19, [x0, #(_JB_X19 * 8)] ldr x19, [x0, #(_JB_X19 * 8)]
m_unmangle_registers x2, sp_reg=x10
mov sp, x10
stp x0, x1, [sp, #-16]!
.cfi_adjust_cfa_offset 16
.cfi_rel_offset x0, 0
.cfi_rel_offset x1, 8
stp x30, xzr, [sp, #-16]!
.cfi_adjust_cfa_offset 16
.cfi_rel_offset x30, 0
ldr x0, [x0, #(_JB_SIGFLAG * 8)]
bl __bionic_setjmp_cookie_check
ldp x30, xzr, [sp], #16
.cfi_adjust_cfa_offset -16
.cfi_restore x30
ldp x0, x1, [sp], #16
.cfi_adjust_cfa_offset -16
.cfi_restore x0
.cfi_restore x1
// Restore floating point registers. // Restore floating point registers.
ldp d14, d15, [x0, #(_JB_D14_D15 * 8)] ldp d14, d15, [x0, #(_JB_D14_D15 * 8)]
@ -133,13 +211,6 @@ ENTRY(siglongjmp)
ldp d10, d11, [x0, #(_JB_D10_D11 * 8)] ldp d10, d11, [x0, #(_JB_D10_D11 * 8)]
ldp d8, d9, [x0, #(_JB_D8_D9 * 8)] ldp d8, d9, [x0, #(_JB_D8_D9 * 8)]
// Validate sp (sp mod 16 = 0) and lr (lr mod 4 = 0).
tst x30, #3
b.ne longjmperror
mov x10, sp
tst x10, #15
b.ne longjmperror
// Set return value. // Set return value.
cmp w1, wzr cmp w1, wzr
csinc w0, w1, wzr, ne csinc w0, w1, wzr, ne