From: Paul Floyd Date: Sun, 3 Oct 2021 17:49:08 +0000 (+0200) Subject: FreeBSD support, patch 4 X-Git-Tag: VALGRIND_3_18_0~40 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7074904a377a52c76cbc8feaf618fa31b8a663b7;p=thirdparty%2Fvalgrind.git FreeBSD support, patch 4 DRD code Mainly just intercepts, but also a hairy fix for early acces to pthread_self() --- diff --git a/drd/drd_main.c b/drd/drd_main.c old mode 100644 new mode 100755 index 2f2279e52d..4a71eebb5f --- a/drd/drd_main.c +++ b/drd/drd_main.c @@ -744,7 +744,7 @@ void drd__atfork_child(ThreadId tid) static void DRD_(post_clo_init)(void) { -#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) +#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) /* fine */ #else VG_(printf)("\nWARNING: DRD has not yet been tested on this operating system.\n\n"); diff --git a/drd/drd_pthread_intercepts.c b/drd/drd_pthread_intercepts.c index 28c0de78bc..8b44543645 100644 --- a/drd/drd_pthread_intercepts.c +++ b/drd/drd_pthread_intercepts.c @@ -57,6 +57,10 @@ #include "drd_clientreq.h" #include "pub_tool_redir.h" /* VG_WRAP_FUNCTION_ZZ() */ +#if defined(VGO_freebsd) +#include +#endif + #if defined(VGO_solaris) /* * Solaris usually provides pthread_* functions on top of Solaris threading @@ -168,6 +172,11 @@ static int never_true; fflush(stdout); \ return pth_func_result; \ } +#elif defined(VG_WRAP_THREAD_FUNCTION_LIBPTHREAD_ONLY) +#define PTH_FUNC(ret_ty, zf, implf, argl_decl, argl) \ +ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl; \ +ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBPTHREAD_SONAME,zf) argl_decl \ +{ return implf argl; } #elif defined(VG_WRAP_THREAD_FUNCTION_LIBC_ONLY) #define PTH_FUNC(ret_ty, zf, implf, argl_decl, argl) \ ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBC_SONAME,zf) argl_decl; \ @@ -185,6 +194,13 @@ static int never_true; # error "Unknown platform/thread wrapping" #endif +#if defined(VGO_freebsd) +#define LIBC_FUNC(ret_ty, zf, implf, argl_decl, argl) \ + ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBC_SONAME,zf) argl_decl; \ + ret_ty VG_WRAP_FUNCTION_ZZ(VG_Z_LIBC_SONAME,zf) argl_decl \ + { return implf argl; } +#endif + /** * Macro for generating three Valgrind interception functions: one with the * Z-encoded name zf, one with ZAZa ("@*") appended to the name zf and one @@ -252,6 +268,27 @@ static void DRD_(sema_up)(DrdSema* sema); */ static void DRD_(init)(void) { +#if defined(VGO_freebsd) + { + /* + * On FreeBSD, pthead functions are all in libthr.so + * However libc.so contains stubs. In this ctor function, + * calling DRD_(set_pthread_id)() results in a call to + * pthread_self() resolving to the libc.so stub which + * returns a junk value for the tid. Subsequent calls + * to pthread_create() then also cause calls to + * DRD_(set_pthread_id)(), but this time with pthread_self() + * resolving to the good libthr.so version (since this is later + * and libthr.so has been loaded). That causes an assert + * since we expect the tid to either be INVALID_POSIX_THREADID + * or the same as the current tid, and the junk value + * is neither. So we force loading of libthr.so, which + * avoids this junk tid value. + */ + dlclose(dlopen("/lib/libthr.so.3", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE)); + } +#endif + DRD_(check_threading_library)(); DRD_(set_pthread_id)(); #if defined(VGO_solaris) @@ -1352,8 +1389,13 @@ int sem_init_intercept(sem_t *sem, int pshared, unsigned int value) return ret; } +#if defined(VGO_freebsd) +LIBC_FUNC(int, semZuinit, sem_init_intercept, + (sem_t *sem, int pshared, unsigned int value), (sem, pshared, value)); +#else PTH_FUNCS(int, semZuinit, sem_init_intercept, (sem_t *sem, int pshared, unsigned int value), (sem, pshared, value)); +#endif #if defined(VGO_solaris) static __always_inline @@ -1390,7 +1432,12 @@ int sem_destroy_intercept(sem_t *sem) return ret; } +#if defined(VGO_freebsd) +LIBC_FUNC(int, semZudestroy, sem_destroy_intercept, (sem_t *sem), (sem)); +#else PTH_FUNCS(int, semZudestroy, sem_destroy_intercept, (sem_t *sem), (sem)); +#endif + #if defined(VGO_solaris) PTH_FUNCS(int, semaZudestroy, sem_destroy_intercept, (sem_t *sem), (sem)); #endif /* VGO_solaris */ @@ -1414,9 +1461,15 @@ sem_t* sem_open_intercept(const char *name, int oflag, mode_t mode, return ret; } +#if defined(VGO_freebsd) +LIBC_FUNC(sem_t *, semZuopen, sem_open_intercept, + (const char *name, int oflag, mode_t mode, unsigned int value), + (name, oflag, mode, value)); +#else PTH_FUNCS(sem_t *, semZuopen, sem_open_intercept, (const char *name, int oflag, mode_t mode, unsigned int value), (name, oflag, mode, value)); +#endif static __always_inline int sem_close_intercept(sem_t *sem) { @@ -1431,7 +1484,11 @@ static __always_inline int sem_close_intercept(sem_t *sem) return ret; } +#if defined(VGO_freebsd) +LIBC_FUNC(int, semZuclose, sem_close_intercept, (sem_t *sem), (sem)); +#else PTH_FUNCS(int, semZuclose, sem_close_intercept, (sem_t *sem), (sem)); +#endif static __always_inline int sem_wait_intercept(sem_t *sem) { @@ -1446,7 +1503,12 @@ static __always_inline int sem_wait_intercept(sem_t *sem) return ret; } +#if defined(VGO_freebsd) +LIBC_FUNC(int, semZuwait, sem_wait_intercept, (sem_t *sem), (sem)); +#else PTH_FUNCS(int, semZuwait, sem_wait_intercept, (sem_t *sem), (sem)); +#endif + #if defined(VGO_solaris) PTH_FUNCS(int, semaZuwait, sem_wait_intercept, (sem_t *sem), (sem)); #endif /* VGO_solaris */ @@ -1464,7 +1526,11 @@ static __always_inline int sem_trywait_intercept(sem_t *sem) return ret; } +#if defined(VGO_freebsd) +LIBC_FUNC(int, semZutrywait, sem_trywait_intercept, (sem_t *sem), (sem)); +#else PTH_FUNCS(int, semZutrywait, sem_trywait_intercept, (sem_t *sem), (sem)); +#endif #if defined(VGO_solaris) PTH_FUNCS(int, semaZutrywait, sem_trywait_intercept, (sem_t *sem), (sem)); #endif /* VGO_solaris */ @@ -1483,9 +1549,15 @@ int sem_timedwait_intercept(sem_t *sem, const struct timespec *abs_timeout) return ret; } +#if defined(VGO_freebsd) +LIBC_FUNC(int, semZutimedwait, sem_timedwait_intercept, + (sem_t *sem, const struct timespec *abs_timeout), + (sem, abs_timeout)); +#else PTH_FUNCS(int, semZutimedwait, sem_timedwait_intercept, (sem_t *sem, const struct timespec *abs_timeout), (sem, abs_timeout)); +#endif #if defined(VGO_solaris) PTH_FUNCS(int, semaZutimedwait, sem_timedwait_intercept, (sem_t *sem, const struct timespec *timeout), @@ -1508,7 +1580,11 @@ static __always_inline int sem_post_intercept(sem_t *sem) return ret; } +#if defined(VGO_freebsd) +LIBC_FUNC(int, semZupost, sem_post_intercept, (sem_t *sem), (sem)); +#else PTH_FUNCS(int, semZupost, sem_post_intercept, (sem_t *sem), (sem)); +#endif #if defined(VGO_solaris) PTH_FUNCS(int, semaZupost, sem_post_intercept, (sem_t *sem), (sem)); #endif /* VGO_solaris */