Implement various SNDRV_CTL_xxx ioctls.
Patch from Ivan Sorokin via BZ#334936.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14111 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/NEWS b/NEWS
index a693111..22e6250 100644
--- a/NEWS
+++ b/NEWS
@@ -160,6 +160,7 @@
334705 sendmsg and recvmsg should guard against bogus msghdr fields.
334727 Build fails with -Werror=format-security
334788 clarify doc about --log-file initial program directory
+334936 patch to fix false positives on alsa SNDRV_CTL_* ioctls
335034 Unhandled ioctl: HCIGETDEVLIST
335155 vgdb, fix error print statement.
335262 arm64: movi 8bit version is not supported
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
index e1157e9..ed10584 100644
--- a/coregrind/m_syswrap/syswrap-linux.c
+++ b/coregrind/m_syswrap/syswrap-linux.c
@@ -6104,6 +6104,39 @@
case VKI_SNDRV_PCM_IOCTL_LINK:
/* these just take an int by value */
break;
+ case VKI_SNDRV_CTL_IOCTL_PVERSION:
+ PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_PVERSION)", (Addr)ARG3, sizeof(int) );
+ break;
+ case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
+ PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_CARD_INFO)", (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
+ break;
+ case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
+ struct vki_snd_ctl_elem_list *data = (struct vki_snd_ctl_elem_list *)ARG3;
+ PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->offset, sizeof(data->offset) );
+ PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->space, sizeof(data->space) );
+ PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->used, sizeof(data->used) );
+ PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->count, sizeof(data->count) );
+ PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)&data->pids, sizeof(data->pids) );
+ if (data->pids) {
+ PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_ELEM_LIST)", (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->space );
+ }
+ break;
+ }
+ case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
+ struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)ARG3;
+ PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->numid, sizeof(data->numid) );
+ PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)&data->length, sizeof(data->length) );
+ PRE_MEM_WRITE( "ioctl(SNDRV_CTL_IOCTL_TLV_READ)", (Addr)data->tlv, data->length );
+ break;
+ }
+ case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
+ case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND: {
+ struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)ARG3;
+ PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->numid, sizeof(data->numid) );
+ PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)&data->length, sizeof(data->length) );
+ PRE_MEM_READ( "ioctl(SNDRV_CTL_IOCTL_TLV_WRITE)", (Addr)data->tlv, data->length );
+ break;
+ }
/* Real Time Clock (/dev/rtc) ioctls */
case VKI_RTC_UIE_ON:
@@ -7449,6 +7482,30 @@
case VKI_SNDRV_TIMER_IOCTL_STOP:
case VKI_SNDRV_TIMER_IOCTL_CONTINUE:
case VKI_SNDRV_TIMER_IOCTL_PAUSE:
+ case VKI_SNDRV_CTL_IOCTL_PVERSION: {
+ POST_MEM_WRITE( (Addr)ARG3, sizeof(int) );
+ break;
+ }
+ case VKI_SNDRV_CTL_IOCTL_CARD_INFO:
+ POST_MEM_WRITE( (Addr)ARG3, sizeof(struct vki_snd_ctl_card_info) );
+ break;
+ case VKI_SNDRV_CTL_IOCTL_ELEM_LIST: {
+ struct vki_snd_ctl_elem_list *data = (struct vki_snd_ctl_elem_list *)ARG3;
+ POST_MEM_WRITE( (Addr)&data->used, sizeof(data->used) );
+ POST_MEM_WRITE( (Addr)&data->count, sizeof(data->count) );
+ if (data->pids) {
+ POST_MEM_WRITE( (Addr)data->pids, sizeof(struct vki_snd_ctl_elem_id) * data->used );
+ }
+ break;
+ }
+ case VKI_SNDRV_CTL_IOCTL_TLV_READ: {
+ struct vki_snd_ctl_tlv *data = (struct vki_snd_ctl_tlv *)ARG3;
+ POST_MEM_WRITE( (Addr)data->tlv, data->length );
+ break;
+ }
+ case VKI_SNDRV_CTL_IOCTL_TLV_WRITE:
+ case VKI_SNDRV_CTL_IOCTL_TLV_COMMAND:
+ break;
/* SCSI no operand */
case VKI_SCSI_IOCTL_DOORLOCK:
diff --git a/docs/internals/3_9_BUGSTATUS.txt b/docs/internals/3_9_BUGSTATUS.txt
index 9e779c3..d972bae 100644
--- a/docs/internals/3_9_BUGSTATUS.txt
+++ b/docs/internals/3_9_BUGSTATUS.txt
@@ -168,7 +168,6 @@
========================================================================
========================================================================
-334936 patch to fix false positives on alsa SNDRV_CTL_* ioctls
333628 Out of tree build (is fixed, but needs to land)
335143 Capabilities not supported
197259 (wine) Unsupported arch_prtctl option
diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h
index 9123e24..9ee8603 100644
--- a/include/vki/vki-linux.h
+++ b/include/vki/vki-linux.h
@@ -2312,6 +2312,59 @@
VKI_SNDRV_TIMER_IOCTL_PAUSE = _VKI_IO('T', 0xa3),
};
+struct vki_snd_ctl_card_info {
+ int card; /* card number */
+ int pad; /* reserved for future (was type) */
+ unsigned char id[16]; /* ID of card (user selectable) */
+ unsigned char driver[16]; /* Driver name */
+ unsigned char name[32]; /* Short name of soundcard */
+ unsigned char longname[80]; /* name + info text about soundcard */
+ unsigned char reserved_[16]; /* reserved for future (was ID of mixer) */
+ unsigned char mixername[80]; /* visual mixer identification */
+ unsigned char components[128]; /* card components / fine identification, delimited with one space (AC97 etc..) */
+};
+
+typedef int vki_snd_ctl_elem_iface_t;
+#define VKI_SNDRV_CTL_ELEM_IFACE_CARD ((vki_snd_ctl_elem_iface_t) 0) /* global control */
+#define VKI_SNDRV_CTL_ELEM_IFACE_HWDEP ((vki_snd_ctl_elem_iface_t) 1) /* hardware dependent device */
+#define VKI_SNDRV_CTL_ELEM_IFACE_MIXER ((vki_snd_ctl_elem_iface_t) 2) /* virtual mixer device */
+#define VKI_SNDRV_CTL_ELEM_IFACE_PCM ((vki_snd_ctl_elem_iface_t) 3) /* PCM device */
+#define VKI_SNDRV_CTL_ELEM_IFACE_RAWMIDI ((vki_snd_ctl_elem_iface_t) 4) /* RawMidi device */
+#define VKI_SNDRV_CTL_ELEM_IFACE_TIMER ((vki_snd_ctl_elem_iface_t) 5) /* timer device */
+#define VKI_SNDRV_CTL_ELEM_IFACE_SEQUENCER ((vki_snd_ctl_elem_iface_t) 6) /* sequencer client */
+#define VKI_SNDRV_CTL_ELEM_IFACE_LAST VKI_SNDRV_CTL_ELEM_IFACE_SEQUENCER
+
+struct vki_snd_ctl_elem_id {
+ unsigned int numid; /* numeric identifier, zero = invalid */
+ vki_snd_ctl_elem_iface_t iface; /* interface identifier */
+ unsigned int device; /* device/client number */
+ unsigned int subdevice; /* subdevice (substream) number */
+ unsigned char name[44]; /* ASCII name of item */
+ unsigned int index; /* index of item */
+};
+
+struct vki_snd_ctl_elem_list {
+ unsigned int offset; /* W: first element ID to get */
+ unsigned int space; /* W: count of element IDs to get */
+ unsigned int used; /* R: count of element IDs set */
+ unsigned int count; /* R: count of all elements */
+ struct vki_snd_ctl_elem_id __user *pids; /* R: IDs */
+ unsigned char reserved[50];
+};
+
+struct vki_snd_ctl_tlv {
+ unsigned int numid; /* control element numeric identification */
+ unsigned int length; /* in bytes aligned to 4 */
+ unsigned int tlv[0]; /* first TLV */
+};
+
+#define VKI_SNDRV_CTL_IOCTL_PVERSION _VKI_IOR('U', 0x00, int)
+#define VKI_SNDRV_CTL_IOCTL_CARD_INFO _VKI_IOR('U', 0x01, struct vki_snd_ctl_card_info)
+#define VKI_SNDRV_CTL_IOCTL_ELEM_LIST _VKI_IOWR('U', 0x10, struct vki_snd_ctl_elem_list)
+#define VKI_SNDRV_CTL_IOCTL_TLV_READ _VKI_IOWR('U', 0x1a, struct vki_snd_ctl_tlv)
+#define VKI_SNDRV_CTL_IOCTL_TLV_WRITE _VKI_IOWR('U', 0x1b, struct vki_snd_ctl_tlv)
+#define VKI_SNDRV_CTL_IOCTL_TLV_COMMAND _VKI_IOWR('U', 0x1c, struct vki_snd_ctl_tlv)
+
//----------------------------------------------------------------------
// From linux-2.6.15.4/include/linux/serial.h
//----------------------------------------------------------------------