Merge "Add libsqlite.so to the grey-list" into nyc-dev
diff --git a/libc/arch-arm/bionic/setjmp.S b/libc/arch-arm/bionic/setjmp.S
index 464f7d8..91d158a 100644
--- a/libc/arch-arm/bionic/setjmp.S
+++ b/libc/arch-arm/bionic/setjmp.S
@@ -36,10 +36,13 @@
 // According to the ARM AAPCS document, we only need to save
 // the following registers:
 //
-//  Core   r4-r14
+//  Core   r4-r11, sp, lr
+//    AAPCS 5.1.1:
+//      A subroutine must preserve the contents of the registers r4-r8, r10, r11
+//      and SP (and r9 in PCS variants that designate r9 as v6).
 //
-//  VFP    d8-d15  (see section 5.1.2.1)
-//
+//  VFP    d8-d15
+//    AAPCS 5.1.2.1:
 //      Registers s16-s31 (d8-d15, q4-q7) must be preserved across subroutine
 //      calls; registers s0-s15 (d0-d7, q0-q3) do not need to be preserved
 //      (and can be used for passing arguments or returning results in standard
@@ -49,14 +52,15 @@
 //  FPSCR  saved because glibc does.
 
 // The internal structure of a jmp_buf is totally private.
-// Current layout (may change in the future):
+// Current layout (changes from release to release):
 //
 // word   name            description
 // 0      sigflag/cookie  setjmp cookie in top 31 bits, signal mask flag in low bit
 // 1      sigmask         signal mask (not used with _setjmp / _longjmp)
 // 2      float_base      base of float registers (d8 to d15)
 // 18     float_state     floating-point status and control register
-// 19     core_base       base of core registers (r4 to r14)
+// 19     core_base       base of core registers (r4-r11, r13-r14)
+// 29     checksum        checksum of all of the core registers, to give better error messages.
 // 30     reserved        reserved entries (room to grow)
 // 64
 //
@@ -69,6 +73,7 @@
 #define _JB_FLOAT_BASE  (_JB_SIGMASK+1)
 #define _JB_FLOAT_STATE (_JB_FLOAT_BASE + (15-8+1)*2)
 #define _JB_CORE_BASE   (_JB_FLOAT_STATE+1)
+#define _JB_CHECKSUM    (_JB_CORE_BASE+10)
 
 ENTRY(setjmp)
   mov r1, #1
@@ -81,6 +86,8 @@
 END(_setjmp)
 
 #define MANGLE_REGISTERS 1
+#define USE_CHECKSUM 1
+
 .macro m_mangle_registers reg
 #if MANGLE_REGISTERS
   eor r4, r4, \reg
@@ -91,7 +98,6 @@
   eor r9, r9, \reg
   eor r10, r10, \reg
   eor r11, r11, \reg
-  eor r12, r12, \reg
   eor r13, r13, \reg
   eor r14, r14, \reg
 #endif
@@ -101,6 +107,14 @@
   m_mangle_registers \reg
 .endm
 
+.macro m_calculate_checksum dst, src, scratch
+  mov \dst, #0
+  .irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28
+    ldr \scratch, [\src, #(\i * 4)]
+    eor \dst, \dst, \scratch
+  .endr
+.endm
+
 // int sigsetjmp(sigjmp_buf env, int save_signal_mask);
 ENTRY(sigsetjmp)
   stmfd sp!, {r0, lr}
@@ -153,8 +167,8 @@
   m_mangle_registers r2
 
   // ARM deprecates using sp in the register list for stmia.
-  stmia r1, {r4-r12, lr}
-  str sp, [r1, #(10 * 4)]
+  stmia r1, {r4-r11, lr}
+  str sp, [r1, #(9 * 4)]
   m_unmangle_registers r2
 
   // Save floating-point registers.
@@ -165,6 +179,12 @@
   fmrx r1, fpscr
   str r1, [r0, #(_JB_FLOAT_STATE * 4)]
 
+#if USE_CHECKSUM
+  // Calculate the checksum.
+  m_calculate_checksum r12, r0, r2
+  str r12, [r0, #(_JB_CHECKSUM * 4)]
+#endif
+
   mov r0, #0
   bx lr
 END(sigsetjmp)
@@ -177,6 +197,15 @@
   .cfi_rel_offset r1, 4
   .cfi_rel_offset lr, 8
 
+#if USE_CHECKSUM
+  // Check the checksum before doing anything.
+  m_calculate_checksum r12, r0, r3
+  ldr r2, [r0, #(_JB_CHECKSUM * 4)]
+
+  teq r2, r12
+  bne __bionic_setjmp_checksum_mismatch
+#endif
+
   // Fetch the signal flag.
   ldr r1, [r0, #(_JB_SIGFLAG * 4)]
 
@@ -203,14 +232,16 @@
   ldr r2, [r0, #(_JB_FLOAT_STATE * 4)]
   fmxr fpscr, r2
 
-  // Restore core registers.
+  // Load the cookie.
   ldr r3, [r0, #(_JB_SIGFLAG * 4)]
   bic r3, r3, #1
+
+  // Restore core registers.
   add r2, r0, #(_JB_CORE_BASE * 4)
 
   // ARM deprecates using sp in the register list for ldmia.
-  ldmia r2, {r4-r12, lr}
-  ldr sp, [r2, #(10 * 4)]
+  ldmia r2, {r4-r11, lr}
+  ldr sp, [r2, #(9 * 4)]
   m_unmangle_registers r3
 
   // Save the return value/address and check the setjmp cookie.
diff --git a/libc/arch-arm64/bionic/setjmp.S b/libc/arch-arm64/bionic/setjmp.S
index c06a671..2550134 100644
--- a/libc/arch-arm64/bionic/setjmp.S
+++ b/libc/arch-arm64/bionic/setjmp.S
@@ -37,6 +37,18 @@
 // NOTE: All the registers saved here will have 64 bit vales.
 //       AAPCS mandates that the higher part of q registers do not need to
 //       be saved by the callee.
+//
+// The internal structure of a jmp_buf is totally private.
+// Current layout (changes from release to release):
+//
+// word   name            description
+// 0      sigflag/cookie  setjmp cookie in top 31 bits, signal mask flag in low bit
+// 1      sigmask         signal mask (not used with _setjmp / _longjmp)
+// 2      core_base       base of core registers (x19-x30, sp)
+// 15     float_base      base of float registers (d8-d15)
+// 23     checksum        checksum of core registers
+// 24     reserved        reserved entries (room to grow)
+// 32
 
 #define _JB_SIGFLAG     0
 #define _JB_SIGMASK     (_JB_SIGFLAG + 1)
@@ -51,8 +63,11 @@
 #define _JB_D12_D13     (_JB_D14_D15 + 2)
 #define _JB_D10_D11     (_JB_D12_D13 + 2)
 #define _JB_D8_D9       (_JB_D10_D11 + 2)
+#define _JB_CHECKSUM    (_JB_D8_D9 + 2)
 
 #define MANGLE_REGISTERS 1
+#define USE_CHECKSUM 1
+
 .macro m_mangle_registers reg, sp_reg
 #if MANGLE_REGISTERS
   eor x19, x19, \reg
@@ -71,6 +86,14 @@
 #endif
 .endm
 
+.macro m_calculate_checksum dst, src, scratch
+  mov \dst, #0
+  .irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22
+    ldr \scratch, [\src, #(\i * 8)]
+    eor \dst, \dst, \scratch
+  .endr
+.endm
+
 .macro m_unmangle_registers reg, sp_reg
   m_mangle_registers \reg, sp_reg=\sp_reg
 .endm
@@ -143,12 +166,27 @@
   stp d10, d11, [x0, #(_JB_D10_D11 * 8)]
   stp d8,  d9,  [x0, #(_JB_D8_D9   * 8)]
 
+#if USE_CHECKSUM
+  // Calculate the checksum.
+  m_calculate_checksum x12, x0, x2
+  str x12, [x0, #(_JB_CHECKSUM * 8)]
+#endif
+
   mov w0, #0
   ret
 END(sigsetjmp)
 
 // void siglongjmp(sigjmp_buf env, int value);
 ENTRY(siglongjmp)
+#if USE_CHECKSUM
+  // Check the checksum before doing anything.
+  m_calculate_checksum x12, x0, x2
+  ldr x2, [x0, #(_JB_CHECKSUM * 8)]
+
+  cmp x2, x12
+  bne __bionic_setjmp_checksum_mismatch
+#endif
+
   // Do we need to restore the signal mask?
   ldr x2, [x0, #(_JB_SIGFLAG * 8)]
   tbz w2, #0, 1f
diff --git a/libc/bionic/setjmp_cookie.cpp b/libc/bionic/setjmp_cookie.cpp
index ce57fd1..3be675a 100644
--- a/libc/bionic/setjmp_cookie.cpp
+++ b/libc/bionic/setjmp_cookie.cpp
@@ -63,3 +63,7 @@
 
   return cookie & 1;
 }
+
+extern "C" __LIBC_HIDDEN__ long __bionic_setjmp_checksum_mismatch() {
+  __libc_fatal("setjmp checksum mismatch");
+}
diff --git a/libdl/libdl.arm.map b/libdl/libdl.arm.map
index 98c0685..9d97bd0 100644
--- a/libdl/libdl.arm.map
+++ b/libdl/libdl.arm.map
@@ -24,12 +24,8 @@
 LIBC_PLATFORM {
   global:
     android_dlwarning;
-} LIBC_N;
-
-LIBC_PRIVATE {
-  global:
     android_get_application_target_sdk_version;
     android_set_application_target_sdk_version;
     android_get_LD_LIBRARY_PATH;
     android_update_LD_LIBRARY_PATH;
-} LIBC_PLATFORM;
+} LIBC_N;
diff --git a/libdl/libdl.arm64.map b/libdl/libdl.arm64.map
index b3de6bf..0a5ac97 100644
--- a/libdl/libdl.arm64.map
+++ b/libdl/libdl.arm64.map
@@ -23,12 +23,8 @@
 LIBC_PLATFORM {
   global:
     android_dlwarning;
-} LIBC_N;
-
-LIBC_PRIVATE {
-  global:
     android_get_application_target_sdk_version;
     android_set_application_target_sdk_version;
     android_get_LD_LIBRARY_PATH;
     android_update_LD_LIBRARY_PATH;
-} LIBC_PLATFORM;
+} LIBC_N;
diff --git a/libdl/libdl.map.txt b/libdl/libdl.map.txt
index e827e22..78ac707 100644
--- a/libdl/libdl.map.txt
+++ b/libdl/libdl.map.txt
@@ -38,12 +38,8 @@
 LIBC_PLATFORM {
   global:
     android_dlwarning;
-} LIBC_N;
-
-LIBC_PRIVATE {
-  global:
     android_get_application_target_sdk_version;
     android_set_application_target_sdk_version;
     android_get_LD_LIBRARY_PATH;
     android_update_LD_LIBRARY_PATH;
-} LIBC_PLATFORM;
+} LIBC_N;
diff --git a/libdl/libdl.mips.map b/libdl/libdl.mips.map
index b3de6bf..0a5ac97 100644
--- a/libdl/libdl.mips.map
+++ b/libdl/libdl.mips.map
@@ -23,12 +23,8 @@
 LIBC_PLATFORM {
   global:
     android_dlwarning;
-} LIBC_N;
-
-LIBC_PRIVATE {
-  global:
     android_get_application_target_sdk_version;
     android_set_application_target_sdk_version;
     android_get_LD_LIBRARY_PATH;
     android_update_LD_LIBRARY_PATH;
-} LIBC_PLATFORM;
+} LIBC_N;
diff --git a/libdl/libdl.mips64.map b/libdl/libdl.mips64.map
index b3de6bf..0a5ac97 100644
--- a/libdl/libdl.mips64.map
+++ b/libdl/libdl.mips64.map
@@ -23,12 +23,8 @@
 LIBC_PLATFORM {
   global:
     android_dlwarning;
-} LIBC_N;
-
-LIBC_PRIVATE {
-  global:
     android_get_application_target_sdk_version;
     android_set_application_target_sdk_version;
     android_get_LD_LIBRARY_PATH;
     android_update_LD_LIBRARY_PATH;
-} LIBC_PLATFORM;
+} LIBC_N;
diff --git a/libdl/libdl.x86.map b/libdl/libdl.x86.map
index b3de6bf..0a5ac97 100644
--- a/libdl/libdl.x86.map
+++ b/libdl/libdl.x86.map
@@ -23,12 +23,8 @@
 LIBC_PLATFORM {
   global:
     android_dlwarning;
-} LIBC_N;
-
-LIBC_PRIVATE {
-  global:
     android_get_application_target_sdk_version;
     android_set_application_target_sdk_version;
     android_get_LD_LIBRARY_PATH;
     android_update_LD_LIBRARY_PATH;
-} LIBC_PLATFORM;
+} LIBC_N;
diff --git a/libdl/libdl.x86_64.map b/libdl/libdl.x86_64.map
index b3de6bf..0a5ac97 100644
--- a/libdl/libdl.x86_64.map
+++ b/libdl/libdl.x86_64.map
@@ -23,12 +23,8 @@
 LIBC_PLATFORM {
   global:
     android_dlwarning;
-} LIBC_N;
-
-LIBC_PRIVATE {
-  global:
     android_get_application_target_sdk_version;
     android_set_application_target_sdk_version;
     android_get_LD_LIBRARY_PATH;
     android_update_LD_LIBRARY_PATH;
-} LIBC_PLATFORM;
+} LIBC_N;
diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp
index c75ab51..b7e856f 100644
--- a/tests/setjmp_test.cpp
+++ b/tests/setjmp_test.cpp
@@ -247,3 +247,17 @@
   *sigflag &= 1;
   EXPECT_DEATH(longjmp(jb, 0), "");
 }
+
+TEST(setjmp, setjmp_cookie_checksum) {
+  jmp_buf jb;
+  int value = setjmp(jb);
+
+  if (value == 0) {
+    // Flip a bit.
+    reinterpret_cast<long*>(jb)[0] ^= 1;
+
+    EXPECT_DEATH(longjmp(jb, 1), "checksum mismatch");
+  } else {
+    fprintf(stderr, "setjmp_cookie_checksum: longjmp succeeded?");
+  }
+}