process.c: move prctl and arch_prctl parsers to a separate file
* prctl.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* process.c: Move sys_prctl, sys_arch_prctl, and related code to prctl.c.
diff --git a/prctl.c b/prctl.c
new file mode 100644
index 0000000..71f26c0
--- /dev/null
+++ b/prctl.c
@@ -0,0 +1,143 @@
+#include "defs.h"
+
+#ifdef HAVE_PRCTL
+#include <sys/prctl.h>
+
+#include "xlat/prctl_options.h"
+
+static const char *
+unalignctl_string(unsigned int ctl)
+{
+ static char buf[sizeof(int)*2 + 2];
+
+ switch (ctl) {
+#ifdef PR_UNALIGN_NOPRINT
+ case PR_UNALIGN_NOPRINT:
+ return "NOPRINT";
+#endif
+#ifdef PR_UNALIGN_SIGBUS
+ case PR_UNALIGN_SIGBUS:
+ return "SIGBUS";
+#endif
+ default:
+ break;
+ }
+ sprintf(buf, "%x", ctl);
+ return buf;
+}
+
+int
+sys_prctl(struct tcb *tcp)
+{
+ unsigned int i;
+
+ if (entering(tcp)) {
+ printxval(prctl_options, tcp->u_arg[0], "PR_???");
+ switch (tcp->u_arg[0]) {
+#ifdef PR_GETNSHARE
+ case PR_GETNSHARE:
+ break;
+#endif
+#ifdef PR_SET_PDEATHSIG
+ case PR_SET_PDEATHSIG:
+ tprintf(", %lu", tcp->u_arg[1]);
+ break;
+#endif
+#ifdef PR_GET_PDEATHSIG
+ case PR_GET_PDEATHSIG:
+ break;
+#endif
+#ifdef PR_SET_DUMPABLE
+ case PR_SET_DUMPABLE:
+ tprintf(", %lu", tcp->u_arg[1]);
+ break;
+#endif
+#ifdef PR_GET_DUMPABLE
+ case PR_GET_DUMPABLE:
+ break;
+#endif
+#ifdef PR_SET_UNALIGN
+ case PR_SET_UNALIGN:
+ tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
+ break;
+#endif
+#ifdef PR_GET_UNALIGN
+ case PR_GET_UNALIGN:
+ tprintf(", %#lx", tcp->u_arg[1]);
+ break;
+#endif
+#ifdef PR_SET_KEEPCAPS
+ case PR_SET_KEEPCAPS:
+ tprintf(", %lu", tcp->u_arg[1]);
+ break;
+#endif
+#ifdef PR_GET_KEEPCAPS
+ case PR_GET_KEEPCAPS:
+ break;
+#endif
+ default:
+ for (i = 1; i < tcp->s_ent->nargs; i++)
+ tprintf(", %#lx", tcp->u_arg[i]);
+ break;
+ }
+ } else {
+ switch (tcp->u_arg[0]) {
+#ifdef PR_GET_PDEATHSIG
+ case PR_GET_PDEATHSIG:
+ if (umove(tcp, tcp->u_arg[1], &i) < 0)
+ tprintf(", %#lx", tcp->u_arg[1]);
+ else
+ tprintf(", {%u}", i);
+ break;
+#endif
+#ifdef PR_GET_DUMPABLE
+ case PR_GET_DUMPABLE:
+ return RVAL_UDECIMAL;
+#endif
+#ifdef PR_GET_UNALIGN
+ case PR_GET_UNALIGN:
+ if (syserror(tcp) || umove(tcp, tcp->u_arg[1], &i) < 0)
+ break;
+ tcp->auxstr = unalignctl_string(i);
+ return RVAL_STR;
+#endif
+#ifdef PR_GET_KEEPCAPS
+ case PR_GET_KEEPCAPS:
+ return RVAL_UDECIMAL;
+#endif
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+#endif /* HAVE_PRCTL */
+
+#if defined X86_64 || defined X32
+# include <asm/prctl.h>
+# include "xlat/archvals.h"
+
+int
+sys_arch_prctl(struct tcb *tcp)
+{
+ if (entering(tcp)) {
+ printxval(archvals, tcp->u_arg[0], "ARCH_???");
+ if (tcp->u_arg[0] == ARCH_SET_GS
+ || tcp->u_arg[0] == ARCH_SET_FS
+ ) {
+ tprintf(", %#lx", tcp->u_arg[1]);
+ }
+ } else {
+ if (tcp->u_arg[0] == ARCH_GET_GS
+ || tcp->u_arg[0] == ARCH_GET_FS
+ ) {
+ long int v;
+ if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
+ tprintf(", [%#lx]", v);
+ else
+ tprintf(", %#lx", tcp->u_arg[1]);
+ }
+ }
+ return 0;
+}
+#endif /* X86_64 || X32 */