pkgsrc-WIP-changes archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Import libpthread_dbg-20161124 as wip/libpthread_dbg.
Module Name: pkgsrc-wip
Committed By: Kamil Rytarowski <n54%gmx.com@localhost>
Pushed By: kamil
Date: Wed Feb 8 01:07:55 2017 +0100
Changeset: 86b79a5f9a2c6e24bffdc32f3d6c2e70bde98006
Added Files:
libpthread_dbg/DESCR
libpthread_dbg/Makefile
libpthread_dbg/PLIST
libpthread_dbg/distinfo
libpthread_dbg/files/Makefile
libpthread_dbg/files/pthread.h
libpthread_dbg/files/pthread_dbg.3
libpthread_dbg/files/pthread_dbg.c
libpthread_dbg/files/pthread_dbg.h
libpthread_dbg/files/pthread_dbg_int.h
libpthread_dbg/files/pthread_int.h
libpthread_dbg/files/shlib_version
libpthread_dbg/files/td_map_pth2thr.3
libpthread_dbg/files/td_open.3
libpthread_dbg/files/td_thr_getname.3
libpthread_dbg/files/td_thr_info.3
libpthread_dbg/files/td_thr_iter.3
Log Message:
Import libpthread_dbg-20161124 as wip/libpthread_dbg.
The pthread_dbg library provides an implementation of the standard POSIX
threads library debugging facilities.
The NetBSD implementation is based on 1:1 thread model, therefore each
pthread(3) has a kernel thread, called a light-weight process (LWP).
Note that the system private thread interfaces upon which the pthread(3)
library is built are subject to change without notice. In order to
remain compatible with future NetBSD releases, programs must be linked
against the dynamic version of the thread library. Statically linked
programs using the POSIX threads framework may not work when run on a
future version of the system.
The pthread_dbg library is designed to be used in debuggers and to
control and introspect the NetBSD implementation of the POSIX threads.
Software may use native LWP threads without pthread(3) layer, in that
case pthread_dbg cannot be used.
To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=86b79a5f9a2c6e24bffdc32f3d6c2e70bde98006
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
diffstat:
libpthread_dbg/DESCR | 17 ++
libpthread_dbg/Makefile | 21 ++
libpthread_dbg/PLIST | 7 +
libpthread_dbg/distinfo | 2 +
libpthread_dbg/files/Makefile | 21 ++
libpthread_dbg/files/pthread.h | 422 ++++++++++++++++++++++++++
libpthread_dbg/files/pthread_dbg.3 | 148 ++++++++++
libpthread_dbg/files/pthread_dbg.c | 520 +++++++++++++++++++++++++++++++++
libpthread_dbg/files/pthread_dbg.h | 200 +++++++++++++
libpthread_dbg/files/pthread_dbg_int.h | 48 +++
libpthread_dbg/files/pthread_int.h | 333 +++++++++++++++++++++
libpthread_dbg/files/shlib_version | 5 +
libpthread_dbg/files/td_map_pth2thr.3 | 71 +++++
libpthread_dbg/files/td_open.3 | 79 +++++
libpthread_dbg/files/td_thr_getname.3 | 75 +++++
libpthread_dbg/files/td_thr_info.3 | 109 +++++++
libpthread_dbg/files/td_thr_iter.3 | 69 +++++
17 files changed, 2147 insertions(+)
diffs:
diff --git a/libpthread_dbg/DESCR b/libpthread_dbg/DESCR
new file mode 100644
index 0000000000..f452105a11
--- /dev/null
+++ b/libpthread_dbg/DESCR
@@ -0,0 +1,17 @@
+The pthread_dbg library provides an implementation of the standard POSIX
+threads library debugging facilities.
+
+The NetBSD implementation is based on 1:1 thread model, therefore each
+pthread(3) has a kernel thread, called a light-weight process (LWP).
+
+Note that the system private thread interfaces upon which the pthread(3)
+library is built are subject to change without notice. In order to
+remain compatible with future NetBSD releases, programs must be linked
+against the dynamic version of the thread library. Statically linked
+programs using the POSIX threads framework may not work when run on a
+future version of the system.
+
+The pthread_dbg library is designed to be used in debuggers and to
+control and introspect the NetBSD implementation of the POSIX threads.
+Software may use native LWP threads without pthread(3) layer, in that
+case pthread_dbg cannot be used.
diff --git a/libpthread_dbg/Makefile b/libpthread_dbg/Makefile
new file mode 100644
index 0000000000..acb43435ca
--- /dev/null
+++ b/libpthread_dbg/Makefile
@@ -0,0 +1,21 @@
+# $NetBSD: Makefile,v 1.2 2016/12/16 00:01:04 joerg Exp $
+#
+
+PKGNAME= libpthread_dbg-20161124
+CATEGORIES= pkgtools
+
+MAINTAINER= pkgsrc-users%NetBSD.org@localhost
+#HOMEPAGE=
+COMMENT= POSIX Debug Threads Library
+LICENSE= 2-clause-bsd
+
+USE_BSD_MAKEFILE= yes
+USE_TOOLS= nroff
+
+INSTALLATION_DIRS+= include ${PKGMANDIR}/man3
+PKGSRC_LOCKTYPE= none # avoid "bootstrapping problem"
+
+do-extract:
+ ${CP} -R ${FILESDIR} ${WRKSRC}
+
+.include "../../mk/bsd.pkg.mk"
diff --git a/libpthread_dbg/PLIST b/libpthread_dbg/PLIST
new file mode 100644
index 0000000000..a078f9b9bb
--- /dev/null
+++ b/libpthread_dbg/PLIST
@@ -0,0 +1,7 @@
+@comment $NetBSD: PLIST,v 1.1 2016/10/01 18:37:15 kamil Exp $
+bin/plist-add
+bin/plist-del
+bin/plist-sort
+man/man1/plist-add.1
+man/man1/plist-del.1
+man/man1/plist-sort.1
diff --git a/libpthread_dbg/distinfo b/libpthread_dbg/distinfo
new file mode 100644
index 0000000000..afc76512f4
--- /dev/null
+++ b/libpthread_dbg/distinfo
@@ -0,0 +1,2 @@
+$NetBSD$
+
diff --git a/libpthread_dbg/files/Makefile b/libpthread_dbg/files/Makefile
new file mode 100644
index 0000000000..fd1cfab0df
--- /dev/null
+++ b/libpthread_dbg/files/Makefile
@@ -0,0 +1,21 @@
+# $NetBSD: Makefile,v 1.16 2016/11/22 03:52:01 kamil Exp $
+#
+
+#.include <bsd.own.mk>
+
+SRCS= pthread_dbg.c
+
+CPPFLAGS+= -D__LIBPTHREAD_SOURCE__
+
+INCS= pthread_dbg.h
+
+MAN+= pthread_dbg.3
+MAN+= td_open.3
+MAN+= td_map_pth2thr.3
+MAN+= td_thr_getname.3
+MAN+= td_thr_info.3
+MAN+= td_thr_iter.3
+
+MLINKS+= td_open.3 td_close.3
+
+.include <bsd.lib.mk>
diff --git a/libpthread_dbg/files/pthread.h b/libpthread_dbg/files/pthread.h
new file mode 100644
index 0000000000..fed3221652
--- /dev/null
+++ b/libpthread_dbg/files/pthread.h
@@ -0,0 +1,422 @@
+/* $NetBSD: pthread.h,v 1.38 2016/10/30 23:26:33 kamil Exp $ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nathan J. Williams.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LIB_PTHREAD_H
+#define _LIB_PTHREAD_H
+
+#include <sys/cdefs.h>
+
+#include <time.h> /* For timespec */
+#include <sched.h>
+#include <sys/featuretest.h>
+
+#include <pthread_types.h>
+
+__BEGIN_DECLS
+int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
+int pthread_create(pthread_t * __restrict,
+ const pthread_attr_t * __restrict, void *(*)(void *),
+ void * __restrict);
+void pthread_exit(void *) __attribute__((__noreturn__));
+int pthread_join(pthread_t, void **);
+int pthread_equal(pthread_t, pthread_t);
+pthread_t pthread_self(void);
+int pthread_detach(pthread_t);
+
+int pthread_getrrtimer_np(void);
+int pthread_setrrtimer_np(int);
+
+int pthread_attr_init(pthread_attr_t *);
+int pthread_attr_destroy(pthread_attr_t *);
+int pthread_attr_get_np(pthread_t, pthread_attr_t *);
+int pthread_attr_getguardsize(const pthread_attr_t * __restrict,
+ size_t * __restrict);
+int pthread_attr_setguardsize(pthread_attr_t *, size_t);
+int pthread_attr_getinheritsched(const pthread_attr_t * __restrict,
+ int * __restrict);
+int pthread_attr_setinheritsched(pthread_attr_t *, int);
+int pthread_attr_getschedparam(const pthread_attr_t * __restrict,
+ struct sched_param * __restrict);
+int pthread_attr_setschedparam(pthread_attr_t * __restrict,
+ const struct sched_param * __restrict);
+int pthread_attr_getschedpolicy(const pthread_attr_t * __restrict,
+ int * __restrict);
+int pthread_attr_setschedpolicy(pthread_attr_t *, int);
+int pthread_attr_getscope(const pthread_attr_t * __restrict,
+ int * __restrict);
+int pthread_attr_setscope(pthread_attr_t *, int);
+int pthread_attr_getstack(const pthread_attr_t * __restrict,
+ void ** __restrict, size_t * __restrict);
+int pthread_attr_setstack(pthread_attr_t *, void *, size_t);
+int pthread_attr_getstacksize(const pthread_attr_t * __restrict,
+ size_t * __restrict);
+int pthread_attr_setstacksize(pthread_attr_t *, size_t);
+int pthread_attr_getstackaddr(const pthread_attr_t * __restrict,
+ void ** __restrict);
+int pthread_attr_setstackaddr(pthread_attr_t *, void *);
+int pthread_attr_getdetachstate(const pthread_attr_t *, int *);
+int pthread_attr_setdetachstate(pthread_attr_t *, int);
+int pthread_attr_getname_np(const pthread_attr_t *, char *,
+ size_t, void **);
+int pthread_attr_setname_np(pthread_attr_t *, const char *, void *);
+
+int pthread_mutex_init(pthread_mutex_t * __restrict,
+ const pthread_mutexattr_t * __restrict);
+int pthread_mutex_destroy(pthread_mutex_t *);
+int pthread_mutex_lock(pthread_mutex_t *);
+int pthread_mutex_trylock(pthread_mutex_t *);
+int pthread_mutex_unlock(pthread_mutex_t *);
+int pthread_mutex_timedlock(pthread_mutex_t * __restrict,
+ const struct timespec * __restrict);
+int pthread_mutex_getprioceiling(const pthread_mutex_t * __restrict,
+ int * __restrict);
+int pthread_mutex_setprioceiling(pthread_mutex_t * __restrict, int,
+ int * __restrict);
+int pthread_mutexattr_init(pthread_mutexattr_t *);
+int pthread_mutexattr_destroy(pthread_mutexattr_t *);
+#ifdef _PTHREAD_PSHARED
+int pthread_mutexattr_getpshared(const pthread_mutexattr_t * __restrict,
+ int * __restrict);
+int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int);
+#endif
+int pthread_mutexattr_gettype(const pthread_mutexattr_t * __restrict,
+ int * __restrict);
+int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int);
+int pthread_mutexattr_getprotocol(const pthread_mutexattr_t * __restrict,
+ int * __restrict);
+int pthread_mutexattr_setprotocol(pthread_mutexattr_t*,
+ int);
+int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t * __restrict,
+ int * __restrict);
+int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *,
+ int);
+int pthread_cond_init(pthread_cond_t * __restrict,
+ const pthread_condattr_t * __restrict);
+int pthread_cond_destroy(pthread_cond_t *);
+int pthread_cond_wait(pthread_cond_t * __restrict,
+ pthread_mutex_t * __restrict);
+#ifndef __LIBC12_SOURCE__
+int pthread_cond_timedwait(pthread_cond_t * __restrict,
+ pthread_mutex_t * __restrict, const struct timespec * __restrict);
+#endif
+int pthread_cond_signal(pthread_cond_t *);
+int pthread_cond_broadcast(pthread_cond_t *);
+int pthread_condattr_init(pthread_condattr_t *);
+#if defined(_NETBSD_SOURCE)
+int pthread_condattr_setclock(pthread_condattr_t *, clockid_t);
+int pthread_condattr_getclock(const pthread_condattr_t * __restrict,
+ clockid_t * __restrict);
+#endif
+int pthread_condattr_destroy(pthread_condattr_t *);
+#ifdef _PTHREAD_PSHARED
+int pthread_condattr_getpshared(const pthread_condattr_t * __restrict,
+ int * __restrict);
+int pthread_condattr_setpshared(pthread_condattr_t *, int);
+#endif
+int pthread_once(pthread_once_t *, void (*)(void));
+
+int pthread_key_create(pthread_key_t *, void (*)(void *));
+int pthread_key_delete(pthread_key_t);
+int pthread_setspecific(pthread_key_t, const void *);
+void* pthread_getspecific(pthread_key_t);
+
+int pthread_cancel(pthread_t);
+int pthread_setcancelstate(int, int *);
+int pthread_setcanceltype(int, int *);
+void pthread_testcancel(void);
+
+int pthread_getname_np(pthread_t, char *, size_t);
+int pthread_setname_np(pthread_t, const char *, void *);
+
+int pthread_attr_setcreatesuspend_np(pthread_attr_t *);
+int pthread_suspend_np(pthread_t);
+int pthread_resume_np(pthread_t);
+
+unsigned int pthread_curcpu_np(void);
+
+int pthread_getcpuclockid(pthread_t, clockid_t *);
+
+struct pthread_cleanup_store {
+ void *pad[4];
+};
+
+#define pthread_cleanup_push(routine, arg) \
+ { \
+ struct pthread_cleanup_store __store; \
+ pthread__cleanup_push((routine),(arg), &__store);
+
+#define pthread_cleanup_pop(execute) \
+ pthread__cleanup_pop((execute), &__store); \
+ }
+
+void pthread__cleanup_push(void (*)(void *), void *, void *);
+void pthread__cleanup_pop(int, void *);
+
+int pthread_spin_init(pthread_spinlock_t *, int);
+int pthread_spin_destroy(pthread_spinlock_t *);
+int pthread_spin_lock(pthread_spinlock_t *);
+int pthread_spin_trylock(pthread_spinlock_t *);
+int pthread_spin_unlock(pthread_spinlock_t *);
+
+int pthread_rwlock_init(pthread_rwlock_t * __restrict,
+ const pthread_rwlockattr_t * __restrict);
+int pthread_rwlock_destroy(pthread_rwlock_t *);
+int pthread_rwlock_rdlock(pthread_rwlock_t *);
+int pthread_rwlock_tryrdlock(pthread_rwlock_t *);
+int pthread_rwlock_wrlock(pthread_rwlock_t *);
+int pthread_rwlock_trywrlock(pthread_rwlock_t *);
+#ifndef __LIBC12_SOURCE__
+int pthread_rwlock_timedrdlock(pthread_rwlock_t * __restrict,
+ const struct timespec * __restrict);
+int pthread_rwlock_timedwrlock(pthread_rwlock_t * __restrict,
+ const struct timespec * __restrict);
+#endif
+int pthread_rwlock_unlock(pthread_rwlock_t *);
+int pthread_rwlockattr_init(pthread_rwlockattr_t *);
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
+#ifdef _PTHREAD_PSHARED
+int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t * __restrict,
+ int * __restrict);
+int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int);
+#endif
+int pthread_barrier_init(pthread_barrier_t * __restrict,
+ const pthread_barrierattr_t * __restrict, unsigned int);
+int pthread_barrier_wait(pthread_barrier_t *);
+int pthread_barrier_destroy(pthread_barrier_t *);
+int pthread_barrierattr_init(pthread_barrierattr_t *);
+int pthread_barrierattr_destroy(pthread_barrierattr_t *);
+#ifdef _PTHREAD_PSHARED
+int pthread_barrierattr_getpshared(const pthread_barrierattr_t * __restrict,
+ int * __restrict);
+int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int);
+#endif
+int pthread_getschedparam(pthread_t, int * __restrict,
+ struct sched_param * __restrict);
+int pthread_setschedparam(pthread_t, int, const struct sched_param *);
+int pthread_setschedprio(pthread_t, int);
+
+int *pthread__errno(void);
+
+#if defined(_NETBSD_SOURCE)
+int pthread_getaffinity_np(pthread_t, size_t, cpuset_t *);
+int pthread_setaffinity_np(pthread_t, size_t, cpuset_t *);
+int pthread_getattr_np(pthread_t, pthread_attr_t *);
+
+int pthread_mutex_held_np(pthread_mutex_t *);
+pthread_t pthread_mutex_owner_np(pthread_mutex_t *);
+
+int pthread_rwlock_held_np(pthread_rwlock_t *);
+int pthread_rwlock_wrheld_np(pthread_rwlock_t *);
+int pthread_rwlock_rdheld_np(pthread_rwlock_t *);
+
+int pthread_cond_has_waiters_np(pthread_cond_t *);
+#endif /* _NETBSD_SOURCE */
+
+__END_DECLS
+
+#define PTHREAD_CREATE_JOINABLE 0
+#define PTHREAD_CREATE_DETACHED 1
+
+#define PTHREAD_INHERIT_SCHED 0
+#define PTHREAD_EXPLICIT_SCHED 1
+
+#define PTHREAD_SCOPE_PROCESS 0
+#define PTHREAD_SCOPE_SYSTEM 1
+
+#define PTHREAD_PROCESS_PRIVATE 0
+#define PTHREAD_PROCESS_SHARED 1
+
+#define PTHREAD_CANCEL_DEFERRED 0
+#define PTHREAD_CANCEL_ASYNCHRONOUS 1
+
+#define PTHREAD_CANCEL_ENABLE 0
+#define PTHREAD_CANCEL_DISABLE 1
+
+#define PTHREAD_BARRIER_SERIAL_THREAD 1234567
+
+/*
+ * POSIX 1003.1-2001, section 2.5.9.3: "The symbolic constant
+ * PTHREAD_CANCELED expands to a constant expression of type (void *)
+ * whose value matches no pointer to an object in memory nor the value
+ * NULL."
+ */
+#define PTHREAD_CANCELED ((void *) 1)
+
+/*
+ * Maximum length of a thread's name, including the terminating NUL.
+ */
+#define PTHREAD_MAX_NAMELEN_NP 32
+
+/*
+ * Mutex attributes.
+ */
+#define PTHREAD_MUTEX_NORMAL 0
+#define PTHREAD_MUTEX_ERRORCHECK 1
+#define PTHREAD_MUTEX_RECURSIVE 2
+#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
+
+#define PTHREAD_PRIO_NONE 0
+#define PTHREAD_PRIO_INHERIT 1
+#define PTHREAD_PRIO_PROTECT 2
+
+#define PTHREAD_COND_INITIALIZER _PTHREAD_COND_INITIALIZER
+#define PTHREAD_MUTEX_INITIALIZER _PTHREAD_MUTEX_INITIALIZER
+#define PTHREAD_ONCE_INIT _PTHREAD_ONCE_INIT
+#define PTHREAD_RWLOCK_INITIALIZER _PTHREAD_RWLOCK_INITIALIZER
+#define PTHREAD_SPINLOCK_INITIALIZER _PTHREAD_SPINLOCK_INITIALIZER
+
+/*
+ * Use macros to rename many pthread functions to the corresponding
+ * libc symbols which are either trivial/no-op stubs or the real
+ * thing, depending on whether libpthread is linked in to the
+ * program. This permits code, particularly libraries that do not
+ * directly use threads but want to be thread-safe in the presence of
+ * threaded callers, to use pthread mutexes and the like without
+ * unnecessairly including libpthread in their linkage.
+ *
+ * Left out of this list are functions that can't sensibly be trivial
+ * or no-op stubs in a single-threaded process (pthread_create,
+ * pthread_kill, pthread_detach), functions that normally block and
+ * wait for another thread to do something (pthread_join), and
+ * functions that don't make sense without the previous functions
+ * (pthread_attr_*). The pthread_cond_wait and pthread_cond_timedwait
+ * functions are useful in implementing certain protection mechanisms,
+ * though a non-buggy app shouldn't end up calling them in
+ * single-threaded mode.
+ *
+ * The rename is done as:
+ * #define pthread_foo __libc_foo
+ * instead of
+ * #define pthread_foo(x) __libc_foo((x))
+ * in order that taking the address of the function ("func =
+ * &pthread_foo;") continue to work.
+ *
+ * POSIX/SUSv3 requires that its functions exist as functions (even if
+ * macro versions exist) and specifically that "#undef pthread_foo" is
+ * legal and should not break anything. Code that does such will not
+ * successfully get the stub behavior implemented here and will
+ * require libpthread to be linked in.
+ */
+
+#ifndef __LIBPTHREAD_SOURCE__
+__BEGIN_DECLS
+int __libc_mutex_init(pthread_mutex_t * __restrict, const pthread_mutexattr_t * __restrict);
+int __libc_mutex_lock(pthread_mutex_t *);
+int __libc_mutex_trylock(pthread_mutex_t *);
+int __libc_mutex_unlock(pthread_mutex_t *);
+int __libc_mutex_destroy(pthread_mutex_t *);
+
+int __libc_mutexattr_init(pthread_mutexattr_t *);
+int __libc_mutexattr_settype(pthread_mutexattr_t *, int);
+int __libc_mutexattr_destroy(pthread_mutexattr_t *);
+__END_DECLS
+
+#define pthread_mutex_init __libc_mutex_init
+#define pthread_mutex_lock __libc_mutex_lock
+#define pthread_mutex_trylock __libc_mutex_trylock
+#define pthread_mutex_unlock __libc_mutex_unlock
+#define pthread_mutex_destroy __libc_mutex_destroy
+
+#define pthread_mutexattr_init __libc_mutexattr_init
+#define pthread_mutexattr_settype __libc_mutexattr_settype
+#define pthread_mutexattr_destroy __libc_mutexattr_destroy
+
+__BEGIN_DECLS
+int __libc_cond_init(pthread_cond_t * __restrict,
+ const pthread_condattr_t * __restrict);
+int __libc_cond_signal(pthread_cond_t *);
+int __libc_cond_broadcast(pthread_cond_t *);
+int __libc_cond_wait(pthread_cond_t * __restrict,
+ pthread_mutex_t * __restrict);
+#ifndef __LIBC12_SOURCE__
+int __libc_cond_timedwait(pthread_cond_t * __restrict,
+ pthread_mutex_t * __restrict, const struct timespec * __restrict);
+#endif
+int __libc_cond_destroy(pthread_cond_t *);
+__END_DECLS
+
+#define pthread_cond_init __libc_cond_init
+#define pthread_cond_signal __libc_cond_signal
+#define pthread_cond_broadcast __libc_cond_broadcast
+#define pthread_cond_wait __libc_cond_wait
+#define pthread_cond_timedwait __libc_cond_timedwait
+#define pthread_cond_destroy __libc_cond_destroy
+
+__BEGIN_DECLS
+int __libc_rwlock_init(pthread_rwlock_t * __restrict,
+ const pthread_rwlockattr_t * __restrict);
+int __libc_rwlock_rdlock(pthread_rwlock_t *);
+int __libc_rwlock_wrlock(pthread_rwlock_t *);
+int __libc_rwlock_tryrdlock(pthread_rwlock_t *);
+int __libc_rwlock_trywrlock(pthread_rwlock_t *);
+int __libc_rwlock_unlock(pthread_rwlock_t *);
+int __libc_rwlock_destroy(pthread_rwlock_t *);
+__END_DECLS
+
+#define pthread_rwlock_init __libc_rwlock_init
+#define pthread_rwlock_rdlock __libc_rwlock_rdlock
+#define pthread_rwlock_wrlock __libc_rwlock_wrlock
+#define pthread_rwlock_tryrdlock __libc_rwlock_tryrdlock
+#define pthread_rwlock_trywrlock __libc_rwlock_trywrlock
+#define pthread_rwlock_unlock __libc_rwlock_unlock
+#define pthread_rwlock_destroy __libc_rwlock_destroy
+
+__BEGIN_DECLS
+int __libc_thr_keycreate(pthread_key_t *, void (*)(void *));
+int __libc_thr_setspecific(pthread_key_t, const void *);
+void *__libc_thr_getspecific(pthread_key_t);
+int __libc_thr_keydelete(pthread_key_t);
+__END_DECLS
+
+#define pthread_key_create __libc_thr_keycreate
+#define pthread_setspecific __libc_thr_setspecific
+#define pthread_getspecific __libc_thr_getspecific
+#define pthread_key_delete __libc_thr_keydelete
+
+__BEGIN_DECLS
+int __libc_thr_once(pthread_once_t *, void (*)(void));
+pthread_t __libc_thr_self(void);
+void __libc_thr_exit(void *) __attribute__((__noreturn__));
+int __libc_thr_setcancelstate(int, int *);
+int __libc_thr_equal(pthread_t, pthread_t);
+unsigned int __libc_thr_curcpu(void);
+__END_DECLS
+
+#define pthread_once __libc_thr_once
+#define pthread_self __libc_thr_self
+#define pthread_exit __libc_thr_exit
+#define pthread_setcancelstate __libc_thr_setcancelstate
+#define pthread_equal __libc_thr_equal
+#define pthread_curcpu_np __libc_thr_curcpu
+
+#endif /* __LIBPTHREAD_SOURCE__ */
+
+#endif /* _LIB_PTHREAD_H */
diff --git a/libpthread_dbg/files/pthread_dbg.3 b/libpthread_dbg/files/pthread_dbg.3
new file mode 100644
index 0000000000..0f33a06126
--- /dev/null
+++ b/libpthread_dbg/files/pthread_dbg.3
@@ -0,0 +1,148 @@
+.\" $NetBSD: pthread_dbg.3,v 1.4 2016/11/24 12:18:02 wiz Exp $
+.\"
+.\"
+.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd November 21, 2016
+.Dt PTHREAD_DBG 3
+.Os
+.Sh NAME
+.Nm pthread_dbg
+.Nd POSIX Debug Threads Library
+.Sh LIBRARY
+.Lb libpthread_dbg
+.Sh SYNOPSIS
+.In pthread_dbg.h
+.Pp
+.Nm cc
+.Op Ar flags
+.Ar files
+.Fl lpthread_dbg
+.Op Ar libraries
+.Sh DESCRIPTION
+The
+.Nm
+library provides an implementation of the standard
+.Tn POSIX
+threads library debugging facilities.
+.Pp
+The
+.Nx
+implementation is based on 1:1 thread model, therefore each
+.Xr pthread 3
+has a kernel thread, called a light-weight process (LWP).
+.Pp
+Note that the system private thread interfaces upon which the
+.Xr pthread 3
+library is built are subject to change without notice.
+In order to remain compatible with future
+.Nx
+releases, programs must be linked against the dynamic version of the
+thread library.
+Statically linked programs using the
+.Tn POSIX
+threads framework may not work when run on a future version of the system.
+.Pp
+The
+.Nm
+library is designed to be used in debuggers and to control and introspect the
+.Nx
+implementation of the
+.Tn POSIX
+threads.
+Software may use native
+.Tn LWP
+threads without
+.Xr pthread 3
+layer,
+in that case
+.Nm
+cannot be used.
+.Ss Error codes
+The following error codes are defined in
+.Nm
+functions:
+.Pp
+.Bl -column ".Sy TD_ERR_BADTHREAD" "Request is not meaningful for that thread" -compact
+.\".It Sy "Symbol" Ta Sy "Descriptive name"
+.It Dv TD_ERR_OK Ta "Success"
+.It Dv TD_ERR_ERR Ta "Generic error"
+.It Dv TD_ERR_NOSYM Ta "Symbol not found (proc_lookup)"
+.It Dv TD_ERR_NOOBJ Ta "No object matched the request"
+.It Dv TD_ERR_BADTHREAD Ta "Request is not meaningful for that thread"
+.It Dv TD_ERR_INUSE Ta "The process is already being debugged"
+.It Dv TD_ERR_NOLIB Ta "The process is not using libpthread"
+.It Dv TD_ERR_NOMEM Ta "Memory allocation failed"
+.It Dv TD_ERR_IO Ta "A callback failed to read or write"
+.It Dv TD_ERR_INVAL Ta "Invalid parameter"
+.El
+.Sh FUNCTIONS
+The following functions comprise the core of the
+.Nm
+library:
+.Bl -column -offset indent "td_thr_getname(3)" "convert the pthread_t to a thread handle"
+.It Sy Function Ta Sy Description
+.It Xr td_close 3 Ta close connection to a threaded process
+.It Xr td_map_pth2thr 3 Ta convert a pthread_t to a thread handle
+.It Xr td_open 3 Ta make connection to a threaded process
+.It Xr td_thr_getname 3 Ta get the user-assigned name of a thread
+.It Xr td_thr_info 3 Ta get information on a thread
+.It Xr td_thr_iter 3 Ta iterate over the threads in the process
+.El
+.Sh SEE ALSO
+.Xr pthread 3
+.Sh STANDARDS
+The
+.Nm
+library is a
+.Nx
+extension.
+.Sh HISTORY
+The
+.Nm
+library first appeared in
+.Nx 2.0
+along with the Scheduler Activation thread interface.
+This interface was authored by
+.An Nathan J. Williams
+and merged by
+.An Jason R. Thorpe .
+In
+.Nx 5.0
+the
+.Nm
+library was moved to the new 1:1 thread model.
+.Sh AUTHORS
+.An -nosplit
+.An Nathan J. Williams Aq Mt nathanw%NetBSD.org@localhost
+.Pp
+This manual page was written by
+.An Kamil Rytarowski Aq Mt kamil%NetBSD.org@localhost .
+.Sh BUGS
+It is not possible to debug the
+.Nx
+library with a debugger that is using
+.Nm
+internally.
diff --git a/libpthread_dbg/files/pthread_dbg.c b/libpthread_dbg/files/pthread_dbg.c
new file mode 100644
index 0000000000..70a821ab4b
--- /dev/null
+++ b/libpthread_dbg/files/pthread_dbg.c
@@ -0,0 +1,520 @@
+/* $NetBSD: pthread_dbg.c,v 1.51 2016/11/22 04:51:06 kamil Exp $ */
+
+/*-
+ * Copyright (c) 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Nathan J. Williams for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: pthread_dbg.c,v 1.51 2016/11/22 04:51:06 kamil Exp $");
+
+#define __EXPOSE_STACK 1
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/lock.h>
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <lwp.h>
+
+#include <machine/reg.h>
+
+#include <pthread.h>
+#include <pthread_int.h>
+#include <pthread_dbg.h>
+#include <pthread_dbg_int.h>
+
+#define PT_STACKMASK (proc->stackmask)
+#define OFFSET(thread, field) \
+ (((char *)(thread)->addr) + offsetof(struct __pthread_st, field))
+
+/* Compensate for debuggers that want a zero ID to be a sentinel */
+#define TN_OFFSET 1
+
+static int td__getthread(td_proc_t *proc, caddr_t addr, td_thread_t **threadp);
+
+int
+td_open(struct td_proc_callbacks_t *cb, void *arg, td_proc_t **procp)
+{
+ td_proc_t *proc;
+ caddr_t addr;
+ int dbg;
+ int val;
+
+ proc = malloc(sizeof(*proc));
+ if (proc == NULL)
+ return TD_ERR_NOMEM;
+ proc->cb = cb;
+ proc->arg = arg;
+
+ val = LOOKUP(proc, "pthread__dbg", &addr);
+ if (val != 0) {
+ if (val == TD_ERR_NOSYM)
+ val = TD_ERR_NOLIB;
+ goto error;
+ }
+ proc->dbgaddr = addr;
+
+ val = LOOKUP(proc, "pthread__allqueue", &addr);
+ if (val != 0)
+ goto error;
+ proc->allqaddr = addr;
+
+ val = LOOKUP(proc, "pthread__tsd_list", &addr);
+ if (val != 0)
+ goto error;
+ proc->tsdlistaddr = addr;
+
+ val = LOOKUP(proc, "pthread__tsd_destructors", &addr);
+ if (val != 0)
+ goto error;
+ proc->tsddestaddr = addr;
+
+ val = READ(proc, proc->dbgaddr, &dbg, sizeof(int));
+ if (val != 0)
+ goto error;
+
+ if (dbg != 0) {
+ /* Another instance of libpthread_dbg is already attached. */
+ val = TD_ERR_INUSE;
+ goto error;
+ }
+
+ val = LOOKUP(proc, "pthread__stacksize_lg", &addr);
+ if (val == 0)
+ proc->stacksizeaddr = addr;
+ else
+ proc->stacksizeaddr = NULL;
+ proc->stacksizelg = -1;
+ proc->stacksize = 0;
+ proc->stackmask = 0;
+
+ proc->regbuf = NULL;
+ proc->fpregbuf = NULL;
+
+ dbg = getpid();
+ /*
+ * If this fails it probably means we're debugging a core file and
+ * can't write to it.
+ * If it's something else we'll lose the next time we hit WRITE,
+ * but not before, and that's OK.
+ */
+ WRITE(proc, proc->dbgaddr, &dbg, sizeof(int));
+
+ PTQ_INIT(&proc->threads);
+
+ *procp = proc;
+
+ return 0;
+
+ error:
+ free(proc);
+ return val;
+}
+
+int
+td_close(td_proc_t *proc)
+{
+ int dbg;
+ td_thread_t *t, *next;
+
+ dbg = 0;
+ /*
+ * Error returns from this write are mot really a problem;
+ * the process doesn't exist any more.
+ */
+ WRITE(proc, proc->dbgaddr, &dbg, sizeof(int));
+
+ /* Deallocate the list of thread structures */
+ for (t = PTQ_FIRST(&proc->threads); t; t = next) {
+ next = PTQ_NEXT(t, list);
+ PTQ_REMOVE(&proc->threads, t, list);
+ free(t);
+ }
+ if (proc->regbuf != NULL) {
+ free(proc->regbuf);
+ free(proc->fpregbuf);
+ }
+
+ free(proc);
+ return 0;
+}
+
+
+int
+td_thr_iter(td_proc_t *proc, int (*call)(td_thread_t *, void *), void *callarg)
+{
+ int val;
+ caddr_t next;
+ pthread_queue_t allq;
+ td_thread_t *thread;
+
+ val = READ(proc, proc->allqaddr, &allq, sizeof(allq));
+ if (val != 0)
+ return val;
+
+ next = (void *)allq.ptqh_first;
+ while (next != NULL) {
+ val = td__getthread(proc, next, &thread);
+ if (val != 0)
+ return val;
+ val = (*call)(thread, callarg);
+ if (val != 0)
+ return 0;
+
+ val = READ(proc,
+ next + offsetof(struct __pthread_st, pt_allq.ptqe_next),
+ &next, sizeof(next));
+ if (val != 0)
+ return val;
+ }
+ return 0;
+}
+
+int
+td_thr_info(td_thread_t *thread, td_thread_info_t *info)
+{
+ int tmp, val;
+
+ val = READ(thread->proc, OFFSET(thread, pt_magic), &tmp, sizeof(tmp));
+ if (val != 0)
+ return val;
+
+ if (tmp != PT_MAGIC)
+ return TD_ERR_BADTHREAD;
+
+ info->thread_addr = thread->addr;
+ if ((val = READ(thread->proc,
+ OFFSET(thread, pt_state), &tmp, sizeof(tmp))) != 0)
+ return val;
+ switch (tmp) {
+ case PT_STATE_RUNNING:
+ info->thread_state = TD_STATE_RUNNING;
+ break;
+ case PT_STATE_ZOMBIE:
+ info->thread_state = TD_STATE_ZOMBIE;
+ break;
+ case PT_STATE_DEAD:
+ info->thread_state = TD_STATE_DEAD;
+ break;
+ default:
+ info->thread_state = TD_STATE_UNKNOWN;
+ }
+
+ if ((val = READ(thread->proc, OFFSET(thread, pt_stack),
+ &info->thread_stack, sizeof(stack_t))) != 0)
+ return val;
+
+ if ((val = READ(thread->proc, OFFSET(thread, pt_errno),
+ &info->thread_errno, sizeof(info->thread_errno))) != 0)
+ return val;
+
+ if ((val = READ(thread->proc, OFFSET(thread, pt_lid),
+ &info->thread_id, sizeof(info->thread_id))) != 0)
+ return val;
+
+ info->thread_id += TN_OFFSET;
+
+ return 0;
+}
+
+int
+td_thr_getname(td_thread_t *thread, char *name, int len)
+{
+ int val, tmp;
+ caddr_t nameaddr;
+
+
+ val = READ(thread->proc, OFFSET(thread, pt_magic), &tmp, sizeof(tmp));
+ if (val != 0)
+ return val;
+
+ if (tmp != PT_MAGIC)
+ return TD_ERR_BADTHREAD;
+
+ if ((val = READ(thread->proc, OFFSET(thread, pt_name),
+ &nameaddr, sizeof(nameaddr))) != 0)
+ return val;
+
+ if (nameaddr == 0)
+ name[0] = '\0';
+ else if ((val = READ(thread->proc, nameaddr,
+ name, (size_t)MIN(PTHREAD_MAX_NAMELEN_NP, len))) != 0)
+ return val;
+
+ if (len < PTHREAD_MAX_NAMELEN_NP)
+ name[len - 1] = '\0';
+
+ return 0;
+}
+
+int
+td_thr_getregs(td_thread_t *thread, int regset, void *buf)
+{
+ int tmp, val;
+
+ if ((val = READ(thread->proc, OFFSET(thread, pt_state),
+ &tmp, sizeof(tmp))) != 0)
+ return val;
+
+ switch (tmp) {
+ case PT_STATE_RUNNING:
+ /*
+ * The register state of the thread is live in the
+ * inferior process's register state.
+ */
+ val = GETREGS(thread->proc, regset, thread->lwp, buf);
+ if (val != 0)
+ return val;
+ break;
+ case PT_STATE_ZOMBIE:
+ case PT_STATE_DEAD:
+ default:
+ return TD_ERR_BADTHREAD;
+ }
+
+ return 0;
+}
+
+int
+td_thr_setregs(td_thread_t *thread, int regset, void *buf)
+{
+ int val, tmp;
+
+ if ((val = READ(thread->proc, OFFSET(thread, pt_state),
+ &tmp, sizeof(tmp))) != 0)
+ return val;
+
+ switch (tmp) {
+ case PT_STATE_RUNNING:
+ /*
+ * The register state of the thread is live in the
+ * inferior process's register state.
+ */
+ val = SETREGS(thread->proc, regset, thread->lwp, buf);
+ if (val != 0)
+ return val;
+ break;
+ case PT_STATE_ZOMBIE:
+ case PT_STATE_DEAD:
+ default:
+ return TD_ERR_BADTHREAD;
+ }
+
+ return 0;
+}
+
+int
+td_map_pth2thr(td_proc_t *proc, pthread_t thread, td_thread_t **threadp)
+{
+ int magic, val;
+
+ val = READ(proc, (caddr_t)&thread->pt_magic, &magic, sizeof(magic));
+ if (val != 0)
+ return val;
+
+ if (magic != PT_MAGIC)
+ return TD_ERR_NOOBJ;
+
+ val = td__getthread(proc, (void *)thread, threadp);
+ if (val != 0)
+ return val;
+
+ return 0;
+}
+
+int
+td_map_id2thr(td_proc_t *proc, int threadid, td_thread_t **threadp)
+{
+ int val, num;
+ caddr_t next;
+ pthread_queue_t allq;
+ td_thread_t *thread;
+
+
+ val = READ(proc, proc->allqaddr, &allq, sizeof(allq));
+ if (val != 0)
+ return val;
+
+ /* Correct for offset */
+ threadid -= TN_OFFSET;
+ next = (void *)allq.ptqh_first;
+ while (next != NULL) {
+ val = READ(proc, next + offsetof(struct __pthread_st, pt_lid),
+ &num, sizeof(num));
+
+ if (num == threadid)
+ break;
+
+ val = READ(proc,
+ next + offsetof(struct __pthread_st, pt_allq.ptqe_next),
+ &next, sizeof(next));
+ if (val != 0)
+ return val;
+ }
+
+ if (next == 0) {
+ /* A matching thread was not found. */
+ return TD_ERR_NOOBJ;
+ }
+
+ val = td__getthread(proc, next, &thread);
+ if (val != 0)
+ return val;
+ *threadp = thread;
+
+ return 0;
+}
+
+int
+td_tsd_iter(td_proc_t *proc,
+ int (*call)(pthread_key_t, void (*)(void *), void *), void *arg)
+{
+#ifdef notyet
+ int val;
+ int i;
+ void *allocated;
+ void (*destructor)(void *);
+
+ for (i = 0; i < pthread_keys_max; i++) {
+ val = READ(proc, proc->tsdlistaddr + i * sizeof(allocated),
+ &allocated, sizeof(allocated));
+ if (val != 0)
+ return val;
+
+ if ((uintptr_t)allocated) {
+ val = READ(proc, proc->tsddestaddr +
+ i * sizeof(destructor),
+ &destructor, sizeof(destructor));
+ if (val != 0)
+ return val;
+
+ val = (call)(i, destructor, arg);
+ if (val != 0)
+ return val;
+ }
+ }
+#else
+ abort();
+#endif
+
+ return 0;
+}
+
+/* Suspend a thread from running */
+int
+td_thr_suspend(td_thread_t *thread)
+{
+ int tmp, val;
+
+ /* validate the thread */
+ val = READ(thread->proc, OFFSET(thread, pt_magic), &tmp, sizeof(tmp));
+ if (val != 0)
+ return val;
+ if (tmp != PT_MAGIC)
+ return TD_ERR_BADTHREAD;
+
+ val = READ(thread->proc, OFFSET(thread, pt_lid), &tmp, sizeof(tmp));
+ if (val != 0)
+ return val;
+
+ /* XXXLWP continue the sucker */;
+
+ return 0;
+}
+
+/* Restore a suspended thread to its previous state */
+int
+td_thr_resume(td_thread_t *thread)
+{
+ int tmp, val;
+
+ /* validate the thread */
+ val = READ(thread->proc, OFFSET(thread, pt_magic), &tmp, sizeof(tmp));
+ if (val != 0)
+ return val;
+ if (tmp != PT_MAGIC)
+ return TD_ERR_BADTHREAD;
+
+ val = READ(thread->proc, OFFSET(thread, pt_lid), &tmp, sizeof(tmp));
+ if (val != 0)
+ return val;
+
+ /* XXXLWP continue the sucker */;
+
+ return 0;
+}
+
+static int
+td__getthread(td_proc_t *proc, caddr_t addr, td_thread_t **threadp)
+{
+ td_thread_t *thread;
+
+ /*
+ * Check if we've allocated a descriptor for this thread.
+ * Sadly, this makes iterating over a set of threads O(N^2)
+ * in the number of threads. More sophisticated data structures
+ * can wait.
+ */
+ PTQ_FOREACH(thread, &proc->threads, list) {
+ if (thread->addr == addr)
+ break;
+ }
+ if (thread == NULL) {
+ thread = malloc(sizeof(*thread));
+ if (thread == NULL)
+ return TD_ERR_NOMEM;
+ thread->proc = proc;
+ thread->addr = addr;
+ thread->lwp = 0;
+ PTQ_INSERT_HEAD(&proc->threads, thread, list);
+ }
+
+ *threadp = thread;
+ return 0;
+}
+
+int
+td_thr_tsd(td_thread_t *thread, pthread_key_t key, void **value)
+{
+ int val;
+
+ val = READ(thread->proc, OFFSET(thread, pt_specific) +
+ key * sizeof(void *), value, sizeof(*value));
+
+ return val;
+}
diff --git a/libpthread_dbg/files/pthread_dbg.h b/libpthread_dbg/files/pthread_dbg.h
new file mode 100644
index 0000000000..3edde66a70
--- /dev/null
+++ b/libpthread_dbg/files/pthread_dbg.h
@@ -0,0 +1,200 @@
+/* $NetBSD: pthread_dbg.h,v 1.9 2016/11/22 04:51:06 kamil Exp $ */
+
+/*-
+ * Copyright (c) 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Nathan J. Williams for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LIB_PTHREAD_DBG_H
+#define _LIB_PTHREAD_DBG_H
+
+#include <sys/types.h>
+#include <signal.h>
+
+__BEGIN_DECLS
+
+struct td_proc_st;
+struct td_thread_st;
+struct td_sync_st;
+
+typedef struct td_proc_st td_proc_t;
+typedef struct td_thread_st td_thread_t;
+typedef struct td_sync_st td_sync_t;
+
+struct td_proc_callbacks_t {
+ int (*proc_read)(void *arg, caddr_t addr, void *buf, size_t size);
+ int (*proc_write)(void *arg, caddr_t addr, void *buf, size_t size);
+ int (*proc_lookup)(void *arg, const char *sym, caddr_t *addr);
+ int (*proc_regsize)(void *arg, int regset, size_t *size);
+ int (*proc_getregs)(void *arg, int regset, int lwp, void *buf);
+ int (*proc_setregs)(void *arg, int regset, int lwp, void *buf);
+};
+
+
+typedef struct td_thread_info_st {
+ caddr_t thread_addr; /* Address of data structure */
+ int thread_state; /* TD_STATE_*; see below */
+ int thread_type; /* TD_TYPE_*; see below */
+ int thread_id;
+ stack_t thread_stack;
+ int thread_hasjoiners; /* 1 if threads are waiting */
+ caddr_t thread_tls;
+ int thread_errno;
+ sigset_t thread_sigmask;
+ sigset_t thread_sigpending;
+ long pad[32];
+} td_thread_info_t;
+
+#define TD_STATE_UNKNOWN 0
+#define TD_STATE_RUNNING 1 /* On a processor */
+#define TD_STATE_UNUSED2 2 /* former TD_STATE_RUNNABLE for SA */
+#define TD_STATE_UNUSED3 3 /* former TD_STATE_BLOCKED for SA */
+#define TD_STATE_UNUSED4 4 /* former TD_STATE_SLEEPING for SA */
+#define TD_STATE_ZOMBIE 5
+#define TD_STATE_UNUSED6 6 /* former TD_STATE_SUSPENDED for SA */
+#define TD_STATE_DEAD 7
+
+#define TD_TYPE_UNUSED0 0
+#define TD_TYPE_UNUSED1 1
+#define TD_TYPE_UNUSED2 2
+
+typedef struct {
+ caddr_t sync_addr; /* Address within the process */
+ int sync_type; /* TD_SYNC_*; see below */
+ size_t sync_size;
+ int sync_haswaiters; /* 1 if threads are known to be waiting */
+ union {
+ struct {
+ int locked;
+ td_thread_t *owner;
+ } mutex;
+ struct {
+ int locked;
+ } spin;
+ struct {
+ td_thread_t *thread;
+ } join;
+ struct {
+ int locked;
+ int readlocks;
+ td_thread_t *writeowner;
+ } rwlock;
+ long pad[8];
+ } sync_data;
+} td_sync_info_t;
+
+#define TD_SYNC_UNKNOWN 0
+#define TD_SYNC_MUTEX 1 /* pthread_mutex_t */
+#define TD_SYNC_COND 2 /* pthread_cond_t */
+#define TD_SYNC_SPIN 3 /* pthread_spinlock_t */
+#define TD_SYNC_JOIN 4 /* thread being joined */
+#define TD_SYNC_RWLOCK 5 /* pthread_rwlock_t */
+
+/* Error return codes */
+#define TD_ERR_OK 0
+#define TD_ERR_ERR 1 /* Generic error */
+#define TD_ERR_NOSYM 2 /* Symbol not found (proc_lookup) */
+#define TD_ERR_NOOBJ 3 /* No object matched the request */
+#define TD_ERR_BADTHREAD 4 /* Request is not meaningful for that thread */
+#define TD_ERR_INUSE 5 /* The process is already being debugged */
+#define TD_ERR_NOLIB 6 /* The process is not using libpthread */
+#define TD_ERR_NOMEM 7 /* malloc() failed */
+#define TD_ERR_IO 8 /* A callback failed to read or write */
+#define TD_ERR_INVAL 9 /* Invalid parameter */
+
+/* Make a connection to a threaded process */
+int td_open(struct td_proc_callbacks_t *, void *arg, td_proc_t **);
+int td_close(td_proc_t *);
+
+/* Iterate over the threads in the process */
+int td_thr_iter(td_proc_t *, int (*)(td_thread_t *, void *), void *);
+
+/* Get information on a thread */
+int td_thr_info(td_thread_t *, td_thread_info_t *);
+
+/* Get the user-assigned name of a thread */
+int td_thr_getname(td_thread_t *, char *, int);
+
+/* Get register state of a thread */
+int td_thr_getregs(td_thread_t *, int, void *);
+
+/* Set register state of a thread */
+int td_thr_setregs(td_thread_t *, int, void *);
+
+/* Iterate over the set of threads that are joining with the given thread */
+int td_thr_join_iter(td_thread_t *, int (*)(td_thread_t *, void *), void *);
+
+/* Get the synchronization object that the thread is sleeping on */
+int td_thr_sleepinfo(td_thread_t *, td_sync_t **);
+
+/* Get information on a synchronization object */
+int td_sync_info(td_sync_t *, td_sync_info_t *);
+
+/* Iterate over the set of threads waiting on a synchronization object */
+int td_sync_waiters_iter(td_sync_t *, int (*)(td_thread_t *, void *), void *);
+
+/* Convert the process address to a synchronization handle, if possible */
+int td_map_addr2sync(td_proc_t *, caddr_t addr, td_sync_t **);
+
+/* Convert the pthread_t to a thread handle, if possible */
+int td_map_pth2thr(td_proc_t *, pthread_t, td_thread_t **);
+
+/* Convert the thread ID to a thread handle, if possible */
+int td_map_id2thr(td_proc_t *, int, td_thread_t **);
+
+/* Return the thread handle of the thread running on the given LWP */
+int td_map_lwp2thr(td_proc_t *, int, td_thread_t **);
+
+/*
+ * Establish a mapping between threads and LWPs. Must be called
+ * every time a live process runs before calling td_thr_getregs() or
+ * td_thr_setregs().
+ */
+int td_map_lwps(td_proc_t *);
+
+/* Iterate over the set of TSD keys in the process */
+int td_tsd_iter(td_proc_t *, int (*)(pthread_key_t, void (*)(void *), void *),
+ void *);
+
+/* Get a TSD value from a thread */
+int td_thr_tsd(td_thread_t *, pthread_key_t, void **);
+
+/* Suspend a thread from running */
+int td_thr_suspend(td_thread_t *);
+
+/* Restore a suspended thread to its previous state */
+int td_thr_resume(td_thread_t *);
+
+__END_DECLS
+
+#endif /* _LIB_PTHREAD_DBG_H */
diff --git a/libpthread_dbg/files/pthread_dbg_int.h b/libpthread_dbg/files/pthread_dbg_int.h
new file mode 100644
index 0000000000..03cc588231
--- /dev/null
+++ b/libpthread_dbg/files/pthread_dbg_int.h
@@ -0,0 +1,48 @@
+
+PTQ_HEAD(thread_queue_t, td_thread_st);
+PTQ_HEAD(sync_queue_t, td_sync_st);
+
+struct td_proc_st {
+ struct td_proc_callbacks_t *cb;
+ void *arg;
+
+ void *dbgaddr;
+ void *allqaddr;
+ void *runqaddr;
+ void *idleqaddr;
+ void *suspqaddr;
+ void *maxlwpsaddr;
+ void *tsdlistaddr;
+ void *tsddestaddr;
+
+ void *stacksizeaddr;
+ int stacksizelg;
+ size_t stacksize;
+ uintptr_t stackmask;
+ struct reg *regbuf;
+ struct fpreg *fpregbuf;
+
+ struct thread_queue_t threads;
+};
+
+
+struct td_thread_st {
+ td_proc_t *proc;
+ void *addr;
+ lwpid_t lwp;
+ PTQ_ENTRY(td_thread_st) list;
+};
+
+
+struct td_sync_st {
+ td_proc_t *proc;
+ void *addr;
+ PTQ_ENTRY(td_sync_st) list;
+};
+
+#define READ(proc, addr, buf, size) ((proc)->cb->proc_read((proc)->arg, (addr), (buf), (size)))
+#define WRITE(proc, addr, buf, size) ((proc)->cb->proc_write((proc)->arg, (addr), (buf), (size)))
+#define LOOKUP(proc, sym, addr) ((proc)->cb->proc_lookup((proc)->arg, (sym), (addr)))
+#define REGSIZE(proc, regset, size) ((proc)->cb->proc_regsize((proc)->arg, (regset), (size)))
+#define GETREGS(proc, regset, lwp, buf) ((proc)->cb->proc_getregs((proc)->arg, (regset), (lwp), (buf)))
+#define SETREGS(proc, regset, lwp, buf) ((proc)->cb->proc_setregs((proc)->arg, (regset), (lwp), (buf)))
diff --git a/libpthread_dbg/files/pthread_int.h b/libpthread_dbg/files/pthread_int.h
new file mode 100644
index 0000000000..b3463ee598
--- /dev/null
+++ b/libpthread_dbg/files/pthread_int.h
@@ -0,0 +1,333 @@
+/* $NetBSD: pthread_int.h,v 1.92 2015/05/29 16:05:13 christos Exp $ */
+
+/*-
+ * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Nathan J. Williams and Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * NOTE: when changing anything in this file, please ensure that
+ * libpthread_dbg still compiles.
+ */
+
+#ifndef _LIB_PTHREAD_INT_H
+#define _LIB_PTHREAD_INT_H
+
+#include <sys/tls.h>
+
+/* #define PTHREAD__DEBUG */
+#define ERRORCHECK
+
+#include "pthread_types.h"
+#include "pthread_queue.h"
+#include "pthread_md.h"
+
+/* Need to use libc-private names for atomic operations. */
+#include "../../common/lib/libc/atomic/atomic_op_namespace.h"
+
+#include <sys/atomic.h>
+#include <sys/rbtree.h>
+
+#include <limits.h>
+#include <lwp.h>
+#include <signal.h>
+#include <stdbool.h>
+
+#ifdef __GNUC__
+#define PTHREAD_HIDE __attribute__ ((visibility("hidden")))
+#else
+#define PTHREAD_HIDE /* nothing */
+#endif
+
+#define PTHREAD__UNPARK_MAX 32
+
+/*
+ * The size of this structure needs to be no larger than struct
+ * __pthread_cleanup_store, defined in pthread.h.
+ */
+struct pt_clean_t {
+ PTQ_ENTRY(pt_clean_t) ptc_next;
+ void (*ptc_cleanup)(void *);
+ void *ptc_arg;
+};
+
+/* Private data for pthread_attr_t */
+struct pthread_attr_private {
+ char ptap_name[PTHREAD_MAX_NAMELEN_NP];
+ void *ptap_namearg;
+ void *ptap_stackaddr;
+ size_t ptap_stacksize;
+ size_t ptap_guardsize;
+ struct sched_param ptap_sp;
+ int ptap_policy;
+};
+
+struct pthread_lock_ops {
+ void (*plo_init)(__cpu_simple_lock_t *);
+ int (*plo_try)(__cpu_simple_lock_t *);
+ void (*plo_unlock)(__cpu_simple_lock_t *);
+ void (*plo_lock)(__cpu_simple_lock_t *);
+};
+
+struct __pthread_st {
+ pthread_t pt_self; /* Must be first. */
+#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
+ struct tls_tcb *pt_tls; /* Thread Local Storage area */
+#endif
+ unsigned int pt_magic; /* Magic number */
+ int pt_state; /* running, blocked, etc. */
+ pthread_mutex_t pt_lock; /* lock on state */
+ int pt_flags; /* see PT_FLAG_* below */
+ int pt_cancel; /* Deferred cancellation */
+ int pt_errno; /* Thread-specific errno. */
+ stack_t pt_stack; /* Our stack */
+ bool pt_stack_allocated;
+ size_t pt_guardsize;
+ void *pt_exitval; /* Read by pthread_join() */
+ char *pt_name; /* Thread's name, set by the app. */
+ int pt_willpark; /* About to park */
+ lwpid_t pt_unpark; /* Unpark this when parking */
+ struct pthread_lock_ops pt_lockops;/* Cached to avoid PIC overhead */
+ pthread_mutex_t *pt_droplock; /* Drop this lock if cancelled */
+ pthread_cond_t pt_joiners; /* Threads waiting to join. */
+ void *(*pt_func)(void *);/* Function to call at start. */
+ void *pt_arg; /* Argument to pass at start. */
+
+ /* Threads to defer waking, usually until pthread_mutex_unlock(). */
+ lwpid_t pt_waiters[PTHREAD__UNPARK_MAX];
+ size_t pt_nwaiters;
+
+ /* Stack of cancellation cleanup handlers and their arguments */
+ PTQ_HEAD(, pt_clean_t) pt_cleanup_stack;
+
+ /* LWP ID and entry on the list of all threads. */
+ lwpid_t pt_lid;
+ rb_node_t pt_alltree;
+ PTQ_ENTRY(__pthread_st) pt_allq;
+ PTQ_ENTRY(__pthread_st) pt_deadq;
+
+ /*
+ * General synchronization data. We try to align, as threads
+ * on other CPUs will access this data frequently.
+ */
+ int pt_dummy1 __aligned(128);
+ struct lwpctl *pt_lwpctl; /* Kernel/user comms area */
+ volatile int pt_blocking; /* Blocking in userspace */
+ volatile int pt_rwlocked; /* Handed rwlock successfully */
+ volatile int pt_signalled; /* Received pthread_cond_signal() */
+ volatile int pt_mutexwait; /* Waiting to acquire mutex */
+ void * volatile pt_mutexnext; /* Next thread in chain */
+ void * volatile pt_sleepobj; /* Object slept on */
+ PTQ_ENTRY(__pthread_st) pt_sleep;
+ void (*pt_early)(void *);
+ int pt_dummy2 __aligned(128);
+
+ /* Thread-specific data. Large so it sits close to the end. */
+ int pt_havespecific;
+ struct pt_specific {
+ void *pts_value;
+ PTQ_ENTRY(pt_specific) pts_next;
+ } pt_specific[];
+};
+
+/* Thread states */
+#define PT_STATE_RUNNING 1
+#define PT_STATE_ZOMBIE 5
+#define PT_STATE_DEAD 6
+
+/* Flag values */
+
+#define PT_FLAG_DETACHED 0x0001
+#define PT_FLAG_CS_DISABLED 0x0004 /* Cancellation disabled */
+#define PT_FLAG_CS_ASYNC 0x0008 /* Cancellation is async */
+#define PT_FLAG_CS_PENDING 0x0010
+#define PT_FLAG_SCOPE_SYSTEM 0x0040
+#define PT_FLAG_EXPLICIT_SCHED 0x0080
+#define PT_FLAG_SUSPENDED 0x0100 /* In the suspended queue */
+
+#define PT_MAGIC 0x11110001
+#define PT_DEAD 0xDEAD0001
+
+#define PT_ATTR_MAGIC 0x22220002
+#define PT_ATTR_DEAD 0xDEAD0002
+
+extern size_t pthread__stacksize;
+extern size_t pthread__pagesize;
+extern int pthread__nspins;
+extern int pthread__concurrency;
+extern int pthread__osrev;
+extern int pthread__unpark_max;
+extern int pthread_keys_max;
+
+extern int __uselibcstub;
+
+/* Flag to be used in a ucontext_t's uc_flags indicating that
+ * the saved register state is "user" state only, not full
+ * trap state.
+ */
+#define _UC_USER_BIT 30
+#define _UC_USER (1LU << _UC_USER_BIT)
+
+/* Utility functions */
+void pthread__unpark_all(pthread_queue_t *, pthread_t, pthread_mutex_t *)
+ PTHREAD_HIDE;
+void pthread__unpark(pthread_queue_t *, pthread_t, pthread_mutex_t *)
+ PTHREAD_HIDE;
+int pthread__park(pthread_t, pthread_mutex_t *, pthread_queue_t *,
+ const struct timespec *, int, const void *)
+ PTHREAD_HIDE;
+pthread_mutex_t *pthread__hashlock(volatile const void *) PTHREAD_HIDE;
+
+/* Internal locking primitives */
+void pthread__lockprim_init(void) PTHREAD_HIDE;
+void pthread_lockinit(pthread_spin_t *) PTHREAD_HIDE;
+
+static inline void pthread__spinlock(pthread_t, pthread_spin_t *)
+ __attribute__((__always_inline__));
+static inline void
+pthread__spinlock(pthread_t self, pthread_spin_t *lock)
+{
+ if (__predict_true((*self->pt_lockops.plo_try)(lock)))
+ return;
+ (*self->pt_lockops.plo_lock)(lock);
+}
+
+static inline int pthread__spintrylock(pthread_t, pthread_spin_t *)
+ __attribute__((__always_inline__));
+static inline int
+pthread__spintrylock(pthread_t self, pthread_spin_t *lock)
+{
+ return (*self->pt_lockops.plo_try)(lock);
+}
+
+static inline void pthread__spinunlock(pthread_t, pthread_spin_t *)
+ __attribute__((__always_inline__));
+static inline void
+pthread__spinunlock(pthread_t self, pthread_spin_t *lock)
+{
+ (*self->pt_lockops.plo_unlock)(lock);
+}
+
+extern const struct pthread_lock_ops *pthread__lock_ops;
+
+int pthread__simple_locked_p(__cpu_simple_lock_t *) PTHREAD_HIDE;
+#define pthread__simple_lock_init(alp) (*pthread__lock_ops->plo_init)(alp)
+#define pthread__simple_lock_try(alp) (*pthread__lock_ops->plo_try)(alp)
+#define pthread__simple_unlock(alp) (*pthread__lock_ops->plo_unlock)(alp)
+
+void pthread__testcancel(pthread_t) PTHREAD_HIDE;
+int pthread__find(pthread_t) PTHREAD_HIDE;
+
+#ifndef PTHREAD_MD_INIT
+#define PTHREAD_MD_INIT
+#endif
+
+#ifndef _INITCONTEXT_U_MD
+#define _INITCONTEXT_U_MD(ucp)
+#endif
+
+#define _INITCONTEXT_U(ucp) do { \
+ (ucp)->uc_flags = _UC_CPU | _UC_STACK; \
+ _INITCONTEXT_U_MD(ucp) \
+ } while (/*CONSTCOND*/0)
+
+
+#if !defined(__HAVE_TLS_VARIANT_I) && !defined(__HAVE_TLS_VARIANT_II)
+#error Either __HAVE_TLS_VARIANT_I or __HAVE_TLS_VARIANT_II must be defined
+#endif
+
+#ifdef _PTHREAD_GETTCB_EXT
+struct tls_tcb *_PTHREAD_GETTCB_EXT(void);
+#endif
+
+static inline pthread_t __constfunc
+pthread__self(void)
+{
+#if defined(_PTHREAD_GETTCB_EXT)
+ struct tls_tcb * const tcb = _PTHREAD_GETTCB_EXT();
+#elif defined(__HAVE___LWP_GETTCB_FAST)
+ struct tls_tcb * const tcb = __lwp_gettcb_fast();
+#else
+ struct tls_tcb * const tcb = __lwp_getprivate_fast();
+#endif
+ return (pthread_t)tcb->tcb_pthread;
+}
+
+#define pthread__abort() \
+ pthread__assertfunc(__FILE__, __LINE__, __func__, "unreachable")
+
+#define pthread__assert(e) do { \
+ if (__predict_false(!(e))) \
+ pthread__assertfunc(__FILE__, __LINE__, __func__, #e); \
+ } while (/*CONSTCOND*/0)
+
+#define pthread__error(err, msg, e) do { \
+ if (__predict_false(!(e))) { \
+ pthread__errorfunc(__FILE__, __LINE__, __func__, msg); \
+ return (err); \
+ } \
+ } while (/*CONSTCOND*/0)
+
+void *pthread_tsd_init(size_t *) PTHREAD_HIDE;
+void pthread__destroy_tsd(pthread_t) PTHREAD_HIDE;
+__dead void pthread__assertfunc(const char *, int, const char *, const char *)
+ PTHREAD_HIDE;
+void pthread__errorfunc(const char *, int, const char *, const char *)
+ PTHREAD_HIDE;
+char *pthread__getenv(const char *) PTHREAD_HIDE;
+__dead void pthread__cancelled(void) PTHREAD_HIDE;
+void pthread__mutex_deferwake(pthread_t, pthread_mutex_t *) PTHREAD_HIDE;
+int pthread__checkpri(int) PTHREAD_HIDE;
+int pthread__add_specific(pthread_t, pthread_key_t, const void *) PTHREAD_HIDE;
+
+#ifndef pthread__smt_pause
+#define pthread__smt_pause() /* nothing */
+#endif
+#ifndef pthread__smt_wake
+#define pthread__smt_wake() /* nothing */
+#endif
+
+/*
+ * Bits in the owner field of the lock that indicate lock state. If the
+ * WRITE_LOCKED bit is clear, then the owner field is actually a count of
+ * the number of readers.
+ */
+#define RW_HAS_WAITERS 0x01 /* lock has waiters */
+#define RW_WRITE_WANTED 0x02 /* >= 1 waiter is a writer */
+#define RW_WRITE_LOCKED 0x04 /* lock is currently write locked */
+#define RW_UNUSED 0x08 /* currently unused */
+
+#define RW_FLAGMASK 0x0f
+
+#define RW_READ_COUNT_SHIFT 4
+#define RW_READ_INCR (1 << RW_READ_COUNT_SHIFT)
+#define RW_THREAD ((uintptr_t)-RW_READ_INCR)
+#define RW_OWNER(rw) ((rw)->rw_owner & RW_THREAD)
+#define RW_COUNT(rw) ((rw)->rw_owner & RW_THREAD)
+#define RW_FLAGS(rw) ((rw)->rw_owner & ~RW_THREAD)
+
+#endif /* _LIB_PTHREAD_INT_H */
diff --git a/libpthread_dbg/files/shlib_version b/libpthread_dbg/files/shlib_version
new file mode 100644
index 0000000000..dc91478808
--- /dev/null
+++ b/libpthread_dbg/files/shlib_version
@@ -0,0 +1,5 @@
+# $NetBSD: shlib_version,v 1.5 2009/01/11 03:07:49 christos Exp $
+# Remember to update distrib/sets/lists/base/shl.* when changing
+#
+major=2
+minor=0
diff --git a/libpthread_dbg/files/td_map_pth2thr.3 b/libpthread_dbg/files/td_map_pth2thr.3
new file mode 100644
index 0000000000..159d38578e
--- /dev/null
+++ b/libpthread_dbg/files/td_map_pth2thr.3
@@ -0,0 +1,71 @@
+.\" $NetBSD: td_map_pth2thr.3,v 1.2 2016/11/24 12:18:02 wiz Exp $
+.\"
+.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd November 22, 2016
+.Dt TD_MAP_PTH2THR 3
+.Os
+.Sh NAME
+.Nm td_map_pth2thr
+.Nd convert a pthread_t to a thread handle
+.Sh LIBRARY
+.Lb libpthread_dbg
+.Sh SYNOPSIS
+.In pthread_dbg.h
+.Ft int
+.Fn td_thr_getname "td_proc_t *proc" "pthread_t thread" "td_thread_t **threadp"
+.Sh DESCRIPTION
+The
+.Nm
+function converts a
+.Ta POSIX
+thread
+.Fa thread
+to a
+.Xr pthread_dbg 3
+specific thread passed in the
+.Fa threadp
+argument.
+.Sh RETURN VALUES
+If successful, the
+.Nm
+function will return
+.Dv TD_ERR_OK .
+Otherwise an error number will be returned to indicate failure as described in
+.Xr pthread_dbg 3 .
+.Sh SEE ALSO
+.Xr pthread 3 ,
+.Xr pthread_dbg 3
+.Sh HISTORY
+The
+.Nm
+function first appeared in
+.Nx 2.0 .
+.Sh AUTHORS
+.An -nosplit
+.An Nathan J. Williams Aq Mt nathanw%NetBSD.org@localhost
+.Pp
+This manual page was written by
+.An Kamil Rytarowski Aq Mt kamil%NetBSD.org@localhost .
diff --git a/libpthread_dbg/files/td_open.3 b/libpthread_dbg/files/td_open.3
new file mode 100644
index 0000000000..93158ff74b
--- /dev/null
+++ b/libpthread_dbg/files/td_open.3
@@ -0,0 +1,79 @@
+.\" $NetBSD: td_open.3,v 1.2 2016/11/24 12:18:02 wiz Exp $
+.\"
+.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd November 21, 2016
+.Dt TD_OPEN 3
+.Os
+.Sh NAME
+.Nm td_open ,
+.Nm td_close
+.Nd make or close a connection to a threaded process
+.Sh LIBRARY
+.Lb libpthread_dbg
+.Sh SYNOPSIS
+.In pthread_dbg.h
+.Ft int
+.Fn td_open "struct td_proc_callbacks_t *cb" "void *arg" "td_proc_t **procp"
+.Ft int
+.Fn td_close "td_proc_t *proc"
+.Sh DESCRIPTION
+The
+.Fn td_open
+function makes a connection to a threaded process.
+That program must be a consumer of the
+.Tn POSIX
+threads implementation using the
+.Xr pthread 3
+library.
+.Pp
+The
+.Fn td_close
+function closes a connection to a threaded process.
+.Sh RETURN VALUES
+If successful, the
+.Fn td_open
+and
+.Fn td_close
+functions will return
+.Dv TD_ERR_OK .
+Otherwise an error number will be returned to indicate failure as described in
+.Xr pthread_dbg 3 .
+.Sh SEE ALSO
+.Xr pthread 3 ,
+.Xr pthread_dbg 3
+.Sh HISTORY
+The
+.Fn td_open
+and
+.Fn td_close
+functions first appeared in
+.Nx 2.0 .
+.Sh AUTHORS
+.An -nosplit
+.An Nathan J. Williams Aq Mt nathanw%NetBSD.org@localhost
+.Pp
+This manual page was written by
+.An Kamil Rytarowski Aq Mt kamil%NetBSD.org@localhost .
diff --git a/libpthread_dbg/files/td_thr_getname.3 b/libpthread_dbg/files/td_thr_getname.3
new file mode 100644
index 0000000000..49e596c88c
--- /dev/null
+++ b/libpthread_dbg/files/td_thr_getname.3
@@ -0,0 +1,75 @@
+.\" $NetBSD: td_thr_getname.3,v 1.2 2016/11/24 12:18:02 wiz Exp $
+.\"
+.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd November 22, 2016
+.Dt TD_THR_GETNAME 3
+.Os
+.Sh NAME
+.Nm td_thr_getname
+.Nd get the user-assigned name of a thread
+.Sh LIBRARY
+.Lb libpthread_dbg
+.Sh SYNOPSIS
+.In pthread_dbg.h
+.Ft int
+.Fn td_thr_getname "td_thread_t *thread" "char *name" "int len"
+.Sh DESCRIPTION
+The
+.Nm
+function retrieves the user-assigned name of a thread
+.Fa thread
+and stores it in the buffer
+.Fa name
+of length
+.Fa len .
+If the name is longer than the buffer size, the result will be truncated.
+The returned string always terminates with a
+.Dv NUL
+byte.
+The maximum length of a thread's name,
+including terminating character, is defined by
+.Dv PTHREAD_MAX_NAMELEN_NP .
+.Sh RETURN VALUES
+If successful, the
+.Nm
+function will return
+.Dv TD_ERR_OK .
+Otherwise an error number will be returned to indicate failure as described in
+.Xr pthread_dbg 3 .
+.Sh SEE ALSO
+.Xr pthread 3 ,
+.Xr pthread_dbg 3
+.Sh HISTORY
+The
+.Nm
+function first appeared in
+.Nx 2.0 .
+.Sh AUTHORS
+.An -nosplit
+.An Nathan J. Williams Aq Mt nathanw%NetBSD.org@localhost
+.Pp
+This manual page was written by
+.An Kamil Rytarowski Aq Mt kamil%NetBSD.org@localhost .
diff --git a/libpthread_dbg/files/td_thr_info.3 b/libpthread_dbg/files/td_thr_info.3
new file mode 100644
index 0000000000..33cea0fde3
--- /dev/null
+++ b/libpthread_dbg/files/td_thr_info.3
@@ -0,0 +1,109 @@
+.\" $NetBSD: td_thr_info.3,v 1.2 2016/11/24 12:18:02 wiz Exp $
+.\"
+.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd November 21, 2016
+.Dt TD_THR_INFO 3
+.Os
+.Sh NAME
+.Nm td_thr_info
+.Nd get information on a thread
+.Sh LIBRARY
+.Lb libpthread_dbg
+.Sh SYNOPSIS
+.In pthread_dbg.h
+.Ft int
+.Fn td_thr_info "td_thread_t *thread" "td_thread_info_t *info"
+.Sh DESCRIPTION
+The
+.Fn td_thr_info
+function retrieves information on a thread specified in the
+.Fa thread
+argument and saves the result in
+.Fa info .
+.Pp
+The following members are defined in the
+.Dv td_thread_info_t
+structure:
+.Bl -column "thread_state" "caddr_t" "Pointer to underlaying Dv pthread_t object"
+.It Sy Name Ta Sy Type Ta Sy Description
+.It thread_addr Ta Dv caddr_t Ta Points to underlaying Dv pthread_t object
+.It thread_state Ta Dv int Ta Defines Dv TD_STATE of the thread
+.\" TODO: Add ATF tests, verify and document:
+.\" thread_type
+.\" thread_id
+.\" thread_stack
+.\" thread_hasjoiners
+.\" thread_tls
+.\" thread_errno
+.\" thread_sigmask
+.\" thread_sigpending
+.El
+.Ss Thread State types
+The following state types are possible in
+.Dv thread_state :
+.Pp
+.Bl -column ".Sy TD_STATE_RUNNING" "Thread is alive" -compact
+.It Dv TD_STATE_UNKNOWN Ta "Unknown state"
+.It Dv TD_STATE_RUNNING Ta "Thread is alive"
+.It Dv TD_STATE_ZOMBIE Ta "Thread is in the zombie state"
+.It Dv TD_STATE_DEAD Ta "Thread is dead"
+.El
+.Pp
+It is not possible to retrieve information whether a thread
+is suspended or resumed using this interface,
+as this data is stored only inside the kernel and not in the
+.Dv pthread_t
+object.
+The
+.Dv TD_STATE_RUNNING
+name is kept for backwards compatibility with old Scheduler Activation threads.
+The
+.Dv TD_STATE_RUNNING
+state might only be returned for a mismatch between the versions of
+.Xr pthread 3
+and
+.Xr pthread_dbg 3 .
+.Sh RETURN VALUES
+If successful, the
+.Nm
+function will return
+.Dv TD_ERR_OK .
+Otherwise an error number will be returned to indicate failure as described in
+.Xr pthread_dbg 3 .
+.Sh SEE ALSO
+.Xr pthread 3 ,
+.Xr pthread_dbg 3
+.Sh HISTORY
+The
+.Nm
+function first appeared in
+.Nx 2.0 .
+.Sh AUTHORS
+.An -nosplit
+.An Nathan J. Williams Aq Mt nathanw%NetBSD.org@localhost
+.Pp
+This manual page was written by
+.An Kamil Rytarowski Aq Mt kamil%NetBSD.org@localhost .
diff --git a/libpthread_dbg/files/td_thr_iter.3 b/libpthread_dbg/files/td_thr_iter.3
new file mode 100644
index 0000000000..854245bea1
--- /dev/null
+++ b/libpthread_dbg/files/td_thr_iter.3
@@ -0,0 +1,69 @@
+.\" $NetBSD: td_thr_iter.3,v 1.2 2016/11/24 12:18:02 wiz Exp $
+.\"
+.\" Copyright (c) 2016 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd November 21, 2016
+.Dt TD_THR_ITER 3
+.Os
+.Sh NAME
+.Nm td_thr_iter
+.Nd iterate over the threads in a process
+.Sh LIBRARY
+.Lb libpthread_dbg
+.Sh SYNOPSIS
+.In pthread_dbg.h
+.Ft int
+.Fn td_thr_iter "td_proc_t *proc" "int (*call)(td_thread_t *, void *)" "void *callarg"
+.Sh DESCRIPTION
+The
+.Fn td_thr_iter
+function iterates over all threads in the
+.Fa proc
+process and calls the
+.Fa call
+function for each of them with the
+.Fa callarg
+argument.
+.Sh RETURN VALUES
+If successful, the
+.Nm
+function will return
+.Dv TD_ERR_OK .
+Otherwise an error number will be returned to indicate failure as described in
+.Xr pthread_dbg 3 .
+.Sh SEE ALSO
+.Xr pthread 3 ,
+.Xr pthread_dbg 3
+.Sh HISTORY
+The
+.Nm
+function first appeared in
+.Nx 2.0 .
+.Sh AUTHORS
+.An -nosplit
+.An Nathan J. Williams Aq Mt nathanw%NetBSD.org@localhost
+.Pp
+This manual page was written by
+.An Kamil Rytarowski Aq Mt kamil%NetBSD.org@localhost .
Home |
Main Index |
Thread Index |
Old Index