From: Nicholas Nethercote Date: Fri, 22 May 2009 00:15:06 +0000 (+0000) Subject: DARWIN sync: add ML_({PRE,POST}_unknown_ioctl). X-Git-Tag: svn/VALGRIND_3_5_0~621 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b4dbd225dd7cce21cdf27dd87f954b867c965b33;p=thirdparty%2Fvalgrind.git DARWIN sync: add ML_({PRE,POST}_unknown_ioctl). git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10089 --- diff --git a/coregrind/m_syswrap/priv_syswrap-generic.h b/coregrind/m_syswrap/priv_syswrap-generic.h index 29a66e0dff..376c2b507c 100644 --- a/coregrind/m_syswrap/priv_syswrap-generic.h +++ b/coregrind/m_syswrap/priv_syswrap-generic.h @@ -79,6 +79,12 @@ extern void ML_(buf_and_len_post_check) ( ThreadId tid, SysRes res, Addr buf_p, Addr buflen_p, Char* s ); +/* PRE and POST for unknown ioctls based on ioctl request encoding */ +extern +void ML_(PRE_unknown_ioctl)(ThreadId tid, UWord request, UWord arg); +extern +void ML_(POST_unknown_ioctl)(ThreadId tid, UInt res, UWord request, UWord arg); + DECL_TEMPLATE(generic, sys_ni_syscall); // * P -- unimplemented DECL_TEMPLATE(generic, sys_exit); diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index da1e357ca1..3290785b1b 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -3075,6 +3075,70 @@ PRE(sys_getuid) PRE_REG_READ0(long, "getuid"); } +void ML_(PRE_unknown_ioctl)(ThreadId tid, UWord request, UWord arg) +{ + /* We don't have any specific information on it, so + try to do something reasonable based on direction and + size bits. The encoding scheme is described in + /usr/include/asm/ioctl.h or /usr/include/sys/ioccom.h . + + According to Simon Hausmann, _IOC_READ means the kernel + writes a value to the ioctl value passed from the user + space and the other way around with _IOC_WRITE. */ + + UInt dir = _VKI_IOC_DIR(request); + UInt size = _VKI_IOC_SIZE(request); + if (VG_(strstr)(VG_(clo_sim_hints), "lax-ioctls") != NULL) { + /* + * Be very lax about ioctl handling; the only + * assumption is that the size is correct. Doesn't + * require the full buffer to be initialized when + * writing. Without this, using some device + * drivers with a large number of strange ioctl + * commands becomes very tiresome. + */ + } else if (/* size == 0 || */ dir == _VKI_IOC_NONE) { + //VG_(message)(Vg_UserMsg, "UNKNOWN ioctl %#lx\n", request); + //VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size)); + static Int moans = 3; + if (moans > 0 && !VG_(clo_xml)) { + moans--; + VG_UMSG("Warning: noted but unhandled ioctl 0x%lx" + " with no size/direction hints", request); + VG_UMSG(" This could cause spurious value errors to appear."); + VG_UMSG(" See README_MISSING_SYSCALL_OR_IOCTL for " + "guidance on writing a proper wrapper." ); + } + } else { + //VG_(message)(Vg_UserMsg, "UNKNOWN ioctl %#lx\n", request); + //VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size)); + if ((dir & _VKI_IOC_WRITE) && size > 0) + PRE_MEM_READ( "ioctl(generic)", arg, size); + if ((dir & _VKI_IOC_READ) && size > 0) + PRE_MEM_WRITE( "ioctl(generic)", arg, size); + } +} + +void ML_(POST_unknown_ioctl)(ThreadId tid, UInt res, UWord request, UWord arg) +{ + /* We don't have any specific information on it, so + try to do something reasonable based on direction and + size bits. The encoding scheme is described in + /usr/include/asm/ioctl.h or /usr/include/sys/ioccom.h . + + According to Simon Hausmann, _IOC_READ means the kernel + writes a value to the ioctl value passed from the user + space and the other way around with _IOC_WRITE. */ + + UInt dir = _VKI_IOC_DIR(request); + UInt size = _VKI_IOC_SIZE(request); + if (size > 0 && (dir & _VKI_IOC_READ) + && res == 0 + && arg != (Addr)NULL) + { + POST_MEM_WRITE(arg, size); + } +} /* If we're sending a SIGKILL to one of our own threads, then simulate diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index a753a2ad69..b68672ca6c 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -4353,49 +4353,9 @@ PRE(sys_ioctl) } break; - /* We don't have any specific information on it, so - try to do something reasonable based on direction and - size bits. The encoding scheme is described in - /usr/include/asm/ioctl.h. - - According to Simon Hausmann, _IOC_READ means the kernel - writes a value to the ioctl value passed from the user - space and the other way around with _IOC_WRITE. */ - default: { - UInt dir = _VKI_IOC_DIR(ARG2); - UInt size = _VKI_IOC_SIZE(ARG2); - if (VG_(strstr)(VG_(clo_sim_hints), "lax-ioctls") != NULL) { - /* - * Be very lax about ioctl handling; the only - * assumption is that the size is correct. Doesn't - * require the full buffer to be initialized when - * writing. Without this, using some device - * drivers with a large number of strange ioctl - * commands becomes very tiresome. - */ - } else if (/* size == 0 || */ dir == _VKI_IOC_NONE) { - static Int moans = 3; - if (moans > 0 && !VG_(clo_xml)) { - moans--; - VG_(message)(Vg_UserMsg, - "Warning: noted but unhandled ioctl 0x%lx" - " with no size/direction hints", - ARG2); - VG_(message)(Vg_UserMsg, - " This could cause spurious value errors" - " to appear."); - VG_(message)(Vg_UserMsg, - " See README_MISSING_SYSCALL_OR_IOCTL for " - "guidance on writing a proper wrapper." ); - } - } else { - if ((dir & _VKI_IOC_WRITE) && size > 0) - PRE_MEM_READ( "ioctl(generic)", ARG3, size); - if ((dir & _VKI_IOC_READ) && size > 0) - PRE_MEM_WRITE( "ioctl(generic)", ARG3, size); - } + default: + ML_(PRE_unknown_ioctl)(tid, ARG2, ARG3); break; - } } } @@ -5159,24 +5119,10 @@ POST(sys_ioctl) } break; - /* We don't have any specific information on it, so - try to do something reasonable based on direction and - size bits. The encoding scheme is described in - /usr/include/asm/ioctl.h. - - According to Simon Hausmann, _IOC_READ means the kernel - writes a value to the ioctl value passed from the user - space and the other way around with _IOC_WRITE. */ - default: { - UInt dir = _VKI_IOC_DIR(ARG2); - UInt size = _VKI_IOC_SIZE(ARG2); - if (size > 0 && (dir & _VKI_IOC_READ) - && RES == 0 - && ARG3 != (Addr)NULL) - POST_MEM_WRITE(ARG3, size); + default: + ML_(POST_unknown_ioctl)(tid, RES, ARG2, ARG3); break; } - } } /* ---------------------------------------------------------------------