]> granicus.if.org Git - strace/blob - process.c
tests: tabulate pread64-pwrite64.test
[strace] / process.c
1 /*
2  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4  * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5  * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6  * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7  *                     Linux for s390 port by D.J. Barrow
8  *                    <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
9  * Copyright (c) 2000 PocketPenguins Inc.  Linux for Hitachi SuperH
10  *                    port by Greg Banks <gbanks@pocketpenguins.com>
11  *
12  * All rights reserved.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  * 3. The name of the author may not be used to endorse or promote products
23  *    derived from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  */
36
37 #include "defs.h"
38
39 #ifdef HAVE_ELF_H
40 # include <elf.h>
41 #endif
42
43 #include "xlat/nt_descriptor_types.h"
44
45 #include "regs.h"
46 #include "ptrace.h"
47 #include "xlat/ptrace_cmds.h"
48 #include "xlat/ptrace_setoptions_flags.h"
49 #include "xlat/ptrace_peeksiginfo_flags.h"
50
51 #define uoff(member)    offsetof(struct user, member)
52 #define XLAT_UOFF(member)       { uoff(member), "offsetof(struct user, " #member ")" }
53
54 static const struct xlat struct_user_offsets[] = {
55 #include "userent.h"
56         XLAT_END
57 };
58
59 static void
60 print_user_offset_addr(const kernel_ulong_t addr)
61 {
62         const struct xlat *x;
63
64         for (x = struct_user_offsets; x->str; ++x) {
65                 if (x->val >= addr)
66                         break;
67         }
68
69         if (!x->str) {
70                 printaddr(addr);
71         } else if (x->val > addr) {
72                 if (x == struct_user_offsets) {
73                         printaddr(addr);
74                 } else {
75                         --x;
76                         tprintf("%s + %" PRI_klu,
77                                 x->str, addr - (kernel_ulong_t) x->val);
78                 }
79         } else {
80                 tprints(x->str);
81         }
82 }
83
84 SYS_FUNC(ptrace)
85 {
86         const kernel_ulong_t request = tcp->u_arg[0];
87         const int pid = tcp->u_arg[1];
88         const kernel_ulong_t addr = tcp->u_arg[2];
89         const kernel_ulong_t data = tcp->u_arg[3];
90
91         if (entering(tcp)) {
92                 /* request */
93                 printxval64(ptrace_cmds, request, "PTRACE_???");
94
95                 if (request == PTRACE_TRACEME) {
96                         /* pid, addr, and data are ignored. */
97                         return RVAL_DECODED;
98                 }
99
100                 /* pid */
101                 tprintf(", %d", pid);
102
103                 /* addr */
104                 switch (request) {
105                 case PTRACE_ATTACH:
106                 case PTRACE_INTERRUPT:
107                 case PTRACE_KILL:
108                 case PTRACE_LISTEN:
109                         /* addr and data are ignored */
110                         return RVAL_DECODED;
111                 case PTRACE_PEEKUSER:
112                 case PTRACE_POKEUSER:
113                         tprints(", ");
114                         print_user_offset_addr(addr);
115                         break;
116                 case PTRACE_GETREGSET:
117                 case PTRACE_SETREGSET:
118                         tprints(", ");
119                         printxval(nt_descriptor_types, addr, "NT_???");
120                         break;
121                 case PTRACE_GETSIGMASK:
122                 case PTRACE_SETSIGMASK:
123                 case PTRACE_SECCOMP_GET_FILTER:
124                         tprintf(", %" PRI_klu, addr);
125                         break;
126                 case PTRACE_PEEKSIGINFO: {
127                         tprints(", ");
128                         struct {
129                                 uint64_t off;
130                                 uint32_t flags;
131                                 uint32_t nr;
132                         } psi;
133                         if (umove_or_printaddr(tcp, addr, &psi)) {
134                                 tprints(", ");
135                                 printaddr(data);
136                                 return RVAL_DECODED;
137                         }
138                         tprintf("{off=%" PRIu64 ", flags=", psi.off);
139                         printflags(ptrace_peeksiginfo_flags, psi.flags,
140                                    "PTRACE_PEEKSIGINFO_???");
141                         tprintf(", nr=%u}", psi.nr);
142                         break;
143                 }
144                 default:
145                         tprints(", ");
146                         printaddr(addr);
147                 }
148
149 # if defined IA64 || defined SPARC || defined SPARC64
150                 switch (request) {
151 #  ifdef IA64
152                 case PTRACE_PEEKDATA:
153                 case PTRACE_PEEKTEXT:
154                 case PTRACE_PEEKUSER:
155                         /* data is ignored */
156                         return RVAL_DECODED | RVAL_HEX;
157 #  endif /* IA64 */
158 #  if defined SPARC || defined SPARC64
159                 case PTRACE_GETREGS:
160                 case PTRACE_SETREGS:
161                 case PTRACE_GETFPREGS:
162                 case PTRACE_SETFPREGS:
163                         /* data is ignored */
164                         return RVAL_DECODED;
165 #  endif /* SPARC || SPARC64 */
166                 }
167 # endif /* IA64 || SPARC || SPARC64 */
168
169                 tprints(", ");
170
171                 /* data */
172                 switch (request) {
173                 case PTRACE_CONT:
174                 case PTRACE_DETACH:
175                 case PTRACE_SYSCALL:
176 #ifdef PTRACE_SINGLESTEP
177                 case PTRACE_SINGLESTEP:
178 #endif
179 #ifdef PTRACE_SINGLEBLOCK
180                 case PTRACE_SINGLEBLOCK:
181 #endif
182 #ifdef PTRACE_SYSEMU
183                 case PTRACE_SYSEMU:
184 #endif
185 #ifdef PTRACE_SYSEMU_SINGLESTEP
186                 case PTRACE_SYSEMU_SINGLESTEP:
187 #endif
188                         printsignal(data);
189                         break;
190                 case PTRACE_SEIZE:
191                 case PTRACE_SETOPTIONS:
192 #ifdef PTRACE_OLDSETOPTIONS
193                 case PTRACE_OLDSETOPTIONS:
194 #endif
195                         printflags64(ptrace_setoptions_flags, data, "PTRACE_O_???");
196                         break;
197                 case PTRACE_SETSIGINFO:
198                         printsiginfo_at(tcp, data);
199                         break;
200                 case PTRACE_SETSIGMASK:
201                         print_sigset_addr_len(tcp, data, addr);
202                         break;
203                 case PTRACE_SETREGSET:
204                         tprint_iov(tcp, /*len:*/ 1, data, IOV_DECODE_ADDR);
205                         break;
206 #ifndef IA64
207                 case PTRACE_PEEKDATA:
208                 case PTRACE_PEEKTEXT:
209                 case PTRACE_PEEKUSER:
210 #endif
211                 case PTRACE_GETEVENTMSG:
212                 case PTRACE_GETREGSET:
213                 case PTRACE_GETSIGINFO:
214                 case PTRACE_GETSIGMASK:
215                 case PTRACE_PEEKSIGINFO:
216                 case PTRACE_SECCOMP_GET_FILTER:
217                         if (verbose(tcp)) {
218                                 /* print data on exiting syscall */
219                                 return 0;
220                         }
221                         /* fall through */
222                 default:
223                         printaddr(data);
224                         break;
225                 }
226
227                 return RVAL_DECODED;
228         } else {
229                 switch (request) {
230 #ifndef IA64
231                 case PTRACE_PEEKDATA:
232                 case PTRACE_PEEKTEXT:
233                 case PTRACE_PEEKUSER:
234                         printnum_ptr(tcp, data);
235                         break;
236 #endif
237                 case PTRACE_GETEVENTMSG:
238                         printnum_ulong(tcp, data);
239                         break;
240                 case PTRACE_GETREGSET:
241                         tprint_iov(tcp, /*len:*/ 1, data, IOV_DECODE_ADDR);
242                         break;
243                 case PTRACE_GETSIGINFO:
244                         printsiginfo_at(tcp, data);
245                         break;
246                 case PTRACE_GETSIGMASK:
247                         print_sigset_addr_len(tcp, data, addr);
248                         break;
249                 case PTRACE_PEEKSIGINFO:
250                         print_siginfo_array(tcp, data, tcp->u_rval);
251                         break;
252                 case PTRACE_SECCOMP_GET_FILTER:
253                         print_seccomp_fprog(tcp, data, tcp->u_rval);
254                         break;
255                 }
256         }
257         return 0;
258 }