OSDN Git Service

Implement setjmp cookies on AArch64.
authorJosh Gao <jmgao@google.com>
Fri, 11 Sep 2015 22:23:32 +0000 (15:23 -0700)
committerJosh Gao <jmgao@google.com>
Thu, 17 Sep 2015 21:07:24 +0000 (14:07 -0700)
Bug: http://b/23942752
Change-Id: I81408ef0dd53010140b51e3083d357d3f2961112

libc/arch-arm64/bionic/setjmp.S

index ba0a226..c06a671 100644 (file)
 #define _JB_D10_D11     (_JB_D12_D13 + 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)
   mov w1, #1
   b sigsetjmp
@@ -64,23 +87,47 @@ END(_setjmp)
 
 // int sigsetjmp(sigjmp_buf env, int save_signal_mask);
 ENTRY(sigsetjmp)
-  // Record whether or not we're saving the signal mask.
-  str w1, [x0, #(_JB_SIGFLAG * 8)]
+  stp x0, x30, [sp, #-16]!
+  .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?
-  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.
-  stp x0, x30, [sp, #-16]!
   // The 'how' argument is ignored if new_mask is NULL.
   mov x1, #0 // NULL.
   add x2, x0, #(_JB_SIGMASK * 8) // old_mask.
   bl sigprocmask
-  ldp x0, x30, [sp], #16
+
+  ldp x1, xzr, [sp], #16
+  .cfi_adjust_cfa_offset -16
 
 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.
   mov x10, sp
+  m_mangle_registers x1, sp_reg=x10
   stp x30, x10, [x0, #(_JB_X30_SP  * 8)]
   stp x28, x29, [x0, #(_JB_X28_X29 * 8)]
   stp x26, x27, [x0, #(_JB_X26_X27 * 8)]
@@ -88,6 +135,7 @@ ENTRY(sigsetjmp)
   stp x22, x23, [x0, #(_JB_X22_X23 * 8)]
   stp x20, x21, [x0, #(_JB_X20_X21 * 8)]
   str x19,      [x0, #(_JB_X19     * 8)]
+  m_unmangle_registers x1, sp_reg=x10
 
   // Save floating point registers.
   stp d14, d15, [x0, #(_JB_D14_D15 * 8)]
@@ -102,30 +150,60 @@ END(sigsetjmp)
 // void siglongjmp(sigjmp_buf env, int value);
 ENTRY(siglongjmp)
   // Do we need to restore the signal mask?
-  ldr w9, [x0, #(_JB_SIGFLAG * 8)]
-  cbz w9, 1f
+  ldr x2, [x0, #(_JB_SIGFLAG * 8)]
+  tbz w2, #0, 1f
 
-  // Restore signal mask.
   stp x0, x30, [sp, #-16]!
+  .cfi_adjust_cfa_offset 16
+  .cfi_rel_offset x0, 0
+  .cfi_rel_offset x30, 8
+
+  // Restore signal mask.
   mov x19, x1 // Save 'value'.
+
   mov x2, x0
   mov x0, #2 // SIG_SETMASK
   add x1, x2, #(_JB_SIGMASK * 8) // new_mask.
   mov x2, #0 // NULL.
   bl sigprocmask
   mov x1, x19 // Restore 'value'.
+
+  // 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:
   // Restore core registers.
+  bic x2, x2, #1
   ldp x30, x10, [x0, #(_JB_X30_SP  * 8)]
-  mov sp, x10
   ldp x28, x29, [x0, #(_JB_X28_X29 * 8)]
   ldp x26, x27, [x0, #(_JB_X26_X27 * 8)]
   ldp x24, x25, [x0, #(_JB_X24_X25 * 8)]
   ldp x22, x23, [x0, #(_JB_X22_X23 * 8)]
   ldp x20, x21, [x0, #(_JB_X20_X21 * 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.
   ldp d14, d15, [x0, #(_JB_D14_D15 * 8)]
@@ -133,13 +211,6 @@ ENTRY(siglongjmp)
   ldp d10, d11, [x0, #(_JB_D10_D11 * 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.
   cmp w1, wzr
   csinc w0, w1, wzr, ne