[PATCH v2 3/3] hdio: improve HDIO support
Srikavin Ramkumar
srikavinramkumar at gmail.com
Wed Sep 8 15:36:54 UTC 2021
Add decoders for HDIO_DRIVE_RESET, HDIO_GET_32BIT, HDIO_GET_ACOUSTIC,
HDIO_GET_ADDRESS, HDIO_GET_BUSSTATE, HDIO_GET_DMA, HDIO_GET_IDENTITY,
HDIO_GET_KEEPSETTINGS, HDIO_GET_MULTCOUNT, HDIO_GET_NICE, HDIO_GET_NOWERR,
HDIO_GET_UNMASKINTR, HDIO_GET_WCACHE, HDIO_OBSOLETE_IDENTITY, HDIO_SCAN_HWIF,
HDIO_SET_32BIT, HDIO_SET_ACOUSTIC, HDIO_SET_ADDRESS, HDIO_SET_BUSSTATE,
HDIO_SET_DMA, HDIO_SET_KEEPSETTINGS, HDIO_SET_MULTCOUNT, HDIO_SET_NICE,
HDIO_SET_NOWERR, HDIO_SET_PIO_MODE, HDIO_SET_UNMASKINTR, HDIO_SET_WCACHE,
and HDIO_UNREGISTER_HWIF.
* maint/gen/defs/common.def: Add decoder for uint32_t arrays.
* maint/gen/defs/hdio.def: New file.
* NEWS: Mention this change.
* src/Makefile.am (libstrace_a_SOURCES): Add gen/generated.h and gen/gen_hdio.c.
* src/gen/gen_hdio.c: Add generated file.
* src/gen/generated.h: New file.
* src/hdio.c: Add call to generated file for unimplemented commands.
* src/xlat/hdio_busstates.in: New file.
* src/xlat/hdio_ide_nice.in: Likewise.
* tests/ioctl_hdio.c: Add tests for newly implemented commands.
---
Changes since V1:
* maint/gen/defs/common.def: Changed ptr[in, array[uint32_t, length]] decoder
to use print_xint32_array_member.
* maint/gen/defs/hdio.def: Added decoders for SET_32BIT, SET_NOWERR, SET_DMA,
SET_WCACHE, SET_ACOUSTIC, SET_ADDRESS, UNREGISTER_HWIF,
SET_PIO_MODE, SCAN_HWIF (and updated commit message).
* src/Makefile.am: Fixed indentation.
* src/gen/gen_hdio.c: Regenerated from hdio.def.
* src/xlat/hdio_busstates.in: Use #unconditional and #value_indexed instead of #enum.
* tests/ioctl_hdio.c: Added tests for new decoders and check that hexadecimal values
are printed for the HDIO_DRIVE_RESET command.
* NEWS: Added entry listing new HDIO command decoders.
The following HDIO commands are still unimplemented:
(undocumented): HDIO_GET_QDMA, HDIO_SET_XFER, HDIO_SET_QDMA, HDIO_TRISTATE_HWIF
(complex): HDIO_DRIVE_TASKFILE, HDIO_DRIVE_TASK
NEWS | 1 +
maint/gen/defs/common.def | 2 +-
maint/gen/defs/hdio.def | 51 +++++
src/Makefile.am | 2 +
src/gen/gen_hdio.c | 441 +++++++++++++++++++++++++++++++++++++
src/gen/generated.h | 4 +
src/hdio.c | 4 +-
src/xlat/hdio_busstates.in | 5 +
src/xlat/hdio_ide_nice.in | 5 +
tests/ioctl_hdio.c | 215 +++++++++++++++---
10 files changed, 698 insertions(+), 32 deletions(-)
create mode 100644 maint/gen/defs/hdio.def
create mode 100644 src/gen/gen_hdio.c
create mode 100644 src/gen/generated.h
create mode 100644 src/xlat/hdio_busstates.in
create mode 100644 src/xlat/hdio_ide_nice.in
diff --git a/NEWS b/NEWS
index df032f85c..d7805d9f2 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,7 @@ Noteworthy changes in release 5.14 (2021-09-02)
* Updated lists of BPF_*, IORING_*, MADV_*, MOUNT_ATTR_*, SCTP_*,
and UFFD_* constants.
* Updated lists of ioctl commands from Linux 5.14.
+ * Enhanced decoding of HDIO_* commands.
* Bug fixes
* Fixed build using bionic libc.
diff --git a/maint/gen/defs/common.def b/maint/gen/defs/common.def
index 24322e9c1..0d8fa096a 100644
--- a/maint/gen/defs/common.def
+++ b/maint/gen/defs/common.def
@@ -36,7 +36,7 @@
:ptr[in, array[uint32_t, $1]] %{
{
uint32_t int_buffer;
- print_array(tcp, $$, $1, &int_buffer, sizeof(int_buffer), tfetch_mem, print_uint32_array_member, 0);
+ print_array(tcp, $$, $1, &int_buffer, sizeof(int_buffer), tfetch_mem, print_xint32_array_member, 0);
}
%}
diff --git a/maint/gen/defs/hdio.def b/maint/gen/defs/hdio.def
new file mode 100644
index 000000000..751978f09
--- /dev/null
+++ b/maint/gen/defs/hdio.def
@@ -0,0 +1,51 @@
+#import "defs/common.def"
+
+include <linux/hdreg.h>
+
+include "xlat/hdio_ide_nice.h"
+include "xlat/hdio_busstates.h"
+
+ioctl$HDIO(fd fd, code kernel_ulong_t, arg3 kernel_ulong_t)
+
+ioctl$HDIO$GET_UNMASKINTR(fd fd, code const[HDIO_GET_UNMASKINTR], unmaskintr ptr[out, ulong])
+ioctl$HDIO$SET_UNMASKINTR(fd fd, code const[HDIO_SET_UNMASKINTR], unmaskintr kernel_ulong_t)
+
+ioctl$HDIO$GET_MULTCOUNT(fd fd, code const[HDIO_GET_MULTCOUNT], multcount ptr[out, ulong])
+ioctl$HDIO$SET_MULTCOUNT(fd fd, code const[HDIO_SET_MULTCOUNT], multcount kernel_ulong_t)
+
+ioctl$HDIO$OBSOLETE_IDENTITY(fd fd, code const[HDIO_OBSOLETE_IDENTITY], identity ptr[out, stringnoz[142]])
+ioctl$HDIO$GET_IDENTITY(fd fd, code const[HDIO_GET_IDENTITY], identity ptr[out, stringnoz[512]])
+
+ioctl$HDIO$GET_KEEPSETTINGS(fd fd, code const[HDIO_GET_KEEPSETTINGS], keep_settings ptr[out, ulong])
+ioctl$HDIO$SET_KEEPSETTINGS(fd fd, code const[HDIO_SET_KEEPSETTINGS], keep_settings kernel_ulong_t)
+
+ioctl$HDIO$GET_32BIT(fd fd, code const[HDIO_GET_32BIT], arg ptr[out, ulong])
+ioctl$HDIO$SET_32BIT(fd fd, code const[HDIO_SET_32BIT], arg kernel_ulong_t)
+
+ioctl$HDIO$GET_NOWERR(fd fd, code const[HDIO_GET_NOWERR], arg ptr[out, ulong])
+ioctl$HDIO$SET_NOWERR(fd fd, code const[HDIO_SET_NOWERR], arg kernel_ulong_t)
+
+ioctl$HDIO$GET_DMA(fd fd, code const[HDIO_GET_DMA], arg ptr[out, ulong])
+ioctl$HDIO$SET_DMA(fd fd, code const[HDIO_SET_DMA], arg kernel_ulong_t)
+
+ioctl$HDIO$GET_NICE(fd fd, code const[HDIO_GET_NICE], arg ptr[out, or_flags[hdio_ide_nice, IDE_NICE_???, ulong]])
+ioctl$HDIO$SET_NICE(fd fd, code const[HDIO_SET_NICE], arg or_flags[hdio_ide_nice, IDE_NICE_???, kernel_ulong_t])
+
+ioctl$HDIO$GET_WCACHE(fd fd, code const[HDIO_GET_WCACHE], arg ptr[out, ulong])
+ioctl$HDIO$SET_WCACHE(fd fd, code const[HDIO_SET_WCACHE], arg kernel_ulong_t)
+
+ioctl$HDIO$GET_ACOUSTIC(fd fd, code const[HDIO_GET_ACOUSTIC], arg ptr[out, ulong])
+ioctl$HDIO$SET_ACOUSTIC(fd fd, code const[HDIO_SET_ACOUSTIC], arg kernel_ulong_t)
+
+ioctl$HDIO$GET_ADDRESS(fd fd, code const[HDIO_GET_ADDRESS], arg ptr[out, ulong])
+ioctl$HDIO$SET_ADDRESS(fd fd, code const[HDIO_SET_ADDRESS], arg kernel_ulong_t)
+
+ioctl$HDIO$GET_BUSSTATE(fd fd, code const[HDIO_GET_BUSSTATE], arg ptr[out, xor_flags[hdio_busstates, BUSSTATE_???, ulong]])
+ioctl$HDIO$SET_BUSSTATE(fd fd, code const[HDIO_SET_BUSSTATE], arg xor_flags[hdio_busstates, BUSSTATE_???, kernel_ulong_t])
+
+ioctl$HDIO$SET_PIO_MODE(fd fd, code const[HDIO_SET_PIO_MODE], arg kernel_ulong_t)
+
+ioctl$HDIO$UNREGISTER_HWIF(fd fd, code const[HDIO_UNREGISTER_HWIF], arg kernel_ulong_t)
+
+ioctl$HDIO$DRIVE_RESET(fd fd, code const[HDIO_DRIVE_RESET], arg ptr[in, array[uint32_t, 3]])
+ioctl$HDIO$SCAN_HWIF(fd fd, code const[HDIO_SCAN_HWIF], arg ptr[in, array[uint32_t, 3]])
diff --git a/src/Makefile.am b/src/Makefile.am
index b7e74a76e..aae7f86f1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -132,6 +132,8 @@ libstrace_a_SOURCES = \
fstatfs64.c \
futex.c \
gcc_compat.h \
+ gen/gen_hdio.c \
+ gen/generated.h \
get_personality.c \
get_personality.h \
get_robust_list.c \
diff --git a/src/gen/gen_hdio.c b/src/gen/gen_hdio.c
new file mode 100644
index 000000000..563f14939
--- /dev/null
+++ b/src/gen/gen_hdio.c
@@ -0,0 +1,441 @@
+/* Generated by ./maint/gen/generate.sh from ./maint/gen/defs/hdio.def; do not edit. */
+
+#include <stddef.h>
+#include "generated.h"
+
+typedef kernel_ulong_t kernel_size_t;
+
+#include <linux/hdreg.h>
+#include "xlat/hdio_ide_nice.h"
+#include "xlat/hdio_busstates.h"
+static int
+var_leaf_ioctl_HDIO_DRIVE_RESET(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ tprint_arg_next();
+ /* arg: arg (array *) */
+ /* using decoder from defs/common.def:36:1 */
+
+ {
+ uint32_t int_buffer;
+ print_array(tcp, (arg), (3), &int_buffer, sizeof(int_buffer), tfetch_mem, print_xint32_array_member, 0);
+ }
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_32BIT(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ if (entering(tcp)) {
+ tprint_arg_next();
+ return 0;
+ }
+ /* arg: arg (unsigned long *) */
+ /* using decoder from defs/common.def:43:1 */
+
+ if (exiting(tcp)) {
+ printnum_ulong(tcp, (arg));
+ }
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_ACOUSTIC(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ if (entering(tcp)) {
+ tprint_arg_next();
+ return 0;
+ }
+ /* arg: arg (unsigned long *) */
+ /* using decoder from defs/common.def:43:1 */
+
+ if (exiting(tcp)) {
+ printnum_ulong(tcp, (arg));
+ }
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_ADDRESS(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ if (entering(tcp)) {
+ tprint_arg_next();
+ return 0;
+ }
+ /* arg: arg (unsigned long *) */
+ /* using decoder from defs/common.def:43:1 */
+
+ if (exiting(tcp)) {
+ printnum_ulong(tcp, (arg));
+ }
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_BUSSTATE(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ if (entering(tcp)) {
+ tprint_arg_next();
+ return 0;
+ }
+ /* arg: arg (unsigned long *) */
+ unsigned long tmpvar_arg;
+ if (!umove_or_printaddr(tcp, arg, &tmpvar_arg)) {
+ tprint_indirect_begin();
+ printxval(hdio_busstates, tmpvar_arg, "BUSSTATE_???");
+ tprint_indirect_end();
+ }
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_DMA(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ if (entering(tcp)) {
+ tprint_arg_next();
+ return 0;
+ }
+ /* arg: arg (unsigned long *) */
+ /* using decoder from defs/common.def:43:1 */
+
+ if (exiting(tcp)) {
+ printnum_ulong(tcp, (arg));
+ }
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_IDENTITY(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ if (entering(tcp)) {
+ tprint_arg_next();
+ return 0;
+ }
+ /* arg: identity (stringnoz *) */
+ /* using decoder from defs/common.def:5:1 */
+
+ if (entering(tcp)) {
+ printstrn(tcp, (arg), (512));
+ } else if (syserror(tcp)) {
+ printaddr((arg));
+ } else {
+ printstrn(tcp, (arg), (512));
+ }
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_KEEPSETTINGS(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ if (entering(tcp)) {
+ tprint_arg_next();
+ return 0;
+ }
+ /* arg: keep_settings (unsigned long *) */
+ /* using decoder from defs/common.def:43:1 */
+
+ if (exiting(tcp)) {
+ printnum_ulong(tcp, (arg));
+ }
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_MULTCOUNT(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ if (entering(tcp)) {
+ tprint_arg_next();
+ return 0;
+ }
+ /* arg: multcount (unsigned long *) */
+ /* using decoder from defs/common.def:43:1 */
+
+ if (exiting(tcp)) {
+ printnum_ulong(tcp, (arg));
+ }
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_NICE(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ if (entering(tcp)) {
+ tprint_arg_next();
+ return 0;
+ }
+ /* arg: arg (unsigned long *) */
+ unsigned long tmpvar_arg;
+ if (!umove_or_printaddr(tcp, arg, &tmpvar_arg)) {
+ tprint_indirect_begin();
+ printflags(hdio_ide_nice, tmpvar_arg, "IDE_NICE_???");
+ tprint_indirect_end();
+ }
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_NOWERR(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ if (entering(tcp)) {
+ tprint_arg_next();
+ return 0;
+ }
+ /* arg: arg (unsigned long *) */
+ /* using decoder from defs/common.def:43:1 */
+
+ if (exiting(tcp)) {
+ printnum_ulong(tcp, (arg));
+ }
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_UNMASKINTR(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ if (entering(tcp)) {
+ tprint_arg_next();
+ return 0;
+ }
+ /* arg: unmaskintr (unsigned long *) */
+ /* using decoder from defs/common.def:43:1 */
+
+ if (exiting(tcp)) {
+ printnum_ulong(tcp, (arg));
+ }
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_GET_WCACHE(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ if (entering(tcp)) {
+ tprint_arg_next();
+ return 0;
+ }
+ /* arg: arg (unsigned long *) */
+ /* using decoder from defs/common.def:43:1 */
+
+ if (exiting(tcp)) {
+ printnum_ulong(tcp, (arg));
+ }
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_OBSOLETE_IDENTITY(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ if (entering(tcp)) {
+ tprint_arg_next();
+ return 0;
+ }
+ /* arg: identity (stringnoz *) */
+ /* using decoder from defs/common.def:5:1 */
+
+ if (entering(tcp)) {
+ printstrn(tcp, (arg), (142));
+ } else if (syserror(tcp)) {
+ printaddr((arg));
+ } else {
+ printstrn(tcp, (arg), (142));
+ }
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SCAN_HWIF(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ tprint_arg_next();
+ /* arg: arg (array *) */
+ /* using decoder from defs/common.def:36:1 */
+
+ {
+ uint32_t int_buffer;
+ print_array(tcp, (arg), (3), &int_buffer, sizeof(int_buffer), tfetch_mem, print_xint32_array_member, 0);
+ }
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_32BIT(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ tprint_arg_next();
+ /* arg: arg (kernel_ulong_t) */
+ PRINT_VAL_U((kernel_ulong_t) arg);
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_ACOUSTIC(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ tprint_arg_next();
+ /* arg: arg (kernel_ulong_t) */
+ PRINT_VAL_U((kernel_ulong_t) arg);
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_ADDRESS(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ tprint_arg_next();
+ /* arg: arg (kernel_ulong_t) */
+ PRINT_VAL_U((kernel_ulong_t) arg);
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_BUSSTATE(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ tprint_arg_next();
+ /* arg: arg (kernel_ulong_t) */
+ printxval(hdio_busstates, arg, "BUSSTATE_???");
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_DMA(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ tprint_arg_next();
+ /* arg: arg (kernel_ulong_t) */
+ PRINT_VAL_U((kernel_ulong_t) arg);
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_KEEPSETTINGS(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ tprint_arg_next();
+ /* arg: keep_settings (kernel_ulong_t) */
+ PRINT_VAL_U((kernel_ulong_t) arg);
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_MULTCOUNT(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ tprint_arg_next();
+ /* arg: multcount (kernel_ulong_t) */
+ PRINT_VAL_U((kernel_ulong_t) arg);
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_NICE(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ tprint_arg_next();
+ /* arg: arg (kernel_ulong_t) */
+ printflags(hdio_ide_nice, arg, "IDE_NICE_???");
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_NOWERR(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ tprint_arg_next();
+ /* arg: arg (kernel_ulong_t) */
+ PRINT_VAL_U((kernel_ulong_t) arg);
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_PIO_MODE(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ tprint_arg_next();
+ /* arg: arg (kernel_ulong_t) */
+ PRINT_VAL_U((kernel_ulong_t) arg);
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_UNMASKINTR(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ tprint_arg_next();
+ /* arg: unmaskintr (kernel_ulong_t) */
+ PRINT_VAL_U((kernel_ulong_t) arg);
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_SET_WCACHE(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ tprint_arg_next();
+ /* arg: arg (kernel_ulong_t) */
+ PRINT_VAL_U((kernel_ulong_t) arg);
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO_UNREGISTER_HWIF(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ tprint_arg_next();
+ /* arg: arg (kernel_ulong_t) */
+ PRINT_VAL_U((kernel_ulong_t) arg);
+
+ return RVAL_IOCTL_DECODED;
+}
+static int
+var_leaf_ioctl_HDIO(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ return RVAL_DECODED;
+}
+int
+var_ioctl_HDIO(struct tcb *tcp, unsigned int code, kernel_ulong_t arg)
+{
+ if ((code) == (HDIO_DRIVE_RESET)) {
+ return var_leaf_ioctl_HDIO_DRIVE_RESET(tcp, code, arg);
+ } else if ((code) == (HDIO_GET_32BIT)) {
+ return var_leaf_ioctl_HDIO_GET_32BIT(tcp, code, arg);
+ } else if ((code) == (HDIO_GET_ACOUSTIC)) {
+ return var_leaf_ioctl_HDIO_GET_ACOUSTIC(tcp, code, arg);
+ } else if ((code) == (HDIO_GET_ADDRESS)) {
+ return var_leaf_ioctl_HDIO_GET_ADDRESS(tcp, code, arg);
+ } else if ((code) == (HDIO_GET_BUSSTATE)) {
+ return var_leaf_ioctl_HDIO_GET_BUSSTATE(tcp, code, arg);
+ } else if ((code) == (HDIO_GET_DMA)) {
+ return var_leaf_ioctl_HDIO_GET_DMA(tcp, code, arg);
+ } else if ((code) == (HDIO_GET_IDENTITY)) {
+ return var_leaf_ioctl_HDIO_GET_IDENTITY(tcp, code, arg);
+ } else if ((code) == (HDIO_GET_KEEPSETTINGS)) {
+ return var_leaf_ioctl_HDIO_GET_KEEPSETTINGS(tcp, code, arg);
+ } else if ((code) == (HDIO_GET_MULTCOUNT)) {
+ return var_leaf_ioctl_HDIO_GET_MULTCOUNT(tcp, code, arg);
+ } else if ((code) == (HDIO_GET_NICE)) {
+ return var_leaf_ioctl_HDIO_GET_NICE(tcp, code, arg);
+ } else if ((code) == (HDIO_GET_NOWERR)) {
+ return var_leaf_ioctl_HDIO_GET_NOWERR(tcp, code, arg);
+ } else if ((code) == (HDIO_GET_UNMASKINTR)) {
+ return var_leaf_ioctl_HDIO_GET_UNMASKINTR(tcp, code, arg);
+ } else if ((code) == (HDIO_GET_WCACHE)) {
+ return var_leaf_ioctl_HDIO_GET_WCACHE(tcp, code, arg);
+ } else if ((code) == (HDIO_OBSOLETE_IDENTITY)) {
+ return var_leaf_ioctl_HDIO_OBSOLETE_IDENTITY(tcp, code, arg);
+ } else if ((code) == (HDIO_SCAN_HWIF)) {
+ return var_leaf_ioctl_HDIO_SCAN_HWIF(tcp, code, arg);
+ } else if ((code) == (HDIO_SET_32BIT)) {
+ return var_leaf_ioctl_HDIO_SET_32BIT(tcp, code, arg);
+ } else if ((code) == (HDIO_SET_ACOUSTIC)) {
+ return var_leaf_ioctl_HDIO_SET_ACOUSTIC(tcp, code, arg);
+ } else if ((code) == (HDIO_SET_ADDRESS)) {
+ return var_leaf_ioctl_HDIO_SET_ADDRESS(tcp, code, arg);
+ } else if ((code) == (HDIO_SET_BUSSTATE)) {
+ return var_leaf_ioctl_HDIO_SET_BUSSTATE(tcp, code, arg);
+ } else if ((code) == (HDIO_SET_DMA)) {
+ return var_leaf_ioctl_HDIO_SET_DMA(tcp, code, arg);
+ } else if ((code) == (HDIO_SET_KEEPSETTINGS)) {
+ return var_leaf_ioctl_HDIO_SET_KEEPSETTINGS(tcp, code, arg);
+ } else if ((code) == (HDIO_SET_MULTCOUNT)) {
+ return var_leaf_ioctl_HDIO_SET_MULTCOUNT(tcp, code, arg);
+ } else if ((code) == (HDIO_SET_NICE)) {
+ return var_leaf_ioctl_HDIO_SET_NICE(tcp, code, arg);
+ } else if ((code) == (HDIO_SET_NOWERR)) {
+ return var_leaf_ioctl_HDIO_SET_NOWERR(tcp, code, arg);
+ } else if ((code) == (HDIO_SET_PIO_MODE)) {
+ return var_leaf_ioctl_HDIO_SET_PIO_MODE(tcp, code, arg);
+ } else if ((code) == (HDIO_SET_UNMASKINTR)) {
+ return var_leaf_ioctl_HDIO_SET_UNMASKINTR(tcp, code, arg);
+ } else if ((code) == (HDIO_SET_WCACHE)) {
+ return var_leaf_ioctl_HDIO_SET_WCACHE(tcp, code, arg);
+ } else if ((code) == (HDIO_UNREGISTER_HWIF)) {
+ return var_leaf_ioctl_HDIO_UNREGISTER_HWIF(tcp, code, arg);
+ } else {
+ return var_leaf_ioctl_HDIO(tcp, code, arg);
+ }
+}
diff --git a/src/gen/generated.h b/src/gen/generated.h
new file mode 100644
index 000000000..ab8a7bab2
--- /dev/null
+++ b/src/gen/generated.h
@@ -0,0 +1,4 @@
+#include "defs.h"
+
+int
+var_ioctl_HDIO(struct tcb *tcp, unsigned int code, kernel_ulong_t arg);
diff --git a/src/hdio.c b/src/hdio.c
index 9a260a423..b681dc6fa 100644
--- a/src/hdio.c
+++ b/src/hdio.c
@@ -19,6 +19,8 @@ typedef struct hd_geometry struct_hd_geometry;
#include "xlat/hdio_drive_cmds.h"
+#include "gen/generated.h"
+
static int
print_hdio_getgeo(struct tcb *const tcp, const kernel_ulong_t arg)
{
@@ -113,7 +115,7 @@ MPERS_PRINTER_DECL(int, hdio_ioctl, struct tcb *const tcp,
case HDIO_DRIVE_CMD:
return print_hdio_drive_cmd(tcp, arg);
default:
- return RVAL_DECODED;
+ return var_ioctl_HDIO(tcp, code, arg);
}
return RVAL_IOCTL_DECODED;
diff --git a/src/xlat/hdio_busstates.in b/src/xlat/hdio_busstates.in
new file mode 100644
index 000000000..9224700a7
--- /dev/null
+++ b/src/xlat/hdio_busstates.in
@@ -0,0 +1,5 @@
+#unconditional
+#value_indexed
+BUSSTATE_OFF
+BUSSTATE_ON
+BUSSTATE_TRISTATE
diff --git a/src/xlat/hdio_ide_nice.in b/src/xlat/hdio_ide_nice.in
new file mode 100644
index 000000000..6dd3bb0fd
--- /dev/null
+++ b/src/xlat/hdio_ide_nice.in
@@ -0,0 +1,5 @@
+1 << IDE_NICE_DSC_OVERLAP
+1 << IDE_NICE_ATAPI_OVERLAP
+1 << IDE_NICE_1
+1 << IDE_NICE_0
+1 << IDE_NICE_2
diff --git a/tests/ioctl_hdio.c b/tests/ioctl_hdio.c
index 96cd4696e..2d246c5fe 100644
--- a/tests/ioctl_hdio.c
+++ b/tests/ioctl_hdio.c
@@ -14,6 +14,10 @@
#include <stdlib.h>
#include <linux/hdreg.h>
#include <sys/ioctl.h>
+#include "xlat.h"
+
+#include "xlat/hdio_busstates.h"
+#include "xlat/hdio_ide_nice.h"
static const char *errstr;
@@ -59,7 +63,7 @@ main(int argc, char *argv[])
for (size_t i = 0; i < num_skip; i++) {
long ret = ioctl(-1, HDIO_GET_UNMASKINTR, 0);
- printf("ioctl(-1, %s, 0) = %s%s\n",
+ printf("ioctl(-1, %s, NULL) = %s%s\n",
XLAT_STR(HDIO_GET_UNMASKINTR), sprintrc(ret),
ret == INJECT_RETVAL ? " (INJECTED)" : "");
@@ -72,7 +76,7 @@ main(int argc, char *argv[])
if (!locked)
error_msg_and_fail("Hasn't locked on ioctl(-1"
- ", HDIO_GET_UNMASKINTR, 0) returning %d",
+ ", HDIO_GET_UNMASKINTR, NULL) returning %d",
INJECT_RETVAL);
#endif
@@ -83,40 +87,12 @@ main(int argc, char *argv[])
uint32_t cmd;
const char *str;
} unsupp_cmds[] = {
- { ARG_STR(HDIO_GET_UNMASKINTR) },
- { ARG_STR(HDIO_GET_MULTCOUNT) },
{ ARG_STR(HDIO_GET_QDMA) },
{ ARG_STR(HDIO_SET_XFER) },
- { ARG_STR(HDIO_OBSOLETE_IDENTITY) },
- { ARG_STR(HDIO_GET_KEEPSETTINGS) },
- { ARG_STR(HDIO_GET_32BIT) },
- { ARG_STR(HDIO_GET_NOWERR) },
- { ARG_STR(HDIO_GET_DMA) },
- { ARG_STR(HDIO_GET_NICE) },
- { ARG_STR(HDIO_GET_IDENTITY) },
- { ARG_STR(HDIO_GET_WCACHE) },
- { ARG_STR(HDIO_GET_ACOUSTIC) },
- { ARG_STR(HDIO_GET_ADDRESS) },
- { ARG_STR(HDIO_GET_BUSSTATE) },
{ ARG_STR(HDIO_TRISTATE_HWIF) },
- { ARG_STR(HDIO_DRIVE_RESET) },
{ ARG_STR(HDIO_DRIVE_TASKFILE) },
{ ARG_STR(HDIO_DRIVE_TASK) },
- { ARG_STR(HDIO_SET_MULTCOUNT) },
- { ARG_STR(HDIO_SET_UNMASKINTR) },
- { ARG_STR(HDIO_SET_KEEPSETTINGS) },
- { ARG_STR(HDIO_SET_32BIT) },
- { ARG_STR(HDIO_SET_NOWERR) },
- { ARG_STR(HDIO_SET_DMA) },
- { ARG_STR(HDIO_SET_PIO_MODE) },
- { ARG_STR(HDIO_SCAN_HWIF) },
- { ARG_STR(HDIO_UNREGISTER_HWIF) },
- { ARG_STR(HDIO_SET_NICE) },
- { ARG_STR(HDIO_SET_WCACHE) },
- { ARG_STR(HDIO_SET_ACOUSTIC) },
- { ARG_STR(HDIO_SET_BUSSTATE) },
{ ARG_STR(HDIO_SET_QDMA) },
- { ARG_STR(HDIO_SET_ADDRESS) },
};
for (size_t i = 0; i < ARRAY_SIZE(unsupp_cmds); i++) {
@@ -220,6 +196,185 @@ main(int argc, char *argv[])
}
printf("}) = %s\n", errstr);
+ /* HDIO_DRIVE_RESET */
+ printf("ioctl(-1, %s, NULL) = %s\n", XLAT_STR(HDIO_DRIVE_RESET), errstr);
+ do_ioctl_ptr(HDIO_DRIVE_RESET, 0);
+
+ printf("ioctl(-1, %s, %p) = %s\n", XLAT_STR(HDIO_DRIVE_RESET),
+ (void *) 0xdeadbeef, errstr);
+ do_ioctl(HDIO_DRIVE_RESET, 0xdeadbeef);
+
+ printf("ioctl(-1, %s, [%#x, %#x, %#x]) = %s\n", XLAT_STR(HDIO_DRIVE_RESET),
+ (unsigned) 0xdeadbeef, (unsigned) 0xAAAAAAAA, (unsigned) 0xbeefbeef, errstr);
+ int drive_reset_args[3] = {0xdeadbeef, 0xAAAAAAAA, 0xbeefbeef};
+ do_ioctl_ptr(HDIO_DRIVE_RESET, &drive_reset_args);
+
+ /* HDIO_SCAN_HWIF */
+ printf("ioctl(-1, %s, NULL) = %s\n", XLAT_STR(HDIO_SCAN_HWIF), errstr);
+ do_ioctl_ptr(HDIO_SCAN_HWIF, 0);
+
+ printf("ioctl(-1, %s, %p) = %s\n", XLAT_STR(HDIO_SCAN_HWIF),
+ (void *) 0xdeadbeef, errstr);
+ do_ioctl(HDIO_SCAN_HWIF, 0xdeadbeef);
+
+ printf("ioctl(-1, %s, [%#x, %#x, %#x]) = %s\n", XLAT_STR(HDIO_SCAN_HWIF),
+ (unsigned) 0xdeadbeef, (unsigned) 0xAAAAAAAA, (unsigned) 0xbeefbeef, errstr);
+ int scan_hwif_args[3] = {0xdeadbeef, 0xAAAAAAAA, 0xbeefbeef};
+ do_ioctl_ptr(HDIO_SCAN_HWIF, &scan_hwif_args);
+
+ /* Getters of the form ioctl(..., ..., &val) */
+ static const struct {
+ uint32_t cmd;
+ const char *str;
+ } getter_cmds[] = {
+ { ARG_STR(HDIO_GET_32BIT) },
+ { ARG_STR(HDIO_GET_ACOUSTIC) },
+ { ARG_STR(HDIO_GET_ADDRESS) },
+ { ARG_STR(HDIO_GET_DMA) },
+ { ARG_STR(HDIO_GET_KEEPSETTINGS) },
+ { ARG_STR(HDIO_GET_MULTCOUNT) },
+ { ARG_STR(HDIO_GET_NOWERR) },
+ { ARG_STR(HDIO_GET_UNMASKINTR) },
+ { ARG_STR(HDIO_GET_WCACHE) },
+ };
+
+ for (size_t i = 0; i < ARRAY_SIZE(getter_cmds); i++) {
+ unsigned long val = 0xdeadbeef;
+
+ rc = do_ioctl_ptr(getter_cmds[i].cmd, &val);
+ printf("ioctl(-1, " XLAT_FMT ", ", XLAT_SEL(getter_cmds[i].cmd, getter_cmds[i].str));
+ if (rc >= 0) {
+ printf("[%lu]", val);
+ } else {
+ printf("%p", &val);
+ }
+ printf(") = %s\n", errstr);
+ }
+
+ /* Setters of the form ioctl(..., ..., val) */
+ static const struct {
+ uint32_t cmd;
+ const char *str;
+ } setter_cmds[] = {
+ { ARG_STR(HDIO_SET_32BIT) },
+ { ARG_STR(HDIO_SET_ACOUSTIC) },
+ { ARG_STR(HDIO_SET_ADDRESS) },
+ { ARG_STR(HDIO_SET_DMA) },
+ { ARG_STR(HDIO_SET_KEEPSETTINGS) },
+ { ARG_STR(HDIO_SET_MULTCOUNT) },
+ { ARG_STR(HDIO_SET_NOWERR) },
+ { ARG_STR(HDIO_SET_PIO_MODE) },
+ { ARG_STR(HDIO_SET_UNMASKINTR) },
+ { ARG_STR(HDIO_SET_WCACHE) },
+ { ARG_STR(HDIO_UNREGISTER_HWIF) },
+ };
+
+ for (size_t i = 0; i < ARRAY_SIZE(setter_cmds); i++) {
+ unsigned long val = 0xdeadbeef;
+
+ rc = do_ioctl(setter_cmds[i].cmd, val);
+ printf("ioctl(-1, " XLAT_FMT ", %lu) = %s\n", XLAT_SEL(setter_cmds[i].cmd, setter_cmds[i].str),
+ val, errstr);
+ }
+
+ /* HDIO_OBSOLETE_IDENTITY */
+ do_ioctl_ptr(HDIO_OBSOLETE_IDENTITY, NULL);
+ printf("ioctl(-1, %s, NULL) = %s\n", XLAT_STR(HDIO_OBSOLETE_IDENTITY), errstr);
+
+ char obsolete_identity[142];
+ rc = do_ioctl_ptr(HDIO_OBSOLETE_IDENTITY, obsolete_identity);
+
+ printf("ioctl(-1, %s, ", XLAT_STR(HDIO_OBSOLETE_IDENTITY));
+
+ if (rc >= 0) {
+ print_quoted_memory(obsolete_identity, DEFAULT_STRLEN);
+ printf("...");
+ } else {
+ printf("%p", obsolete_identity);
+ }
+ printf(") = %s\n", errstr);
+
+ /* HDIO_GET_IDENTITY */
+ do_ioctl_ptr(HDIO_GET_IDENTITY, NULL);
+ printf("ioctl(-1, %s, NULL) = %s\n", XLAT_STR(HDIO_GET_IDENTITY), errstr);
+
+ char identity[512];
+ rc = do_ioctl_ptr(HDIO_GET_IDENTITY, identity);
+
+ printf("ioctl(-1, %s, ", XLAT_STR(HDIO_GET_IDENTITY));
+
+ if (rc >= 0) {
+ print_quoted_memory(identity, DEFAULT_STRLEN);
+ printf("...");
+ } else {
+ printf("%p", identity);
+ }
+ printf(") = %s\n", errstr);
+
+ /* HDIO_GET_NICE */
+ unsigned long nice_val = 0xdeadffff;
+
+ rc = do_ioctl_ptr(HDIO_GET_NICE, &nice_val);
+ printf("ioctl(-1, %s, ", XLAT_STR(HDIO_GET_NICE));
+ if (rc >= 0) {
+ printf("[");
+#if XLAT_RAW
+ printf("%#lx", nice_val);
+#else
+#if XLAT_VERBOSE
+ printf("%#lx /* ", nice_val);
+#endif
+ printflags(hdio_ide_nice, nice_val, "IDE_NICE_???");
+#if XLAT_VERBOSE
+ printf(" */");
+#endif
+#endif
+ printf("]");
+ } else {
+ printf("%p", &nice_val);
+ }
+ printf(") = %s\n", errstr);
+
+ /* HDIO_SET_NICE */
+ nice_val = 0xc0dec0de;
+ do_ioctl(HDIO_SET_NICE, nice_val);
+ printf("ioctl(-1, %s, ", XLAT_STR(HDIO_SET_NICE));
+#if XLAT_RAW
+ printf("%#lx", nice_val);
+#else
+#if XLAT_VERBOSE
+ printf("%#lx /* ", nice_val);
+#endif
+ printflags(hdio_ide_nice, nice_val, "IDE_NICE_???");
+#if XLAT_VERBOSE
+ printf(" */");
+#endif
+#endif
+ printf(") = %s\n", errstr);
+
+ /* HDIO_GET_BUSSTATE */
+ unsigned long busstate_value = 0xdeadffff;
+
+ rc = do_ioctl_ptr(HDIO_GET_BUSSTATE, &busstate_value);
+ printf("ioctl(-1, %s, ", XLAT_STR(HDIO_GET_BUSSTATE));
+ if (rc >= 0) {
+ printf("[");
+ printxval(hdio_busstates, busstate_value, "BUSSTATE_???");
+ printf("]");
+ } else {
+ printf("%p", &busstate_value);
+ }
+ printf(") = %s\n", errstr);
+
+
+ /* HDIO_SET_BUSSTATE */
+ busstate_value = 0xc0dec0de;
+
+ do_ioctl(HDIO_SET_BUSSTATE, busstate_value);
+ printf("ioctl(-1, %s, ", XLAT_STR(HDIO_SET_BUSSTATE));
+ printxval(hdio_busstates, busstate_value, "BUSSTATE_???");
+ printf(") = %s\n", errstr);
+
puts("+++ exited with 0 +++");
return 0;
}
--
2.25.1
More information about the Strace-devel
mailing list