Implement setjmp cookies on AArch64.
Bug: http://b/23942752 Change-Id: I81408ef0dd53010140b51e3083d357d3f2961112
This commit is contained in:
parent
7fda8d2aa4
commit
54db0df8d6
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user