From: Julian Seward Date: Wed, 23 Oct 2002 21:53:49 +0000 (+0000) Subject: Merge patch from Jeremy Fitzhardinge: X-Git-Tag: svn/VALGRIND_1_9_4~182 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=af9e404d3ee657c8acac18b65fcdbeace40a3e7d;p=thirdparty%2Fvalgrind.git Merge patch from Jeremy Fitzhardinge: 16-function-intercept Implement a more reliable for vg_libpthread to intercept libc calls. Since the only reliable way of making sure that our code defines the symbol is by making sure that valgrind.so itself does it, this patch adds a new file, vg_intercept.so, which defines those symbols. They are then passed off to a weak local function if libpthread isn't present, or to the libpthread version if it is. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1265 --- diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am index 225033f0de..8fb589ead6 100644 --- a/coregrind/Makefile.am +++ b/coregrind/Makefile.am @@ -45,6 +45,7 @@ valgrind_so_SOURCES = \ vg_from_ucode.c \ vg_helpers.S \ vg_instrument.c \ + vg_intercept.c \ vg_main.c \ vg_malloc2.c \ vg_memory.c \ diff --git a/coregrind/arch/x86-linux/vg_libpthread.c b/coregrind/arch/x86-linux/vg_libpthread.c index 771ed74de5..ed22be61ae 100644 --- a/coregrind/arch/x86-linux/vg_libpthread.c +++ b/coregrind/arch/x86-linux/vg_libpthread.c @@ -1826,8 +1826,8 @@ int close(int fd) extern int __libc_accept(int s, struct sockaddr *addr, socklen_t *addrlen); -__attribute__((weak)) -int accept(int s, struct sockaddr *addr, socklen_t *addrlen) + +int VGL_(accept)(int s, struct sockaddr *addr, socklen_t *addrlen) { __my_pthread_testcancel(); wait_for_fd_to_be_readable_or_erring(s); @@ -3067,7 +3067,7 @@ static inline int sys_ipc(unsigned call, int first, int second, int third, void /* Turn a blocking msgsnd() into a polling non-blocking one, so that other threads make progress */ -int msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg) +int VGL_(msgsnd)(int msgid, const void *msgp, size_t msgsz, int msgflg) { struct vki_timespec nanosleep_interval; int err; @@ -3102,7 +3102,7 @@ int msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg) /* Turn a blocking msgrcv() into a polling non-blocking one, so that other threads make progress */ -int msgrcv( int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg ) +int VGL_(msgrcv)( int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg ) { struct vki_timespec nanosleep_interval; int err; diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h index d657850ad1..5de1d30f66 100644 --- a/coregrind/vg_include.h +++ b/coregrind/vg_include.h @@ -1453,6 +1453,7 @@ extern Int VG_(compact_helper_offsets)[]; extern Addr VG_(noncompact_helper_addrs) []; extern Int VG_(noncompact_helper_offsets)[]; +#define VGL_(x) vgIntercept_##x #endif /* ndef __VG_INCLUDE_H */ diff --git a/coregrind/vg_intercept.c b/coregrind/vg_intercept.c new file mode 100644 index 0000000000..7b984c9eec --- /dev/null +++ b/coregrind/vg_intercept.c @@ -0,0 +1,111 @@ +/* + * Intercepts for various libc functions we want to capture (mostly for threading purposes) + * + * This has some nasty duplication of stuff from vg_libpthread.c + */ + +#include +#include + +#include "valgrind.h" +#include "vg_include.h" + +# define strong_alias(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((alias (#name))); + +# define weak_alias(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))); + +#define WEAK __attribute__((weak)) + +#include "vg_kerneliface.h" + +static +__inline__ +int is_kerror ( int res ) +{ + if (res >= -4095 && res <= -1) + return 1; + else + return 0; +} + + +static inline +int my_do_syscall5 ( int syscallno, + int arg1, int arg2, int arg3, int arg4, int arg5 ) +{ + int __res; + __asm__ volatile ("int $0x80" + : "=a" (__res) + : "0" (syscallno), + "b" (arg1), + "c" (arg2), + "d" (arg3), + "S" (arg4), + "D" (arg5)); + return __res; +} + +/* -------------------------------- msgsnd -------------------------------- */ +#include /* for ipc_kludge */ + +static inline int sys_ipc(unsigned call, int first, int second, int third, void *ptr) +{ + return my_do_syscall5(__NR_ipc, call, first, second, third, (int)ptr); +} + +WEAK int VGL_(msgsnd)(int msgid, const void *msgp, size_t msgsz, int msgflg) +{ + int err = sys_ipc(11, msgid, msgsz, msgflg, (void *)msgp); + if (is_kerror(err)) { + *(__errno_location()) = -err; + return -1; + } + return 0; +} + +int msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg) +{ + return VGL_(msgsnd)(msgid, msgp, msgsz, msgflg); +} + +/* -------------------------------- msgrcv -------------------------------- */ + +WEAK int VGL_(msgrcv)( int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg ) +{ + struct ipc_kludge tmp; + int err; + + tmp.msgp = msgp; + tmp.msgtyp = msgtyp; + + err = sys_ipc(12, msqid, msgsz, msgflg, &tmp ); + + if (is_kerror(err)) { + *(__errno_location()) = -err; + return -1; + } + return 0; +} + +int msgrcv( int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg ) +{ + return VGL_(msgrcv)( msqid, msgp, msgsz, msgtyp, msgflg ); +} + +/* -------------------------------- accept -------------------------------- */ + +#include + +extern +int __libc_accept(int s, struct sockaddr *addr, socklen_t *addrlen); +WEAK int VGL_(accept)(int s, struct sockaddr *addr, socklen_t *addrlen) +{ + return __libc_accept(s, addr, addrlen); +} + +int accept(int s, struct sockaddr *addr, socklen_t *addrlen) +{ + return VGL_(accept)(s, addr, addrlen); +} diff --git a/coregrind/vg_libpthread.c b/coregrind/vg_libpthread.c index 771ed74de5..ed22be61ae 100644 --- a/coregrind/vg_libpthread.c +++ b/coregrind/vg_libpthread.c @@ -1826,8 +1826,8 @@ int close(int fd) extern int __libc_accept(int s, struct sockaddr *addr, socklen_t *addrlen); -__attribute__((weak)) -int accept(int s, struct sockaddr *addr, socklen_t *addrlen) + +int VGL_(accept)(int s, struct sockaddr *addr, socklen_t *addrlen) { __my_pthread_testcancel(); wait_for_fd_to_be_readable_or_erring(s); @@ -3067,7 +3067,7 @@ static inline int sys_ipc(unsigned call, int first, int second, int third, void /* Turn a blocking msgsnd() into a polling non-blocking one, so that other threads make progress */ -int msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg) +int VGL_(msgsnd)(int msgid, const void *msgp, size_t msgsz, int msgflg) { struct vki_timespec nanosleep_interval; int err; @@ -3102,7 +3102,7 @@ int msgsnd(int msgid, const void *msgp, size_t msgsz, int msgflg) /* Turn a blocking msgrcv() into a polling non-blocking one, so that other threads make progress */ -int msgrcv( int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg ) +int VGL_(msgrcv)( int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg ) { struct vki_timespec nanosleep_interval; int err;