blob: 71f26c042d8bd67beb459f47b29e443a3b26421b [file] [log] [blame]
Dmitry V. Levin53c993d2014-12-11 19:25:02 +00001#include "defs.h"
2
3#ifdef HAVE_PRCTL
4#include <sys/prctl.h>
5
6#include "xlat/prctl_options.h"
7
8static const char *
9unalignctl_string(unsigned int ctl)
10{
11 static char buf[sizeof(int)*2 + 2];
12
13 switch (ctl) {
14#ifdef PR_UNALIGN_NOPRINT
15 case PR_UNALIGN_NOPRINT:
16 return "NOPRINT";
17#endif
18#ifdef PR_UNALIGN_SIGBUS
19 case PR_UNALIGN_SIGBUS:
20 return "SIGBUS";
21#endif
22 default:
23 break;
24 }
25 sprintf(buf, "%x", ctl);
26 return buf;
27}
28
29int
30sys_prctl(struct tcb *tcp)
31{
32 unsigned int i;
33
34 if (entering(tcp)) {
35 printxval(prctl_options, tcp->u_arg[0], "PR_???");
36 switch (tcp->u_arg[0]) {
37#ifdef PR_GETNSHARE
38 case PR_GETNSHARE:
39 break;
40#endif
41#ifdef PR_SET_PDEATHSIG
42 case PR_SET_PDEATHSIG:
43 tprintf(", %lu", tcp->u_arg[1]);
44 break;
45#endif
46#ifdef PR_GET_PDEATHSIG
47 case PR_GET_PDEATHSIG:
48 break;
49#endif
50#ifdef PR_SET_DUMPABLE
51 case PR_SET_DUMPABLE:
52 tprintf(", %lu", tcp->u_arg[1]);
53 break;
54#endif
55#ifdef PR_GET_DUMPABLE
56 case PR_GET_DUMPABLE:
57 break;
58#endif
59#ifdef PR_SET_UNALIGN
60 case PR_SET_UNALIGN:
61 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
62 break;
63#endif
64#ifdef PR_GET_UNALIGN
65 case PR_GET_UNALIGN:
66 tprintf(", %#lx", tcp->u_arg[1]);
67 break;
68#endif
69#ifdef PR_SET_KEEPCAPS
70 case PR_SET_KEEPCAPS:
71 tprintf(", %lu", tcp->u_arg[1]);
72 break;
73#endif
74#ifdef PR_GET_KEEPCAPS
75 case PR_GET_KEEPCAPS:
76 break;
77#endif
78 default:
79 for (i = 1; i < tcp->s_ent->nargs; i++)
80 tprintf(", %#lx", tcp->u_arg[i]);
81 break;
82 }
83 } else {
84 switch (tcp->u_arg[0]) {
85#ifdef PR_GET_PDEATHSIG
86 case PR_GET_PDEATHSIG:
87 if (umove(tcp, tcp->u_arg[1], &i) < 0)
88 tprintf(", %#lx", tcp->u_arg[1]);
89 else
90 tprintf(", {%u}", i);
91 break;
92#endif
93#ifdef PR_GET_DUMPABLE
94 case PR_GET_DUMPABLE:
95 return RVAL_UDECIMAL;
96#endif
97#ifdef PR_GET_UNALIGN
98 case PR_GET_UNALIGN:
99 if (syserror(tcp) || umove(tcp, tcp->u_arg[1], &i) < 0)
100 break;
101 tcp->auxstr = unalignctl_string(i);
102 return RVAL_STR;
103#endif
104#ifdef PR_GET_KEEPCAPS
105 case PR_GET_KEEPCAPS:
106 return RVAL_UDECIMAL;
107#endif
108 default:
109 break;
110 }
111 }
112 return 0;
113}
114#endif /* HAVE_PRCTL */
115
116#if defined X86_64 || defined X32
117# include <asm/prctl.h>
118# include "xlat/archvals.h"
119
120int
121sys_arch_prctl(struct tcb *tcp)
122{
123 if (entering(tcp)) {
124 printxval(archvals, tcp->u_arg[0], "ARCH_???");
125 if (tcp->u_arg[0] == ARCH_SET_GS
126 || tcp->u_arg[0] == ARCH_SET_FS
127 ) {
128 tprintf(", %#lx", tcp->u_arg[1]);
129 }
130 } else {
131 if (tcp->u_arg[0] == ARCH_GET_GS
132 || tcp->u_arg[0] == ARCH_GET_FS
133 ) {
134 long int v;
135 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
136 tprintf(", [%#lx]", v);
137 else
138 tprintf(", %#lx", tcp->u_arg[1]);
139 }
140 }
141 return 0;
142}
143#endif /* X86_64 || X32 */