ioctl: add decoding for parametrized command names
Some ioctl commands from evdev, hiddev, mixer, uinput, spi, and joystick are parametrized by a size or a number that are variable. This change implements printing of these parametrized ioctl command names. * configure.ac (AC_CHECK_HEADERS): Add linux/input.h. * defs.h (ioctl_decode_number): New prototype. * io.c (sys_ioctl): Use ioctl_decode_number. * ioctl.c (ioctl_decode_number): New function. * xlat/evdev_abs.in: New file. * xlat/evdev_ev.in: New file. Signed-off-by: Gabriel Laskar <gabriel@lse.epita.fr>
This commit is contained in:
parent
63630746ef
commit
6f9a01c721
@ -223,6 +223,7 @@ AC_CHECK_HEADERS(m4_normalize([
|
||||
inttypes.h
|
||||
ioctls.h
|
||||
linux/falloc.h
|
||||
linux/input.h
|
||||
linux/perf_event.h
|
||||
linux/ptrace.h
|
||||
linux/utsname.h
|
||||
|
1
defs.h
1
defs.h
@ -735,6 +735,7 @@ extern const struct_ioctlent *ioctl_lookup(const unsigned int);
|
||||
extern const struct_ioctlent *ioctl_next_match(const struct_ioctlent *);
|
||||
extern void ioctl_print_code(const unsigned int);
|
||||
extern int ioctl_decode(struct tcb *, const unsigned int, long);
|
||||
extern int ioctl_decode_command_number(const unsigned int);
|
||||
extern int block_ioctl(struct tcb *, const unsigned int, long);
|
||||
extern int loop_ioctl(struct tcb *, const unsigned int, long);
|
||||
extern int mtd_ioctl(struct tcb *, const unsigned int, long);
|
||||
|
17
io.c
17
io.c
@ -398,13 +398,16 @@ sys_ioctl(struct tcb *tcp)
|
||||
if (entering(tcp)) {
|
||||
printfd(tcp, tcp->u_arg[0]);
|
||||
tprints(", ");
|
||||
iop = ioctl_lookup(tcp->u_arg[1]);
|
||||
if (iop) {
|
||||
tprints(iop->symbol);
|
||||
while ((iop = ioctl_next_match(iop)))
|
||||
tprintf(" or %s", iop->symbol);
|
||||
} else
|
||||
ioctl_print_code(tcp->u_arg[1]);
|
||||
if (!ioctl_decode_command_number(tcp->u_arg[1])) {
|
||||
iop = ioctl_lookup(tcp->u_arg[1]);
|
||||
if (iop) {
|
||||
tprints(iop->symbol);
|
||||
while ((iop = ioctl_next_match(iop)))
|
||||
tprintf(" or %s", iop->symbol);
|
||||
} else {
|
||||
ioctl_print_code(tcp->u_arg[1]);
|
||||
}
|
||||
}
|
||||
ioctl_decode(tcp, tcp->u_arg[1], tcp->u_arg[2]);
|
||||
}
|
||||
else {
|
||||
|
145
ioctl.c
145
ioctl.c
@ -32,6 +32,13 @@
|
||||
#include <asm/ioctl.h>
|
||||
#include "xlat/ioctl_dirs.h"
|
||||
|
||||
#ifdef HAVE_LINUX_INPUT_H
|
||||
# include <linux/input.h>
|
||||
#endif
|
||||
|
||||
#include "xlat/evdev_abs.h"
|
||||
#include "xlat/evdev_ev.h"
|
||||
|
||||
static int
|
||||
compare(const void *a, const void *b)
|
||||
{
|
||||
@ -77,6 +84,144 @@ ioctl_print_code(const unsigned int code)
|
||||
_IOC_TYPE(code), _IOC_NR(code), _IOC_SIZE(code));
|
||||
}
|
||||
|
||||
static int
|
||||
evdev_decode_number(unsigned int arg)
|
||||
{
|
||||
unsigned int nr = _IOC_NR(arg);
|
||||
|
||||
if (_IOC_DIR(arg) == _IOC_WRITE) {
|
||||
if (nr >= 0xc0 && nr <= 0xc0 + 0x3f) {
|
||||
tprints("EVIOCSABS(");
|
||||
printxval(evdev_abs, nr - 0xc0, "EV_???");
|
||||
tprints(")");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (_IOC_DIR(arg) != _IOC_READ)
|
||||
return 0;
|
||||
|
||||
if (nr >= 0x20 && nr <= 0x20 + 0x1f) {
|
||||
tprints("EVIOCGBIT(");
|
||||
printxval(evdev_ev, nr - 0x20, "EV_???");
|
||||
tprintf(", %u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
} else if (nr >= 0x40 && nr <= 0x40 + 0x3f) {
|
||||
tprints("EVIOCGABS(");
|
||||
printxval(evdev_abs, nr - 0x40, "ABS_???");
|
||||
tprints(")");
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (_IOC_NR(nr)) {
|
||||
case 0x06:
|
||||
tprintf("EVIOCGNAME(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
case 0x07:
|
||||
tprintf("EVIOCGPHYS(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
case 0x08:
|
||||
tprintf("EVIOCGUNIQ(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
case 0x09:
|
||||
tprintf("EVIOCGPROP(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
case 0x0a:
|
||||
tprintf("EVIOCGMTSLOTS(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
case 0x18:
|
||||
tprintf("EVIOCGKEY(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
case 0x19:
|
||||
tprintf("EVIOCGLED(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
case 0x1a:
|
||||
tprintf("EVIOCGSND(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
case 0x1b:
|
||||
tprintf("EVIOCGSW(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
hiddev_decode_number(unsigned int arg)
|
||||
{
|
||||
if (_IOC_DIR(arg) == _IOC_READ) {
|
||||
switch (_IOC_NR(arg)) {
|
||||
case 0x04:
|
||||
tprintf("HIDIOCGRAWNAME(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
case 0x05:
|
||||
tprintf("HIDIOCGRAWPHYS(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
case 0x06:
|
||||
tprintf("HIDIOCSFEATURE(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
case 0x12:
|
||||
tprintf("HIDIOCGPHYS(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
} else if (_IOC_DIR(arg) == (_IOC_READ | _IOC_WRITE)) {
|
||||
switch (_IOC_NR(arg)) {
|
||||
case 0x06:
|
||||
tprintf("HIDIOCSFEATURE(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
case 0x07:
|
||||
tprintf("HIDIOCGFEATURE(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ioctl_decode_command_number(unsigned int arg)
|
||||
{
|
||||
switch (_IOC_TYPE(arg)) {
|
||||
case 'E':
|
||||
return evdev_decode_number(arg);
|
||||
case 'H':
|
||||
return hiddev_decode_number(arg);
|
||||
case 'M':
|
||||
if (_IOC_DIR(arg) == _IOC_WRITE) {
|
||||
tprintf("MIXER_WRITE(%u)", _IOC_NR(arg));
|
||||
return 1;
|
||||
} else if (_IOC_DIR(arg) == _IOC_READ) {
|
||||
tprintf("MIXER_READ(%u)", _IOC_NR(arg));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
case 'U':
|
||||
if (_IOC_DIR(arg) == _IOC_READ && _IOC_NR(arg) == 0x2c) {
|
||||
tprintf("UI_GET_SYSNAME(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
case 'j':
|
||||
if (_IOC_DIR(arg) == _IOC_READ && _IOC_NR(arg) == 0x13) {
|
||||
tprintf("JSIOCGNAME(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
case 'k':
|
||||
if (_IOC_DIR(arg) == _IOC_WRITE && _IOC_NR(arg) == 0) {
|
||||
tprintf("SPI_IOC_MESSAGE(%u)", _IOC_SIZE(arg));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ioctl_decode(struct tcb *tcp, unsigned int code, long arg)
|
||||
{
|
||||
|
41
xlat/evdev_abs.in
Normal file
41
xlat/evdev_abs.in
Normal file
@ -0,0 +1,41 @@
|
||||
ABS_X
|
||||
ABS_Y
|
||||
ABS_Z
|
||||
ABS_RX
|
||||
ABS_RY
|
||||
ABS_RZ
|
||||
ABS_THROTTLE
|
||||
ABS_RUDDER
|
||||
ABS_WHEEL
|
||||
ABS_GAS
|
||||
ABS_BRAKE
|
||||
ABS_HAT0X
|
||||
ABS_HAT0Y
|
||||
ABS_HAT1X
|
||||
ABS_HAT1Y
|
||||
ABS_HAT2X
|
||||
ABS_HAT2Y
|
||||
ABS_HAT3X
|
||||
ABS_HAT3Y
|
||||
ABS_PRESSURE
|
||||
ABS_DISTANCE
|
||||
ABS_TILT_X
|
||||
ABS_TILT_Y
|
||||
ABS_TOOL_WIDTH
|
||||
ABS_VOLUME
|
||||
ABS_MISC
|
||||
ABS_MT_SLOT
|
||||
ABS_MT_TOUCH_MAJOR
|
||||
ABS_MT_TOUCH_MINOR
|
||||
ABS_MT_WIDTH_MAJOR
|
||||
ABS_MT_WIDTH_MINOR
|
||||
ABS_MT_ORIENTATION
|
||||
ABS_MT_POSITION_X
|
||||
ABS_MT_POSITION_Y
|
||||
ABS_MT_TOOL_TYPE
|
||||
ABS_MT_BLOB_ID
|
||||
ABS_MT_TRACKING_ID
|
||||
ABS_MT_PRESSURE
|
||||
ABS_MT_DISTANCE
|
||||
ABS_MT_TOOL_X
|
||||
ABS_MT_TOOL_Y
|
12
xlat/evdev_ev.in
Normal file
12
xlat/evdev_ev.in
Normal file
@ -0,0 +1,12 @@
|
||||
EV_SYN
|
||||
EV_KEY
|
||||
EV_REL
|
||||
EV_ABS
|
||||
EV_MSC
|
||||
EV_SW
|
||||
EV_LED
|
||||
EV_SND
|
||||
EV_REP
|
||||
EV_FF
|
||||
EV_PWR
|
||||
EV_FF_STATUS
|
Loading…
x
Reference in New Issue
Block a user