]> granicus.if.org Git - strace/blob - process.c
xlat: provide fallback definitions for XDP_FLAGS_* constants
[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  * Copyright (c) 1999-2018 The strace developers.
12  *
13  * All rights reserved.
14  *
15  * SPDX-License-Identifier: LGPL-2.1-or-later
16  */
17
18 #include "defs.h"
19
20 #ifdef HAVE_ELF_H
21 # include <elf.h>
22 #endif
23
24 #include "ptrace.h"
25 #include "ptrace_syscall_info.h"
26 #include "regs.h"
27
28 #include "xlat/nt_descriptor_types.h"
29 #include "xlat/ptrace_cmds.h"
30 #include "xlat/ptrace_setoptions_flags.h"
31 #include "xlat/ptrace_peeksiginfo_flags.h"
32
33 #define uoff(member)    offsetof(struct user, member)
34 #define XLAT_UOFF(member)       { uoff(member), "offsetof(struct user, " #member ")" }
35
36 static const struct xlat_data struct_user_offsets_data[] = {
37 #include "userent.h"
38         XLAT_END
39 };
40
41 static const struct xlat struct_user_offsets = {
42         .type = XT_SORTED,
43         .size = ARRAY_SIZE(struct_user_offsets_data) - 1,
44         .data = struct_user_offsets_data,
45 };
46
47 static void
48 print_user_offset_addr(const kernel_ulong_t addr)
49 {
50         const uint64_t last_user_offset = struct_user_offsets.size ?
51                 struct_user_offsets.data[struct_user_offsets.size - 1].val : 0;
52
53         uint64_t base_addr = addr;
54         const char *str = xlookup_le(&struct_user_offsets, &base_addr);
55
56         /* We don't want to pretty print addresses beyond struct user */
57         if (addr > base_addr && base_addr == last_user_offset)
58                 str = NULL;
59
60         if (!str || xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV)
61                 printaddr(addr);
62         if (!str || xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
63                 return;
64
65         if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
66                 tprints(" /* ");
67
68         if (base_addr == addr)
69                 tprints(str);
70         else
71                 tprintf("%s + %" PRI_klu,
72                         str, addr - (kernel_ulong_t) base_addr);
73
74         if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
75                 tprints(" */");
76 }
77
78 SYS_FUNC(ptrace)
79 {
80         const kernel_ulong_t request = tcp->u_arg[0];
81         const int pid = tcp->u_arg[1];
82         const kernel_ulong_t addr = tcp->u_arg[2];
83         const kernel_ulong_t data = tcp->u_arg[3];
84
85         if (entering(tcp)) {
86                 /* request */
87                 printxval64(ptrace_cmds, request, "PTRACE_???");
88
89                 if (request == PTRACE_TRACEME) {
90                         /* pid, addr, and data are ignored. */
91                         return RVAL_DECODED;
92                 }
93
94                 /* pid */
95                 tprintf(", %d", pid);
96
97                 /* addr */
98                 switch (request) {
99                 case PTRACE_ATTACH:
100                 case PTRACE_INTERRUPT:
101                 case PTRACE_KILL:
102                 case PTRACE_LISTEN:
103                         /* addr and data are ignored */
104                         return RVAL_DECODED;
105                 case PTRACE_PEEKUSER:
106                 case PTRACE_POKEUSER:
107                         tprints(", ");
108                         print_user_offset_addr(addr);
109                         break;
110                 case PTRACE_GETREGSET:
111                 case PTRACE_SETREGSET:
112                         tprints(", ");
113                         printxval(nt_descriptor_types, addr, "NT_???");
114                         break;
115                 case PTRACE_GETSIGMASK:
116                 case PTRACE_SETSIGMASK:
117                 case PTRACE_SECCOMP_GET_FILTER:
118                 case PTRACE_SECCOMP_GET_METADATA:
119                 case PTRACE_GET_SYSCALL_INFO:
120                         tprintf(", %" PRI_klu, addr);
121                         break;
122                 case PTRACE_PEEKSIGINFO: {
123                         tprints(", ");
124                         struct {
125                                 uint64_t off;
126                                 uint32_t flags;
127                                 uint32_t nr;
128                         } psi;
129                         if (umove_or_printaddr(tcp, addr, &psi)) {
130                                 tprints(", ");
131                                 printaddr(data);
132                                 return RVAL_DECODED;
133                         }
134                         tprintf("{off=%" PRIu64 ", flags=", psi.off);
135                         printflags(ptrace_peeksiginfo_flags, psi.flags,
136                                    "PTRACE_PEEKSIGINFO_???");
137                         tprintf(", nr=%u}", psi.nr);
138                         break;
139                 }
140                 default:
141                         tprints(", ");
142                         printaddr(addr);
143                 }
144
145 #if defined IA64 || defined SPARC || defined SPARC64
146                 switch (request) {
147 # ifdef IA64
148                 case PTRACE_PEEKDATA:
149                 case PTRACE_PEEKTEXT:
150                 case PTRACE_PEEKUSER:
151                         /* data is ignored */
152                         return RVAL_DECODED | RVAL_HEX;
153 # endif /* IA64 */
154 # if defined SPARC || defined SPARC64
155                 case PTRACE_GETREGS:
156                 case PTRACE_SETREGS:
157                 case PTRACE_GETFPREGS:
158                 case PTRACE_SETFPREGS:
159                         /* data is ignored */
160                         return RVAL_DECODED;
161 # endif /* SPARC || SPARC64 */
162                 }
163 #endif /* IA64 || SPARC || SPARC64 */
164
165                 tprints(", ");
166
167                 /* data */
168                 switch (request) {
169                 case PTRACE_CONT:
170                 case PTRACE_DETACH:
171                 case PTRACE_SYSCALL:
172 #ifdef PTRACE_SINGLESTEP
173                 case PTRACE_SINGLESTEP:
174 #endif
175 #ifdef PTRACE_SINGLEBLOCK
176                 case PTRACE_SINGLEBLOCK:
177 #endif
178 #ifdef PTRACE_SYSEMU
179                 case PTRACE_SYSEMU:
180 #endif
181 #ifdef PTRACE_SYSEMU_SINGLESTEP
182                 case PTRACE_SYSEMU_SINGLESTEP:
183 #endif
184                         printsignal(data);
185                         break;
186                 case PTRACE_SEIZE:
187                 case PTRACE_SETOPTIONS:
188 #ifdef PTRACE_OLDSETOPTIONS
189                 case PTRACE_OLDSETOPTIONS:
190 #endif
191                         printflags64(ptrace_setoptions_flags, data, "PTRACE_O_???");
192                         break;
193                 case PTRACE_SETSIGINFO:
194                         printsiginfo_at(tcp, data);
195                         break;
196                 case PTRACE_SETSIGMASK:
197                         print_sigset_addr_len(tcp, data, addr);
198                         break;
199                 case PTRACE_SETREGSET:
200                         tprint_iov(tcp, /*len:*/ 1, data, IOV_DECODE_ADDR);
201                         break;
202                 case PTRACE_SECCOMP_GET_METADATA:
203                         if (verbose(tcp)) {
204                                 uint64_t filter_off;
205                                 if (addr < sizeof(filter_off) ||
206                                     umove(tcp, data, &filter_off)) {
207                                         printaddr(data);
208                                         return RVAL_DECODED;
209                                 }
210
211                                 tprintf("{filter_off=%" PRIu64, filter_off);
212                                 return 0;
213                         }
214
215                         printaddr(data);
216                         break;
217 #ifndef IA64
218                 case PTRACE_PEEKDATA:
219                 case PTRACE_PEEKTEXT:
220                 case PTRACE_PEEKUSER:
221 #endif
222                 case PTRACE_GETEVENTMSG:
223                 case PTRACE_GETREGSET:
224                 case PTRACE_GETSIGINFO:
225                 case PTRACE_GETSIGMASK:
226                 case PTRACE_PEEKSIGINFO:
227                 case PTRACE_SECCOMP_GET_FILTER:
228                 case PTRACE_GET_SYSCALL_INFO:
229                         if (verbose(tcp)) {
230                                 /* print data on exiting syscall */
231                                 return 0;
232                         }
233                         ATTRIBUTE_FALLTHROUGH;
234                 default:
235                         printaddr(data);
236                         break;
237                 }
238
239                 return RVAL_DECODED;
240         } else {
241                 switch (request) {
242 #ifndef IA64
243                 case PTRACE_PEEKDATA:
244                 case PTRACE_PEEKTEXT:
245                 case PTRACE_PEEKUSER:
246                         printnum_ptr(tcp, data);
247                         break;
248 #endif
249                 case PTRACE_GETEVENTMSG:
250                         printnum_ulong(tcp, data);
251                         break;
252                 case PTRACE_GETREGSET:
253                         tprint_iov(tcp, /*len:*/ 1, data, IOV_DECODE_ADDR);
254                         break;
255                 case PTRACE_GETSIGINFO:
256                         printsiginfo_at(tcp, data);
257                         break;
258                 case PTRACE_GETSIGMASK:
259                         print_sigset_addr_len(tcp, data, addr);
260                         break;
261                 case PTRACE_PEEKSIGINFO:
262                         print_siginfo_array(tcp, data, tcp->u_rval);
263                         break;
264                 case PTRACE_SECCOMP_GET_FILTER:
265                         print_seccomp_fprog(tcp, data, tcp->u_rval);
266                         break;
267                 case PTRACE_SECCOMP_GET_METADATA: {
268                         const size_t offset = sizeof(uint64_t);
269                         uint64_t flags = 0;
270                         size_t ret_size = MIN((kernel_ulong_t) tcp->u_rval,
271                                               offset + sizeof(flags));
272
273                         if (syserror(tcp) || ret_size <= offset) {
274                                 tprints("}");
275                                 return 0;
276                         }
277
278                         if (umoven(tcp, data + offset, ret_size - offset,
279                                    &flags)) {
280                                 tprints(", ...}");
281                                 return 0;
282                         }
283
284                         tprints(", flags=");
285                         printflags64(seccomp_filter_flags, flags,
286                                      "SECCOMP_FILTER_FLAG_???");
287
288                         if ((kernel_ulong_t) tcp->u_rval > ret_size)
289                                 tprints(", ...");
290
291                         tprints("}");
292                         break;
293                 }
294                 case PTRACE_GET_SYSCALL_INFO:
295                         print_ptrace_syscall_info(tcp, data, addr);
296                         break;
297                 }
298         }
299         return 0;
300 }