From 3bfae3eec150e54b44fd5d7e1d032d74a69c7fe8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 17 Feb 2009 00:23:30 +0000 Subject: [PATCH] Merged r9185 (fix up getsockopt mess) from the DARWIN branch, minus the Darwin-specific parts. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9186 --- coregrind/m_syswrap/priv_syswrap-generic.h | 9 +- coregrind/m_syswrap/priv_syswrap-linux.h | 12 ++- coregrind/m_syswrap/syswrap-amd64-linux.c | 6 +- coregrind/m_syswrap/syswrap-generic.c | 108 +++++---------------- coregrind/m_syswrap/syswrap-linux.c | 66 +++++++++++++ coregrind/m_syswrap/syswrap-ppc32-linux.c | 10 +- coregrind/m_syswrap/syswrap-ppc64-linux.c | 10 +- coregrind/m_syswrap/syswrap-x86-linux.c | 10 +- 8 files changed, 122 insertions(+), 109 deletions(-) diff --git a/coregrind/m_syswrap/priv_syswrap-generic.h b/coregrind/m_syswrap/priv_syswrap-generic.h index a2d327ce18..87e3779757 100644 --- a/coregrind/m_syswrap/priv_syswrap-generic.h +++ b/coregrind/m_syswrap/priv_syswrap-generic.h @@ -69,6 +69,13 @@ void ML_(notify_aspacem_and_tool_of_mmap) ( Addr a, SizeT len, UInt prot, UInt mm_flags, Int fd, Off64T offset ); +extern void +ML_(buf_and_len_pre_check) ( ThreadId tid, Addr buf_p, Addr buflen_p, + Char* buf_s, Char* buflen_s ); +extern void +ML_(buf_and_len_post_check) ( ThreadId tid, SysRes res, + Addr buf_p, Addr buflen_p, Char* s ); + DECL_TEMPLATE(generic, sys_ni_syscall); // * P -- unimplemented DECL_TEMPLATE(generic, sys_exit); @@ -220,8 +227,6 @@ extern void ML_(generic_PRE_sys_recv) ( TId, UW, UW, UW ); extern void ML_(generic_POST_sys_recv) ( TId, UW, UW, UW, UW ); extern void ML_(generic_PRE_sys_connect) ( TId, UW, UW, UW ); extern void ML_(generic_PRE_sys_setsockopt) ( TId, UW, UW, UW, UW, UW ); -extern void ML_(generic_PRE_sys_getsockopt) ( TId, UW, UW, UW, UW, UW ); -extern void ML_(generic_POST_sys_getsockopt) ( TId, SR, UW, UW, UW, UW, UW ); extern void ML_(generic_PRE_sys_getsockname) ( TId, UW, UW, UW ); extern void ML_(generic_POST_sys_getsockname) ( TId, SR, UW, UW, UW ); extern void ML_(generic_PRE_sys_getpeername) ( TId, UW, UW, UW ); diff --git a/coregrind/m_syswrap/priv_syswrap-linux.h b/coregrind/m_syswrap/priv_syswrap-linux.h index 3cd0ca2351..09c4372bbe 100644 --- a/coregrind/m_syswrap/priv_syswrap-linux.h +++ b/coregrind/m_syswrap/priv_syswrap-linux.h @@ -252,11 +252,13 @@ DECL_TEMPLATE(linux, sys_lookup_dcookie); // (*/32/64) L #define UW UWord #define SR SysRes -extern void ML_(linux_PRE_sys_msgsnd) ( TId, UW, UW, UW, UW ); -extern void ML_(linux_PRE_sys_msgrcv) ( TId, UW, UW, UW, UW, UW ); -extern void ML_(linux_POST_sys_msgrcv) ( TId, UW, UW, UW, UW, UW, UW ); -extern void ML_(linux_PRE_sys_msgctl) ( TId, UW, UW, UW ); -extern void ML_(linux_POST_sys_msgctl) ( TId, UW, UW, UW, UW ); +extern void ML_(linux_PRE_sys_msgsnd) ( TId, UW, UW, UW, UW ); +extern void ML_(linux_PRE_sys_msgrcv) ( TId, UW, UW, UW, UW, UW ); +extern void ML_(linux_POST_sys_msgrcv) ( TId, UW, UW, UW, UW, UW, UW ); +extern void ML_(linux_PRE_sys_msgctl) ( TId, UW, UW, UW ); +extern void ML_(linux_POST_sys_msgctl) ( TId, UW, UW, UW, UW ); +extern void ML_(linux_PRE_sys_getsockopt) ( TId, UW, UW, UW, UW, UW ); +extern void ML_(linux_POST_sys_getsockopt) ( TId, SR, UW, UW, UW, UW, UW ); #undef TId #undef UW diff --git a/coregrind/m_syswrap/syswrap-amd64-linux.c b/coregrind/m_syswrap/syswrap-amd64-linux.c index a82ad21b5f..69ad744389 100644 --- a/coregrind/m_syswrap/syswrap-amd64-linux.c +++ b/coregrind/m_syswrap/syswrap-amd64-linux.c @@ -641,13 +641,13 @@ PRE(sys_getsockopt) PRE_REG_READ5(long, "getsockopt", int, s, int, level, int, optname, void *, optval, int, *optlen); - ML_(generic_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5); + ML_(linux_PRE_sys_getsockopt)(tid, ARG1,ARG2,ARG3,ARG4,ARG5); } POST(sys_getsockopt) { vg_assert(SUCCESS); - ML_(generic_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES), - ARG1,ARG2,ARG3,ARG4,ARG5); + ML_(linux_POST_sys_getsockopt)(tid, VG_(mk_SysRes_Success)(RES), + ARG1,ARG2,ARG3,ARG4,ARG5); } PRE(sys_connect) diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index c759682dd1..05419b9d0a 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -947,9 +947,8 @@ static UInt deref_UInt ( ThreadId tid, Addr a, Char* s ) return *a_p; } -static -void buf_and_len_pre_check( ThreadId tid, Addr buf_p, Addr buflen_p, - Char* buf_s, Char* buflen_s ) +void ML_(buf_and_len_pre_check) ( ThreadId tid, Addr buf_p, Addr buflen_p, + Char* buf_s, Char* buflen_s ) { if (VG_(tdict).track_pre_mem_write) { UInt buflen_in = deref_UInt( tid, buflen_p, buflen_s); @@ -959,9 +958,8 @@ void buf_and_len_pre_check( ThreadId tid, Addr buf_p, Addr buflen_p, } } -static -void buf_and_len_post_check( ThreadId tid, SysRes res, - Addr buf_p, Addr buflen_p, Char* s ) +void ML_(buf_and_len_post_check) ( ThreadId tid, SysRes res, + Addr buf_p, Addr buflen_p, Char* s ) { if (!res.isError && VG_(tdict).track_post_mem_write) { UInt buflen_out = deref_UInt( tid, buflen_p, s); @@ -1244,9 +1242,9 @@ ML_(generic_PRE_sys_accept) ( ThreadId tid, Addr addr_p = arg1; Addr addrlen_p = arg2; if (addr_p != (Addr)NULL) - buf_and_len_pre_check ( tid, addr_p, addrlen_p, - "socketcall.accept(addr)", - "socketcall.accept(addrlen_in)" ); + ML_(buf_and_len_pre_check) ( tid, addr_p, addrlen_p, + "socketcall.accept(addr)", + "socketcall.accept(addrlen_in)" ); } SysRes @@ -1263,8 +1261,8 @@ ML_(generic_POST_sys_accept) ( ThreadId tid, Addr addr_p = arg1; Addr addrlen_p = arg2; if (addr_p != (Addr)NULL) - buf_and_len_post_check ( tid, res, addr_p, addrlen_p, - "socketcall.accept(addrlen_out)" ); + ML_(buf_and_len_post_check) ( tid, res, addr_p, addrlen_p, + "socketcall.accept(addrlen_out)" ); if (VG_(clo_track_fds)) ML_(record_fd_open_nameless)(tid, res.res); } @@ -1318,9 +1316,9 @@ ML_(generic_PRE_sys_recvfrom) ( ThreadId tid, Addr fromlen_p = arg5; PRE_MEM_WRITE( "socketcall.recvfrom(buf)", buf_p, len ); if (from_p != (Addr)NULL) - buf_and_len_pre_check ( tid, from_p, fromlen_p, - "socketcall.recvfrom(from)", - "socketcall.recvfrom(fromlen_in)" ); + ML_(buf_and_len_pre_check) ( tid, from_p, fromlen_p, + "socketcall.recvfrom(from)", + "socketcall.recvfrom(fromlen_in)" ); } void @@ -1336,8 +1334,8 @@ ML_(generic_POST_sys_recvfrom) ( ThreadId tid, vg_assert(!res.isError); /* guaranteed by caller */ if (from_p != (Addr)NULL) - buf_and_len_post_check ( tid, res, from_p, fromlen_p, - "socketcall.recvfrom(fromlen_out)" ); + ML_(buf_and_len_post_check) ( tid, res, from_p, fromlen_p, + "socketcall.recvfrom(fromlen_out)" ); POST_MEM_WRITE( buf_p, len ); } @@ -1401,64 +1399,6 @@ ML_(generic_PRE_sys_setsockopt) ( ThreadId tid, /* ------ */ -void -ML_(generic_PRE_sys_getsockopt) ( ThreadId tid, - UWord arg0, UWord arg1, UWord arg2, - UWord arg3, UWord arg4 ) -{ - /* int getsockopt(int s, int level, int optname, - void *optval, socklen_t *optlen); */ - Addr optval_p = arg3; - Addr optlen_p = arg4; - /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */ - if (optval_p != (Addr)NULL) { - buf_and_len_pre_check ( tid, optval_p, optlen_p, - "socketcall.getsockopt(optval)", - "socketcall.getsockopt(optlen)" ); - if (arg1 == VKI_SOL_SCTP && - (arg2 == VKI_SCTP_GET_PEER_ADDRS || arg2 == VKI_SCTP_GET_LOCAL_ADDRS)) { - struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3; - int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num; - PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)", (Addr)ga->addrs, address_bytes ); - } - } -} - -void -ML_(generic_POST_sys_getsockopt) ( ThreadId tid, - SysRes res, - UWord arg0, UWord arg1, UWord arg2, - UWord arg3, UWord arg4 ) -{ - Addr optval_p = arg3; - Addr optlen_p = arg4; - vg_assert(!res.isError); /* guaranteed by caller */ - if (optval_p != (Addr)NULL) { - buf_and_len_post_check ( tid, res, optval_p, optlen_p, - "socketcall.getsockopt(optlen_out)" ); - if (arg1 == VKI_SOL_SCTP && - (arg2 == VKI_SCTP_GET_PEER_ADDRS || arg2 == VKI_SCTP_GET_LOCAL_ADDRS)) { - struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3; - struct vki_sockaddr *a = ga->addrs; - int i; - for (i = 0; i < ga->addr_num; i++) { - int sl = 0; - if (a->sa_family == VKI_AF_INET) - sl = sizeof(struct vki_sockaddr_in); - else if (a->sa_family == VKI_AF_INET6) - sl = sizeof(struct vki_sockaddr_in6); - else { - VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled address type %d", a->sa_family); - } - a = (struct vki_sockaddr*)((char*)a + sl); - } - POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs ); - } - } -} - -/* ------ */ - void ML_(generic_PRE_sys_getsockname) ( ThreadId tid, UWord arg0, UWord arg1, UWord arg2 ) @@ -1467,9 +1407,9 @@ ML_(generic_PRE_sys_getsockname) ( ThreadId tid, Addr name_p = arg1; Addr namelen_p = arg2; /* Nb: name_p cannot be NULL */ - buf_and_len_pre_check ( tid, name_p, namelen_p, - "socketcall.getsockname(name)", - "socketcall.getsockname(namelen_in)" ); + ML_(buf_and_len_pre_check) ( tid, name_p, namelen_p, + "socketcall.getsockname(name)", + "socketcall.getsockname(namelen_in)" ); } void @@ -1480,8 +1420,8 @@ ML_(generic_POST_sys_getsockname) ( ThreadId tid, Addr name_p = arg1; Addr namelen_p = arg2; vg_assert(!res.isError); /* guaranteed by caller */ - buf_and_len_post_check ( tid, res, name_p, namelen_p, - "socketcall.getsockname(namelen_out)" ); + ML_(buf_and_len_post_check) ( tid, res, name_p, namelen_p, + "socketcall.getsockname(namelen_out)" ); } /* ------ */ @@ -1494,9 +1434,9 @@ ML_(generic_PRE_sys_getpeername) ( ThreadId tid, Addr name_p = arg1; Addr namelen_p = arg2; /* Nb: name_p cannot be NULL */ - buf_and_len_pre_check ( tid, name_p, namelen_p, - "socketcall.getpeername(name)", - "socketcall.getpeername(namelen_in)" ); + ML_(buf_and_len_pre_check) ( tid, name_p, namelen_p, + "socketcall.getpeername(name)", + "socketcall.getpeername(namelen_in)" ); } void @@ -1507,8 +1447,8 @@ ML_(generic_POST_sys_getpeername) ( ThreadId tid, Addr name_p = arg1; Addr namelen_p = arg2; vg_assert(!res.isError); /* guaranteed by caller */ - buf_and_len_post_check ( tid, res, name_p, namelen_p, - "socketcall.getpeername(namelen_out)" ); + ML_(buf_and_len_post_check) ( tid, res, name_p, namelen_p, + "socketcall.getpeername(namelen_out)" ); } /* ------ */ diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index d2a4e5dc88..442f9aedb6 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -3155,6 +3155,72 @@ POST(sys_lookup_dcookie) } #endif +/* --------------------------------------------------------------------- + socketcall wrapper helpers + ------------------------------------------------------------------ */ + +void +ML_(linux_PRE_sys_getsockopt) ( ThreadId tid, + UWord arg0, UWord arg1, UWord arg2, + UWord arg3, UWord arg4 ) +{ + /* int getsockopt(int s, int level, int optname, + void *optval, socklen_t *optlen); */ + Addr optval_p = arg3; + Addr optlen_p = arg4; + /* vg_assert(sizeof(socklen_t) == sizeof(UInt)); */ + if (optval_p != (Addr)NULL) { + ML_(buf_and_len_pre_check) ( tid, optval_p, optlen_p, + "socketcall.getsockopt(optval)", + "socketcall.getsockopt(optlen)" ); + if (arg1 == VKI_SOL_SCTP && + (arg2 == VKI_SCTP_GET_PEER_ADDRS || + arg2 == VKI_SCTP_GET_LOCAL_ADDRS)) + { + struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3; + int address_bytes = sizeof(struct vki_sockaddr_in6) * ga->addr_num; + PRE_MEM_WRITE( "socketcall.getsockopt(optval.addrs)", + (Addr)ga->addrs, address_bytes ); + } + } +} + +void +ML_(linux_POST_sys_getsockopt) ( ThreadId tid, + SysRes res, + UWord arg0, UWord arg1, UWord arg2, + UWord arg3, UWord arg4 ) +{ + Addr optval_p = arg3; + Addr optlen_p = arg4; + vg_assert(!res.isError); /* guaranteed by caller */ + if (optval_p != (Addr)NULL) { + ML_(buf_and_len_post_check) ( tid, res, optval_p, optlen_p, + "socketcall.getsockopt(optlen_out)" ); + if (arg1 == VKI_SOL_SCTP && + (arg2 == VKI_SCTP_GET_PEER_ADDRS || + arg2 == VKI_SCTP_GET_LOCAL_ADDRS)) + { + struct vki_sctp_getaddrs *ga = (struct vki_sctp_getaddrs*)arg3; + struct vki_sockaddr *a = ga->addrs; + int i; + for (i = 0; i < ga->addr_num; i++) { + int sl = 0; + if (a->sa_family == VKI_AF_INET) + sl = sizeof(struct vki_sockaddr_in); + else if (a->sa_family == VKI_AF_INET6) + sl = sizeof(struct vki_sockaddr_in6); + else { + VG_(message)(Vg_UserMsg, "Warning: getsockopt: unhandled address type %d", a->sa_family); + } + a = (struct vki_sockaddr*)((char*)a + sl); + } + POST_MEM_WRITE( (Addr)ga->addrs, (char*)a - (char*)ga->addrs ); + } + } +} + + #undef PRE #undef POST diff --git a/coregrind/m_syswrap/syswrap-ppc32-linux.c b/coregrind/m_syswrap/syswrap-ppc32-linux.c index 4121c41fbc..432c0afcb4 100644 --- a/coregrind/m_syswrap/syswrap-ppc32-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc32-linux.c @@ -507,8 +507,8 @@ PRE(sys_socketcall) /* int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); */ PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) ); - ML_(generic_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, - ARG2_3, ARG2_4 ); + ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, + ARG2_3, ARG2_4 ); break; case VKI_SYS_GETSOCKNAME: @@ -628,9 +628,9 @@ POST(sys_socketcall) break; case VKI_SYS_GETSOCKOPT: - ML_(generic_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES), - ARG2_0, ARG2_1, - ARG2_2, ARG2_3, ARG2_4 ); + ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES), + ARG2_0, ARG2_1, + ARG2_2, ARG2_3, ARG2_4 ); break; case VKI_SYS_GETSOCKNAME: diff --git a/coregrind/m_syswrap/syswrap-ppc64-linux.c b/coregrind/m_syswrap/syswrap-ppc64-linux.c index 5f4215b8b7..f98eb83155 100644 --- a/coregrind/m_syswrap/syswrap-ppc64-linux.c +++ b/coregrind/m_syswrap/syswrap-ppc64-linux.c @@ -534,8 +534,8 @@ PRE(sys_socketcall) /* int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); */ PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) ); - ML_(generic_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, - ARG2_3, ARG2_4 ); + ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, + ARG2_3, ARG2_4 ); break; case VKI_SYS_GETSOCKNAME: @@ -655,9 +655,9 @@ POST(sys_socketcall) break; case VKI_SYS_GETSOCKOPT: - ML_(generic_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES), - ARG2_0, ARG2_1, - ARG2_2, ARG2_3, ARG2_4 ); + ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES), + ARG2_0, ARG2_1, + ARG2_2, ARG2_3, ARG2_4 ); break; case VKI_SYS_GETSOCKNAME: diff --git a/coregrind/m_syswrap/syswrap-x86-linux.c b/coregrind/m_syswrap/syswrap-x86-linux.c index 4838271ed4..b787bd406b 100644 --- a/coregrind/m_syswrap/syswrap-x86-linux.c +++ b/coregrind/m_syswrap/syswrap-x86-linux.c @@ -1512,8 +1512,8 @@ PRE(sys_socketcall) /* int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen); */ PRE_MEM_READ( "socketcall.getsockopt(args)", ARG2, 5*sizeof(Addr) ); - ML_(generic_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, - ARG2_3, ARG2_4 ); + ML_(linux_PRE_sys_getsockopt)( tid, ARG2_0, ARG2_1, ARG2_2, + ARG2_3, ARG2_4 ); break; case VKI_SYS_GETSOCKNAME: @@ -1633,9 +1633,9 @@ POST(sys_socketcall) break; case VKI_SYS_GETSOCKOPT: - ML_(generic_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES), - ARG2_0, ARG2_1, - ARG2_2, ARG2_3, ARG2_4 ); + ML_(linux_POST_sys_getsockopt)( tid, VG_(mk_SysRes_Success)(RES), + ARG2_0, ARG2_1, + ARG2_2, ARG2_3, ARG2_4 ); break; case VKI_SYS_GETSOCKNAME: -- 2.47.3