ARM: fix sigreturn decoding
Decoding of test/sigreturn testcase:
Was:
sigreturn() (mask [QUIT TRAP ABRT BUS SEGV USR2 PIPE STKFLT STOP XCPU VTALRM PROF WINCH IO PWR RTMIN]) = 0
Now:
sigreturn() (mask [CHLD RT_1 RT_3 RT_31 RT_32]) = 0
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
diff --git a/signal.c b/signal.c
index e433306..4e35274 100644
--- a/signal.c
+++ b/signal.c
@@ -84,51 +84,6 @@
};
# endif /* M68K */
#endif /* !HAVE_ASM_SIGCONTEXT_H */
-#if defined(I386) || defined(X86_64)
-struct i386_sigcontext_struct {
- uint16_t gs, __gsh;
- uint16_t fs, __fsh;
- uint16_t es, __esh;
- uint16_t ds, __dsh;
- uint32_t edi;
- uint32_t esi;
- uint32_t ebp;
- uint32_t esp;
- uint32_t ebx;
- uint32_t edx;
- uint32_t ecx;
- uint32_t eax;
- uint32_t trapno;
- uint32_t err;
- uint32_t eip;
- uint16_t cs, __csh;
- uint32_t eflags;
- uint32_t esp_at_signal;
- uint16_t ss, __ssh;
- uint32_t i387;
- uint32_t oldmask;
- uint32_t cr2;
-};
-struct i386_fpstate {
- uint32_t cw;
- uint32_t sw;
- uint32_t tag;
- uint32_t ipoff;
- uint32_t cssel;
- uint32_t dataoff;
- uint32_t datasel;
- uint8_t st[8][10]; /* 8*10 bytes: FP regs */
- uint16_t status;
- uint16_t magic;
- uint32_t fxsr_env[6];
- uint32_t mxcsr;
- uint32_t reserved;
- uint8_t stx[8][16]; /* 8*16 bytes: FP regs, each padded to 16 bytes */
- uint8_t xmm[8][16]; /* 8 XMM regs */
- uint32_t padding1[44];
- uint32_t padding2[12]; /* union with struct _fpx_sw_bytes */
-};
-#endif
#ifndef NSIG
# warning: NSIG is not defined, using 32
@@ -829,12 +784,54 @@
{
#if defined(ARM)
if (entering(tcp)) {
- struct sigcontext_struct sc;
+ struct arm_sigcontext {
+ unsigned long trap_no;
+ unsigned long error_code;
+ unsigned long oldmask;
+ unsigned long arm_r0;
+ unsigned long arm_r1;
+ unsigned long arm_r2;
+ unsigned long arm_r3;
+ unsigned long arm_r4;
+ unsigned long arm_r5;
+ unsigned long arm_r6;
+ unsigned long arm_r7;
+ unsigned long arm_r8;
+ unsigned long arm_r9;
+ unsigned long arm_r10;
+ unsigned long arm_fp;
+ unsigned long arm_ip;
+ unsigned long arm_sp;
+ unsigned long arm_lr;
+ unsigned long arm_pc;
+ unsigned long arm_cpsr;
+ unsigned long fault_address;
+ };
+ struct arm_ucontext {
+ unsigned long uc_flags;
+ unsigned long uc_link; /* struct ucontext* */
+ /* The next three members comprise stack_t struct: */
+ unsigned long ss_sp; /* void* */
+ unsigned long ss_flags; /* int */
+ unsigned long ss_size; /* size_t */
+ struct arm_sigcontext sc;
+ /* These two members are sigset_t: */
+ unsigned long uc_sigmask[2];
+ /* more fields follow, which we aren't interested in */
+ };
+ struct arm_ucontext uc;
sigset_t sigm;
- if (umove(tcp, arm_regs.ARM_sp, &sc) < 0)
+ if (umove(tcp, arm_regs.ARM_sp, &uc) < 0)
return 0;
- long_to_sigset(sc.oldmask, &sigm);
- tprints(sprintsigmask(") (mask ", &sigm, 0));
+ /* Kernel fills out uc.sc.oldmask too when it sets up signal stack,
+ * but for sigmask restore, sigreturn syscall uses uc.uc_sigmask instead.
+ * long_to_sigset(uc.sc.oldmask, &sigm);
+ * tprints(sprintsigmask(") (mask ", &sigm, 0));
+ */
+ sigemptyset(&sigm);
+ ((uint32_t*)&sigm)[0] = uc.uc_sigmask[0];
+ ((uint32_t*)&sigm)[1] = uc.uc_sigmask[1];
+ tprints(sprintsigmask(") (mask ", &sigm, /*rt:*/ 1));
}
#elif defined(S390) || defined(S390X)
if (entering(tcp)) {
@@ -852,6 +849,49 @@
return 0;
# endif
if (entering(tcp)) {
+ struct i386_sigcontext_struct {
+ uint16_t gs, __gsh;
+ uint16_t fs, __fsh;
+ uint16_t es, __esh;
+ uint16_t ds, __dsh;
+ uint32_t edi;
+ uint32_t esi;
+ uint32_t ebp;
+ uint32_t esp;
+ uint32_t ebx;
+ uint32_t edx;
+ uint32_t ecx;
+ uint32_t eax;
+ uint32_t trapno;
+ uint32_t err;
+ uint32_t eip;
+ uint16_t cs, __csh;
+ uint32_t eflags;
+ uint32_t esp_at_signal;
+ uint16_t ss, __ssh;
+ uint32_t i387;
+ uint32_t oldmask;
+ uint32_t cr2;
+ };
+ struct i386_fpstate {
+ uint32_t cw;
+ uint32_t sw;
+ uint32_t tag;
+ uint32_t ipoff;
+ uint32_t cssel;
+ uint32_t dataoff;
+ uint32_t datasel;
+ uint8_t st[8][10]; /* 8*10 bytes: FP regs */
+ uint16_t status;
+ uint16_t magic;
+ uint32_t fxsr_env[6];
+ uint32_t mxcsr;
+ uint32_t reserved;
+ uint8_t stx[8][16]; /* 8*16 bytes: FP regs, each padded to 16 bytes */
+ uint8_t xmm[8][16]; /* 8 XMM regs */
+ uint32_t padding1[44];
+ uint32_t padding2[12]; /* union with struct _fpx_sw_bytes */
+ };
struct {
struct i386_sigcontext_struct sc;
struct i386_fpstate fp;