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 {
#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)
{
_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)
{