]> granicus.if.org Git - strace/blob - evdev.c
tests: add support of multi-line diagnostics to check_h
[strace] / evdev.c
1 /*
2  * Copyright (c) 2015 Etienne Gemsa <etienne.gemsa@lse.epita.fr>
3  * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
4  * Copyright (c) 2015-2019 The strace developers.
5  * All rights reserved.
6  *
7  * SPDX-License-Identifier: LGPL-2.1-or-later
8  */
9
10 #include "defs.h"
11
12 #include "xlat/evdev_abs.h"
13 #include "xlat/evdev_ev.h"
14
15 #ifdef HAVE_LINUX_INPUT_H
16
17 # include <linux/ioctl.h>
18 # include <linux/input.h>
19
20 # include "xlat/evdev_autorepeat.h"
21 # include "xlat/evdev_ff_status.h"
22 # include "xlat/evdev_ff_types.h"
23 # include "xlat/evdev_keycode.h"
24 # include "xlat/evdev_leds.h"
25 # include "xlat/evdev_misc.h"
26 # include "xlat/evdev_mtslots.h"
27 # include "xlat/evdev_prop.h"
28 # include "xlat/evdev_relative_axes.h"
29 # include "xlat/evdev_snd.h"
30 # include "xlat/evdev_switch.h"
31
32 # ifndef SYN_MAX
33 #  define SYN_MAX 0xf
34 # endif
35
36 static int
37 abs_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
38 {
39         tprints(", ");
40
41         struct input_absinfo absinfo;
42
43         if (!umove_or_printaddr(tcp, arg, &absinfo)) {
44                 tprintf("{value=%u"
45                         ", minimum=%u, ",
46                         absinfo.value,
47                         absinfo.minimum);
48
49                 if (!abbrev(tcp)) {
50                         tprintf("maximum=%u"
51                                 ", fuzz=%u"
52                                 ", flat=%u",
53                                 absinfo.maximum,
54                                 absinfo.fuzz,
55                                 absinfo.flat);
56 # ifdef HAVE_STRUCT_INPUT_ABSINFO_RESOLUTION
57                         tprintf(", resolution=%u",
58                                 absinfo.resolution);
59 # endif
60                 } else {
61                         tprints("...");
62                 }
63
64                 tprints("}");
65         }
66
67         return RVAL_IOCTL_DECODED;
68 }
69
70 static int
71 keycode_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
72 {
73         tprints(", ");
74
75         unsigned int keycode[2];
76
77         if (!umove_or_printaddr(tcp, arg, &keycode)) {
78                 tprintf("[%u, ", keycode[0]);
79                 printxval(evdev_keycode, keycode[1], "KEY_???");
80                 tprints("]");
81         }
82
83         return RVAL_IOCTL_DECODED;
84 }
85
86 # ifdef EVIOCGKEYCODE_V2
87 static int
88 keycode_V2_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
89 {
90         tprints(", ");
91
92         struct input_keymap_entry ike;
93
94         if (umove_or_printaddr(tcp, arg, &ike))
95                 return RVAL_IOCTL_DECODED;
96
97         tprintf("{flags=%" PRIu8
98                 ", len=%" PRIu8 ", ",
99                 ike.flags,
100                 ike.len);
101
102         if (!abbrev(tcp)) {
103                 unsigned int i;
104
105                 tprintf("index=%" PRIu16 ", keycode=", ike.index);
106                 printxval(evdev_keycode, ike.keycode, "KEY_???");
107                 tprints(", scancode=[");
108                 for (i = 0; i < ARRAY_SIZE(ike.scancode); i++) {
109                         if (i > 0)
110                                 tprints(", ");
111                         tprintf("%" PRIx8, ike.scancode[i]);
112                 }
113                 tprints("]");
114         } else {
115                 tprints("...");
116         }
117
118         tprints("}");
119
120         return RVAL_IOCTL_DECODED;
121 }
122 # endif /* EVIOCGKEYCODE_V2 */
123
124 static int
125 getid_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
126 {
127         tprints(", ");
128
129         struct input_id id;
130
131         if (!umove_or_printaddr(tcp, arg, &id))
132                 tprintf("{ID_BUS=%" PRIu16
133                         ", ID_VENDOR=%" PRIu16
134                         ", ID_PRODUCT=%" PRIu16
135                         ", ID_VERSION=%" PRIu16 "}",
136                         id.bustype,
137                         id.vendor,
138                         id.product,
139                         id.version);
140
141         return RVAL_IOCTL_DECODED;
142 }
143
144 static int
145 decode_bitset(struct tcb *const tcp, const kernel_ulong_t arg,
146               const struct xlat *decode_nr, const unsigned int max_nr,
147               const char *const dflt)
148 {
149         tprints(", ");
150
151         unsigned int size;
152         unsigned int size_bits;
153
154         if ((kernel_ulong_t) tcp->u_rval > max_nr / 8)
155                 size_bits = max_nr;
156         else
157                 size_bits = tcp->u_rval * 8;
158
159         size = ROUNDUP(ROUNDUP_DIV(size_bits, 8), current_wordsize);
160
161         if (syserror(tcp) || !size) {
162                 printaddr(arg);
163
164                 return RVAL_IOCTL_DECODED;
165         }
166
167         char decoded_arg[size];
168
169         if (umove_or_printaddr(tcp, arg, &decoded_arg))
170                 return RVAL_IOCTL_DECODED;
171
172         if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_RAW) {
173                 tprints("[");
174
175                 int bit_displayed = 0;
176                 int i = next_set_bit(decoded_arg, 0, size_bits);
177                 if (i < 0) {
178                         tprints(" 0 ");
179                 } else {
180                         printxval(decode_nr, i, dflt);
181
182                         while ((i = next_set_bit(decoded_arg, i + 1,
183                                                  size_bits)) > 0) {
184                                 if (abbrev(tcp) && bit_displayed >= 3) {
185                                         tprints(", ...");
186                                         break;
187                                 }
188                                 tprints(", ");
189                                 printxval(decode_nr, i, dflt);
190                                 bit_displayed++;
191                         }
192                 }
193
194                 tprints("]");
195         }
196
197         if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
198                 tprints(" /* ");
199
200         if (xlat_verbose(xlat_verbosity) != XLAT_STYLE_ABBREV) {
201                 uint64_t elem;
202
203                 print_local_array(tcp, decoded_arg, size / current_wordsize,
204                                   &elem, current_wordsize,
205                                   print_xlong_array_member, NULL, 0);
206         }
207
208         if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_VERBOSE)
209                 tprints(" */");
210
211         return RVAL_IOCTL_DECODED;
212 }
213
214 # ifdef EVIOCGMTSLOTS
215 static int
216 mtslots_ioctl(struct tcb *const tcp, const unsigned int code,
217               const kernel_ulong_t arg)
218 {
219         tprints(", ");
220
221         const size_t size = _IOC_SIZE(code) / sizeof(int);
222         if (!size) {
223                 printaddr(arg);
224                 return RVAL_IOCTL_DECODED;
225         }
226
227         int buffer[size];
228
229         if (umove_or_printaddr(tcp, arg, &buffer))
230                 return RVAL_IOCTL_DECODED;
231
232         tprints("{code=");
233         printxval(evdev_mtslots, buffer[0], "ABS_MT_???");
234
235         tprints(", values=[");
236
237         unsigned int i;
238         for (i = 1; i < ARRAY_SIZE(buffer); i++)
239                 tprintf("%s%d", i > 1 ? ", " : "", buffer[i]);
240
241         tprints("]}");
242
243         return RVAL_IOCTL_DECODED;
244 }
245 # endif /* EVIOCGMTSLOTS */
246
247 # if defined EVIOCGREP || defined EVIOCSREP
248 static int
249 repeat_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
250 {
251         tprints(", ");
252         printpair_int(tcp, arg, "%u");
253         return RVAL_IOCTL_DECODED;
254 }
255 # endif /* EVIOCGREP || EVIOCSREP */
256
257 static int
258 bit_ioctl(struct tcb *const tcp, const unsigned int ev_nr,
259           const kernel_ulong_t arg)
260 {
261         switch (ev_nr) {
262                 case 0:
263                         return decode_bitset(tcp, arg, evdev_ev,
264                                              EV_MAX, "EV_???");
265                 case EV_KEY:
266                         return decode_bitset(tcp, arg, evdev_keycode,
267                                              KEY_MAX, "KEY_???");
268                 case EV_REL:
269                         return decode_bitset(tcp, arg, evdev_relative_axes,
270                                              REL_MAX, "REL_???");
271                 case EV_ABS:
272                         return decode_bitset(tcp, arg, evdev_abs,
273                                              ABS_MAX, "ABS_???");
274                 case EV_MSC:
275                         return decode_bitset(tcp, arg, evdev_misc,
276                                              MSC_MAX, "MSC_???");
277                 case EV_SW:
278                         return decode_bitset(tcp, arg, evdev_switch,
279                                              SW_MAX, "SW_???");
280                 case EV_LED:
281                         return decode_bitset(tcp, arg, evdev_leds,
282                                              LED_MAX, "LED_???");
283                 case EV_SND:
284                         return decode_bitset(tcp, arg, evdev_snd,
285                                              SND_MAX, "SND_???");
286                 case EV_REP:
287                         return decode_bitset(tcp, arg, evdev_autorepeat,
288                                              REP_MAX, "REP_???");
289                 case EV_FF:
290                         return decode_bitset(tcp, arg, evdev_ff_types,
291                                              FF_MAX, "FF_???");
292                 case EV_PWR:
293                         tprints(", ");
294                         printnum_int(tcp, arg, "%d");
295                         return RVAL_IOCTL_DECODED;
296                 case EV_FF_STATUS:
297                         return decode_bitset(tcp, arg, evdev_ff_status,
298                                              FF_STATUS_MAX, "FF_STATUS_???");
299                 default:
300                         tprints(", ");
301                         printaddr(arg);
302                         return RVAL_IOCTL_DECODED;
303         }
304 }
305
306 static int
307 evdev_read_ioctl(struct tcb *const tcp, const unsigned int code,
308                  const kernel_ulong_t arg)
309 {
310         /* fixed-number fixed-length commands */
311         switch (code) {
312                 case EVIOCGVERSION:
313                         tprints(", ");
314                         printnum_int(tcp, arg, "%#x");
315                         return RVAL_IOCTL_DECODED;
316                 case EVIOCGEFFECTS:
317                         tprints(", ");
318                         printnum_int(tcp, arg, "%u");
319                         return RVAL_IOCTL_DECODED;
320                 case EVIOCGID:
321                         return getid_ioctl(tcp, arg);
322 # ifdef EVIOCGREP
323                 case EVIOCGREP:
324                         return repeat_ioctl(tcp, arg);
325 # endif
326                 case EVIOCGKEYCODE:
327                         return keycode_ioctl(tcp, arg);
328 # ifdef EVIOCGKEYCODE_V2
329                 case EVIOCGKEYCODE_V2:
330                         return keycode_V2_ioctl(tcp, arg);
331 # endif
332         }
333
334         /* fixed-number variable-length commands */
335         switch (_IOC_NR(code)) {
336 # ifdef EVIOCGMTSLOTS
337                 case _IOC_NR(EVIOCGMTSLOTS(0)):
338                         return mtslots_ioctl(tcp, code, arg);
339 # endif
340                 case _IOC_NR(EVIOCGNAME(0)):
341                 case _IOC_NR(EVIOCGPHYS(0)):
342                 case _IOC_NR(EVIOCGUNIQ(0)):
343                         tprints(", ");
344                         if (syserror(tcp))
345                                 printaddr(arg);
346                         else
347                                 printstrn(tcp, arg, tcp->u_rval);
348                         return RVAL_IOCTL_DECODED;
349 # ifdef EVIOCGPROP
350                 case _IOC_NR(EVIOCGPROP(0)):
351                         return decode_bitset(tcp, arg, evdev_prop,
352                                              INPUT_PROP_MAX, "PROP_???");
353 # endif
354                 case _IOC_NR(EVIOCGSND(0)):
355                         return decode_bitset(tcp, arg, evdev_snd,
356                                              SND_MAX, "SND_???");
357 # ifdef EVIOCGSW
358                 case _IOC_NR(EVIOCGSW(0)):
359                         return decode_bitset(tcp, arg, evdev_switch,
360                                              SW_MAX, "SW_???");
361 # endif
362                 case _IOC_NR(EVIOCGKEY(0)):
363                         return decode_bitset(tcp, arg, evdev_keycode,
364                                              KEY_MAX, "KEY_???");
365                 case _IOC_NR(EVIOCGLED(0)):
366                         return decode_bitset(tcp, arg, evdev_leds,
367                                              LED_MAX, "LED_???");
368         }
369
370         /* multi-number fixed-length commands */
371         if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0)))
372                 return abs_ioctl(tcp, arg);
373
374         /* multi-number variable-length commands */
375         if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
376                 return bit_ioctl(tcp, _IOC_NR(code) & EV_MAX, arg);
377
378         return 0;
379 }
380
381 static int
382 evdev_write_ioctl(struct tcb *const tcp, const unsigned int code,
383                   const kernel_ulong_t arg)
384 {
385         /* fixed-number fixed-length commands */
386         switch (code) {
387 # ifdef EVIOCSREP
388                 case EVIOCSREP:
389                         return repeat_ioctl(tcp, arg);
390 # endif
391                 case EVIOCSKEYCODE:
392                         return keycode_ioctl(tcp, arg);
393 # ifdef EVIOCSKEYCODE_V2
394                 case EVIOCSKEYCODE_V2:
395                         return keycode_V2_ioctl(tcp, arg);
396 # endif
397                 case EVIOCRMFF:
398                         tprintf(", %d", (int) arg);
399                         return RVAL_IOCTL_DECODED;
400                 case EVIOCGRAB:
401 # ifdef EVIOCREVOKE
402                 case EVIOCREVOKE:
403 # endif
404                         tprintf(", %" PRI_klu, arg);
405                         return RVAL_IOCTL_DECODED;
406 # ifdef EVIOCSCLOCKID
407                 case EVIOCSCLOCKID:
408                         tprints(", ");
409                         printnum_int(tcp, arg, "%u");
410                         return RVAL_IOCTL_DECODED;
411 # endif
412                 default: {
413                         int rc = evdev_write_ioctl_mpers(tcp, code, arg);
414
415                         if (rc != RVAL_DECODED)
416                                 return rc;
417                 }
418         }
419
420         /* multi-number fixed-length commands */
421         if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0)))
422                 return abs_ioctl(tcp, arg);
423
424         return 0;
425 }
426
427 void
428 print_evdev_ff_type(const kernel_ulong_t val)
429 {
430         printxval(evdev_ff_types, val, "FF_???");
431 }
432
433 int
434 evdev_ioctl(struct tcb *const tcp,
435             const unsigned int code, const kernel_ulong_t arg)
436 {
437         switch (_IOC_DIR(code)) {
438                 case _IOC_READ:
439                         if (entering(tcp))
440                                 return 0;
441                         return evdev_read_ioctl(tcp, code, arg);
442                 case _IOC_WRITE:
443                         return evdev_write_ioctl(tcp, code, arg) | RVAL_DECODED;
444                 default:
445                         return RVAL_DECODED;
446         }
447 }
448
449 #endif /* HAVE_LINUX_INPUT_H */