From c244fcb8a3396f94976a56379cce144c4451c3d4 Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Tue, 29 Mar 2016 14:34:03 -0700 Subject: [PATCH] Delete lies from x86_64 setjmp implementation. Previously, the implementation of setjmp on x86_64 claimed that sigprocmask would write to two longs' worth of bytes. Bug: http://b/27856501 Change-Id: I9f32b40ac773a0cd91a976aace5bfba6e67fb0f8 --- libc/arch-x86_64/bionic/setjmp.S | 19 ++++++++++++++++--- tests/signal_test.cpp | 10 ++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/libc/arch-x86_64/bionic/setjmp.S b/libc/arch-x86_64/bionic/setjmp.S index 56ebb074f..92bd5a9a8 100644 --- a/libc/arch-x86_64/bionic/setjmp.S +++ b/libc/arch-x86_64/bionic/setjmp.S @@ -35,8 +35,22 @@ #include -// These are only the callee-saved registers. Code calling setjmp -// will expect the rest to be clobbered anyway. + +// The internal structure of a jmp_buf is totally private. +// Current layout (changes from release to release): +// +// word name description +// 0 rbx registers +// 1 rbp +// 2 r12 +// 3 r13 +// 4 r14 +// 5 r15 +// 6 rsp +// 7 pc +// 8 sigflag/cookie setjmp cookie in top 31 bits, signal mask flag in low bit +// 9 sigmask signal mask (includes rt signals as well) +// 10 reserved #define _JB_RBX 0 #define _JB_RBP 1 @@ -48,7 +62,6 @@ #define _JB_PC 7 #define _JB_SIGFLAG 8 #define _JB_SIGMASK 9 -#define _JB_SIGMASK_RT 10 // sigprocmask will write here too. #define MANGLE_REGISTERS 1 .macro m_mangle_registers reg diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp index 32308aa19..c5128eafc 100644 --- a/tests/signal_test.cpp +++ b/tests/signal_test.cpp @@ -411,4 +411,14 @@ TEST(signal, rt_tgsigqueueinfo) { << sent.si_code << ", received " << received.si_code << error_msg; } + +#if defined(__arm__) || defined(__aarch64__) || defined(__i386__) || defined(__x86_64__) +TEST(signal, sigset_size) { + // The setjmp implementations for ARM, AArch64, x86, and x86_64 assume that sigset_t can fit in a + // long. This is true because ARM and x86 have broken rt signal support, and AArch64 and x86_64 + // both have a SIGRTMAX defined as 64. + static_assert(sizeof(sigset_t) <= sizeof(long), "sigset_t doesn't fit in a long"); +} + +#endif #endif