]> granicus.if.org Git - strace/blobdiff - sigreturn.c
Mpersify RTC_* ioctl parser
[strace] / sigreturn.c
index 7a0dc0620813e2529df022497a8fc466a22f481e..f0dab0da9adbcad6d59c0cebc5931b9a7126a939 100644 (file)
@@ -1,4 +1,5 @@
 #include "defs.h"
+#include <signal.h>
 #include "regs.h"
 #include "ptrace.h"
 
 # error NSIG < 32
 #endif
 
-int
-sys_sigreturn(struct tcb *tcp)
-{
-#if defined AARCH64 || defined ARM
-       if (entering(tcp)) {
-# define SIZEOF_STRUCT_SIGINFO 128
-# define SIZEOF_STRUCT_SIGCONTEXT (21 * 4)
-# define OFFSETOF_STRUCT_UCONTEXT_UC_SIGMASK (5 * 4 + SIZEOF_STRUCT_SIGCONTEXT)
-               const long addr =
-# ifdef AARCH64
-                       current_personality == 1 ?
-                               (*aarch64_sp_ptr + SIZEOF_STRUCT_SIGINFO +
-                                offsetof(struct ucontext, uc_sigmask)) :
-# endif
-                               (*arm_sp_ptr +
-                                OFFSETOF_STRUCT_UCONTEXT_UC_SIGMASK);
-               tprints("{mask=");
-               print_sigset_addr_len(tcp, addr, NSIG / 8);
-               tprints("}");
-       }
-#elif defined(S390) || defined(S390X)
-       if (entering(tcp)) {
-               long mask[NSIG / 8 / sizeof(long)];
-               tprints("{mask=");
-               const long addr = *s390_frame_ptr + __SIGNAL_FRAMESIZE;
-               if (umove(tcp, addr, &mask) < 0) {
-                       tprintf("%#lx", addr);
-               } else {
-# ifdef S390
-                       long v = mask[0];
-                       mask[0] = mask[1];
-                       mask[1] = v;
-# endif
-                       tprintsigmask_addr("", mask);
-               }
-               tprints("}");
-       }
-#elif defined I386 || defined X86_64 || defined X32
-       if (entering(tcp)) {
-# ifndef I386
-               if (current_personality != 1) {
-                       const unsigned long addr =
-                               (unsigned long) *x86_64_rsp_ptr +
-                               offsetof(struct ucontext, uc_sigmask);
-                       tprints("{mask=");
-                       print_sigset_addr_len(tcp, addr, NSIG / 8);
-                       tprints("}");
-                       return 0;
-               }
-# endif
-               /*
-                * On i386, sigcontext is followed on stack by struct fpstate
-                * and after it an additional u32 extramask which holds
-                * upper half of the mask.
-                */
-               struct {
-                       uint32_t struct_sigcontext_padding1[20];
-                       uint32_t oldmask;
-                       uint32_t struct_sigcontext_padding2;
-                       uint32_t struct_fpstate_padding[156];
-                       uint32_t extramask;
-               } frame;
-               tprints("{mask=");
-               if (umove(tcp, *i386_esp_ptr, &frame) < 0) {
-                       tprintf("%#lx", (unsigned long) *i386_esp_ptr);
-               } else {
-                       uint32_t mask[2] = { frame.oldmask, frame.extramask };
-                       tprintsigmask_addr("", mask);
-               }
-               tprints("}");
-       }
-#elif defined(IA64)
-       if (entering(tcp)) {
-               /* offsetof(struct sigframe, sc) */
-#              define OFFSETOF_STRUCT_SIGFRAME_SC      0xA0
-               const long addr = *ia64_frame_ptr + 16 +
-                                 OFFSETOF_STRUCT_SIGFRAME_SC +
-                                 offsetof(struct sigcontext, sc_mask);
-               tprints("{mask=");
-               print_sigset_addr_len(tcp, addr, NSIG / 8);
-               tprints("}");
-       }
-#elif defined(POWERPC)
-       if (entering(tcp)) {
-               long esp = ppc_regs.gpr[1];
-               struct sigcontext sc;
-
-               /* Skip dummy stack frame. */
-#ifdef POWERPC64
-               if (current_personality == 0)
-                       esp += 128;
-               else
-#endif
-                       esp += 64;
+#include "arch_sigreturn.c"
 
-               tprints("{mask=");
-               if (umove(tcp, esp, &sc) < 0) {
-                       tprintf("%#lx", esp);
-               } else {
-                       unsigned long mask[NSIG / 8 / sizeof(long)];
-#ifdef POWERPC64
-                       mask[0] = sc.oldmask | (sc._unused[3] << 32);
-#else
-                       mask[0] = sc.oldmask;
-                       mask[1] = sc._unused[3];
-#endif
-                       tprintsigmask_addr("", mask);
-               }
-               tprints("}");
-       }
-#elif defined(M68K)
-       if (entering(tcp)) {
-               long addr;
-               if (upeek(tcp->pid, 4*PT_USP, &addr) < 0)
-                       return 0;
-               /* Fetch pointer to struct sigcontext.  */
-               if (umove(tcp, addr + 2 * sizeof(int), &addr) < 0)
-                       return 0;
-               unsigned long mask[NSIG / 8 / sizeof(long)];
-               /* Fetch first word of signal mask.  */
-               if (umove(tcp, addr, &mask[0]) < 0)
-                       return 0;
-               /* Fetch remaining words of signal mask, located
-                  immediately before.  */
-               addr -= sizeof(mask) - sizeof(long);
-               if (umoven(tcp, addr, sizeof(mask) - sizeof(long), &mask[1]) < 0)
-                       return 0;
-               tprints("{mask=");
-               tprintsigmask_addr("", mask);
-               tprints("}");
-       }
-#elif defined(ALPHA)
-       if (entering(tcp)) {
-               long addr;
-               if (upeek(tcp->pid, REG_FP, &addr) < 0)
-                       return 0;
-               addr += offsetof(struct sigcontext, sc_mask);
-               tprints("{mask=");
-               print_sigset_addr_len(tcp, addr, NSIG / 8);
-               tprints("}");
-       }
-#elif defined(SPARC) || defined(SPARC64)
-       if (entering(tcp)) {
-               long fp = sparc_regs.u_regs[U_REG_FP] + sizeof(struct sparc_stackf);
-               struct {
-                       struct pt_regs si_regs;
-                       int si_mask;
-                       void *fpu_save;
-                       long insns[2] __attribute__ ((aligned (8)));
-                       unsigned int extramask[NSIG / 8 / sizeof(int) - 1];
-               } frame;
-
-               tprints("{mask=");
-               if (umove(tcp, fp, &frame) < 0) {
-                       tprintf("%#lx", fp);
-               } else {
-                       unsigned int mask[NSIG / 8 / sizeof(int)];
+SYS_FUNC(sigreturn)
+{
+       arch_sigreturn(tcp);
 
-                       mask[0] = frame.si_mask;
-                       memcpy(mask + 1, frame.extramask, sizeof(frame.extramask));
-                       tprintsigmask_addr("", mask);
-               }
-               tprints("}");
-       }
-#elif defined MIPS
-       if (entering(tcp)) {
-# if defined LINUX_MIPSO32
-               /*
-                * offsetof(struct sigframe, sf_mask) ==
-                * sizeof(sf_ass) + sizeof(sf_pad) + sizeof(struct sigcontext)
-                */
-               const long addr = mips_REG_SP + 6 * 4 +
-                                 sizeof(struct sigcontext);
-# else
-               /*
-                * This decodes rt_sigreturn.
-                * The 64-bit ABIs do not have sigreturn.
-                *
-                * offsetof(struct rt_sigframe, rs_uc) ==
-                * sizeof(sf_ass) + sizeof(sf_pad) + sizeof(struct siginfo)
-                */
-               const long addr = mips_REG_SP + 6 * 4 + 128 +
-                                 offsetof(struct ucontext, uc_sigmask);
-# endif
-               tprints("{mask=");
-               print_sigset_addr_len(tcp, addr, NSIG / 8);
-               tprints("}");
-       }
-#elif defined(CRISV10) || defined(CRISV32)
-       if (entering(tcp)) {
-               long regs[PT_MAX+1];
-               if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long)regs) < 0) {
-                       perror_msg("sigreturn: PTRACE_GETREGS");
-                       return 0;
-               }
-               const long addr = regs[PT_USP] +
-                       offsetof(struct sigcontext, oldmask);
-               tprints("{mask=");
-               print_sigset_addr_len(tcp, addr, NSIG / 8);
-               tprints("}");
-       }
-#elif defined(TILE)
-       if (entering(tcp)) {
-               /* offset of ucontext in the kernel's sigframe structure */
-# define SIGFRAME_UC_OFFSET C_ABI_SAVE_AREA_SIZE + sizeof(siginfo_t)
-               const long addr = tile_regs.sp + SIGFRAME_UC_OFFSET +
-                                 offsetof(struct ucontext, uc_sigmask);
-               tprints("{mask=");
-               print_sigset_addr_len(tcp, addr, NSIG / 8);
-               tprints("}");
-       }
-#elif defined(MICROBLAZE)
-       /* TODO: Verify that this is correct...  */
-       if (entering(tcp)) {
-               long addr;
-               /* Read r1, the stack pointer.  */
-               if (upeek(tcp->pid, 1 * 4, &addr) < 0)
-                       return 0;
-               addr += offsetof(struct sigcontext, oldmask);
-               tprints("{mask=");
-               print_sigset_addr_len(tcp, addr, NSIG / 8);
-               tprints("}");
-       }
-#else
-# warning sigreturn/rt_sigreturn signal mask decoding is not implemented for this architecture
-#endif
-       return 0;
+       return RVAL_DECODED;
 }