]> granicus.if.org Git - strace/blob - prctl.c
process.c: move prctl and arch_prctl parsers to a separate file
[strace] / prctl.c
1 #include "defs.h"
2
3 #ifdef HAVE_PRCTL
4 #include <sys/prctl.h>
5
6 #include "xlat/prctl_options.h"
7
8 static const char *
9 unalignctl_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
29 int
30 sys_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
120 int
121 sys_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 */