|
|
86f512 |
From 5680918c9e2cc8b2418a3809892532be0d10018a Mon Sep 17 00:00:00 2001
|
|
|
86f512 |
From: Eugene Syromyatnikov <evgsyr@gmail.com>
|
|
|
86f512 |
Date: Thu, 17 Oct 2019 15:29:50 +0200
|
|
|
86f512 |
Subject: [PATCH 70/76] evdev: decode struct input_absinfo regardless of
|
|
|
86f512 |
in-kernel definitions
|
|
|
86f512 |
|
|
|
86f512 |
* evdev.c (struct_input_absinfo): New typedef.
|
|
|
86f512 |
(abs_ioctl): Add code argument. Add orig_sz, res_sz, sz, read_sz local
|
|
|
86f512 |
variables. Decode resolution field regardless of
|
|
|
86f512 |
HAVE_STRUCT_INPUT_ABSINFO_RESOLUTION.
|
|
|
86f512 |
(evdev_read_ioctl, evdev_write_ioctl): Pass code to abs_ioctl.
|
|
|
86f512 |
* tests/ioctl_evdev-success.c (print_input_absinfo): Update expected
|
|
|
86f512 |
output.
|
|
|
86f512 |
(main): Add absinfo_sz, absinfo_24, absinfo_32 local variables; add
|
|
|
86f512 |
additional checks for struct input_absinfo.
|
|
|
86f512 |
|
|
|
86f512 |
References: https://bugzilla.redhat.com/show_bug.cgi?id=1758201
|
|
|
86f512 |
---
|
|
|
86f512 |
evdev.c | 78 ++++++++++++++++++++++++++++++---------------
|
|
|
86f512 |
tests/ioctl_evdev-success.c | 51 ++++++++++++++++++++++++++---
|
|
|
86f512 |
2 files changed, 99 insertions(+), 30 deletions(-)
|
|
|
86f512 |
|
|
|
86f512 |
Index: strace-5.1/evdev.c
|
|
|
86f512 |
===================================================================
|
|
|
86f512 |
--- strace-5.1.orig/evdev.c 2020-01-29 12:37:35.139765850 +0100
|
|
|
86f512 |
+++ strace-5.1/evdev.c 2020-01-29 12:39:10.344891943 +0100
|
|
|
86f512 |
@@ -37,6 +37,15 @@
|
|
|
86f512 |
# define SYN_MAX 0xf
|
|
|
86f512 |
# endif
|
|
|
86f512 |
|
|
|
86f512 |
+typedef struct {
|
|
|
86f512 |
+ int32_t value;
|
|
|
86f512 |
+ int32_t minimum;
|
|
|
86f512 |
+ int32_t maximum;
|
|
|
86f512 |
+ int32_t fuzz;
|
|
|
86f512 |
+ int32_t flat;
|
|
|
86f512 |
+ int32_t resolution; /**< Added by Linux commit v2.6.31-rc1~100^2~1 */
|
|
|
86f512 |
+} struct_input_absinfo;
|
|
|
86f512 |
+
|
|
|
86f512 |
/** Added by Linux commit v2.6.37-rc1~5^2~3^2~47 */
|
|
|
86f512 |
typedef struct {
|
|
|
86f512 |
uint8_t flags;
|
|
|
86f512 |
@@ -53,6 +62,9 @@
|
|
|
86f512 |
uint64_t codes_ptr;
|
|
|
86f512 |
} struct_input_mask;
|
|
|
86f512 |
|
|
|
86f512 |
+static_assert(sizeof(struct input_absinfo) <= sizeof(struct_input_absinfo),
|
|
|
86f512 |
+ "Unexpected struct input_absinfo size, please update "
|
|
|
86f512 |
+ "the decoder");
|
|
|
86f512 |
# ifdef HAVE_STRUCT_INPUT_KEYMAP_ENTRY
|
|
|
86f512 |
static_assert(sizeof(struct input_keymap_entry)
|
|
|
86f512 |
== sizeof(struct_input_keymap_entry),
|
|
|
86f512 |
@@ -85,36 +97,50 @@
|
|
|
86f512 |
const size_t evdev_abs_size = ARRAY_SIZE(evdev_abs) - 1;
|
|
|
86f512 |
|
|
|
86f512 |
static int
|
|
|
86f512 |
-abs_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
|
|
|
86f512 |
+abs_ioctl(struct tcb *const tcp, const unsigned int code,
|
|
|
86f512 |
+ const kernel_ulong_t arg)
|
|
|
86f512 |
{
|
|
|
86f512 |
+ static const size_t orig_sz = offsetofend(struct_input_absinfo, flat);
|
|
|
86f512 |
+ static const size_t res_sz = offsetofend(struct_input_absinfo,
|
|
|
86f512 |
+ resolution);
|
|
|
86f512 |
+
|
|
|
86f512 |
+ struct_input_absinfo absinfo;
|
|
|
86f512 |
+ size_t sz = _IOC_SIZE(code);
|
|
|
86f512 |
+ size_t read_sz = MIN(sz, sizeof(absinfo));
|
|
|
86f512 |
+
|
|
|
86f512 |
+ if (sz < orig_sz)
|
|
|
86f512 |
+ return RVAL_DECODED;
|
|
|
86f512 |
+
|
|
|
86f512 |
tprints(", ");
|
|
|
86f512 |
|
|
|
86f512 |
- struct input_absinfo absinfo;
|
|
|
86f512 |
+ if (umoven_or_printaddr(tcp, arg, read_sz, &absinfo))
|
|
|
86f512 |
+ return RVAL_IOCTL_DECODED;
|
|
|
86f512 |
|
|
|
86f512 |
- if (!umove_or_printaddr(tcp, arg, &absinfo)) {
|
|
|
86f512 |
- tprintf("{value=%u"
|
|
|
86f512 |
- ", minimum=%u, ",
|
|
|
86f512 |
- absinfo.value,
|
|
|
86f512 |
- absinfo.minimum);
|
|
|
86f512 |
-
|
|
|
86f512 |
- if (!abbrev(tcp)) {
|
|
|
86f512 |
- tprintf("maximum=%u"
|
|
|
86f512 |
- ", fuzz=%u"
|
|
|
86f512 |
- ", flat=%u",
|
|
|
86f512 |
- absinfo.maximum,
|
|
|
86f512 |
- absinfo.fuzz,
|
|
|
86f512 |
- absinfo.flat);
|
|
|
86f512 |
-# ifdef HAVE_STRUCT_INPUT_ABSINFO_RESOLUTION
|
|
|
86f512 |
- tprintf(", resolution=%u",
|
|
|
86f512 |
- absinfo.resolution);
|
|
|
86f512 |
-# endif
|
|
|
86f512 |
- } else {
|
|
|
86f512 |
- tprints("...");
|
|
|
86f512 |
- }
|
|
|
86f512 |
+ tprintf("{value=%u"
|
|
|
86f512 |
+ ", minimum=%u, ",
|
|
|
86f512 |
+ absinfo.value,
|
|
|
86f512 |
+ absinfo.minimum);
|
|
|
86f512 |
|
|
|
86f512 |
- tprints("}");
|
|
|
86f512 |
+ if (!abbrev(tcp)) {
|
|
|
86f512 |
+ tprintf("maximum=%u"
|
|
|
86f512 |
+ ", fuzz=%u"
|
|
|
86f512 |
+ ", flat=%u",
|
|
|
86f512 |
+ absinfo.maximum,
|
|
|
86f512 |
+ absinfo.fuzz,
|
|
|
86f512 |
+ absinfo.flat);
|
|
|
86f512 |
+ if (sz >= res_sz) {
|
|
|
86f512 |
+ tprintf(", resolution=%u%s",
|
|
|
86f512 |
+ absinfo.resolution,
|
|
|
86f512 |
+ sz > res_sz ? ", ..." : "");
|
|
|
86f512 |
+ } else if (sz > orig_sz) {
|
|
|
86f512 |
+ tprints(", ...");
|
|
|
86f512 |
+ }
|
|
|
86f512 |
+ } else {
|
|
|
86f512 |
+ tprints("...");
|
|
|
86f512 |
}
|
|
|
86f512 |
|
|
|
86f512 |
+ tprints("}");
|
|
|
86f512 |
+
|
|
|
86f512 |
return RVAL_IOCTL_DECODED;
|
|
|
86f512 |
}
|
|
|
86f512 |
|
|
|
86f512 |
@@ -394,7 +420,7 @@
|
|
|
86f512 |
|
|
|
86f512 |
/* multi-number fixed-length commands */
|
|
|
86f512 |
if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0)))
|
|
|
86f512 |
- return abs_ioctl(tcp, arg);
|
|
|
86f512 |
+ return abs_ioctl(tcp, code, arg);
|
|
|
86f512 |
|
|
|
86f512 |
/* multi-number variable-length commands */
|
|
|
86f512 |
if ((_IOC_NR(code) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
|
|
|
86f512 |
@@ -435,7 +461,7 @@
|
|
|
86f512 |
|
|
|
86f512 |
/* multi-number fixed-length commands */
|
|
|
86f512 |
if ((_IOC_NR(code) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0)))
|
|
|
86f512 |
- return abs_ioctl(tcp, arg);
|
|
|
86f512 |
+ return abs_ioctl(tcp, code, arg);
|
|
|
86f512 |
|
|
|
86f512 |
return 0;
|
|
|
86f512 |
}
|
|
|
86f512 |
Index: strace-5.1/tests/ioctl_evdev-success.c
|
|
|
86f512 |
===================================================================
|
|
|
86f512 |
--- strace-5.1.orig/tests/ioctl_evdev-success.c 2020-01-27 19:35:30.929507199 +0100
|
|
|
86f512 |
+++ strace-5.1/tests/ioctl_evdev-success.c 2020-01-29 12:39:10.345891934 +0100
|
|
|
86f512 |
@@ -56,6 +56,9 @@
|
|
|
86f512 |
print_input_absinfo(long rc, const void *ptr, const void *arg)
|
|
|
86f512 |
{
|
|
|
86f512 |
const struct input_absinfo *absinfo = ptr;
|
|
|
86f512 |
+# if VERBOSE
|
|
|
86f512 |
+ const uintptr_t sz = (uintptr_t) arg;
|
|
|
86f512 |
+# endif
|
|
|
86f512 |
|
|
|
86f512 |
if (rc < 0) {
|
|
|
86f512 |
printf("%p", absinfo);
|
|
|
86f512 |
@@ -67,9 +70,20 @@
|
|
|
86f512 |
PRINT_FIELD_U(", ", *absinfo, maximum);
|
|
|
86f512 |
PRINT_FIELD_U(", ", *absinfo, fuzz);
|
|
|
86f512 |
PRINT_FIELD_U(", ", *absinfo, flat);
|
|
|
86f512 |
+ if (sz > offsetofend(struct input_absinfo, flat)) {
|
|
|
86f512 |
+ if (sz >= 24) {
|
|
|
86f512 |
# ifdef HAVE_STRUCT_INPUT_ABSINFO_RESOLUTION
|
|
|
86f512 |
- PRINT_FIELD_U(", ", *absinfo, resolution);
|
|
|
86f512 |
+ PRINT_FIELD_U(", ", *absinfo, resolution);
|
|
|
86f512 |
+# else
|
|
|
86f512 |
+ printf(", resolution=%u", *((int *) ptr + 5));
|
|
|
86f512 |
# endif
|
|
|
86f512 |
+
|
|
|
86f512 |
+ if (sz > 24)
|
|
|
86f512 |
+ printf(", ...");
|
|
|
86f512 |
+ } else {
|
|
|
86f512 |
+ printf(", ...");
|
|
|
86f512 |
+ }
|
|
|
86f512 |
+ }
|
|
|
86f512 |
# else
|
|
|
86f512 |
printf(", ...");
|
|
|
86f512 |
# endif
|
|
|
86f512 |
@@ -176,10 +190,22 @@
|
|
|
86f512 |
", EVIOCGID, NULL) returning %lu",
|
|
|
86f512 |
inject_retval);
|
|
|
86f512 |
|
|
|
86f512 |
+ static const void *absinfo_sz =
|
|
|
86f512 |
+ (const void *) (uintptr_t) sizeof(struct input_absinfo);
|
|
|
86f512 |
+
|
|
|
86f512 |
TAIL_ALLOC_OBJECT_CONST_PTR(struct input_id, id);
|
|
|
86f512 |
TAIL_ALLOC_OBJECT_CONST_PTR(struct input_absinfo, absinfo);
|
|
|
86f512 |
TAIL_ALLOC_OBJECT_CONST_PTR(int, bad_addr_slot);
|
|
|
86f512 |
|
|
|
86f512 |
+ struct input_absinfo *absinfo_24 = tail_alloc(MAX(sizeof(*absinfo_24),
|
|
|
86f512 |
+ 24));
|
|
|
86f512 |
+ struct input_absinfo *absinfo_32 = tail_alloc(MAX(sizeof(*absinfo_32),
|
|
|
86f512 |
+ 32));
|
|
|
86f512 |
+
|
|
|
86f512 |
+ fill_memory(absinfo, sizeof(struct input_absinfo));
|
|
|
86f512 |
+ fill_memory(absinfo_24, 24);
|
|
|
86f512 |
+ fill_memory(absinfo_32, 32);
|
|
|
86f512 |
+
|
|
|
86f512 |
# ifdef EVIOCGMTSLOTS
|
|
|
86f512 |
int mtslots[] = { ABS_MT_SLOT, 1, 3 };
|
|
|
86f512 |
/* we use the second element to indicate the number of values */
|
|
|
86f512 |
@@ -236,9 +262,26 @@
|
|
|
86f512 |
const void *ptr;
|
|
|
86f512 |
} a[] = {
|
|
|
86f512 |
{ { ARG_STR(EVIOCGID), id, print_input_id }, NULL },
|
|
|
86f512 |
- { { ARG_STR(EVIOCGABS(ABS_X)), absinfo, print_input_absinfo }, NULL },
|
|
|
86f512 |
- { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo }, NULL },
|
|
|
86f512 |
- { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo }, NULL },
|
|
|
86f512 |
+ { { _IOC(_IOC_READ, 'E', 0x40 + ABS_Y, 19), "EVIOCGABS(ABS_Y)",
|
|
|
86f512 |
+ absinfo, NULL }, NULL },
|
|
|
86f512 |
+ { { _IOC(_IOC_READ, 'E', 0x40 + ABS_Y, 20),
|
|
|
86f512 |
+ "EVIOCGABS(ABS_Y)", absinfo, print_input_absinfo },
|
|
|
86f512 |
+ (const void *) (uintptr_t) 20 },
|
|
|
86f512 |
+ { { _IOC(_IOC_READ, 'E', 0x40 + ABS_Y, 21),
|
|
|
86f512 |
+ "EVIOCGABS(ABS_Y)", absinfo_24, print_input_absinfo },
|
|
|
86f512 |
+ (const void *) (uintptr_t) 21 },
|
|
|
86f512 |
+ { { _IOC(_IOC_READ, 'E', 0x40 + ABS_Y, 24),
|
|
|
86f512 |
+ "EVIOCGABS(ABS_Y)", absinfo_24, print_input_absinfo },
|
|
|
86f512 |
+ (const void *) (uintptr_t) 24 },
|
|
|
86f512 |
+ { { _IOC(_IOC_READ, 'E', 0x40 + ABS_Y, 32),
|
|
|
86f512 |
+ "EVIOCGABS(ABS_Y)", absinfo_32, print_input_absinfo },
|
|
|
86f512 |
+ (const void *) (uintptr_t) 32 },
|
|
|
86f512 |
+ { { ARG_STR(EVIOCGABS(ABS_X)), absinfo, print_input_absinfo },
|
|
|
86f512 |
+ absinfo_sz},
|
|
|
86f512 |
+ { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo },
|
|
|
86f512 |
+ absinfo_sz },
|
|
|
86f512 |
+ { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo },
|
|
|
86f512 |
+ absinfo_sz },
|
|
|
86f512 |
{ { ARG_STR(EVIOCGBIT(0, 0)), ev_more, print_getbit },
|
|
|
86f512 |
inject_retval * 8 <= EV_LED
|
|
|
86f512 |
? (const void *) &ev_more_str_2
|
|
|
86f512 |
Index: strace-5.1/tests-m32/ioctl_evdev-success.c
|
|
|
86f512 |
===================================================================
|
|
|
86f512 |
--- strace-5.1.orig/tests-m32/ioctl_evdev-success.c 2020-01-27 19:35:30.932507172 +0100
|
|
|
86f512 |
+++ strace-5.1/tests-m32/ioctl_evdev-success.c 2020-01-29 12:39:23.992766667 +0100
|
|
|
86f512 |
@@ -56,6 +56,9 @@
|
|
|
86f512 |
print_input_absinfo(long rc, const void *ptr, const void *arg)
|
|
|
86f512 |
{
|
|
|
86f512 |
const struct input_absinfo *absinfo = ptr;
|
|
|
86f512 |
+# if VERBOSE
|
|
|
86f512 |
+ const uintptr_t sz = (uintptr_t) arg;
|
|
|
86f512 |
+# endif
|
|
|
86f512 |
|
|
|
86f512 |
if (rc < 0) {
|
|
|
86f512 |
printf("%p", absinfo);
|
|
|
86f512 |
@@ -67,9 +70,20 @@
|
|
|
86f512 |
PRINT_FIELD_U(", ", *absinfo, maximum);
|
|
|
86f512 |
PRINT_FIELD_U(", ", *absinfo, fuzz);
|
|
|
86f512 |
PRINT_FIELD_U(", ", *absinfo, flat);
|
|
|
86f512 |
+ if (sz > offsetofend(struct input_absinfo, flat)) {
|
|
|
86f512 |
+ if (sz >= 24) {
|
|
|
86f512 |
# ifdef HAVE_STRUCT_INPUT_ABSINFO_RESOLUTION
|
|
|
86f512 |
- PRINT_FIELD_U(", ", *absinfo, resolution);
|
|
|
86f512 |
+ PRINT_FIELD_U(", ", *absinfo, resolution);
|
|
|
86f512 |
+# else
|
|
|
86f512 |
+ printf(", resolution=%u", *((int *) ptr + 5));
|
|
|
86f512 |
# endif
|
|
|
86f512 |
+
|
|
|
86f512 |
+ if (sz > 24)
|
|
|
86f512 |
+ printf(", ...");
|
|
|
86f512 |
+ } else {
|
|
|
86f512 |
+ printf(", ...");
|
|
|
86f512 |
+ }
|
|
|
86f512 |
+ }
|
|
|
86f512 |
# else
|
|
|
86f512 |
printf(", ...");
|
|
|
86f512 |
# endif
|
|
|
86f512 |
@@ -176,10 +190,22 @@
|
|
|
86f512 |
", EVIOCGID, NULL) returning %lu",
|
|
|
86f512 |
inject_retval);
|
|
|
86f512 |
|
|
|
86f512 |
+ static const void *absinfo_sz =
|
|
|
86f512 |
+ (const void *) (uintptr_t) sizeof(struct input_absinfo);
|
|
|
86f512 |
+
|
|
|
86f512 |
TAIL_ALLOC_OBJECT_CONST_PTR(struct input_id, id);
|
|
|
86f512 |
TAIL_ALLOC_OBJECT_CONST_PTR(struct input_absinfo, absinfo);
|
|
|
86f512 |
TAIL_ALLOC_OBJECT_CONST_PTR(int, bad_addr_slot);
|
|
|
86f512 |
|
|
|
86f512 |
+ struct input_absinfo *absinfo_24 = tail_alloc(MAX(sizeof(*absinfo_24),
|
|
|
86f512 |
+ 24));
|
|
|
86f512 |
+ struct input_absinfo *absinfo_32 = tail_alloc(MAX(sizeof(*absinfo_32),
|
|
|
86f512 |
+ 32));
|
|
|
86f512 |
+
|
|
|
86f512 |
+ fill_memory(absinfo, sizeof(struct input_absinfo));
|
|
|
86f512 |
+ fill_memory(absinfo_24, 24);
|
|
|
86f512 |
+ fill_memory(absinfo_32, 32);
|
|
|
86f512 |
+
|
|
|
86f512 |
# ifdef EVIOCGMTSLOTS
|
|
|
86f512 |
int mtslots[] = { ABS_MT_SLOT, 1, 3 };
|
|
|
86f512 |
/* we use the second element to indicate the number of values */
|
|
|
86f512 |
@@ -236,9 +262,26 @@
|
|
|
86f512 |
const void *ptr;
|
|
|
86f512 |
} a[] = {
|
|
|
86f512 |
{ { ARG_STR(EVIOCGID), id, print_input_id }, NULL },
|
|
|
86f512 |
- { { ARG_STR(EVIOCGABS(ABS_X)), absinfo, print_input_absinfo }, NULL },
|
|
|
86f512 |
- { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo }, NULL },
|
|
|
86f512 |
- { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo }, NULL },
|
|
|
86f512 |
+ { { _IOC(_IOC_READ, 'E', 0x40 + ABS_Y, 19), "EVIOCGABS(ABS_Y)",
|
|
|
86f512 |
+ absinfo, NULL }, NULL },
|
|
|
86f512 |
+ { { _IOC(_IOC_READ, 'E', 0x40 + ABS_Y, 20),
|
|
|
86f512 |
+ "EVIOCGABS(ABS_Y)", absinfo, print_input_absinfo },
|
|
|
86f512 |
+ (const void *) (uintptr_t) 20 },
|
|
|
86f512 |
+ { { _IOC(_IOC_READ, 'E', 0x40 + ABS_Y, 21),
|
|
|
86f512 |
+ "EVIOCGABS(ABS_Y)", absinfo_24, print_input_absinfo },
|
|
|
86f512 |
+ (const void *) (uintptr_t) 21 },
|
|
|
86f512 |
+ { { _IOC(_IOC_READ, 'E', 0x40 + ABS_Y, 24),
|
|
|
86f512 |
+ "EVIOCGABS(ABS_Y)", absinfo_24, print_input_absinfo },
|
|
|
86f512 |
+ (const void *) (uintptr_t) 24 },
|
|
|
86f512 |
+ { { _IOC(_IOC_READ, 'E', 0x40 + ABS_Y, 32),
|
|
|
86f512 |
+ "EVIOCGABS(ABS_Y)", absinfo_32, print_input_absinfo },
|
|
|
86f512 |
+ (const void *) (uintptr_t) 32 },
|
|
|
86f512 |
+ { { ARG_STR(EVIOCGABS(ABS_X)), absinfo, print_input_absinfo },
|
|
|
86f512 |
+ absinfo_sz},
|
|
|
86f512 |
+ { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo },
|
|
|
86f512 |
+ absinfo_sz },
|
|
|
86f512 |
+ { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo },
|
|
|
86f512 |
+ absinfo_sz },
|
|
|
86f512 |
{ { ARG_STR(EVIOCGBIT(0, 0)), ev_more, print_getbit },
|
|
|
86f512 |
inject_retval * 8 <= EV_LED
|
|
|
86f512 |
? (const void *) &ev_more_str_2
|
|
|
86f512 |
Index: strace-5.1/tests-mx32/ioctl_evdev-success.c
|
|
|
86f512 |
===================================================================
|
|
|
86f512 |
--- strace-5.1.orig/tests-mx32/ioctl_evdev-success.c 2020-01-27 19:35:30.933507163 +0100
|
|
|
86f512 |
+++ strace-5.1/tests-mx32/ioctl_evdev-success.c 2020-01-29 12:39:23.994766648 +0100
|
|
|
86f512 |
@@ -56,6 +56,9 @@
|
|
|
86f512 |
print_input_absinfo(long rc, const void *ptr, const void *arg)
|
|
|
86f512 |
{
|
|
|
86f512 |
const struct input_absinfo *absinfo = ptr;
|
|
|
86f512 |
+# if VERBOSE
|
|
|
86f512 |
+ const uintptr_t sz = (uintptr_t) arg;
|
|
|
86f512 |
+# endif
|
|
|
86f512 |
|
|
|
86f512 |
if (rc < 0) {
|
|
|
86f512 |
printf("%p", absinfo);
|
|
|
86f512 |
@@ -67,9 +70,20 @@
|
|
|
86f512 |
PRINT_FIELD_U(", ", *absinfo, maximum);
|
|
|
86f512 |
PRINT_FIELD_U(", ", *absinfo, fuzz);
|
|
|
86f512 |
PRINT_FIELD_U(", ", *absinfo, flat);
|
|
|
86f512 |
+ if (sz > offsetofend(struct input_absinfo, flat)) {
|
|
|
86f512 |
+ if (sz >= 24) {
|
|
|
86f512 |
# ifdef HAVE_STRUCT_INPUT_ABSINFO_RESOLUTION
|
|
|
86f512 |
- PRINT_FIELD_U(", ", *absinfo, resolution);
|
|
|
86f512 |
+ PRINT_FIELD_U(", ", *absinfo, resolution);
|
|
|
86f512 |
+# else
|
|
|
86f512 |
+ printf(", resolution=%u", *((int *) ptr + 5));
|
|
|
86f512 |
# endif
|
|
|
86f512 |
+
|
|
|
86f512 |
+ if (sz > 24)
|
|
|
86f512 |
+ printf(", ...");
|
|
|
86f512 |
+ } else {
|
|
|
86f512 |
+ printf(", ...");
|
|
|
86f512 |
+ }
|
|
|
86f512 |
+ }
|
|
|
86f512 |
# else
|
|
|
86f512 |
printf(", ...");
|
|
|
86f512 |
# endif
|
|
|
86f512 |
@@ -176,10 +190,22 @@
|
|
|
86f512 |
", EVIOCGID, NULL) returning %lu",
|
|
|
86f512 |
inject_retval);
|
|
|
86f512 |
|
|
|
86f512 |
+ static const void *absinfo_sz =
|
|
|
86f512 |
+ (const void *) (uintptr_t) sizeof(struct input_absinfo);
|
|
|
86f512 |
+
|
|
|
86f512 |
TAIL_ALLOC_OBJECT_CONST_PTR(struct input_id, id);
|
|
|
86f512 |
TAIL_ALLOC_OBJECT_CONST_PTR(struct input_absinfo, absinfo);
|
|
|
86f512 |
TAIL_ALLOC_OBJECT_CONST_PTR(int, bad_addr_slot);
|
|
|
86f512 |
|
|
|
86f512 |
+ struct input_absinfo *absinfo_24 = tail_alloc(MAX(sizeof(*absinfo_24),
|
|
|
86f512 |
+ 24));
|
|
|
86f512 |
+ struct input_absinfo *absinfo_32 = tail_alloc(MAX(sizeof(*absinfo_32),
|
|
|
86f512 |
+ 32));
|
|
|
86f512 |
+
|
|
|
86f512 |
+ fill_memory(absinfo, sizeof(struct input_absinfo));
|
|
|
86f512 |
+ fill_memory(absinfo_24, 24);
|
|
|
86f512 |
+ fill_memory(absinfo_32, 32);
|
|
|
86f512 |
+
|
|
|
86f512 |
# ifdef EVIOCGMTSLOTS
|
|
|
86f512 |
int mtslots[] = { ABS_MT_SLOT, 1, 3 };
|
|
|
86f512 |
/* we use the second element to indicate the number of values */
|
|
|
86f512 |
@@ -236,9 +262,26 @@
|
|
|
86f512 |
const void *ptr;
|
|
|
86f512 |
} a[] = {
|
|
|
86f512 |
{ { ARG_STR(EVIOCGID), id, print_input_id }, NULL },
|
|
|
86f512 |
- { { ARG_STR(EVIOCGABS(ABS_X)), absinfo, print_input_absinfo }, NULL },
|
|
|
86f512 |
- { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo }, NULL },
|
|
|
86f512 |
- { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo }, NULL },
|
|
|
86f512 |
+ { { _IOC(_IOC_READ, 'E', 0x40 + ABS_Y, 19), "EVIOCGABS(ABS_Y)",
|
|
|
86f512 |
+ absinfo, NULL }, NULL },
|
|
|
86f512 |
+ { { _IOC(_IOC_READ, 'E', 0x40 + ABS_Y, 20),
|
|
|
86f512 |
+ "EVIOCGABS(ABS_Y)", absinfo, print_input_absinfo },
|
|
|
86f512 |
+ (const void *) (uintptr_t) 20 },
|
|
|
86f512 |
+ { { _IOC(_IOC_READ, 'E', 0x40 + ABS_Y, 21),
|
|
|
86f512 |
+ "EVIOCGABS(ABS_Y)", absinfo_24, print_input_absinfo },
|
|
|
86f512 |
+ (const void *) (uintptr_t) 21 },
|
|
|
86f512 |
+ { { _IOC(_IOC_READ, 'E', 0x40 + ABS_Y, 24),
|
|
|
86f512 |
+ "EVIOCGABS(ABS_Y)", absinfo_24, print_input_absinfo },
|
|
|
86f512 |
+ (const void *) (uintptr_t) 24 },
|
|
|
86f512 |
+ { { _IOC(_IOC_READ, 'E', 0x40 + ABS_Y, 32),
|
|
|
86f512 |
+ "EVIOCGABS(ABS_Y)", absinfo_32, print_input_absinfo },
|
|
|
86f512 |
+ (const void *) (uintptr_t) 32 },
|
|
|
86f512 |
+ { { ARG_STR(EVIOCGABS(ABS_X)), absinfo, print_input_absinfo },
|
|
|
86f512 |
+ absinfo_sz},
|
|
|
86f512 |
+ { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo },
|
|
|
86f512 |
+ absinfo_sz },
|
|
|
86f512 |
+ { { ARG_STR(EVIOCGABS(ABS_Y)), absinfo, print_input_absinfo },
|
|
|
86f512 |
+ absinfo_sz },
|
|
|
86f512 |
{ { ARG_STR(EVIOCGBIT(0, 0)), ev_more, print_getbit },
|
|
|
86f512 |
inject_retval * 8 <= EV_LED
|
|
|
86f512 |
? (const void *) &ev_more_str_2
|