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