Merge "Clean up bcopy cruft."
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/arch-x86_64/string/sse2-memset-slm.S b/libc/arch-x86_64/string/sse2-memset-slm.S
index 48671ec..1cf9f4b 100644
--- a/libc/arch-x86_64/string/sse2-memset-slm.S
+++ b/libc/arch-x86_64/string/sse2-memset-slm.S
@@ -28,11 +28,9 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "cache.h"
+#include <private/bionic_asm.h>
-#ifndef MEMSET
-# define MEMSET memset
-#endif
+#include "cache.h"
#ifndef L
# define L(label) .L##label
@@ -42,30 +40,19 @@
# define ALIGN(n) .p2align n
#endif
-#ifndef cfi_startproc
-# define cfi_startproc .cfi_startproc
-#endif
-#ifndef cfi_endproc
-# define cfi_endproc .cfi_endproc
-#endif
+ENTRY(__memset_chk)
+ # %rdi = dst, %rsi = byte, %rdx = n, %rcx = dst_len
+ cmp %rdx, %rcx
+ jl memset
-#ifndef ENTRY
-# define ENTRY(name) \
- .type name, @function; \
- .globl name; \
-name: \
- cfi_startproc
-#endif
+ # TODO: include __memset_chk_fail in the backtrace?
+ call PIC_PLT(__memset_chk_fail)
+END(__memset_chk)
-#ifndef END
-# define END(name) \
- cfi_endproc; \
- .size name, .-name
-#endif
.section .text.sse2,"ax",@progbits
-ENTRY (MEMSET)
+ENTRY(memset)
movq %rdi, %rax
and $0xff, %rsi
mov $0x0101010101010101, %rcx
@@ -161,4 +148,4 @@
sfence
ret
-END (MEMSET)
+END(memset)
diff --git a/libc/bionic/fortify.cpp b/libc/bionic/fortify.cpp
index a1db2a4..ccbdec0 100644
--- a/libc/bionic/fortify.cpp
+++ b/libc/bionic/fortify.cpp
@@ -153,7 +153,7 @@
return memrchr(s, c, n);
}
-#if !defined(__aarch64__) && !defined(__arm__) // TODO: add optimized assembler for the others too.
+#if !defined(__aarch64__) && !defined(__arm__) && !defined(__x86_64__) // TODO: add optimized assembler for the others too.
// Runtime implementation of __builtin___memset_chk (used directly by compiler, not in headers).
extern "C" void* __memset_chk(void* dst, int byte, size_t count, size_t dst_len) {
__check_count("memset", "count", count);
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/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?");
+ }
+}