]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
FreeBSD support, patch 5
authorPaul Floyd <pjfloyd@wanadoo.fr>
Mon, 4 Oct 2021 21:02:40 +0000 (23:02 +0200)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Wed, 6 Oct 2021 20:17:18 +0000 (22:17 +0200)
helgrind code
Mainly intercepts and changes to conditional compilation

helgrind/hg_errors.c
helgrind/hg_intercepts.c

index 58801b66f2490e9d980457d4b19af50a9f1eb12e..e612449b5444c5e1c26b427cfee76ff692643c1b 100644 (file)
@@ -474,7 +474,7 @@ void HG_(record_error_Race) ( Thread* thr,
    XError xe;
    tl_assert( HG_(is_sane_Thread)(thr) );
 
-#  if defined(VGO_linux)
+#  if defined(VGO_linux) || defined(VGO_freebsd)
    /* Skip any races on locations apparently in GOTPLT sections.  This
       is said to be caused by ld.so poking PLT table entries (or
       whatever) when it writes the resolved address of a dynamically
index 2bc89f8a09b953fb437e07b5b83c1e28cb48fcd3..866efdbaa81f7438e05a5921ba2611b816c7cd08 100644 (file)
 #  error "Unknown platform/thread wrapping"
 #endif
 
+#if defined(VGO_freebsd)
+#define LIBC_FUNC(ret_ty, f, args...) \
+   ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBC_SONAME,f)(args); \
+   ret_ty I_WRAP_SONAME_FNNAME_ZZ(VG_Z_LIBC_SONAME,f)(args)
+#endif
+
 // Do a client request.  These are macros rather than a functions so
 // as to avoid having an extra frame in stack traces.
 
@@ -250,7 +256,9 @@ static const HChar* lame_strerror ( long err )
       case EDEADLK:     return "EDEADLK: Resource deadlock would occur";
       case EOPNOTSUPP:  return "EOPNOTSUPP: Operation not supported on "
                                "transport endpoint"; /* honest, guv */
+#if !defined(VGO_freebsd)
       case ETIME:       return "ETIME: Timer expired";
+#endif
       default:          return "hg_intercepts.c: lame_strerror(): "
                                "unhandled case -- please fix me!";
    }
@@ -404,6 +412,7 @@ static void* mythread_wrapper ( void* xargsV )
 // glibc:  pthread_create@@GLIBC_2.2.5
 // darwin: pthread_create
 // darwin: pthread_create_suspended_np (trapped)
+// FreeBSD: pthread_create
 //
 /* ensure this has its own frame, so as to make it more distinguishable
    in suppressions */
@@ -468,6 +477,12 @@ static int pthread_create_WRK(pthread_t *thread, const pthread_attr_t *attr,
                  void *(*start) (void *), void *arg) {
       return pthread_create_WRK(thread, attr, start, arg);
    }
+#elif defined(VGO_freebsd)
+   PTH_FUNC(int, pthreadZucreate, // pthread_create
+                 pthread_t *thread, const pthread_attr_t *attr,
+                 void *(*start) (void *), void *arg) {
+      return pthread_create_WRK(thread, attr, start, arg);
+   }
 #elif defined(VGO_darwin)
    PTH_FUNC(int, pthreadZucreate, // pthread_create
                  pthread_t *thread, const pthread_attr_t *attr,
@@ -549,6 +564,7 @@ static int thr_create_WRK(void *stk, size_t stksize, void *(*start)(void *),
 // darwin: pthread_join
 // darwin: pthread_join$NOCANCEL$UNIX2003
 // darwin  pthread_join$UNIX2003
+// FreeBSD: pthread_join
 __attribute__((noinline))
 static int pthread_join_WRK(pthread_t thread, void** value_pointer)
 {
@@ -580,6 +596,11 @@ static int pthread_join_WRK(pthread_t thread, void** value_pointer)
             pthread_t thread, void** value_pointer) {
       return pthread_join_WRK(thread, value_pointer);
    }
+#elif defined(VGO_freebsd)
+   PTH_FUNC(int, pthreadZujoin, // pthread_join
+            pthread_t thread, void** value_pointer) {
+      return pthread_join_WRK(thread, value_pointer);
+   }
 #elif defined(VGO_darwin)
    PTH_FUNC(int, pthreadZujoinZa, // pthread_join*
             pthread_t thread, void** value_pointer) {
@@ -770,6 +791,7 @@ void I_WRAP_SONAME_FNNAME_ZU
 #if !defined(VGO_solaris)
 // glibc:  pthread_mutex_init
 // darwin: pthread_mutex_init
+// FreeBSD: pthread_mutex_init
 PTH_FUNC(int, pthreadZumutexZuinit, // pthread_mutex_init
               pthread_mutex_t *mutex,
               pthread_mutexattr_t* attr)
@@ -842,6 +864,7 @@ PTH_FUNC(int, mutexZuinit, // mutex_init
 // glibc:   pthread_mutex_destroy
 // darwin:  pthread_mutex_destroy
 // Solaris: mutex_destroy (pthread_mutex_destroy is a weak alias)
+// FreeBSD: pthread_mutex_destroy
 __attribute__((noinline))
 static int mutex_destroy_WRK(pthread_mutex_t *mutex)
 {
@@ -876,7 +899,7 @@ static int mutex_destroy_WRK(pthread_mutex_t *mutex)
    return ret;
 }
 
-#if defined(VGO_linux) || defined(VGO_darwin)
+#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
    PTH_FUNC(int, pthreadZumutexZudestroy, // pthread_mutex_destroy
             pthread_mutex_t *mutex) {
       return mutex_destroy_WRK(mutex);
@@ -895,6 +918,7 @@ static int mutex_destroy_WRK(pthread_mutex_t *mutex)
 // glibc:   pthread_mutex_lock
 // darwin:  pthread_mutex_lock
 // Solaris: mutex_lock (pthread_mutex_lock is a weak alias)
+// FreeBSD: pthread_mutex_lock
 __attribute__((noinline))
 static int mutex_lock_WRK(pthread_mutex_t *mutex)
 {
@@ -928,7 +952,7 @@ static int mutex_lock_WRK(pthread_mutex_t *mutex)
    return ret;
 }
 
-#if defined(VGO_linux) || defined(VGO_darwin)
+#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
    PTH_FUNC(int, pthreadZumutexZulock, // pthread_mutex_lock
             pthread_mutex_t *mutex) {
       return mutex_lock_WRK(mutex);
@@ -973,6 +997,7 @@ PTH_FUNC(void, lmutexZulock, // lmutex_lock
 // glibc:   pthread_mutex_trylock
 // darwin:  pthread_mutex_trylock
 // Solaris: mutex_trylock (pthread_mutex_trylock is a weak alias)
+// FreeBSD: pthread_mutext_trylock
 //
 // pthread_mutex_trylock.  The handling needed here is very similar
 // to that for pthread_mutex_lock, except that we need to tell
@@ -1014,7 +1039,7 @@ static int mutex_trylock_WRK(pthread_mutex_t *mutex)
    return ret;
 }
 
-#if defined(VGO_linux) || defined(VGO_darwin)
+#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
    PTH_FUNC(int, pthreadZumutexZutrylock, // pthread_mutex_trylock
             pthread_mutex_t *mutex) {
       return mutex_trylock_WRK(mutex);
@@ -1033,6 +1058,7 @@ static int mutex_trylock_WRK(pthread_mutex_t *mutex)
 // glibc:   pthread_mutex_timedlock
 // darwin:  (doesn't appear to exist)
 // Solaris: pthread_mutex_timedlock
+// FreeBSD: pthread_mutex_timedlock
 //
 // pthread_mutex_timedlock.  Identical logic to pthread_mutex_trylock.
 __attribute__((noinline))
@@ -1089,6 +1115,7 @@ PTH_FUNC(int, pthreadZumutexZureltimedlock, // pthread_mutex_reltimedlock
 // glibc:   pthread_mutex_unlock
 // darwin:  pthread_mutex_unlock
 // Solaris: mutex_unlock (pthread_mutex_unlock is a weak alias)
+// FreeBSD: pthread_mutex_unlock
 __attribute__((noinline))
 static int mutex_unlock_WRK(pthread_mutex_t *mutex)
 {
@@ -1118,7 +1145,7 @@ static int mutex_unlock_WRK(pthread_mutex_t *mutex)
    return ret;
 }
 
-#if defined(VGO_linux) || defined(VGO_darwin)
+#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_freebsd)
    PTH_FUNC(int, pthreadZumutexZuunlock, // pthread_mutex_unlock
             pthread_mutex_t *mutex) {
       return mutex_unlock_WRK(mutex);
@@ -1176,6 +1203,7 @@ PTH_FUNC(void, lmutexZuunlock, // lmutex_unlock
 // darwin:  pthread_cond_wait$NOCANCEL$UNIX2003
 // darwin:  pthread_cond_wait$UNIX2003
 // Solaris: cond_wait (pthread_cond_wait is built atop of cond_wait)
+// FreeBSD: pthread_cond_wait
 //
 __attribute__((noinline))
 static int pthread_cond_wait_WRK(pthread_cond_t* cond,
@@ -1238,6 +1266,11 @@ static int pthread_cond_wait_WRK(pthread_cond_t* cond,
                  pthread_cond_t* cond, pthread_mutex_t* mutex) {
       return pthread_cond_wait_WRK(cond, mutex);
    }
+#elif defined(VGO_freebsd)
+   PTH_FUNC(int, pthreadZucondZuwait, // pthread_cond_wait
+                 pthread_cond_t* cond, pthread_mutex_t* mutex) {
+      return pthread_cond_wait_WRK(cond, mutex);
+   }
 #elif defined(VGO_darwin)
    PTH_FUNC(int, pthreadZucondZuwaitZa, // pthread_cond_wait*
                  pthread_cond_t* cond, pthread_mutex_t* mutex) {
@@ -1263,6 +1296,7 @@ static int pthread_cond_wait_WRK(pthread_cond_t* cond,
 // darwin:  pthread_cond_timedwait_relative_np (trapped)
 // Solaris: cond_timedwait (pthread_cond_timedwait is built on cond_timedwait)
 // Solaris: cond_reltimedwait (pthread_cond_reltimedwait_np is built on this)
+// FreeBSD: pthread_cond_timedwait
 //
 __attribute__((noinline))
 static int pthread_cond_timedwait_WRK(pthread_cond_t* cond,
@@ -1338,6 +1372,12 @@ static int pthread_cond_timedwait_WRK(pthread_cond_t* cond,
                  struct timespec* abstime) {
       return pthread_cond_timedwait_WRK(cond, mutex, abstime, ETIMEDOUT);
    }
+#elif defined(VGO_freebsd)
+   PTH_FUNC(int, pthreadZucondZutimedwait, // pthread_cond_timedwait
+                 pthread_cond_t* cond, pthread_mutex_t* mutex, 
+                 struct timespec* abstime) {
+      return pthread_cond_timedwait_WRK(cond, mutex, abstime, ETIMEDOUT);
+   }
 #elif defined(VGO_darwin)
    PTH_FUNC(int, pthreadZucondZutimedwait, // pthread_cond_timedwait
                  pthread_cond_t* cond, pthread_mutex_t* mutex, 
@@ -1377,6 +1417,7 @@ static int pthread_cond_timedwait_WRK(pthread_cond_t* cond,
 // darwin:  pthread_cond_signal
 // darwin:  pthread_cond_signal_thread_np (don't intercept this)
 // Solaris: cond_signal (pthread_cond_signal is a weak alias)
+// FreeBSD: pthread_cond_signal
 //
 __attribute__((noinline))
 static int pthread_cond_signal_WRK(pthread_cond_t* cond)
@@ -1413,6 +1454,11 @@ static int pthread_cond_signal_WRK(pthread_cond_t* cond)
                  pthread_cond_t* cond) {
       return pthread_cond_signal_WRK(cond);
    }
+#elif defined(VGO_freebsd)
+   PTH_FUNC(int, pthreadZucondZusignal, // pthread_cond_signal
+                 pthread_cond_t* cond) {
+      return pthread_cond_signal_WRK(cond);
+   }
 #elif defined(VGO_darwin)
    PTH_FUNC(int, pthreadZucondZusignal, // pthread_cond_signal
                  pthread_cond_t* cond) {
@@ -1434,6 +1480,7 @@ static int pthread_cond_signal_WRK(pthread_cond_t* cond)
 // glibc:   pthread_cond_broadcast@@GLIBC_2.3.2
 // darwin:  pthread_cond_broadcast
 // Solaris: cond_broadcast (pthread_cond_broadcast is a weak alias)
+// FreeBSD: pthread_cond_broadcast
 //
 // Note, this is pretty much identical, from a dependency-graph
 // point of view, with cond_signal, so the code is duplicated.
@@ -1474,6 +1521,11 @@ static int pthread_cond_broadcast_WRK(pthread_cond_t* cond)
                  pthread_cond_t* cond) {
       return pthread_cond_broadcast_WRK(cond);
    }
+#elif defined(VGO_freebsd)
+   PTH_FUNC(int, pthreadZucondZubroadcast, // pthread_cond_broadcast
+                 pthread_cond_t* cond) {
+      return pthread_cond_broadcast_WRK(cond);
+   }
 #elif defined(VGO_darwin)
    PTH_FUNC(int, pthreadZucondZubroadcast, // pthread_cond_broadcast
                  pthread_cond_t* cond) {
@@ -1493,6 +1545,7 @@ static int pthread_cond_broadcast_WRK(pthread_cond_t* cond)
 // glibc:   pthread_cond_init@@GLIBC_2.3.2
 // darwin:  pthread_cond_init
 // Solaris: cond_init (pthread_cond_init is built atop on this function)
+// FreeBSD: pthread_cond_init
 // Easy way out: Handling of attr could have been messier.
 // It turns out that pthread_cond_init under linux ignores
 // all information in cond_attr, so do we.
@@ -1530,6 +1583,11 @@ static int pthread_cond_init_WRK(pthread_cond_t* cond, pthread_condattr_t *cond_
            pthread_cond_t* cond, pthread_condattr_t* cond_attr) {
      return pthread_cond_init_WRK(cond, cond_attr);
    }
+#elif defined(VGO_freebsd)
+   PTH_FUNC(int, pthreadZucondZuinit, // pthread_cond_init@*
+           pthread_cond_t* cond, pthread_condattr_t* cond_attr) {
+     return pthread_cond_init_WRK(cond, cond_attr);
+   }
 #elif defined(VGO_darwin)
    PTH_FUNC(int, pthreadZucondZuinit, // pthread_cond_init
            pthread_cond_t* cond, pthread_condattr_t * cond_attr) {
@@ -1578,6 +1636,7 @@ PTH_FUNC(int, condZuinit, // cond_init
 // glibc:   pthread_cond_destroy@GLIBC_2.0
 // darwin:  pthread_cond_destroy
 // Solaris: cond_destroy (pthread_cond_destroy is a weak alias)
+// FreeBSD: pthread_cond_destroy
 //
 __attribute__((noinline))
 static int pthread_cond_destroy_WRK(pthread_cond_t* cond)
@@ -1620,6 +1679,11 @@ static int pthread_cond_destroy_WRK(pthread_cond_t* cond)
                  pthread_cond_t* cond) {
       return pthread_cond_destroy_WRK(cond);
    }
+#elif defined(VGO_freebsd)
+   PTH_FUNC(int, pthreadZucondZudestroy, // pthread_cond_destroy@*
+                 pthread_cond_t* cond) {
+      return pthread_cond_destroy_WRK(cond);
+   }
 #elif defined(VGO_darwin)
    PTH_FUNC(int, pthreadZucondZudestroy, // pthread_cond_destroy
                  pthread_cond_t* cond) {
@@ -1656,6 +1720,7 @@ static int pthread_cond_destroy_WRK(pthread_cond_t* cond)
 // glibc:   pthread_barrier_init
 // darwin:  (doesn't appear to exist)
 // Solaris: pthread_barrier_init
+// FreeBSD: pthread_barrier_init
 PTH_FUNC(int, pthreadZubarrierZuinit, // pthread_barrier_init
          pthread_barrier_t* bar,
          pthread_barrierattr_t* attr, unsigned long count)
@@ -1693,6 +1758,7 @@ PTH_FUNC(int, pthreadZubarrierZuinit, // pthread_barrier_init
 // glibc:   pthread_barrier_wait
 // darwin:  (doesn't appear to exist)
 // Solaris: pthread_barrier_wait
+// FreeBSD: pthread_barrier_wait
 PTH_FUNC(int, pthreadZubarrierZuwait, // pthread_barrier_wait
               pthread_barrier_t* bar)
 {
@@ -1731,6 +1797,7 @@ PTH_FUNC(int, pthreadZubarrierZuwait, // pthread_barrier_wait
 // glibc:   pthread_barrier_destroy
 // darwin:  (doesn't appear to exist)
 // Solaris: pthread_barrier_destroy
+// FreeBSD: pthread_barrier_destroy
 PTH_FUNC(int, pthreadZubarrierZudestroy, // pthread_barrier_destroy
          pthread_barrier_t* bar)
 {
@@ -1789,6 +1856,8 @@ PTH_FUNC(int, pthreadZubarrierZudestroy, // pthread_barrier_destroy
 // darwin:  (doesn't appear to exist)
 // Solaris: pthread_spin_init
 // Solaris: pthread_spin_unlock
+// FreeBSD: pthread_spin_init
+// FreeBSD: pthread_spin_unlock
 __attribute__((noinline))
 static int pthread_spin_init_or_unlock_WRK(pthread_spinlock_t* lock,
                                            int pshared) {
@@ -1826,6 +1895,16 @@ static int pthread_spin_init_or_unlock_WRK(pthread_spinlock_t* lock,
       /* this is never actually called */
       return pthread_spin_init_or_unlock_WRK(lock, 0/*pshared*/);
    }
+#elif defined(VGO_freebsd)
+   PTH_FUNC(int, pthreadZuspinZuinit, // pthread_spin_init
+            pthread_spinlock_t* lock, int pshared) {
+      return pthread_spin_init_or_unlock_WRK(lock, pshared);
+   }
+   PTH_FUNC(int, pthreadZuspinZuunlock, // pthread_spin_unlock@*
+            pthread_spinlock_t* lock) {
+      /* this is never actually called */
+      return pthread_spin_init_or_unlock_WRK(lock, 0/*pshared*/);
+   }
 #elif defined(VGO_darwin)
 #elif defined(VGO_solaris)
    PTH_FUNC(int, pthreadZuspinZuinit, // pthread_spin_init
@@ -1845,6 +1924,7 @@ static int pthread_spin_init_or_unlock_WRK(pthread_spinlock_t* lock,
 // glibc:   pthread_spin_destroy
 // darwin:  (doesn't appear to exist)
 // Solaris: pthread_spin_destroy
+// FreeBSD: pthread_spin_destroy
 __attribute__((noinline))
 static int pthread_spin_destroy_WRK(pthread_spinlock_t *lock)
 {
@@ -1870,7 +1950,7 @@ static int pthread_spin_destroy_WRK(pthread_spinlock_t *lock)
    }
    return ret;
 }
-#if defined(VGO_linux)
+#if defined(VGO_linux) || defined(VGO_freebsd)
    PTH_FUNC(int, pthreadZuspinZudestroy, // pthread_spin_destroy
             pthread_spinlock_t *lock) {
       return pthread_spin_destroy_WRK(lock);
@@ -1890,6 +1970,7 @@ static int pthread_spin_destroy_WRK(pthread_spinlock_t *lock)
 // glibc:   pthread_spin_lock
 // darwin:  (doesn't appear to exist)
 // Solaris: pthread_spin_lock
+// FreeBSD: pthread_spin_lock
 __attribute__((noinline))
 static int pthread_spin_lock_WRK(pthread_spinlock_t *lock)
 {
@@ -1923,7 +2004,7 @@ static int pthread_spin_lock_WRK(pthread_spinlock_t *lock)
    }
    return ret;
 }
-#if defined(VGO_linux)
+#if defined(VGO_linux) || defined(VGO_freebsd)
    PTH_FUNC(int, pthreadZuspinZulock, // pthread_spin_lock
                  pthread_spinlock_t *lock) {
       return pthread_spin_lock_WRK(lock);
@@ -1943,6 +2024,7 @@ static int pthread_spin_lock_WRK(pthread_spinlock_t *lock)
 // glibc:   pthread_spin_trylock
 // darwin:  (doesn't appear to exist)
 // Solaris: pthread_spin_trylock
+// FreeBSD: pthread_spin_trylock
 __attribute__((noinline))
 static int pthread_spin_trylock_WRK(pthread_spinlock_t *lock)
 {
@@ -1977,7 +2059,7 @@ static int pthread_spin_trylock_WRK(pthread_spinlock_t *lock)
    }
    return ret;
 }
-#if defined(VGO_linux)
+#if defined(VGO_linux) || defined(VGO_freebsd)
    PTH_FUNC(int, pthreadZuspinZutrylock, // pthread_spin_trylock
                  pthread_spinlock_t *lock) {
       return pthread_spin_trylock_WRK(lock);
@@ -2019,6 +2101,7 @@ static int pthread_spin_trylock_WRK(pthread_spinlock_t *lock)
 // darwin:  pthread_rwlock_init
 // darwin:  pthread_rwlock_init$UNIX2003
 // Solaris: rwlock_init (pthread_rwlock_init is built atop of rwlock_init)
+// FreeBSD: pthread_rwlock_init
 __attribute__((noinline))
 static int pthread_rwlock_init_WRK(pthread_rwlock_t *rwl,
                                    pthread_rwlockattr_t* attr)
@@ -2050,6 +2133,12 @@ static int pthread_rwlock_init_WRK(pthread_rwlock_t *rwl,
                  pthread_rwlockattr_t* attr) {
       return pthread_rwlock_init_WRK(rwl, attr);
    }
+#elif defined(VGO_freebsd)
+   PTH_FUNC(int, pthreadZurwlockZuinit, // pthread_rwlock_init
+                 pthread_rwlock_t *rwl,
+                 pthread_rwlockattr_t* attr) {
+      return pthread_rwlock_init_WRK(rwl, attr);
+   }
 #elif defined(VGO_darwin)
    PTH_FUNC(int, pthreadZurwlockZuinitZa, // pthread_rwlock_init*
                  pthread_rwlock_t *rwl,
@@ -2099,6 +2188,7 @@ PTH_FUNC(int, rwlockZuinit, // rwlock_init
 // darwin:  pthread_rwlock_destroy
 // darwin:  pthread_rwlock_destroy$UNIX2003
 // Solaris: rwlock_destroy (pthread_rwlock_destroy is a weak alias)
+// FreeBSD: pthread_rwlock_destroy
 //
 __attribute__((noinline))
 static int pthread_rwlock_destroy_WRK(pthread_rwlock_t* rwl)
@@ -2129,6 +2219,11 @@ static int pthread_rwlock_destroy_WRK(pthread_rwlock_t* rwl)
                  pthread_rwlock_t *rwl) {
       return pthread_rwlock_destroy_WRK(rwl);
    }
+#elif defined(VGO_freebsd)
+   PTH_FUNC(int, pthreadZurwlockZudestroy, // pthread_rwlock_destroy
+                 pthread_rwlock_t *rwl) {
+      return pthread_rwlock_destroy_WRK(rwl);
+   }
 #elif defined(VGO_darwin)
    PTH_FUNC(int, pthreadZurwlockZudestroyZa, // pthread_rwlock_destroy*
                  pthread_rwlock_t *rwl) {
@@ -2149,6 +2244,7 @@ static int pthread_rwlock_destroy_WRK(pthread_rwlock_t* rwl)
 // darwin:  pthread_rwlock_wrlock
 // darwin:  pthread_rwlock_wrlock$UNIX2003
 // Solaris: rw_wrlock (pthread_rwlock_wrlock is a weak alias)
+// FreeBSD: pthread_rwlock_wrlock
 //
 __attribute__((noinline))
 static int pthread_rwlock_wrlock_WRK(pthread_rwlock_t* rwlock)
@@ -2183,6 +2279,11 @@ static int pthread_rwlock_wrlock_WRK(pthread_rwlock_t* rwlock)
                  pthread_rwlock_t* rwlock) {
       return pthread_rwlock_wrlock_WRK(rwlock);
    }
+#elif defined(VGO_freebsd)
+   PTH_FUNC(int, pthreadZurwlockZuwrlock, // pthread_rwlock_wrlock
+                 pthread_rwlock_t* rwlock) {
+      return pthread_rwlock_wrlock_WRK(rwlock);
+   }
 #elif defined(VGO_darwin)
    PTH_FUNC(int, pthreadZurwlockZuwrlockZa, // pthread_rwlock_wrlock*
                  pthread_rwlock_t* rwlock) {
@@ -2229,6 +2330,7 @@ PTH_FUNC(void, lrwZuwrlock, // lrw_wrlock
 // darwin:  pthread_rwlock_rdlock
 // darwin:  pthread_rwlock_rdlock$UNIX2003
 // Solaris: rw_rdlock (pthread_rwlock_rdlock is a weak alias)
+// FreeBSD: pthread_rwlock_rdlock
 //
 __attribute__((noinline))
 static int pthread_rwlock_rdlock_WRK(pthread_rwlock_t* rwlock)
@@ -2263,6 +2365,11 @@ static int pthread_rwlock_rdlock_WRK(pthread_rwlock_t* rwlock)
                  pthread_rwlock_t* rwlock) {
       return pthread_rwlock_rdlock_WRK(rwlock);
    }
+#elif defined(VGO_freebsd)
+   PTH_FUNC(int, pthreadZurwlockZurdlock, // pthread_rwlock_rdlock
+                 pthread_rwlock_t* rwlock) {
+      return pthread_rwlock_rdlock_WRK(rwlock);
+   }
 #elif defined(VGO_darwin)
    PTH_FUNC(int, pthreadZurwlockZurdlockZa, // pthread_rwlock_rdlock*
                  pthread_rwlock_t* rwlock) {
@@ -2309,6 +2416,7 @@ PTH_FUNC(void, lrwZurdlock, // lrw_rdlock
 // darwin:  pthread_rwlock_trywrlock
 // darwin:  pthread_rwlock_trywrlock$UNIX2003
 // Solaris: rw_trywrlock (pthread_rwlock_trywrlock is a weak alias)
+// FreeBSD: pthread_rwlock_trywrlock
 //
 __attribute__((noinline))
 static int pthread_rwlock_trywrlock_WRK(pthread_rwlock_t* rwlock)
@@ -2349,6 +2457,11 @@ static int pthread_rwlock_trywrlock_WRK(pthread_rwlock_t* rwlock)
                  pthread_rwlock_t* rwlock) {
       return pthread_rwlock_trywrlock_WRK(rwlock);
    }
+#elif defined(VGO_freebsd)
+   PTH_FUNC(int, pthreadZurwlockZutrywrlock, // pthread_rwlock_trywrlock
+                 pthread_rwlock_t* rwlock) {
+      return pthread_rwlock_trywrlock_WRK(rwlock);
+   }
 #elif defined(VGO_darwin)
    PTH_FUNC(int, pthreadZurwlockZutrywrlockZa, // pthread_rwlock_trywrlock*
                  pthread_rwlock_t* rwlock) {
@@ -2369,6 +2482,7 @@ static int pthread_rwlock_trywrlock_WRK(pthread_rwlock_t* rwlock)
 // darwin:  pthread_rwlock_tryrdlock
 // darwin:  pthread_rwlock_tryrdlock$UNIX2003
 // Solaris: rw_tryrdlock (pthread_rwlock_tryrdlock is a weak alias)
+// FreeBSD: pthread_rwlock_tryrdlock
 //
 __attribute__((noinline))
 static int pthread_rwlock_tryrdlock_WRK(pthread_rwlock_t* rwlock)
@@ -2410,6 +2524,11 @@ static int pthread_rwlock_tryrdlock_WRK(pthread_rwlock_t* rwlock)
                  pthread_rwlock_t* rwlock) {
       return pthread_rwlock_tryrdlock_WRK(rwlock);
    }
+#elif defined(VGO_freebsd)
+   PTH_FUNC(int, pthreadZurwlockZutryrdlock, // pthread_rwlock_tryrdlock
+                 pthread_rwlock_t* rwlock) {
+      return pthread_rwlock_tryrdlock_WRK(rwlock);
+   }
 #elif defined(VGO_darwin)
    PTH_FUNC(int, pthreadZurwlockZutryrdlockZa, // pthread_rwlock_tryrdlock*
                  pthread_rwlock_t* rwlock) {
@@ -2430,6 +2549,7 @@ static int pthread_rwlock_tryrdlock_WRK(pthread_rwlock_t* rwlock)
 // darwin:  Unhandled
 // Solaris: pthread_rwlock_timedrdlock
 // Solaris: pthread_rwlock_reltimedrdlock_np
+// FreeBSD: pthread_rwlock_timedrdlock
 //
 __attribute__((noinline)) __attribute__((unused))
 static int pthread_rwlock_timedrdlock_WRK(pthread_rwlock_t *rwlock,
@@ -2462,6 +2582,12 @@ static int pthread_rwlock_timedrdlock_WRK(pthread_rwlock_t *rwlock,
 }
 #if defined(VGO_linux)
 #elif defined(VGO_darwin)
+#elif defined(VGO_freebsd)
+PTH_FUNC(int, pthreadZurwlockZutimedrdlock, // pthread_rwlock_timedrdlock
+              pthread_rwlock_t *rwlock,
+              const struct timespec *timeout) {
+   return pthread_rwlock_timedrdlock_WRK(rwlock, timeout);
+}
 #elif defined(VGO_solaris)
    PTH_FUNC(int, pthreadZurwlockZutimedrdlock, // pthread_rwlock_timedrdlock
                  pthread_rwlock_t *rwlock,
@@ -2483,6 +2609,7 @@ static int pthread_rwlock_timedrdlock_WRK(pthread_rwlock_t *rwlock,
 // darwin:  Unhandled
 // Solaris: pthread_rwlock_timedwrlock
 // Solaris: pthread_rwlock_reltimedwrlock_np
+// FreeBSD: pthread_rwlock_timedwrlock
 //
 __attribute__((noinline)) __attribute__((unused))
 static int pthread_rwlock_timedwrlock_WRK(pthread_rwlock_t *rwlock,
@@ -2515,6 +2642,12 @@ static int pthread_rwlock_timedwrlock_WRK(pthread_rwlock_t *rwlock,
 }
 #if defined(VGO_linux)
 #elif defined(VGO_darwin)
+#elif defined(VGO_freebsd)
+PTH_FUNC(int, pthreadZurwlockZutimedwrlock, // pthread_rwlock_timedwrlock
+              pthread_rwlock_t *rwlock,
+              const struct timespec *timeout) {
+   return pthread_rwlock_timedwrlock_WRK(rwlock, timeout);
+}
 #elif defined(VGO_solaris)
    PTH_FUNC(int, pthreadZurwlockZutimedwrlock, // pthread_rwlock_timedwrlock
                  pthread_rwlock_t *rwlock,
@@ -2536,6 +2669,7 @@ static int pthread_rwlock_timedwrlock_WRK(pthread_rwlock_t *rwlock,
 // darwin:  pthread_rwlock_unlock
 // darwin:  pthread_rwlock_unlock$UNIX2003
 // Solaris: rw_unlock (pthread_rwlock_unlock is a weak alias)
+// FreeBSD: pthread_rwlock_unlock
 __attribute__((noinline))
 static int pthread_rwlock_unlock_WRK(pthread_rwlock_t* rwlock)
 {
@@ -2567,6 +2701,11 @@ static int pthread_rwlock_unlock_WRK(pthread_rwlock_t* rwlock)
                  pthread_rwlock_t* rwlock) {
       return pthread_rwlock_unlock_WRK(rwlock);
    }
+#elif defined(VGO_freebsd)
+   PTH_FUNC(int, pthreadZurwlockZuunlock, // pthread_rwlock_unlock
+                 pthread_rwlock_t* rwlock) {
+      return pthread_rwlock_unlock_WRK(rwlock);
+   }
 #elif defined(VGO_darwin)
    PTH_FUNC(int, pthreadZurwlockZuunlockZa, // pthread_rwlock_unlock*
                  pthread_rwlock_t* rwlock) {
@@ -2615,6 +2754,7 @@ static int pthread_rwlock_unlock_WRK(pthread_rwlock_t* rwlock)
 // glibc:   sem_init@GLIBC_2.0
 // darwin:  sem_init
 // Solaris: sema_init (sem_init is built on top of sem_init)
+// FreeBSD: sem_init (libc)
 //
 #if !defined(VGO_solaris)
 __attribute__((noinline))
@@ -2655,7 +2795,12 @@ static int sem_init_WRK(sem_t* sem, int pshared, unsigned long value)
                  sem_t* sem, int pshared, unsigned long value) {
       return sem_init_WRK(sem, pshared, value);
    }
-#else
+#elif defined(VGO_freebsd)
+  LIBC_FUNC(int, semZuinit, // sem_init
+                sem_t* sem, int pshared, unsigned long value) {
+     return sem_init_WRK(sem, pshared, value);
+  }
+ #else
 #  error "Unsupported OS"
 #endif
 
@@ -2700,6 +2845,7 @@ PTH_FUNC(int, semaZuinit, // sema_init
 // glibc:   sem_destroy@@GLIBC_2.2.5
 // darwin:  sem_destroy
 // Solaris: sema_destroy (sem_destroy is built on top of sema_destroy)
+// FreeBSD: sem_destroy (libc)
 __attribute__((noinline))
 static int sem_destroy_WRK(sem_t* sem)
 {
@@ -2737,6 +2883,11 @@ static int sem_destroy_WRK(sem_t* sem)
                  sem_t* sem) {
       return sem_destroy_WRK(sem);
    }
+#elif defined(VGO_freebsd)
+   LIBC_FUNC(int, semZudestroy,  // sem_destroy
+                 sem_t* sem) {
+      return sem_destroy_WRK(sem);
+   }
 #elif defined(VGO_solaris)
    PTH_FUNC(int, semaZudestroy,  // sema_destroy
                  sem_t *sem) {
@@ -2755,6 +2906,7 @@ static int sem_destroy_WRK(sem_t* sem)
 // darwin:  sem_wait$NOCANCEL$UNIX2003
 // darwin:  sem_wait$UNIX2003
 // Solaris: sema_wait (sem_wait is built on top of sema_wait)
+// FreeBSD: sem_wait (libc)
 //
 /* wait: decrement semaphore - acquire lockage */
 __attribute__((noinline))
@@ -2801,6 +2953,10 @@ static int sem_wait_WRK(sem_t* sem)
    PTH_FUNC(int, semZuwaitZDZa, sem_t* sem) { /* sem_wait$* */
       return sem_wait_WRK(sem);
    }
+#elif defined(VGO_freebsd)
+   LIBC_FUNC(int, semZuwait, sem_t* sem) { /* sem_wait */
+      return sem_wait_WRK(sem);
+   }
 #elif defined(VGO_solaris)
    PTH_FUNC(int, semaZuwait, sem_t *sem) { /* sema_wait */
       return sem_wait_WRK(sem);
@@ -2816,6 +2972,7 @@ static int sem_wait_WRK(sem_t* sem)
 // glibc:   sem_post@@GLIBC_2.1
 // darwin:  sem_post
 // Solaris: sema_post (sem_post is built on top of sema_post)
+// FreeBSD: sem_post (libc)
 //
 /* post: increment semaphore - release lockage */
 __attribute__((noinline))
@@ -2859,6 +3016,10 @@ static int sem_post_WRK(sem_t* sem)
    PTH_FUNC(int, semZupost, sem_t* sem) { /* sem_post */
       return sem_post_WRK(sem);
    }
+#elif defined(VGO_freebsd)
+   LIBC_FUNC(int, semZupost, sem_t* sem) { /* sem_post */
+      return sem_post_WRK(sem);
+   }
 #elif defined(VGO_solaris)
    PTH_FUNC(int, semaZupost, sem_t *sem) { /* sema_post */
       return sem_post_WRK(sem);
@@ -2872,10 +3033,17 @@ static int sem_post_WRK(sem_t* sem)
 // glibc:   sem_open
 // darwin:  sem_open
 // Solaris: sem_open
+// FreeBSD: sem_open
 //
+#if defined(VGO_freebsd)
+LIBC_FUNC(sem_t*, semZuopen,
+                 const char* name, long oflag,
+                 long mode, unsigned long value)
+#else
 PTH_FUNC(sem_t*, semZuopen,
                  const char* name, long oflag,
                  long mode, unsigned long value)
+#endif
 {
    /* A copy of sem_init_WRK (more or less).  Is this correct? */
    OrigFn fn;
@@ -2911,7 +3079,12 @@ PTH_FUNC(sem_t*, semZuopen,
 // glibc:   sem_close
 // darwin:  sem_close
 // Solaris: sem_close
+// FreeBSD: sem_close
+#if defined (VGO_freebsd)
+LIBC_FUNC(int, sem_close, sem_t* sem)
+#else
 PTH_FUNC(int, sem_close, sem_t* sem)
+#endif
 {
    OrigFn fn;
    int    ret;