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