]> granicus.if.org Git - strace/blob - evdev.c
Introduce struct_rt_sigframe type
[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  * 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 DEF_MPERS_TYPE(struct_ff_effect)
34
35 # include <linux/ioctl.h>
36 # include <linux/input.h>
37
38 typedef struct ff_effect struct_ff_effect;
39
40 #endif /* HAVE_LINUX_INPUT_H */
41
42 #include MPERS_DEFS
43
44 #ifdef HAVE_LINUX_INPUT_H
45
46 # include "xlat/evdev_autorepeat.h"
47 # include "xlat/evdev_ff_status.h"
48 # include "xlat/evdev_ff_types.h"
49 # include "xlat/evdev_keycode.h"
50 # include "xlat/evdev_leds.h"
51 # include "xlat/evdev_misc.h"
52 # include "xlat/evdev_mtslots.h"
53 # include "xlat/evdev_prop.h"
54 # include "xlat/evdev_relative_axes.h"
55 # include "xlat/evdev_snd.h"
56 # include "xlat/evdev_switch.h"
57 # include "xlat/evdev_sync.h"
58
59 # ifndef SYN_MAX
60 #  define SYN_MAX 0xf
61 # endif
62
63 static void
64 decode_envelope(void *const data)
65 {
66         const struct ff_envelope *const envelope = data;
67
68         tprintf(", envelope={attack_length=%" PRIu16
69                 ", attack_level=%" PRIu16
70                 ", fade_length=%" PRIu16
71                 ", fade_level=%#x}",
72                 envelope->attack_length,
73                 envelope->attack_level,
74                 envelope->fade_length,
75                 envelope->fade_level);
76 }
77
78 static int
79 ff_effect_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
80 {
81         tprints(", ");
82
83         struct_ff_effect ffe;
84
85         if (umove_or_printaddr(tcp, arg, &ffe))
86                 return 1;
87
88         tprints("{type=");
89         printxval(evdev_ff_types, ffe.type, "FF_???");
90         tprintf(", id=%" PRIu16
91                 ", direction=%" PRIu16 ", ",
92                 ffe.id,
93                 ffe.direction);
94
95         if (abbrev(tcp)) {
96                 tprints("...}");
97                 return 1;
98         }
99
100         tprintf("trigger={button=%" PRIu16
101                 ", interval=%" PRIu16 "}"
102                 ", replay={length=%" PRIu16
103                 ", delay=%" PRIu16 "}",
104                 ffe.trigger.button,
105                 ffe.trigger.interval,
106                 ffe.replay.length,
107                 ffe.replay.delay);
108
109         switch (ffe.type) {
110                 case FF_CONSTANT:
111                         tprintf(", constant={level=%" PRId16,
112                                 ffe.u.constant.level);
113                         decode_envelope(&ffe.u.constant.envelope);
114                         tprints("}");
115                         break;
116                 case FF_RAMP:
117                         tprintf(", ramp={start_level=%" PRId16
118                                 ", end_level=%" PRId16,
119                                 ffe.u.ramp.start_level,
120                                 ffe.u.ramp.end_level);
121                         decode_envelope(&ffe.u.ramp.envelope);
122                         tprints("}");
123                         break;
124                 case FF_PERIODIC:
125                         tprintf(", periodic={waveform=%" PRIu16
126                                 ", period=%" PRIu16
127                                 ", magnitude=%" PRId16
128                                 ", offset=%" PRId16
129                                 ", phase=%" PRIu16,
130                                 ffe.u.periodic.waveform,
131                                 ffe.u.periodic.period,
132                                 ffe.u.periodic.magnitude,
133                                 ffe.u.periodic.offset,
134                                 ffe.u.periodic.phase);
135                         decode_envelope(&ffe.u.periodic.envelope);
136                         tprintf(", custom_len=%u, custom_data=",
137                                 ffe.u.periodic.custom_len);
138                         printaddr(ptr_to_kulong(ffe.u.periodic.custom_data));
139                         tprints("}");
140                         break;
141                 case FF_RUMBLE:
142                         tprintf(", rumble={strong_magnitude=%" PRIu16
143                                 ", weak_magnitude=%" PRIu16 "}",
144                                 ffe.u.rumble.strong_magnitude,
145                                 ffe.u.rumble.weak_magnitude);
146                         break;
147                 default:
148                         break;
149         }
150
151         tprints("}");
152
153         return 1;
154 }
155
156 static int
157 abs_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
158 {
159         tprints(", ");
160
161         struct input_absinfo absinfo;
162
163         if (!umove_or_printaddr(tcp, arg, &absinfo)) {
164                 tprintf("{value=%u"
165                         ", minimum=%u, ",
166                         absinfo.value,
167                         absinfo.minimum);
168
169                 if (!abbrev(tcp)) {
170                         tprintf("maximum=%u"
171                                 ", fuzz=%u"
172                                 ", flat=%u",
173                                 absinfo.maximum,
174                                 absinfo.fuzz,
175                                 absinfo.flat);
176 # ifdef HAVE_STRUCT_INPUT_ABSINFO_RESOLUTION
177                         tprintf(", resolution=%u",
178                                 absinfo.resolution);
179 # endif
180                 } else {
181                         tprints("...");
182                 }
183
184                 tprints("}");
185         }
186
187         return 1;
188 }
189
190 static int
191 keycode_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
192 {
193         tprints(", ");
194
195         unsigned int keycode[2];
196
197         if (!umove_or_printaddr(tcp, arg, &keycode)) {
198                 tprintf("[%u, ", keycode[0]);
199                 printxval(evdev_keycode, keycode[1], "KEY_???");
200                 tprints("]");
201         }
202
203         return 1;
204 }
205
206 # ifdef EVIOCGKEYCODE_V2
207 static int
208 keycode_V2_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
209 {
210         tprints(", ");
211
212         struct input_keymap_entry ike;
213
214         if (umove_or_printaddr(tcp, arg, &ike))
215                 return 1;
216
217         tprintf("{flags=%" PRIu8
218                 ", len=%" PRIu8 ", ",
219                 ike.flags,
220                 ike.len);
221
222         if (!abbrev(tcp)) {
223                 unsigned int i;
224
225                 tprintf("index=%" PRIu16 ", keycode=", ike.index);
226                 printxval(evdev_keycode, ike.keycode, "KEY_???");
227                 tprints(", scancode=[");
228                 for (i = 0; i < ARRAY_SIZE(ike.scancode); i++) {
229                         if (i > 0)
230                                 tprints(", ");
231                         tprintf("%" PRIx8, ike.scancode[i]);
232                 }
233                 tprints("]");
234         } else {
235                 tprints("...");
236         }
237
238         tprints("}");
239
240         return 1;
241 }
242 # endif /* EVIOCGKEYCODE_V2 */
243
244 static int
245 getid_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
246 {
247         tprints(", ");
248
249         struct input_id id;
250
251         if (!umove_or_printaddr(tcp, arg, &id))
252                 tprintf("{ID_BUS=%" PRIu16
253                         ", ID_VENDOR=%" PRIu16
254                         ", ID_PRODUCT=%" PRIu16
255                         ", ID_VERSION=%" PRIu16 "}",
256                         id.bustype,
257                         id.vendor,
258                         id.product,
259                         id.version);
260
261         return 1;
262 }
263
264 static int
265 decode_bitset(struct tcb *const tcp, const kernel_ulong_t arg,
266               const struct xlat decode_nr[], const unsigned int max_nr,
267               const char *const dflt)
268 {
269         tprints(", ");
270
271         unsigned int size;
272         if ((kernel_ulong_t) tcp->u_rval > max_nr)
273                 size = max_nr;
274         else
275                 size = tcp->u_rval;
276         char decoded_arg[size];
277
278         if (umove_or_printaddr(tcp, arg, &decoded_arg))
279                 return 1;
280
281         tprints("[");
282
283         int bit_displayed = 0;
284         int i = next_set_bit(decoded_arg, 0, size);
285         if (i < 0) {
286                 tprints(" 0 ");
287         } else {
288                 printxval(decode_nr, i, dflt);
289
290                 while ((i = next_set_bit(decoded_arg, i + 1, size)) > 0) {
291                         if (abbrev(tcp) && bit_displayed >= 3) {
292                                 tprints(", ...");
293                                 break;
294                         }
295                         tprints(", ");
296                         printxval(decode_nr, i, dflt);
297                         bit_displayed++;
298                 }
299         }
300
301         tprints("]");
302
303         return 1;
304 }
305
306 # ifdef EVIOCGMTSLOTS
307 static int
308 mtslots_ioctl(struct tcb *const tcp, const unsigned int code,
309               const kernel_ulong_t arg)
310 {
311         tprints(", ");
312
313         const size_t size = _IOC_SIZE(code) / sizeof(int);
314         if (!size) {
315                 printaddr(arg);
316                 return 1;
317         }
318
319         int buffer[size];
320
321         if (umove_or_printaddr(tcp, arg, &buffer))
322                 return 1;
323
324         tprints("{code=");
325         printxval(evdev_mtslots, buffer[0], "ABS_MT_???");
326
327         tprints(", values=[");
328
329         unsigned int i;
330         for (i = 1; i < ARRAY_SIZE(buffer); i++)
331                 tprintf("%s%d", i > 1 ? ", " : "", buffer[i]);
332
333         tprints("]}");
334
335         return 1;
336 }
337 # endif /* EVIOCGMTSLOTS */
338
339 # if defined EVIOCGREP || defined EVIOCSREP
340 static int
341 repeat_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
342 {
343         tprints(", ");
344         printpair_int(tcp, arg, "%u");
345         return 1;
346 }
347 # endif /* EVIOCGREP || EVIOCSREP */
348
349 static int
350 bit_ioctl(struct tcb *const tcp, const unsigned int ev_nr,
351           const kernel_ulong_t arg)
352 {
353         switch (ev_nr) {
354                 case EV_SYN:
355                         return decode_bitset(tcp, arg, evdev_sync,
356                                              SYN_MAX, "SYN_???");
357                 case EV_KEY:
358                         return decode_bitset(tcp, arg, evdev_keycode,
359                                              KEY_MAX, "KEY_???");
360                 case EV_REL:
361                         return decode_bitset(tcp, arg, evdev_relative_axes,
362                                              REL_MAX, "REL_???");
363                 case EV_ABS:
364                         return decode_bitset(tcp, arg, evdev_abs,
365                                              ABS_MAX, "ABS_???");
366                 case EV_MSC:
367                         return decode_bitset(tcp, arg, evdev_misc,
368                                              MSC_MAX, "MSC_???");
369 # ifdef EV_SW
370                 case EV_SW:
371                         return decode_bitset(tcp, arg, evdev_switch,
372                                              SW_MAX, "SW_???");
373 # endif
374                 case EV_LED:
375                         return decode_bitset(tcp, arg, evdev_leds,
376                                              LED_MAX, "LED_???");
377                 case EV_SND:
378                         return decode_bitset(tcp, arg, evdev_snd,
379                                              SND_MAX, "SND_???");
380                 case EV_REP:
381                         return decode_bitset(tcp, arg, evdev_autorepeat,
382                                              REP_MAX, "REP_???");
383                 case EV_FF:
384                         return decode_bitset(tcp, arg, evdev_ff_types,
385                                              FF_MAX, "FF_???");
386                 case EV_PWR:
387                         tprints(", ");
388                         printnum_int(tcp, arg, "%d");
389                         return 1;
390                 case EV_FF_STATUS:
391                         return decode_bitset(tcp, arg, evdev_ff_status,
392                                              FF_STATUS_MAX, "FF_STATUS_???");
393                 default:
394                         tprints(", ");
395                         printaddr(arg);
396                         return 1;
397         }
398 }
399
400 static int
401 evdev_read_ioctl(struct tcb *const tcp, const unsigned int code,
402                  const kernel_ulong_t arg)
403 {
404         /* fixed-number fixed-length commands */
405         switch (code) {
406                 case EVIOCGVERSION:
407                         tprints(", ");
408                         printnum_int(tcp, arg, "%#x");
409                         return 1;
410                 case EVIOCGEFFECTS:
411                         tprints(", ");
412                         printnum_int(tcp, arg, "%u");
413                         return 1;
414                 case EVIOCGID:
415                         return getid_ioctl(tcp, arg);
416 # ifdef EVIOCGREP
417                 case EVIOCGREP:
418                         return repeat_ioctl(tcp, arg);
419 # endif
420                 case EVIOCGKEYCODE:
421                         return keycode_ioctl(tcp, arg);
422 # ifdef EVIOCGKEYCODE_V2
423                 case EVIOCGKEYCODE_V2:
424                         return keycode_V2_ioctl(tcp, arg);
425 # endif
426         }
427
428         /* fixed-number variable-length commands */
429         switch (_IOC_NR(code)) {
430 # ifdef EVIOCGMTSLOTS
431                 case _IOC_NR(EVIOCGMTSLOTS(0)):
432                         return mtslots_ioctl(tcp, code, arg);
433 # endif
434                 case _IOC_NR(EVIOCGNAME(0)):
435                 case _IOC_NR(EVIOCGPHYS(0)):
436                 case _IOC_NR(EVIOCGUNIQ(0)):
437                         tprints(", ");
438                         if (syserror(tcp))
439                                 printaddr(arg);
440                         else
441                                 printstrn(tcp, arg, tcp->u_rval);
442                         return 1;
443 # ifdef EVIOCGPROP
444                 case _IOC_NR(EVIOCGPROP(0)):
445                         return decode_bitset(tcp, arg, evdev_prop,
446                                              INPUT_PROP_MAX, "PROP_???");
447 # endif
448                 case _IOC_NR(EVIOCGSND(0)):
449                         return decode_bitset(tcp, arg, evdev_snd,
450                                              SND_MAX, "SND_???");
451 # ifdef EVIOCGSW
452                 case _IOC_NR(EVIOCGSW(0)):
453                         return decode_bitset(tcp, arg, evdev_switch,
454                                              SW_MAX, "SW_???");
455 # endif
456                 case _IOC_NR(EVIOCGKEY(0)):
457                         return decode_bitset(tcp, arg, evdev_keycode,
458                                              KEY_MAX, "KEY_???");
459                 case _IOC_NR(EVIOCGLED(0)):
460                         return decode_bitset(tcp, arg, evdev_leds,
461                                              LED_MAX, "LED_???");
462         }
463
464         /* multi-number fixed-length commands */
465         if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0)))
466                 return abs_ioctl(tcp, arg);
467
468         /* multi-number variable-length commands */
469         if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
470                 return bit_ioctl(tcp, _IOC_NR(code) & EV_MAX, arg);
471
472         return 0;
473 }
474
475 static int
476 evdev_write_ioctl(struct tcb *const tcp, const unsigned int code,
477                   const kernel_ulong_t arg)
478 {
479         /* fixed-number fixed-length commands */
480         switch (code) {
481 # ifdef EVIOCSREP
482                 case EVIOCSREP:
483                         return repeat_ioctl(tcp, arg);
484 # endif
485                 case EVIOCSKEYCODE:
486                         return keycode_ioctl(tcp, arg);
487 # ifdef EVIOCSKEYCODE_V2
488                 case EVIOCSKEYCODE_V2:
489                         return keycode_V2_ioctl(tcp, arg);
490 # endif
491                 case EVIOCSFF:
492                         return ff_effect_ioctl(tcp, arg);
493                 case EVIOCRMFF:
494                         tprintf(", %d", (int) arg);
495                         return 1;
496                 case EVIOCGRAB:
497 # ifdef EVIOCREVOKE
498                 case EVIOCREVOKE:
499 # endif
500                         tprintf(", %" PRI_klu, arg);
501                         return 1;
502 # ifdef EVIOCSCLOCKID
503                 case EVIOCSCLOCKID:
504                         tprints(", ");
505                         printnum_int(tcp, arg, "%u");
506                         return 1;
507 # endif
508         }
509
510         /* multi-number fixed-length commands */
511         if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0)))
512                 return abs_ioctl(tcp, arg);
513
514         return 0;
515 }
516
517 MPERS_PRINTER_DECL(int, evdev_ioctl, struct tcb *const tcp,
518                    const unsigned int code, const kernel_ulong_t arg)
519 {
520         switch(_IOC_DIR(code)) {
521                 case _IOC_READ:
522                         if (entering(tcp))
523                                 return 0;
524                         return evdev_read_ioctl(tcp, code, arg);
525                 case _IOC_WRITE:
526                         return evdev_write_ioctl(tcp, code, arg) | RVAL_DECODED;
527                 default:
528                         return RVAL_DECODED;
529         }
530 }
531
532 #endif /* HAVE_LINUX_INPUT_H */