Add a checksum to jmp_buf on AArch64.

Bug: http://b/27417786
Change-Id: I17c22dc28a46dd6b678b449b506b0da978f3793e
This commit is contained in:
Josh Gao 2016-03-02 19:45:29 -08:00
parent a4c69137c6
commit 0c3655a864

View file

@ -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 @@ ENTRY(sigsetjmp)
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