]> granicus.if.org Git - strace/blobdiff - process.c
2002-12-15 Roland McGrath <roland@redhat.com>
[strace] / process.c
index 6fb953ca52da6ca7621ba066737b542d7ee3bc65..8c9065119950d52b1b17ff89f06abd4ff91b4b44 100644 (file)
--- a/process.c
+++ b/process.c
@@ -6,6 +6,9 @@
  * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *                     Linux for s390 port by D.J. Barrow
  *                    <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
+ * Copyright (c) 2000 PocketPenguins Inc.  Linux for Hitachi SuperH
+ *                    port by Greg Banks <gbanks@pocketpenguins.com>
+
  *
  * All rights reserved.
  *
@@ -457,6 +460,19 @@ struct tcb *tcp;
        return 0;
 }
 
+int
+sys_clone2(tcp)
+struct tcb *tcp;
+{
+       if (exiting(tcp)) {
+               tprintf("child_stack=%#lx, stack_size=%#lx, flags=",
+                       tcp->u_arg[1], tcp->u_arg[2]);
+               if (printflags(clone_flags, tcp->u_arg[0]) == 0)
+                       tprintf("0");
+       }
+       return 0;
+}
+
 #endif
 
 int
@@ -479,15 +495,18 @@ int new;
        if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0) 
                return -1;
        return 0;
+#elif defined(X86_64)
+       /* Attempt to make vfork into fork, which we can follow. */
+       if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0) 
+               return -1;
+       return 0;
 #elif defined(POWERPC)
        if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_R0), new) < 0)
                return -1;
-#elif defined(S390)
-       long    pc;
-       if (upeek(tcp->pid, PT_PSWADDR,&pc)<0)
-               return -1;
-       if (ptrace(PTRACE_POKETEXT, tcp->pid, (char*)(pc-4), new)<0)
-               return -1;
+#elif defined(S390) || defined(S390X)
+       /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
+       if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
+               return -1;
        return 0;
 #elif defined(M68K)
        if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
@@ -509,10 +528,18 @@ int new;
        if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
                return -1;
        return 0;
+#elif defined(IA64)
+       if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
+               return -1;
+       return 0;
 #elif defined(HPPA)
        if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
                return -1;
        return 0;
+#elif defined(SH)
+       if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), new)<0)
+               return -1;
+       return 0;
 #else
 #warning Do not know how to handle change_syscall for this architecture
 #endif /* architecture */
@@ -534,7 +561,7 @@ setarg(tcp, argnum)
 
                ap = ia64_rse_skip_regs(bsp, argnum);
                errno = 0;
-               ptrace(PTRACE_POKEDATA, tcp->pid, ap, tcp->u_arg[argnum]);
+               ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
                if (errno)
                        return -1;
 
@@ -545,6 +572,12 @@ setarg(tcp, argnum)
                if (errno)
                        return -1;
        }
+#elif defined(X86_64)
+       {
+               ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
+               if (errno)
+                       return -1;
+       }
 #elif defined(MIPS)
        {
                errno = 0;
@@ -563,6 +596,18 @@ setarg(tcp, argnum)
                if (errno)
                        return -1;
        }
+#elif defined(S390) || defined(S390X)
+        {
+               if(argnum <= 5)
+                       ptrace(PTRACE_POKEUSER, tcp->pid,
+                              (char *) (argnum==0 ? PT_ORIGGPR2 : 
+                              PT_GPR2 + argnum*sizeof(long)), 
+                              tcp->u_arg[argnum]);
+               else
+                       return -E2BIG;
+               if (errno)
+                       return -1;
+        }
 #else
 # warning Sorry, setargs not implemented for this architecture.
 #endif
@@ -595,14 +640,16 @@ struct tcb *tcp;
                if (!(tcp->flags & TCB_FOLLOWFORK))
                        return 0;
 
-               if (bpt)
-                       clearbpt(tcp);
-
-               if (syserror(tcp))
+               if (syserror(tcp)) {
+                       if (bpt)
+                               clearbpt(tcp);
                        return 0;
+               }
 
                pid = tcp->u_rval;
                if ((tcpchild = alloctcb(pid)) == NULL) {
+                       if (bpt)
+                               clearbpt(tcp);
                        fprintf(stderr, " [tcb table full]\n");
                        kill(pid, SIGKILL); /* XXX */
                        return 0;
@@ -610,12 +657,17 @@ struct tcb *tcp;
 
                /* Attach to the new child */
                if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
+                       if (bpt)
+                               clearbpt(tcp);
                        perror("PTRACE_ATTACH");
                        fprintf(stderr, "Too late?\n");
                        droptcb(tcpchild);
                        return 0;
                }
 
+               if (bpt)
+                       clearbpt(tcp);
+
                tcpchild->flags |= TCB_ATTACHED;
                if (bpt) {
                        tcpchild->flags |= TCB_BPTSET;
@@ -624,6 +676,7 @@ struct tcb *tcp;
                                sizeof tcpchild->inst);
                }
                newoutf(tcpchild);
+               tcpchild->parent = tcp;
                tcp->nchildren++;
                if (!qflag)
                        fprintf(stderr, "Process %d attached\n", pid);
@@ -1075,6 +1128,144 @@ struct tcb *tcp;
        return 0;
 }
 
+#if UNIXWARE >= 2
+
+#include <sys/privilege.h>
+
+
+static struct xlat procpriv_cmds [] = {
+       { SETPRV,       "SETPRV"        },
+       { CLRPRV,       "CLRPRV"        },
+       { PUTPRV,       "PUTPRV"        },
+       { GETPRV,       "GETPRV"        },
+       { CNTPRV,       "CNTPRV"        },
+       { 0,            NULL            },
+};
+
+
+static struct xlat procpriv_priv [] = {
+       { P_OWNER,      "P_OWNER"       },
+       { P_AUDIT,      "P_AUDIT"       },
+       { P_COMPAT,     "P_COMPAT"      },
+       { P_DACREAD,    "P_DACREAD"     },
+       { P_DACWRITE,   "P_DACWRITE"    },
+       { P_DEV,        "P_DEV"         },
+       { P_FILESYS,    "P_FILESYS"     },
+       { P_MACREAD,    "P_MACREAD"     },
+       { P_MACWRITE,   "P_MACWRITE"    },
+       { P_MOUNT,      "P_MOUNT"       },
+       { P_MULTIDIR,   "P_MULTIDIR"    },
+       { P_SETPLEVEL,  "P_SETPLEVEL"   },
+       { P_SETSPRIV,   "P_SETSPRIV"    },
+       { P_SETUID,     "P_SETUID"      },
+       { P_SYSOPS,     "P_SYSOPS"      },
+       { P_SETUPRIV,   "P_SETUPRIV"    },
+       { P_DRIVER,     "P_DRIVER"      },
+       { P_RTIME,      "P_RTIME"       },
+       { P_MACUPGRADE, "P_MACUPGRADE"  },
+       { P_FSYSRANGE,  "P_FSYSRANGE"   },
+       { P_SETFLEVEL,  "P_SETFLEVEL"   },
+       { P_AUDITWR,    "P_AUDITWR"     },
+       { P_TSHAR,      "P_TSHAR"       },
+       { P_PLOCK,      "P_PLOCK"       },
+       { P_CORE,       "P_CORE"        },
+       { P_LOADMOD,    "P_LOADMOD"     },
+       { P_BIND,       "P_BIND"        },
+       { P_ALLPRIVS,   "P_ALLPRIVS"    },
+       { 0,            NULL            },
+};
+
+
+static struct xlat procpriv_type [] = {
+       { PS_FIX,       "PS_FIX"        },
+       { PS_INH,       "PS_INH"        },
+       { PS_MAX,       "PS_MAX"        },
+       { PS_WKG,       "PS_WKG"        },
+       { 0,            NULL            },
+};
+
+
+static void
+printpriv(tcp, addr, len, opt)
+struct tcb *tcp;
+long addr;
+int len;
+struct xlat *opt;
+{
+       priv_t buf [128];
+       int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
+       int dots = len > max;
+       int i;
+       
+       if (len > max) len = max;
+       
+       if (len <= 0 ||
+           umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
+       {
+               tprintf ("%#lx", addr);
+               return;
+       }
+
+       tprintf ("[");
+
+       for (i = 0; i < len; ++i) {
+               char *t, *p;
+
+               if (i) tprintf (", ");
+
+               if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
+                   (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
+               {
+                       tprintf ("%s|%s", t, p);
+               }
+               else {
+                       tprintf ("%#lx", buf [i]);
+               }
+       }
+
+       if (dots) tprintf (" ...");
+
+       tprintf ("]");
+}
+
+
+int
+sys_procpriv(tcp)
+struct tcb *tcp;
+{
+       if (entering(tcp)) {
+               printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
+               switch (tcp->u_arg[0]) {
+                   case CNTPRV:
+                       tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
+                       break;
+
+                   case GETPRV:
+                       break;
+
+                   default:
+                       tprintf (", ");
+                       printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
+                       tprintf (", %ld", tcp->u_arg[2]);
+               }
+       }
+       else if (tcp->u_arg[0] == GETPRV) {
+               if (syserror (tcp)) {
+                       tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
+               }
+               else {
+                       tprintf (", ");
+                       printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
+                       tprintf (", %ld", tcp->u_arg[2]);
+               }
+       }
+       
+       return 0;
+}
+
+#endif
+
+
 void
 fake_execve(tcp, program, argv, envp)
 struct tcb *tcp;
@@ -1198,9 +1389,9 @@ struct tcb *tcp;
                }
        }
 #ifdef LINUX
-#if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(HPPA)
+#if defined(ALPHA) || defined(SPARC) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH)
        tcp->flags |= TCB_WAITEXECVE;
-#endif /* ALPHA || SPARC || POWERPC */
+#endif /* ALPHA || SPARC || POWERPC || IA64 || HPPA || SH */
 #endif /* LINUX */
        return 0;
 }
@@ -1431,213 +1622,6 @@ static struct xlat waitid_types[] = {
        { 0,            NULL            },
 };
 
-static struct xlat siginfo_codes[] = {
-#ifdef SI_NOINFO
-       { SI_NOINFO,    "SI_NOINFO"     },
-#endif
-#ifdef SI_USER
-       { SI_USER,      "SI_USER"       },
-#endif
-#ifdef SI_LWP
-       { SI_LWP,       "SI_LWP"        },
-#endif
-#ifdef SI_QUEUE
-       { SI_QUEUE,     "SI_QUEUE"      },
-#endif
-#ifdef SI_TIMER
-       { SI_TIMER,     "SI_TIMER"      },
-#endif
-#ifdef SI_ASYNCIO
-       { SI_ASYNCIO,   "SI_ASYNCIO"    },
-#endif
-#ifdef SI_MESGQ
-       { SI_MESGQ,     "SI_MESGQ"      },
-#endif
-       { 0,            NULL            },
-};
-
-static struct xlat sigtrap_codes[] = {
-       { TRAP_BRKPT,   "TRAP_BRKPT"    },
-       { TRAP_TRACE,   "TRAP_TRACE"    },
-       { 0,            NULL            },
-};
-
-static struct xlat sigcld_codes[] = {
-       { CLD_EXITED,   "CLD_EXITED"    },
-       { CLD_KILLED,   "CLD_KILLED"    },
-       { CLD_DUMPED,   "CLD_DUMPED"    },
-       { CLD_TRAPPED,  "CLD_TRAPPED"   },
-       { CLD_STOPPED,  "CLD_STOPPED"   },
-       { CLD_CONTINUED,"CLD_CONTINUED" },
-       { 0,            NULL            },
-};
-
-static struct xlat sigpoll_codes[] = {
-       { POLL_IN,      "POLL_IN"       },
-       { POLL_OUT,     "POLL_OUT"      },
-       { POLL_MSG,     "POLL_MSG"      },
-       { POLL_ERR,     "POLL_ERR"      },
-       { POLL_PRI,     "POLL_PRI"      },
-       { POLL_HUP,     "POLL_HUP"      },
-       { 0,            NULL            },
-};
-
-static struct xlat sigprof_codes[] = {
-#ifdef PROF_SIG
-       { PROF_SIG,     "PROF_SIG"      },
-#endif
-       { 0,            NULL            },
-};
-
-static struct xlat sigill_codes[] = {
-       { ILL_ILLOPC,   "ILL_ILLOPC"    },
-       { ILL_ILLOPN,   "ILL_ILLOPN"    },
-       { ILL_ILLADR,   "ILL_ILLADR"    },
-       { ILL_ILLTRP,   "ILL_ILLTRP"    },
-       { ILL_PRVOPC,   "ILL_PRVOPC"    },
-       { ILL_PRVREG,   "ILL_PRVREG"    },
-       { ILL_COPROC,   "ILL_COPROC"    },
-       { ILL_BADSTK,   "ILL_BADSTK"    },
-       { 0,            NULL            },
-};
-
-static struct xlat sigemt_codes[] = {
-#ifdef EMT_TAGOVF
-       { EMT_TAGOVF,   "EMT_TAGOVF"    },
-#endif
-       { 0,            NULL            },
-};
-
-static struct xlat sigfpe_codes[] = {
-       { FPE_INTDIV,   "FPE_INTDIV"    },
-       { FPE_INTOVF,   "FPE_INTOVF"    },
-       { FPE_FLTDIV,   "FPE_FLTDIV"    },
-       { FPE_FLTOVF,   "FPE_FLTOVF"    },
-       { FPE_FLTUND,   "FPE_FLTUND"    },
-       { FPE_FLTRES,   "FPE_FLTRES"    },
-       { FPE_FLTINV,   "FPE_FLTINV"    },
-       { FPE_FLTSUB,   "FPE_FLTSUB"    },
-       { 0,            NULL            },
-};
-
-static struct xlat sigsegv_codes[] = {
-       { SEGV_MAPERR,  "SEGV_MAPERR"   },
-       { SEGV_ACCERR,  "SEGV_ACCERR"   },
-       { 0,            NULL            },
-};
-
-static struct xlat sigbus_codes[] = {
-       { BUS_ADRALN,   "BUS_ADRALN"    },
-       { BUS_ADRERR,   "BUS_ADRERR"    },
-       { BUS_OBJERR,   "BUS_OBJERR"    },
-       { 0,            NULL            },
-};
-
-void
-printsiginfo(sip)
-siginfo_t *sip;
-{
-       char *code;
-
-       tprintf("{si_signo=");
-       printsignal(sip->si_signo);
-       code = xlookup(siginfo_codes, sip->si_code);
-       if (!code) {
-               switch (sip->si_signo) {
-               case SIGTRAP:
-                       code = xlookup(sigtrap_codes, sip->si_code);
-                       break;
-               case SIGCHLD:
-                       code = xlookup(sigcld_codes, sip->si_code);
-                       break;
-               case SIGPOLL:
-                       code = xlookup(sigpoll_codes, sip->si_code);
-                       break;
-               case SIGPROF:
-                       code = xlookup(sigprof_codes, sip->si_code);
-                       break;
-               case SIGILL:
-                       code = xlookup(sigill_codes, sip->si_code);
-                       break;
-               case SIGEMT:
-                       code = xlookup(sigemt_codes, sip->si_code);
-                       break;
-               case SIGFPE:
-                       code = xlookup(sigfpe_codes, sip->si_code);
-                       break;
-               case SIGSEGV:
-                       code = xlookup(sigsegv_codes, sip->si_code);
-                       break;
-               case SIGBUS:
-                       code = xlookup(sigbus_codes, sip->si_code);
-                       break;
-               }
-       }
-       if (code)
-               tprintf(", si_code=%s", code);
-       else
-               tprintf(", si_code=%#x", sip->si_code);
-#ifdef SI_NOINFO
-       if (sip->si_code != SI_NOINFO) {
-#endif
-               if (sip->si_errno) {
-                       if (sip->si_errno < 0 || sip->si_errno >= nerrnos)
-                               tprintf(", si_errno=%d", sip->si_errno);
-                       else
-                               tprintf(", si_errno=%s",
-                                       errnoent[sip->si_errno]);
-               }
-               if (SI_FROMUSER(sip)) {
-#ifdef SI_QUEUE
-                       tprintf(", si_pid=%ld, si_uid=%ld",
-                               sip->si_pid, sip->si_uid);
-                       switch (sip->si_code) {
-                       case SI_QUEUE:
-#ifdef SI_TIMER
-                       case SI_TIMER:
-#endif /* SI_QUEUE */
-                       case SI_ASYNCIO:
-#ifdef SI_MESGQ
-                       case SI_MESGQ:
-#endif /* SI_MESGQ */
-                               tprintf(", si_value=%d",
-                                       sip->si_value.sival_int);
-                               break;
-                       }
-#endif /* SI_QUEUE */
-               }
-               else {
-                       switch (sip->si_signo) {
-                       case SIGCHLD:
-                               tprintf(", si_pid=%ld, si_status=",
-                                       sip->si_pid);
-                               if (sip->si_code == CLD_EXITED)
-                                       tprintf("%d", sip->si_status);
-                               else
-                                       printsignal(sip->si_status);
-                               break;
-                       case SIGILL: case SIGFPE:
-                       case SIGSEGV: case SIGBUS:
-                               tprintf(", si_addr=%#lx",
-                                       (unsigned long) sip->si_addr);
-                               break;
-                       case SIGPOLL:
-                               switch (sip->si_code) {
-                               case POLL_IN: case POLL_OUT: case POLL_MSG:
-                                       tprintf(", si_band=%ld",
-                                               (long) sip->si_band);
-                                       break;
-                               }
-                               break;
-                       }
-               }
-               tprintf(", ...");
-#ifdef SI_NOINFO
-       }
-#endif
-       tprintf("}");
-}
-
 int
 sys_waitid(tcp)
 struct tcb *tcp;
@@ -1664,7 +1648,7 @@ struct tcb *tcp;
                else if (umove(tcp, tcp->u_arg[2], &si) < 0)
                        tprintf("{???}");
                else
-                       printsiginfo(&si);
+                       printsiginfo(&si, verbose (tcp));
                /* options */
                tprintf(", ");
                if (!printflags(wait4_options, tcp->u_arg[3]))
@@ -1771,7 +1755,9 @@ static struct xlat ptrace_cmds[] = {
        { PT_READ_D,            "PT_READ_D"             },
        { PT_WRITE_I,           "PT_WRITE_I"            },
        { PT_WRITE_D,           "PT_WRITE_D"            },
-       { PT_READ_U,            "PT_WRITE_U"            },
+#ifdef PT_READ_U
+       { PT_READ_U,            "PT_READ_U"             },
+#endif
        { PT_CONTINUE,          "PT_CONTINUE"           },
        { PT_KILL,              "PT_KILL"               },
        { PT_STEP,              "PT_STEP"               },
@@ -1793,7 +1779,7 @@ static
 #endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
 struct xlat struct_user_offsets[] = {
 #ifdef LINUX
-#ifdef S390
+#if defined(S390) || defined(S390X)
        { PT_PSWMASK,           "psw_mask"                              },
        { PT_PSWADDR,           "psw_addr"                              },
        { PT_GPR0,              "gpr0"                                  },
@@ -1830,6 +1816,7 @@ struct xlat struct_user_offsets[] = {
        { PT_ACR15,             "acr15"                                 },
        { PT_ORIGGPR2,          "orig_gpr2"                             },
        { PT_FPC,               "fpc"                                   },
+#if defined(S390)
        { PT_FPR0_HI,           "fpr0.hi"                               },
        { PT_FPR0_LO,           "fpr0.lo"                               },
        { PT_FPR1_HI,           "fpr1.hi"                               },
@@ -1862,9 +1849,29 @@ struct xlat struct_user_offsets[] = {
        { PT_FPR14_LO,          "fpr14.lo"                              },
        { PT_FPR15_HI,          "fpr15.hi"                              },
        { PT_FPR15_LO,          "fpr15.lo"                              },
+#endif
+#if defined(S390X)
+       { PT_FPR0,              "fpr0"                                  },
+       { PT_FPR1,              "fpr1"                                  },
+       { PT_FPR2,              "fpr2"                                  },
+       { PT_FPR3,              "fpr3"                                  },
+       { PT_FPR4,              "fpr4"                                  },
+       { PT_FPR5,              "fpr5"                                  },
+       { PT_FPR6,              "fpr6"                                  },
+       { PT_FPR7,              "fpr7"                                  },
+       { PT_FPR8,              "fpr8"                                  },
+       { PT_FPR9,              "fpr9"                                  },
+       { PT_FPR10,             "fpr10"                                 },
+       { PT_FPR11,             "fpr11"                                 },
+       { PT_FPR12,             "fpr12"                                 },
+       { PT_FPR13,             "fpr13"                                 },
+       { PT_FPR14,             "fpr14"                                 },
+       { PT_FPR15,             "fpr15"                                 },
+#endif
        { PT_CR_9,              "cr9"                                   },
        { PT_CR_10,             "cr10"                                  },
        { PT_CR_11,             "cr11"                                  },
+       { PT_IEEE_IP,           "ieee_exception_ip"                     },
 #endif
 #if defined(SPARC)
        /* XXX No support for these offsets yet. */
@@ -2068,6 +2075,35 @@ struct xlat struct_user_offsets[] = {
        { 4*UESP,               "4*UESP"                                },
        { 4*SS,                 "4*SS"                                  },
 #else /* !I386 */
+#ifdef X86_64
+       { 8*RDI,                "8*RDI"                                 },
+       { 8*RSI,                "8*RSI"                                 },
+       { 8*RDX,                "8*RDX"                                 },
+       { 8*R10,                "8*R10" },
+       { 8*R8,                 "8*R8" },
+       { 8*R9,                 "8*R9" },
+       { 8*RBX,                "8*RBX"                                 },
+       { 8*RCX,                "8*RCX"                                 },
+       { 8*RBP,                "8*RBP"                                 },
+       { 8*RAX,                "8*RAX"                                 },
+#if 0
+       { 8*DS,                 "8*DS"                                  },
+       { 8*ES,                 "8*ES"                                  },
+       { 8*FS,                 "8*FS"                                  },
+       { 8*GS,                 "8*GS"                                  },
+#endif
+       { 8*ORIG_RAX,           "8*ORIG_EAX"                            },
+       { 8*RIP,                "8*RIP"                                 },
+       { 8*CS,                 "8*CS"                                  },
+       { 8*EFLAGS,             "8*EFL"                                 },
+       { 8*RSP,                "8*RSP"                         },
+       { 8*SS,                 "8*SS"                                  },
+       { 8*R11,                "8*R11" },
+       { 8*R12,                "8*R12" },
+       { 8*R13,                "8*R13" },
+       { 8*R14,                "8*R14" },
+       { 8*R15,                "8*R15" },
+#endif
 #ifdef M68K
        { 4*PT_D1,              "4*PT_D1"                               },
        { 4*PT_D2,              "4*PT_D2"                               },
@@ -2090,10 +2126,62 @@ struct xlat struct_user_offsets[] = {
        { 4*PT_PC,              "4*PT_PC"                               },
 #endif /* M68K */
 #endif /* !I386 */
-#if !defined(S390) && !defined(MIPS)
+#ifdef SH
+       { 4*REG_REG0,           "4*REG_REG0"                            },
+       { 4*(REG_REG0+1),       "4*REG_REG1"                            },
+       { 4*(REG_REG0+2),       "4*REG_REG2"                            },
+       { 4*(REG_REG0+3),       "4*REG_REG3"                            },
+       { 4*(REG_REG0+4),       "4*REG_REG4"                            },
+       { 4*(REG_REG0+5),       "4*REG_REG5"                            },
+       { 4*(REG_REG0+6),       "4*REG_REG6"                            },
+       { 4*(REG_REG0+7),       "4*REG_REG7"                            },
+       { 4*(REG_REG0+8),       "4*REG_REG8"                            },
+       { 4*(REG_REG0+9),       "4*REG_REG9"                            },
+       { 4*(REG_REG0+10),      "4*REG_REG10"                           },
+       { 4*(REG_REG0+11),      "4*REG_REG11"                           },
+       { 4*(REG_REG0+12),      "4*REG_REG12"                           },
+       { 4*(REG_REG0+13),      "4*REG_REG13"                           },
+       { 4*(REG_REG0+14),      "4*REG_REG14"                           },
+       { 4*REG_REG15,          "4*REG_REG15"                           },
+       { 4*REG_PC,             "4*REG_PC"                              },
+       { 4*REG_PR,             "4*REG_PR"                              },
+       { 4*REG_SR,             "4*REG_SR"                              },
+       { 4*REG_GBR,            "4*REG_GBR"                             },
+       { 4*REG_MACH,           "4*REG_MACH"                            },
+       { 4*REG_MACL,           "4*REG_MACL"                            },
+       { 4*REG_SYSCALL,        "4*REG_SYSCALL"                         },
+       { 4*REG_FPUL,           "4*REG_FPUL"                            },
+       { 4*REG_FPREG0,         "4*REG_FPREG0"                          },
+       { 4*(REG_FPREG0+1),     "4*REG_FPREG1"                          },
+       { 4*(REG_FPREG0+2),     "4*REG_FPREG2"                          },
+       { 4*(REG_FPREG0+3),     "4*REG_FPREG3"                          },
+       { 4*(REG_FPREG0+4),     "4*REG_FPREG4"                          },
+       { 4*(REG_FPREG0+5),     "4*REG_FPREG5"                          },
+       { 4*(REG_FPREG0+6),     "4*REG_FPREG6"                          },
+       { 4*(REG_FPREG0+7),     "4*REG_FPREG7"                          },
+       { 4*(REG_FPREG0+8),     "4*REG_FPREG8"                          },
+       { 4*(REG_FPREG0+9),     "4*REG_FPREG9"                          },
+       { 4*(REG_FPREG0+10),    "4*REG_FPREG10"                         },
+       { 4*(REG_FPREG0+11),    "4*REG_FPREG11"                         },
+       { 4*(REG_FPREG0+12),    "4*REG_FPREG12"                         },
+       { 4*(REG_FPREG0+13),    "4*REG_FPREG13"                         },
+       { 4*(REG_FPREG0+14),    "4*REG_FPREG14"                         },
+       { 4*REG_FPREG15,        "4*REG_FPREG15"                         },
+       { 4*REG_XDREG0,         "4*REG_XDREG0"                          },
+       { 4*(REG_XDREG0+2),     "4*REG_XDREG2"                          },
+       { 4*(REG_XDREG0+4),     "4*REG_XDREG4"                          },
+       { 4*(REG_XDREG0+6),     "4*REG_XDREG6"                          },
+       { 4*(REG_XDREG0+8),     "4*REG_XDREG8"                          },
+       { 4*(REG_XDREG0+10),    "4*REG_XDREG10"                         },
+       { 4*(REG_XDREG0+12),    "4*REG_XDREG12"                         },
+       { 4*REG_XDREG14,        "4*REG_XDREG14"                         },
+       { 4*REG_FPSCR,          "4*REG_FPSCR"                           },
+#endif /* SH */
+
+#if !defined(S390) && !defined(S390X) && !defined(MIPS)
        { uoff(u_fpvalid),      "offsetof(struct user, u_fpvalid)"      },
 #endif
-#ifdef I386
+#if  defined(I386) || defined(X86_64)
        { uoff(i387),           "offsetof(struct user, i387)"           },
 #else /* !I386 */
 #ifdef M68K
@@ -2106,16 +2194,16 @@ struct xlat struct_user_offsets[] = {
        { uoff(start_code),     "offsetof(struct user, start_code)"     },
        { uoff(start_stack),    "offsetof(struct user, start_stack)"    },
        { uoff(signal),         "offsetof(struct user, signal)"         },
-#if !defined(S390) && !defined(MIPS)
+#if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH)
        { uoff(reserved),       "offsetof(struct user, reserved)"       },
 #endif
        { uoff(u_ar0),          "offsetof(struct user, u_ar0)"          },
-#if !defined(ARM) && !defined(MIPS) && !defined(S390)
+#if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
        { uoff(u_fpstate),      "offsetof(struct user, u_fpstate)"      },
 #endif
        { uoff(magic),          "offsetof(struct user, magic)"          },
        { uoff(u_comm),         "offsetof(struct user, u_comm)"         },
-#ifdef I386
+#if defined(I386) || defined(X86_64)
        { uoff(u_debugreg),     "offsetof(struct user, u_debugreg)"     },
 #endif /* I386 */
 #endif /* !IA64 */