]> granicus.if.org Git - strace/blob - evdev.c
evdev.c: fix printing of unrecognized event type passed to EVIOCGBIT
[strace] / evdev.c
1 /*
2  * Copyright (c) 2015 Etienne Gemsa <etienne.gemsa@lse.epita.fr>
3  * Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "defs.h"
30
31 #ifdef HAVE_LINUX_INPUT_H
32
33 # include <linux/ioctl.h>
34 # include <linux/input.h>
35 # include "xlat/evdev_abs.h"
36 # include "xlat/evdev_autorepeat.h"
37 # include "xlat/evdev_ff_status.h"
38 # include "xlat/evdev_ff_types.h"
39 # include "xlat/evdev_keycode.h"
40 # include "xlat/evdev_leds.h"
41 # include "xlat/evdev_misc.h"
42 # include "xlat/evdev_mtslots.h"
43 # include "xlat/evdev_prop.h"
44 # include "xlat/evdev_relative_axes.h"
45 # include "xlat/evdev_snd.h"
46 # include "xlat/evdev_switch.h"
47 # include "xlat/evdev_sync.h"
48
49 # ifndef SYN_MAX
50 #  define SYN_MAX 0xf
51 # endif
52
53 static void
54 decode_envelope(const struct ff_envelope *envelope)
55 {
56         tprintf(", envelope={attack_length=%" PRIu16
57                 ", attack_level=%" PRIu16
58                 ", fade_length=%" PRIu16
59                 ", fade_level=%#x}",
60                 envelope->attack_length,
61                 envelope->attack_level,
62                 envelope->fade_length,
63                 envelope->fade_level);
64 }
65
66 static int
67 ff_effect_ioctl(struct tcb *tcp, long arg)
68 {
69         tprints(", ");
70
71         struct ff_effect ffe;
72
73         if (umove_or_printaddr(tcp, arg, &ffe))
74                 return 1;
75
76         tprints("{type=");
77         printxval(evdev_ff_types, ffe.type, "FF_???");
78         tprintf(", id=%" PRIu16
79                 ", direction=%" PRIu16 ", ",
80                 ffe.id,
81                 ffe.direction);
82
83         if (abbrev(tcp)) {
84                 tprints("...}");
85                 return 1;
86         }
87
88         tprintf("trigger={button=%" PRIu16
89                 ", interval=%" PRIu16 "}"
90                 ", replay={length=%" PRIu16
91                 ", delay=%" PRIu16 "}",
92                 ffe.trigger.button,
93                 ffe.trigger.interval,
94                 ffe.replay.length,
95                 ffe.replay.delay);
96
97         switch (ffe.type) {
98                 case FF_CONSTANT:
99                         tprintf(", constant={level=%" PRId16,
100                                 ffe.u.constant.level);
101                         decode_envelope(&ffe.u.constant.envelope);
102                         tprints("}");
103                         break;
104                 case FF_RAMP:
105                         tprintf(", ramp={start_level=%" PRId16
106                                 ", end_level=%" PRId16,
107                                 ffe.u.ramp.start_level,
108                                 ffe.u.ramp.end_level);
109                         decode_envelope(&ffe.u.ramp.envelope);
110                         tprints("}");
111                         break;
112                 case FF_PERIODIC:
113                         tprintf(", periodic={waveform=%" PRIu16
114                                 ", period=%" PRIu16
115                                 ", magnitude=%" PRId16
116                                 ", offset=%" PRId16
117                                 ", phase=%" PRIu16,
118                                 ffe.u.periodic.waveform,
119                                 ffe.u.periodic.period,
120                                 ffe.u.periodic.magnitude,
121                                 ffe.u.periodic.offset,
122                                 ffe.u.periodic.phase);
123                         decode_envelope(&ffe.u.periodic.envelope);
124                         tprintf(", custom_len=%u"
125                                 ", custom_data=%#lx}",
126                                 ffe.u.periodic.custom_len,
127                                 (unsigned long) ffe.u.periodic.custom_data);
128                         break;
129                 case FF_RUMBLE:
130                         tprintf(", rumble={strong_magnitude=%" PRIu16
131                                 ", weak_magnitude=%" PRIu16 "}",
132                                 ffe.u.rumble.strong_magnitude,
133                                 ffe.u.rumble.weak_magnitude);
134                         break;
135                 default:
136                         break;
137         }
138
139         tprints("}");
140
141         return 1;
142 }
143
144 static int
145 abs_ioctl(struct tcb *tcp, long arg)
146 {
147         tprints(", ");
148
149         struct input_absinfo absinfo;
150
151         if (!umove_or_printaddr(tcp, arg, &absinfo)) {
152                 tprintf("{value=%u"
153                         ", minimum=%u, ",
154                         absinfo.value,
155                         absinfo.minimum);
156
157                 if (!abbrev(tcp)) {
158                         tprintf("maximum=%u"
159                                 ", fuzz=%u"
160                                 ", flat=%u",
161                                 absinfo.maximum,
162                                 absinfo.fuzz,
163                                 absinfo.flat);
164 # ifdef HAVE_STRUCT_INPUT_ABSINFO_RESOLUTION
165                         tprintf(", resolution=%u",
166                                 absinfo.resolution);
167 # endif
168                 } else {
169                         tprints("...");
170                 }
171
172                 tprints("}");
173         }
174
175         return 1;
176 }
177
178 static int
179 keycode_ioctl(struct tcb *tcp, long arg)
180 {
181         tprints(", ");
182
183         unsigned int keycode[2];
184
185         if (!umove_or_printaddr(tcp, arg, &keycode)) {
186                 tprintf("[%u, ", keycode[0]);
187                 printxval(evdev_keycode, keycode[1], "KEY_???");
188                 tprints("]");
189         }
190
191         return 1;
192 }
193
194 # ifdef EVIOCGKEYCODE_V2
195 static int
196 keycode_V2_ioctl(struct tcb *tcp, long arg)
197 {
198         tprints(", ");
199
200         struct input_keymap_entry ike;
201
202         if (umove_or_printaddr(tcp, arg, &ike))
203                 return 1;
204
205         tprintf("{flags=%" PRIu8
206                 ", len=%" PRIu8 ", ",
207                 ike.flags,
208                 ike.len);
209
210         if (!abbrev(tcp)) {
211                 unsigned int i;
212
213                 tprintf("index=%" PRIu16 ", keycode=", ike.index);
214                 printxval(evdev_keycode, ike.keycode, "KEY_???");
215                 tprints(", scancode=[");
216                 for (i = 0; i < ARRAY_SIZE(ike.scancode); i++) {
217                         if (i > 0)
218                                 tprints(", ");
219                         tprintf("%" PRIx8, ike.scancode[i]);
220                 }
221                 tprints("]");
222         } else {
223                 tprints("...");
224         }
225
226         tprints("}");
227
228         return 1;
229 }
230 # endif /* EVIOCGKEYCODE_V2 */
231
232 static int
233 getid_ioctl(struct tcb *tcp, long arg)
234 {
235         tprints(", ");
236
237         struct input_id id;
238
239         if (!umove_or_printaddr(tcp, arg, &id))
240                 tprintf("{ID_BUS=%" PRIu16
241                         ", ID_VENDOR=%" PRIu16
242                         ", ID_PRODUCT=%" PRIu16
243                         ", ID_VERSION=%" PRIu16 "}",
244                         id.bustype,
245                         id.vendor,
246                         id.product,
247                         id.version);
248
249         return 1;
250 }
251
252 static int
253 decode_bitset(struct tcb *tcp, long arg, const struct xlat decode_nr[],
254               const unsigned int max_nr, const char *dflt)
255 {
256         tprints(", ");
257
258         unsigned int size;
259         if ((unsigned long) tcp->u_rval > max_nr)
260                 size = max_nr;
261         else
262                 size = tcp->u_rval;
263         char decoded_arg[size];
264
265         if (umove_or_printaddr(tcp, arg, &decoded_arg))
266                 return 1;
267
268         tprints("[");
269
270         int bit_displayed = 0;
271         int i = next_set_bit(decoded_arg, 0, size);
272         if (i < 0) {
273                 tprints(" 0 ");
274         } else {
275                 printxval(decode_nr, i, dflt);
276
277                 while ((i = next_set_bit(decoded_arg, i + 1, size)) > 0) {
278                         if (abbrev(tcp) && bit_displayed >= 3) {
279                                 tprints(", ...");
280                                 break;
281                         }
282                         tprints(", ");
283                         printxval(decode_nr, i, dflt);
284                         bit_displayed++;
285                 }
286         }
287
288         tprints("]");
289
290         return 1;
291 }
292
293 # ifdef EVIOCGMTSLOTS
294 static int
295 mtslots_ioctl(struct tcb *tcp, const unsigned int code, long arg)
296 {
297         tprints(", ");
298
299         const size_t size = _IOC_SIZE(code) / sizeof(int);
300         if (!size) {
301                 printaddr(arg);
302                 return 1;
303         }
304
305         int buffer[size];
306
307         if (umove_or_printaddr(tcp, arg, &buffer))
308                 return 1;
309
310         tprints("{code=");
311         printxval(evdev_mtslots, buffer[0], "ABS_MT_???");
312
313         tprints(", values=[");
314
315         unsigned int i;
316         for (i = 1; i < ARRAY_SIZE(buffer); i++)
317                 tprintf("%s%d", i > 1 ? ", " : "", buffer[i]);
318
319         tprints("]}");
320
321         return 1;
322 }
323 # endif /* EVIOCGMTSLOTS */
324
325 # if defined EVIOCGREP || defined EVIOCSREP
326 static int
327 repeat_ioctl(struct tcb *tcp, long arg)
328 {
329         tprints(", ");
330         printpair_int(tcp, arg, "%u");
331         return 1;
332 }
333 # endif /* EVIOCGREP || EVIOCSREP */
334
335 static int
336 bit_ioctl(struct tcb *tcp, const unsigned int ev_nr, const long arg)
337 {
338         switch (ev_nr) {
339                 case EV_SYN:
340                         return decode_bitset(tcp, arg, evdev_sync,
341                                              SYN_MAX, "SYN_???");
342                 case EV_KEY:
343                         return decode_bitset(tcp, arg, evdev_keycode,
344                                              KEY_MAX, "KEY_???");
345                 case EV_REL:
346                         return decode_bitset(tcp, arg, evdev_relative_axes,
347                                              REL_MAX, "REL_???");
348                 case EV_ABS:
349                         return decode_bitset(tcp, arg, evdev_abs,
350                                              ABS_MAX, "ABS_???");
351                 case EV_MSC:
352                         return decode_bitset(tcp, arg, evdev_misc,
353                                              MSC_MAX, "MSC_???");
354 # ifdef EV_SW
355                 case EV_SW:
356                         return decode_bitset(tcp, arg, evdev_switch,
357                                              SW_MAX, "SW_???");
358 # endif
359                 case EV_LED:
360                         return decode_bitset(tcp, arg, evdev_leds,
361                                              LED_MAX, "LED_???");
362                 case EV_SND:
363                         return decode_bitset(tcp, arg, evdev_snd,
364                                              SND_MAX, "SND_???");
365                 case EV_REP:
366                         return decode_bitset(tcp, arg, evdev_autorepeat,
367                                              REP_MAX, "REP_???");
368                 case EV_FF:
369                         return decode_bitset(tcp, arg, evdev_ff_types,
370                                              FF_MAX, "FF_???");
371                 case EV_PWR:
372                         tprints(", ");
373                         printnum_int(tcp, arg, "%d");
374                         return 1;
375                 case EV_FF_STATUS:
376                         return decode_bitset(tcp, arg, evdev_ff_status,
377                                              FF_STATUS_MAX, "FF_STATUS_???");
378                 default:
379                         tprints(", ");
380                         printaddr(arg);
381                         return 1;
382         }
383 }
384
385 static int
386 evdev_read_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
387 {
388         /* fixed-number fixed-length commands */
389         switch (code) {
390                 case EVIOCGVERSION:
391                         tprints(", ");
392                         printnum_int(tcp, arg, "%#x");
393                         return 1;
394                 case EVIOCGEFFECTS:
395                         tprints(", ");
396                         printnum_int(tcp, arg, "%u");
397                         return 1;
398                 case EVIOCGID:
399                         return getid_ioctl(tcp, arg);
400 # ifdef EVIOCGREP
401                 case EVIOCGREP:
402                         return repeat_ioctl(tcp, arg);
403 # endif
404                 case EVIOCGKEYCODE:
405                         return keycode_ioctl(tcp, arg);
406 # ifdef EVIOCGKEYCODE_V2
407                 case EVIOCGKEYCODE_V2:
408                         return keycode_V2_ioctl(tcp, arg);
409 # endif
410         }
411
412         /* fixed-number variable-length commands */
413         switch (_IOC_NR(code)) {
414 # ifdef EVIOCGMTSLOTS
415                 case _IOC_NR(EVIOCGMTSLOTS(0)):
416                         return mtslots_ioctl(tcp, code, arg);
417 # endif
418                 case _IOC_NR(EVIOCGNAME(0)):
419                 case _IOC_NR(EVIOCGPHYS(0)):
420                 case _IOC_NR(EVIOCGUNIQ(0)):
421                         tprints(", ");
422                         if (syserror(tcp))
423                                 printaddr(arg);
424                         else
425                                 printstr(tcp, arg, tcp->u_rval);
426                         return 1;
427 # ifdef EVIOCGPROP
428                 case _IOC_NR(EVIOCGPROP(0)):
429                         return decode_bitset(tcp, arg, evdev_prop,
430                                              INPUT_PROP_MAX, "PROP_???");
431 # endif
432                 case _IOC_NR(EVIOCGSND(0)):
433                         return decode_bitset(tcp, arg, evdev_snd,
434                                              SND_MAX, "SND_???");
435 # ifdef EVIOCGSW
436                 case _IOC_NR(EVIOCGSW(0)):
437                         return decode_bitset(tcp, arg, evdev_switch,
438                                              SW_MAX, "SW_???");
439 # endif
440                 case _IOC_NR(EVIOCGKEY(0)):
441                         return decode_bitset(tcp, arg, evdev_keycode,
442                                              KEY_MAX, "KEY_???");
443                 case _IOC_NR(EVIOCGLED(0)):
444                         return decode_bitset(tcp, arg, evdev_leds,
445                                              LED_MAX, "LED_???");
446         }
447
448         /* multi-number fixed-length commands */
449         if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0)))
450                 return abs_ioctl(tcp, arg);
451
452         /* multi-number variable-length commands */
453         if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
454                 return bit_ioctl(tcp, _IOC_NR(code) & EV_MAX, arg);
455
456         return 0;
457 }
458
459 static int
460 evdev_write_ioctl(struct tcb *tcp, const unsigned int code, const long arg)
461 {
462         /* fixed-number fixed-length commands */
463         switch (code) {
464 # ifdef EVIOCSREP
465                 case EVIOCSREP:
466                         return repeat_ioctl(tcp, arg);
467 # endif
468                 case EVIOCSKEYCODE:
469                         return keycode_ioctl(tcp, arg);
470 # ifdef EVIOCSKEYCODE_V2
471                 case EVIOCSKEYCODE_V2:
472                         return keycode_V2_ioctl(tcp, arg);
473 # endif
474                 case EVIOCSFF:
475                         return ff_effect_ioctl(tcp, arg);
476                 case EVIOCRMFF:
477                         tprintf(", %d", (int) arg);
478                         return 1;
479                 case EVIOCGRAB:
480 # ifdef EVIOCREVOKE
481                 case EVIOCREVOKE:
482 # endif
483                         tprintf(", %lu", arg);
484                         return 1;
485 # ifdef EVIOCSCLOCKID
486                 case EVIOCSCLOCKID:
487                         tprints(", ");
488                         printnum_int(tcp, arg, "%u");
489                         return 1;
490 # endif
491         }
492
493         /* multi-number fixed-length commands */
494         if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0)))
495                 return abs_ioctl(tcp, arg);
496
497         return 0;
498 }
499
500 int
501 evdev_ioctl(struct tcb *tcp, const unsigned int code, long arg)
502 {
503         switch(_IOC_DIR(code)) {
504                 case _IOC_READ:
505                         if (entering(tcp))
506                                 return 0;
507                         return evdev_read_ioctl(tcp, code, arg);
508                 case _IOC_WRITE:
509                         return evdev_write_ioctl(tcp, code, arg) | RVAL_DECODED;
510                 default:
511                         return RVAL_DECODED;
512         }
513 }
514
515 #endif /* HAVE_LINUX_INPUT_H */