about summary refs log tree commit diff
path: root/REORG.TODO/nptl_db
diff options
context:
space:
mode:
Diffstat (limited to 'REORG.TODO/nptl_db')
-rw-r--r--REORG.TODO/nptl_db/ChangeLog.old347
-rw-r--r--REORG.TODO/nptl_db/Makefile63
-rw-r--r--REORG.TODO/nptl_db/Versions24
-rw-r--r--REORG.TODO/nptl_db/db-symbols.awk47
-rw-r--r--REORG.TODO/nptl_db/db-symbols.h51
-rw-r--r--REORG.TODO/nptl_db/db_info.c109
-rw-r--r--REORG.TODO/nptl_db/fetch-value.c285
-rw-r--r--REORG.TODO/nptl_db/proc_service.h95
-rw-r--r--REORG.TODO/nptl_db/shlib-versions2
-rw-r--r--REORG.TODO/nptl_db/structs.def123
-rw-r--r--REORG.TODO/nptl_db/td_init.c31
-rw-r--r--REORG.TODO/nptl_db/td_log.c31
-rw-r--r--REORG.TODO/nptl_db/td_symbol_list.c51
-rw-r--r--REORG.TODO/nptl_db/td_ta_clear_event.c77
-rw-r--r--REORG.TODO/nptl_db/td_ta_delete.c41
-rw-r--r--REORG.TODO/nptl_db/td_ta_enable_stats.c34
-rw-r--r--REORG.TODO/nptl_db/td_ta_event_addr.c60
-rw-r--r--REORG.TODO/nptl_db/td_ta_event_getmsg.c104
-rw-r--r--REORG.TODO/nptl_db/td_ta_get_nthreads.c41
-rw-r--r--REORG.TODO/nptl_db/td_ta_get_ph.c35
-rw-r--r--REORG.TODO/nptl_db/td_ta_get_stats.c34
-rw-r--r--REORG.TODO/nptl_db/td_ta_map_id2thr.c37
-rw-r--r--REORG.TODO/nptl_db/td_ta_map_lwp2thr.c208
-rw-r--r--REORG.TODO/nptl_db/td_ta_new.c64
-rw-r--r--REORG.TODO/nptl_db/td_ta_reset_stats.c34
-rw-r--r--REORG.TODO/nptl_db/td_ta_set_event.c77
-rw-r--r--REORG.TODO/nptl_db/td_ta_setconcurrency.c34
-rw-r--r--REORG.TODO/nptl_db/td_ta_thr_iter.c150
-rw-r--r--REORG.TODO/nptl_db/td_ta_tsd_iter.c81
-rw-r--r--REORG.TODO/nptl_db/td_thr_clear_event.c75
-rw-r--r--REORG.TODO/nptl_db/td_thr_dbresume.c29
-rw-r--r--REORG.TODO/nptl_db/td_thr_dbsuspend.c29
-rw-r--r--REORG.TODO/nptl_db/td_thr_event_enable.c49
-rw-r--r--REORG.TODO/nptl_db/td_thr_event_getmsg.c118
-rw-r--r--REORG.TODO/nptl_db/td_thr_get_info.c126
-rw-r--r--REORG.TODO/nptl_db/td_thr_getfpregs.c57
-rw-r--r--REORG.TODO/nptl_db/td_thr_getgregs.c57
-rw-r--r--REORG.TODO/nptl_db/td_thr_getxregs.c29
-rw-r--r--REORG.TODO/nptl_db/td_thr_getxregsize.c29
-rw-r--r--REORG.TODO/nptl_db/td_thr_set_event.c75
-rw-r--r--REORG.TODO/nptl_db/td_thr_setfpregs.c54
-rw-r--r--REORG.TODO/nptl_db/td_thr_setgregs.c54
-rw-r--r--REORG.TODO/nptl_db/td_thr_setprio.c29
-rw-r--r--REORG.TODO/nptl_db/td_thr_setsigpending.c30
-rw-r--r--REORG.TODO/nptl_db/td_thr_setxregs.c29
-rw-r--r--REORG.TODO/nptl_db/td_thr_sigsetmask.c29
-rw-r--r--REORG.TODO/nptl_db/td_thr_tls_get_addr.c42
-rw-r--r--REORG.TODO/nptl_db/td_thr_tlsbase.c243
-rw-r--r--REORG.TODO/nptl_db/td_thr_tsd.c96
-rw-r--r--REORG.TODO/nptl_db/td_thr_validate.c84
-rw-r--r--REORG.TODO/nptl_db/thread_db.h458
-rw-r--r--REORG.TODO/nptl_db/thread_dbP.h268
52 files changed, 4459 insertions, 0 deletions
diff --git a/REORG.TODO/nptl_db/ChangeLog.old b/REORG.TODO/nptl_db/ChangeLog.old
new file mode 100644
index 0000000000..6e74f3ecbb
--- /dev/null
+++ b/REORG.TODO/nptl_db/ChangeLog.old
@@ -0,0 +1,347 @@
+This file describes changes to the nptl_db/ subdirectory prior to 2014-03-03.
+Later nptl_db/ changes go into the top-level ChangeLog file, not here.
+
+
+
+2014-02-26  Joseph Myers  <joseph@codesourcery.com>
+
+	* Makefile: Include Makeconfig immediately after defining subdir.
+
+2014-02-21  Joseph Myers  <joseph@codesourcery.com>
+
+	* Makefile ($(objpfx)db-symbols.out): Use
+	$(evaluate-test).
+
+2013-05-31  Joseph Myers  <joseph@codesourcery.com>
+
+	* Makefile ($(objpfx)libthread_db.so): Remove dependencies on
+	libc.
+
+2013-05-16  Ryan S. Arnold  <rsa@linux.vnet.ibm.com>
+
+	* db_info.c: Add missing #include <stdint.h> due to uint64_t or
+	uint32_t usage.
+	* fetch-value.c: Likewise.
+	* td_ta_clear_event.c: Likewise.
+	* td_ta_set_event.c: Likewise.
+	* td_ta_tsd_iter.c: Likewise.
+	* td_thr_clear_event.c: Likewise.
+	* td_thr_get_info.c: Likewise.
+	* td_thr_set_event.c: Likewise.
+	* td_thr_tsd.c: Likewise.
+
+2013-01-02  Joseph Myers  <joseph@codesourcery.com>
+
+	* All files with FSF copyright notices: Update copyright dates
+	using scripts/update-copyrights.
+
+2013-01-01  Joseph Myers  <joseph@codesourcery.com>
+
+	* td_ta_thr_iter.c: Reformat copyright notice.
+	* td_thr_validate.c: Likewise.
+
+2012-11-23  Mike Frysinger  <vapier@gentoo.org>
+
+	* Makefile ($(objpfx)db-symbols.out): Change readelf to $(READELF).
+
+2012-10-08  Jonathan Nieder  <jrnieder@gmail.com>
+
+	[BZ #14661]
+	* Makefile ($(objpfx)db-symbols.out): Force C locale when running
+	readelf -s.
+
+2012-03-07  Ulrich Drepper  <drepper@gmail.com>
+
+	* Makefile (distribute): Remove variable.
+
+2011-09-15  Andreas Schwab  <schwab@redhat.com>
+
+	* thread_dbP.h: Include <list.h>
+
+2009-08-23  Roland McGrath  <roland@redhat.com>
+
+	* td_ta_map_lwp2thr.c (__td_ta_lookup_th_unique): Move ta_ok check
+	and LOG call back to ...
+	(td_ta_map_lwp2thr): ... here.
+	Reported by Maciej W. Rozycki <macro@codesourcery.com>.
+
+2009-05-25  Aurelien Jarno  <aurelien@aurel32.net>
+
+	[BZ #10200]
+	* db-symbols.awk: Use the last field for the symbol name instead
+	of the 8th one.
+
+2009-03-19  Roland McGrath  <roland@redhat.com>
+
+	* td_symbol_list.c (DB_LOOKUP_NAME, DB_LOOKUP_NAME_TH_UNIQUE):
+	Use STRINGIFY macro in place of #argument.
+
+2009-02-27  Roland McGrath  <roland@redhat.com>
+
+	* td_symbol_list.c (symbol_list_arr): Move initializer guts to ...
+	* db-symbols.h: ... here, new file.
+	* db-symbols.awk: New file.
+	* Makefile (distribute): Add them.
+	($(objpfx)db-symbols.out): New target.
+	(tests): Depend on it.
+	($(objpfx)db-symbols.v.i): New dependent rule.
+
+2009-02-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* td_thr_get_info.c (td_thr_get_info): Initialize schedpolicy in
+	the special case [Coverity CID 251].
+
+2008-03-25  Roland McGrath  <roland@redhat.com>
+
+	[BZ #5983]
+	* structs.def: Add pid field of struct pthread.
+	* td_ta_thr_iter.c (iterate_thread_list): Take new arg MATCH_PID.
+	If a thread's pid does not match nor is < 0 while its tid matches
+	nor is < 0 and equal to -MATCH_PID, ignore it.
+	* td_thr_validate.c (td_thr_validate): Validate thread's pid/tid.
+
+2007-05-16  Roland McGrath  <roland@redhat.com>
+
+	* td_thr_get_info.c: Fake the results for TH->th_unique == 0.
+	* td_thr_validate.c: Likewise.
+	* td_thr_setgregs.c: Likewise.
+	* td_thr_setfpregs.c: Likewise.
+	* td_thr_getgregs.c: Likewise.
+	* td_thr_getfpregs.c: Likewise.
+	* td_thr_tlsbase.c: Likewise.
+
+	* structs.def: Add DB_VARIABLE (__nptl_initial_report_events).
+	* db_info.c: Add necessary declaration.
+	* td_thr_event_enable.c: Set __nptl_initial_report_events too.
+
+	* td_ta_thr_iter.c (iterate_thread_list): Make FAKE_EMPTY bool.
+	Use th_unique=0 in fake descriptor before initialization.
+
+	* td_ta_map_lwp2thr.c (__td_ta_lookup_th_unique): New function, broken
+	out of ...
+	(td_ta_map_lwp2thr): ... here, call it.  But don't before __stack_user
+	is initialized, then fake a handle with th_unique=0.
+	* thread_dbP.h: Declare it.
+
+2006-10-26  Pete Eberlein  <eberlein@us.ibm.com>
+
+	* nptl_db/db_info.c [TLS_DTV_AT_TP]: Fixed size init for dtvp
+	to sizeof a pointer, instead of sizeof the union.
+
+2006-10-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* structs.def: USE_TLS support is now default.
+
+2006-02-03  Roland McGrath  <roland@redhat.com>
+
+	* structs.def: Add a descriptor for pointer.val field of dtv_t.
+	* td_thr_tlsbase.c (td_thr_tlsbase): Extract pointer.val field from
+	DTV slot.
+
+2004-09-09  Roland McGrath  <roland@redhat.com>
+
+	* td_ta_map_lwp2thr.c (td_ta_map_lwp2thr): Don't abort if inferior's
+	descriptor is bogus.
+
+2004-05-27  Roland McGrath  <roland@redhat.com>
+
+	* td_thr_validate.c: When we find no threads and the inferior appears
+	uninitialized, validate the main thread as a special case.
+
+2004-05-01  Jakub Jelinek  <jakub@redhat.com>
+
+	* thread_dbP.h (LOG): Use write instead of __libc_write.
+
+2004-04-03  Ulrich Drepper  <drepper@redhat.com>
+
+	* td_ta_set_event.c (td_ta_set_event): Initialize copy to avoid
+	warnings.
+
+	* td_ta_thr_iter.c (td_ta_thr_iter): Initialize list to avoid warning.
+	* td_ta_clear_event.c (td_ta_clear_event): Initialize eventmask to
+	avoid warning.
+	* td_ta_set_event.c (td_ta_set_event): Likewise.
+
+2004-03-24  Roland McGrath  <roland@redhat.com>
+
+	* fetch-value.c (_td_locate_field): Cast DB_DESC_OFFSET to int32_t.
+	* thread_dbP.h (DB_DESC_OFFSET): Remove cast from definition.
+
+2004-03-13  Jakub Jelinek  <jakub@redhat.com>
+
+	* db_info.c: Don't use TLS_TP_OFFSET in the #if, but
+	TLS_TCB_SIZE == 0 ?: in the DESC macro.
+
+2004-03-12  Roland McGrath  <roland@redhat.com>
+
+	* db_info.c [TLS_DTV_AT_TP && TLS_TP_OFFSET > 0]
+	(_thread_db_pthread_dtvp): Define differently for this case (PowerPC).
+
+2003-12-11  Ulrich Weigand  <uweigand@de.ibm.com>
+
+	* db_info.c (REGISTER): Add bit size of thread register as second
+	parameter to REGISTER macro.
+
+2003-12-02  Roland McGrath  <roland@redhat.com>
+
+	* thread_dbP.h (DB_FUNCTION): New macro.
+	* structs.def: Use it for __nptl_create_event and __nptl_death_event.
+	* db_info.c (DB_FUNCTION): New macro.
+	* td_symbol_list.c (DB_FUNCTION): New macro, prepend "." to symbol
+	name under [HAVE_ASM_GLOBAL_DOT_NAME].
+	(td_lookup) [HAVE_ASM_GLOBAL_DOT_NAME]: If lookup fails with PS_NOSYM
+	and name starts with a dot, try it without the dot.
+
+2003-09-08  Roland McGrath  <roland@redhat.com>
+
+	* td_thr_get_info.c (td_thr_get_info): Cast th_unique to thread_t.
+
+2003-08-22  Roland McGrath  <roland@redhat.com>
+
+	* fetch-value.c (_td_check_sizeof, _td_locate_field): Return
+	TD_NOCAPAB for PS_NOSYM, instead of vanilla TD_ERR.
+	* td_thr_tls_get_addr.c (td_thr_tls_get_addr): Return TD_NOAPLIC when
+	DB_GET_FIELD returns TD_NOCAPAB.
+
+	* thread_db.h (td_thr_tls_get_addr): Use psaddr_t in signature.
+	* structs.def [USE_TLS]: Add DB_STRUCT_FIELD (link_map, l_tls_modid).
+	* db_info.c (link_map): Typedef it.
+	* td_thr_tls_get_addr.c (td_thr_tls_get_addr): Rewritten.
+
+2003-08-14  Roland McGrath  <roland@redhat.com>
+
+	* thread_dbP.h: Mostly rewritten with many new macros and decls.
+	* td_ta_new.c (td_ta_new): Don't cache a lot of symbol values.
+	* structs.def: New file.
+	* db_info.c: New file.
+	* td_symbol_list.c (symbol_list_arr): Define with structs.def macros.
+	* td_ta_clear_event.c: Rewritten.
+	* td_ta_event_addr.c: Rewritten.
+	* td_ta_event_getmsg.c: Rewritten.
+	* td_ta_get_nthreads.c: Rewritten.
+	* td_ta_map_lwp2thr.c: New file.
+	* td_ta_set_event.c: Rewritten.
+	* td_ta_thr_iter.c: Rewritten.
+	* td_ta_tsd_iter.c: Rewritten.
+	* td_thr_clear_event.c: Rewritten.
+	* td_thr_event_enable.c: Rewritten.
+	* td_thr_event_getmsg.c: Rewritten.
+	* td_thr_get_info.c: Rewritten.
+	* td_thr_getfpregs.c: Rewritten.
+	* td_thr_getgregs.c: Rewritten.
+	* td_thr_set_event.c: Rewritten.
+	* td_thr_setfpregs.c: Rewritten.
+	* td_thr_setgregs.c: Rewritten.
+	* td_thr_tlsbase.c: Rewritten.
+	* td_thr_tsd.c: Rewritten.
+	* td_thr_validate.c: Rewritten.
+	* Makefile (distribute): Add them.
+	* fetch-value.c: New file.
+	* Makefile (libthread_db-routines): Add it.
+
+	* thread_db.h (td_err_e): Comment fix.
+
+2003-08-05  Roland McGrath  <roland@redhat.com>
+
+	* thread_dbP.h (td_lookup): Add attribute_hidden to decl.
+
+2003-08-04  Roland McGrath  <roland@redhat.com>
+
+	* td_ta_clear_event.c (td_ta_clear_event): Fix sizes in ps_* calls.
+
+2003-06-23  Roland McGrath  <roland@redhat.com>
+
+	* proc_service.h: Cosmetic and comment fixes.
+
+2003-06-19  Roland McGrath  <roland@redhat.com>
+
+	* td_thr_event_enable.c (td_thr_event_enable): Use proper type `bool'
+	for value written into inferior's `report_events'.
+
+2003-03-18  Roland McGrath  <roland@redhat.com>
+
+	* td_thr_event_getmsg.c (td_thr_event_getmsg): Splice the thread out
+	of the ->nextevent linkage.
+
+	* td_ta_event_getmsg.c (td_ta_event_getmsg): Runtime error instead of
+	assert for reading TD_EVENT_NONE.  Clear the event buffer after
+	reading it.  Add a sanity check for foo->nextevent = foo.
+
+2003-03-15  Roland McGrath  <roland@redhat.com>
+
+	* thread_db.h (td_err_e): Add TD_NOTLS and TD_TLSDEFER.
+	(td_thr_tlsbase): Declare it.
+	* td_thr_tlsbase.c: New file.
+	* Makefile (libthread_db-routines): Add it.
+	* Versions (libthread_db: GLIBC_2.3.3): New set, add td_thr_tlsbase.
+	* td_thr_tls_get_addr.c (td_thr_tls_get_addr): Use td_thr_tlsbase.
+
+2003-03-14  Roland McGrath  <roland@redhat.com>
+
+	* td_thr_tls_get_addr.c (td_thr_tls_get_addr): Use `header.' prefix.
+
+2003-03-10  Roland McGrath  <roland@redhat.com>
+
+	* td_ta_thr_iter.c (iterate_thread_list): Don't use `header.data.'
+	prefix for `struct pthread' members.
+	* td_thr_validate.c (check_thread_list): Likewise.
+	* td_thr_tls_get_addr.c (td_thr_tls_get_addr): Likewise.
+
+2003-03-03  Roland McGrath  <roland@redhat.com>
+
+	* td_thr_tls_get_addr.c (td_thr_tls_get_addr): Handle TLS_DTV_AT_TP.
+
+2003-02-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* td_symbol_list.c: New symbol name for SYM_PTHREAD_NTHREADS.
+
+2003-01-07  Jakub Jelinek  <jakub@redhat.com>
+
+	* td_ta_event_getmsg.c: Include assert.h.
+
+-2003-01-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile (libthread_db.so-no-z-defs): Define.
+
+2003-01-03  Roland McGrath  <roland@redhat.com>
+
+	* td_thr_setgregs.c (td_thr_setgregs): *_BIT -> *_BITMASK
+	* td_thr_setfpregs.c (td_thr_setfpregs): Likewise.
+	* td_thr_get_info.c (td_thr_get_info): Likewise.
+	* td_thr_getgregs.c (td_thr_getgregs): Likewise.
+	* td_thr_getfpregs.c (td_thr_getfpregs): Likewise.
+	* td_ta_thr_iter.c (iterate_thread_list): Likewise.
+
+2002-12-12  Roland McGrath  <roland@redhat.com>
+
+	* td_ta_thr_iter.c (iterate_thread_list): Handle special case of
+	uninitialized __stack_user (zeros), hard-wire just the main thread.
+
+	* td_thr_get_info.c (td_thr_get_info): Fix ti_lid initialization.
+
+2002-12-06  Roland McGrath  <roland@redhat.com>
+
+	* td_ta_event_getmsg.c (td_ta_event_getmsg): Write the NEXT pointer
+	into the inferior's __pthread_last_event variable, not a word from
+	an inferior address used in the parent.  Pass the address of a
+	null word to ps_pdwrite, not a null pointer.
+
+2002-12-04  Roland McGrath  <roland@redhat.com>
+
+	* td_thr_get_info.c (td_thr_get_info): ti_tid is pthread_t, not a PID.
+
+	* thread_db.h (td_thrinfo_t): Comment fix.
+
+	* td_ta_map_lwp2thr.c: Moved to ../nptl/sysdeps/i386/.
+
+2002-12-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* td_ta_thr_iter.c (iterate_thread_list): At end of iteration read
+	pointer to the next element from inferior.
+
+2002-12-02  Roland McGrath  <roland@redhat.com>
+
+	* td_symbol_list.c (symbol_list_arr): pthread_keys -> __pthread_keys
+
+	* td_ta_map_lwp2thr.c (td_ta_map_lwp2thr): Fetch inferior registers to
+	see its %gs value, not our own.
diff --git a/REORG.TODO/nptl_db/Makefile b/REORG.TODO/nptl_db/Makefile
new file mode 100644
index 0000000000..8dc67f4e8d
--- /dev/null
+++ b/REORG.TODO/nptl_db/Makefile
@@ -0,0 +1,63 @@
+# Copyright (C) 2002-2017 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+# Makefile for NPTL debug library subdirectory of GNU C Library.
+
+subdir          := nptl_db
+
+include ../Makeconfig
+
+nptl_db-version = 1.0
+
+extra-libs = libthread_db
+extra-libs-others := $(extra-libs)
+
+headers         = proc_service.h thread_db.h sys/procfs.h
+
+libthread_db-routines = td_init td_log td_ta_new td_ta_delete \
+			td_ta_get_nthreads td_ta_get_ph \
+			td_ta_map_id2thr td_ta_map_lwp2thr \
+			td_ta_thr_iter td_ta_tsd_iter \
+			td_thr_get_info td_thr_getfpregs td_thr_getgregs \
+			td_thr_getxregs td_thr_getxregsize td_thr_setfpregs \
+			td_thr_setgregs td_thr_setprio td_thr_setsigpending \
+			td_thr_setxregs td_thr_sigsetmask td_thr_tsd \
+			td_thr_validate td_thr_dbsuspend td_thr_dbresume \
+			td_ta_setconcurrency td_ta_enable_stats \
+			td_ta_reset_stats td_ta_get_stats td_ta_event_addr \
+			td_thr_event_enable td_thr_set_event \
+			td_thr_clear_event td_thr_event_getmsg \
+			td_ta_set_event td_ta_event_getmsg \
+			td_ta_clear_event td_symbol_list \
+			td_thr_tlsbase td_thr_tls_get_addr \
+			fetch-value
+
+libthread_db-inhibit-o = $(filter-out .os,$(object-suffixes))
+
+# The ps_* callback functions are not defined.
+libthread_db.so-no-z-defs = yes
+
+tests-special += $(objpfx)db-symbols.out
+
+include ../Rules
+
+$(objpfx)db-symbols.out: $(objpfx)db-symbols.v.i \
+			 $(common-objpfx)nptl/libpthread.so
+	LC_ALL=C $(READELF) -W -s $(filter %.so,$^) | $(AWK) -f $< > $@; \
+	$(evaluate-test)
+
+$(objpfx)db-symbols.v.i: db-symbols.awk
diff --git a/REORG.TODO/nptl_db/Versions b/REORG.TODO/nptl_db/Versions
new file mode 100644
index 0000000000..063493c676
--- /dev/null
+++ b/REORG.TODO/nptl_db/Versions
@@ -0,0 +1,24 @@
+libthread_db {
+  GLIBC_2.1.3 {
+    # t*
+    td_init; td_log; td_ta_clear_event; td_ta_delete; td_ta_enable_stats;
+    td_ta_event_addr; td_ta_event_getmsg; td_ta_get_nthreads; td_ta_get_ph;
+    td_ta_get_stats; td_ta_map_id2thr; td_ta_map_lwp2thr; td_ta_new;
+    td_ta_reset_stats; td_ta_set_event; td_ta_setconcurrency;
+    td_ta_thr_iter; td_ta_tsd_iter; td_thr_clear_event; td_thr_dbresume;
+    td_thr_dbsuspend; td_thr_event_enable; td_thr_event_getmsg;
+    td_thr_get_info; td_thr_getfpregs; td_thr_getgregs; td_thr_getxregs;
+    td_thr_getxregsize; td_thr_set_event; td_thr_setfpregs; td_thr_setgregs;
+    td_thr_setprio; td_thr_setsigpending; td_thr_setxregs; td_thr_sigsetmask;
+    td_thr_tsd; td_thr_validate;
+  }
+  GLIBC_2.2.3 {
+    td_symbol_list;
+  }
+  GLIBC_2.3 {
+    td_thr_tls_get_addr;
+  }
+  GLIBC_2.3.3 {
+    td_thr_tlsbase;
+  }
+}
diff --git a/REORG.TODO/nptl_db/db-symbols.awk b/REORG.TODO/nptl_db/db-symbols.awk
new file mode 100644
index 0000000000..eb089e188a
--- /dev/null
+++ b/REORG.TODO/nptl_db/db-symbols.awk
@@ -0,0 +1,47 @@
+# This script processes the output of 'readelf -W -s' on the libpthread.so
+# we've just built.  It checks for all the symbols used in td_symbol_list.
+
+BEGIN {
+%define DB_RTLD_VARIABLE(name) /* Nothing. */
+%define DB_MAIN_VARIABLE(name) /* Nothing. */
+%define DB_LOOKUP_NAME(idx, name)		required[STRINGIFY (name)] = 1;
+%define DB_LOOKUP_NAME_TH_UNIQUE(idx, name)	th_unique[STRINGIFY (name)] = 1;
+%include "db-symbols.h"
+
+   in_symtab = 0;
+}
+
+/Symbol table '.symtab'/ { in_symtab=1; next }
+NF == 0 { in_symtab=0; next }
+
+!in_symtab { next }
+
+NF >= 8 && $7 != "UND" { seen[$NF] = 1 }
+
+END {
+  status = 0;
+
+  for (s in required) {
+    if (s in seen) print s, "ok";
+    else {
+      status = 1;
+      print s, "***MISSING***";
+    }
+  }
+
+  any = "";
+  for (s in th_unique) {
+    if (s in seen) {
+      any = s;
+      break;
+    }
+  }
+  if (any)
+    print "th_unique:", any;
+  else {
+    status = 1;
+    print "th_unique:", "***MISSING***";
+  }
+
+  exit(status);
+}
diff --git a/REORG.TODO/nptl_db/db-symbols.h b/REORG.TODO/nptl_db/db-symbols.h
new file mode 100644
index 0000000000..1572ed58ba
--- /dev/null
+++ b/REORG.TODO/nptl_db/db-symbols.h
@@ -0,0 +1,51 @@
+/* List of symbols in libpthread examined by libthread_db.
+   Copyright (C) 2009-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define DOT(x)	x		/* No prefix.  */
+
+#define STRINGIFY(name)		STRINGIFY_1(name)
+#define STRINGIFY_1(name)	#name
+
+#define DB_STRUCT(type)	\
+  DB_LOOKUP_NAME (SYM_SIZEOF_##type, _thread_db_sizeof_##type)
+#define DB_STRUCT_FIELD(type, field) \
+  DB_LOOKUP_NAME (SYM_##type##_FIELD_##field, _thread_db_##type##_##field)
+#define DB_SYMBOL(name) \
+  DB_LOOKUP_NAME (SYM_##name, name)
+#define DB_FUNCTION(name) \
+  DB_LOOKUP_NAME (SYM_##name, DOT (name))
+#define DB_VARIABLE(name) \
+  DB_LOOKUP_NAME (SYM_##name, name) \
+  DB_LOOKUP_NAME (SYM_DESC_##name, _thread_db_##name)
+
+# include "structs.def"
+
+# undef DB_STRUCT
+# undef DB_FUNCTION
+# undef DB_SYMBOL
+# undef DB_VARIABLE
+# undef DOT
+
+DB_LOOKUP_NAME_TH_UNIQUE (SYM_TH_UNIQUE_REGISTER64, _thread_db_register64)
+DB_LOOKUP_NAME_TH_UNIQUE (SYM_TH_UNIQUE_REGISTER32, _thread_db_register32)
+DB_LOOKUP_NAME_TH_UNIQUE (SYM_TH_UNIQUE_CONST_THREAD_AREA,
+			  _thread_db_const_thread_area)
+DB_LOOKUP_NAME_TH_UNIQUE (SYM_TH_UNIQUE_REGISTER32_THREAD_AREA,
+			  _thread_db_register32_thread_area)
+DB_LOOKUP_NAME_TH_UNIQUE (SYM_TH_UNIQUE_REGISTER64_THREAD_AREA,
+			  _thread_db_register64_thread_area)
diff --git a/REORG.TODO/nptl_db/db_info.c b/REORG.TODO/nptl_db/db_info.c
new file mode 100644
index 0000000000..cdf966632b
--- /dev/null
+++ b/REORG.TODO/nptl_db/db_info.c
@@ -0,0 +1,109 @@
+/* This file is included by pthread_create.c to define in libpthread
+   all the magic symbols required by libthread_db.
+
+   Copyright (C) 2003-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdint.h>
+#include "thread_dbP.h"
+#include <tls.h>
+#include <ldsodefs.h>
+
+typedef struct pthread pthread;
+typedef struct pthread_key_struct pthread_key_struct;
+typedef struct pthread_key_data pthread_key_data;
+typedef struct
+{
+  struct pthread_key_data data[PTHREAD_KEY_2NDLEVEL_SIZE];
+}
+pthread_key_data_level2;
+
+typedef struct
+{
+  union dtv dtv[UINT32_MAX / 2 / sizeof (union dtv)]; /* No constant bound.  */
+} dtv;
+
+typedef struct link_map link_map;
+typedef struct rtld_global rtld_global;
+typedef struct dtv_slotinfo_list dtv_slotinfo_list;
+typedef struct dtv_slotinfo dtv_slotinfo;
+
+/* Actually static in nptl/init.c, but we only need it for typeof.  */
+extern bool __nptl_initial_report_events;
+
+#define schedparam_sched_priority schedparam.sched_priority
+
+#define eventbuf_eventmask eventbuf.eventmask
+#define eventbuf_eventmask_event_bits eventbuf.eventmask.event_bits
+
+#define DESC(name, offset, obj) \
+  DB_DEFINE_DESC (name, 8 * sizeof (obj), 1, offset);
+#define ARRAY_DESC(name, offset, obj) \
+  DB_DEFINE_DESC (name, \
+		  8 * sizeof (obj)[0], sizeof (obj) / sizeof (obj)[0], \
+		  offset);
+
+#if TLS_TCB_AT_TP
+# define dtvp header.dtv
+#elif TLS_DTV_AT_TP
+/* Special case hack.  If TLS_TCB_SIZE == 0 (on PowerPC), there is no TCB
+   containing the DTV at the TP, but actually the TCB lies behind the TP,
+   i.e. at the very end of the area covered by TLS_PRE_TCB_SIZE.  */
+DESC (_thread_db_pthread_dtvp,
+      TLS_PRE_TCB_SIZE + offsetof (tcbhead_t, dtv)
+      - (TLS_TCB_SIZE == 0 ? sizeof (tcbhead_t) : 0), union dtv *)
+#endif
+
+
+#define DB_STRUCT(type) \
+  const uint32_t _thread_db_sizeof_##type = sizeof (type);
+#define DB_STRUCT_FIELD(type, field) \
+  DESC (_thread_db_##type##_##field, \
+	offsetof (type, field), ((type *) 0)->field)
+#define DB_STRUCT_ARRAY_FIELD(type, field) \
+  ARRAY_DESC (_thread_db_##type##_##field, \
+	      offsetof (type, field), ((type *) 0)->field)
+#define DB_VARIABLE(name) DESC (_thread_db_##name, 0, name)
+#define DB_ARRAY_VARIABLE(name) ARRAY_DESC (_thread_db_##name, 0, name)
+#define DB_SYMBOL(name)	/* Nothing.  */
+#define DB_FUNCTION(name) /* Nothing.  */
+#include "structs.def"
+#undef DB_STRUCT
+#undef DB_STRUCT_FIELD
+#undef DB_SYMBOL
+#undef DB_FUNCTION
+#undef DB_VARIABLE
+#undef DESC
+
+
+
+#ifdef DB_THREAD_SELF
+# ifdef DB_THREAD_SELF_INCLUDE
+#  include DB_THREAD_SELF_INCLUDE
+# endif
+
+/* This macro is defined in the machine's tls.h using the three below.  */
+# define CONST_THREAD_AREA(bits, value) \
+  const uint32_t _thread_db_const_thread_area = (value);
+# define REGISTER_THREAD_AREA(bits, regofs, scale) \
+  DB_DEFINE_DESC (_thread_db_register##bits##_thread_area, \
+		  bits, (scale), (regofs));
+# define REGISTER(bits, size, regofs, bias) \
+  DB_DEFINE_DESC (_thread_db_register##bits, size, (uint32_t)(bias), (regofs));
+
+DB_THREAD_SELF
+#endif
diff --git a/REORG.TODO/nptl_db/fetch-value.c b/REORG.TODO/nptl_db/fetch-value.c
new file mode 100644
index 0000000000..95a746efd0
--- /dev/null
+++ b/REORG.TODO/nptl_db/fetch-value.c
@@ -0,0 +1,285 @@
+/* Helper routines for libthread_db.
+   Copyright (C) 2003-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+#include <byteswap.h>
+#include <assert.h>
+#include <stdint.h>
+
+td_err_e
+_td_check_sizeof (td_thragent_t *ta, uint32_t *sizep, int sizep_name)
+{
+  if (*sizep == 0)
+    {
+      psaddr_t descptr;
+      ps_err_e err = td_lookup (ta->ph, sizep_name, &descptr);
+      if (err == PS_NOSYM)
+	return TD_NOCAPAB;
+      if (err == PS_OK)
+	err = ps_pdread (ta->ph, descptr, sizep, sizeof *sizep);
+      if (err != PS_OK)
+	return TD_ERR;
+      if (*sizep & 0xff000000U)
+	*sizep = bswap_32 (*sizep);
+    }
+  return TD_OK;
+}
+
+td_err_e
+_td_locate_field (td_thragent_t *ta,
+		  db_desc_t desc, int descriptor_name,
+		  psaddr_t idx, psaddr_t *address)
+{
+  uint32_t elemsize;
+
+  if (DB_DESC_SIZE (desc) == 0)
+    {
+      /* Read the information about this field from the inferior.  */
+      psaddr_t descptr;
+      ps_err_e err = td_lookup (ta->ph, descriptor_name, &descptr);
+      if (err == PS_NOSYM)
+	return TD_NOCAPAB;
+      if (err == PS_OK)
+	err = ps_pdread (ta->ph, descptr, desc, DB_SIZEOF_DESC);
+      if (err != PS_OK)
+	return TD_ERR;
+      if (DB_DESC_SIZE (desc) == 0)
+	return TD_DBERR;
+      if (DB_DESC_SIZE (desc) & 0xff000000U)
+	{
+	  /* Byte-swap these words, though we leave the size word
+	     in native order as the handy way to distinguish.  */
+	  DB_DESC_OFFSET (desc) = bswap_32 (DB_DESC_OFFSET (desc));
+	  DB_DESC_NELEM (desc) = bswap_32 (DB_DESC_NELEM (desc));
+	}
+    }
+
+  if (idx != 0 && DB_DESC_NELEM (desc) != 0
+      && idx - (psaddr_t) 0 > DB_DESC_NELEM (desc))
+    /* This is an internal indicator to callers with nonzero IDX
+       that the IDX value is too big.  */
+    return TD_NOAPLIC;
+
+  elemsize = DB_DESC_SIZE (desc);
+  if (elemsize & 0xff000000U)
+    elemsize = bswap_32 (elemsize);
+
+  *address += (int32_t) DB_DESC_OFFSET (desc);
+  *address += (elemsize / 8 * (idx - (psaddr_t) 0));
+  return TD_OK;
+}
+
+td_err_e
+_td_fetch_value (td_thragent_t *ta,
+		 db_desc_t desc, int descriptor_name,
+		 psaddr_t idx, psaddr_t address,
+		 psaddr_t *result)
+{
+  ps_err_e err;
+  td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
+  if (terr != TD_OK)
+    return terr;
+
+  if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
+    {
+      uint8_t value;
+      err = ps_pdread (ta->ph, address, &value, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == 32)
+    {
+      uint32_t value;
+      err = ps_pdread (ta->ph, address, &value, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == 64)
+    {
+      uint64_t value;
+      if (sizeof (psaddr_t) < 8)
+	return TD_NOCAPAB;
+      err = ps_pdread (ta->ph, address, &value, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (32))
+    {
+      uint32_t value;
+      err = ps_pdread (ta->ph, address, &value, sizeof value);
+      value = bswap_32 (value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (64))
+    {
+      uint64_t value;
+      if (sizeof (psaddr_t) < 8)
+	return TD_NOCAPAB;
+      err = ps_pdread (ta->ph, address, &value, sizeof value);
+      value = bswap_64 (value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else
+    return TD_DBERR;
+
+  return err == PS_OK ? TD_OK : TD_ERR;
+}
+
+
+td_err_e
+_td_store_value (td_thragent_t *ta,
+		 uint32_t desc[2], int descriptor_name, psaddr_t idx,
+		 psaddr_t address, psaddr_t widened_value)
+{
+  ps_err_e err;
+  td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
+  if (terr != TD_OK)
+    return terr;
+
+  if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
+    {
+      uint8_t value = widened_value - (psaddr_t) 0;
+      err = ps_pdwrite (ta->ph, address, &value, sizeof value);
+    }
+  else if (DB_DESC_SIZE (desc) == 32)
+    {
+      uint32_t value = widened_value - (psaddr_t) 0;
+      err = ps_pdwrite (ta->ph, address, &value, sizeof value);
+    }
+  else if (DB_DESC_SIZE (desc) == 64)
+    {
+      uint64_t value = widened_value - (psaddr_t) 0;
+      if (sizeof (psaddr_t) < 8)
+	return TD_NOCAPAB;
+      err = ps_pdwrite (ta->ph, address, &value, sizeof value);
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (32))
+    {
+      uint32_t value = widened_value - (psaddr_t) 0;
+      value = bswap_32 (value);
+      err = ps_pdwrite (ta->ph, address, &value, sizeof value);
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (64))
+    {
+      uint64_t value = widened_value - (psaddr_t) 0;
+      if (sizeof (psaddr_t) < 8)
+	return TD_NOCAPAB;
+      value = bswap_64 (value);
+      err = ps_pdwrite (ta->ph, address, &value, sizeof value);
+    }
+  else
+    return TD_DBERR;
+
+  return err == PS_OK ? TD_OK : TD_ERR;
+}
+
+td_err_e
+_td_fetch_value_local (td_thragent_t *ta,
+		       db_desc_t desc, int descriptor_name, psaddr_t idx,
+		       void *address,
+		       psaddr_t *result)
+{
+  td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
+  if (terr != TD_OK)
+    return terr;
+
+  if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
+    {
+      uint8_t value;
+      memcpy (&value, address, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == 32)
+    {
+      uint32_t value;
+      memcpy (&value, address, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == 64)
+    {
+      uint64_t value;
+      if (sizeof (psaddr_t) < 8)
+	return TD_NOCAPAB;
+      memcpy (&value, address, sizeof value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (32))
+    {
+      uint32_t value;
+      memcpy (&value, address, sizeof value);
+      value = bswap_32 (value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (64))
+    {
+      uint64_t value;
+      if (sizeof (psaddr_t) < 8)
+	return TD_NOCAPAB;
+      memcpy (&value, address, sizeof value);
+      value = bswap_64 (value);
+      *result = (psaddr_t) 0 + value;
+    }
+  else
+    return TD_DBERR;
+
+  return TD_OK;
+}
+
+
+td_err_e
+_td_store_value_local (td_thragent_t *ta,
+		       uint32_t desc[2], int descriptor_name, psaddr_t idx,
+		       void *address, psaddr_t widened_value)
+{
+  td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
+  if (terr != TD_OK)
+    return terr;
+
+  if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
+    {
+      uint8_t value = widened_value - (psaddr_t) 0;
+      memcpy (address, &value, sizeof value);
+    }
+  else if (DB_DESC_SIZE (desc) == 32)
+    {
+      uint32_t value = widened_value - (psaddr_t) 0;
+      memcpy (address, &value, sizeof value);
+    }
+  else if (DB_DESC_SIZE (desc) == 64)
+    {
+      uint64_t value = widened_value - (psaddr_t) 0;
+      if (sizeof (psaddr_t) < 8)
+	return TD_NOCAPAB;
+      memcpy (address, &value, sizeof value);
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (32))
+    {
+      uint32_t value = widened_value - (psaddr_t) 0;
+      value = bswap_32 (value);
+      memcpy (address, &value, sizeof value);
+    }
+  else if (DB_DESC_SIZE (desc) == bswap_32 (64))
+    {
+      uint64_t value = widened_value - (psaddr_t) 0;
+      if (sizeof (psaddr_t) < 8)
+	return TD_NOCAPAB;
+      value = bswap_64 (value);
+      memcpy (address, &value, sizeof value);
+    }
+  else
+    return TD_DBERR;
+
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/proc_service.h b/REORG.TODO/nptl_db/proc_service.h
new file mode 100644
index 0000000000..4ddeef13ff
--- /dev/null
+++ b/REORG.TODO/nptl_db/proc_service.h
@@ -0,0 +1,95 @@
+/* Callback interface for libthread_db, functions users must define.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _PROC_SERVICE_H
+#define _PROC_SERVICE_H 1
+
+/* The definitions in this file must correspond to those in the debugger.  */
+#include <sys/procfs.h>
+
+__BEGIN_DECLS
+
+/* Functions in this interface return one of these status codes.  */
+typedef enum
+{
+  PS_OK,		/* Generic "call succeeded".  */
+  PS_ERR,		/* Generic error. */
+  PS_BADPID,		/* Bad process handle.  */
+  PS_BADLID,		/* Bad LWP identifier.  */
+  PS_BADADDR,		/* Bad address.  */
+  PS_NOSYM,		/* Could not find given symbol.  */
+  PS_NOFREGS		/* FPU register set not available for given LWP.  */
+} ps_err_e;
+
+
+/* This type is opaque in this interface.
+   It's defined by the user of libthread_db.  */
+struct ps_prochandle;
+
+
+/* Read or write process memory at the given address.  */
+extern ps_err_e ps_pdread (struct ps_prochandle *,
+			   psaddr_t, void *, size_t);
+extern ps_err_e ps_pdwrite (struct ps_prochandle *,
+			    psaddr_t, const void *, size_t);
+extern ps_err_e ps_ptread (struct ps_prochandle *,
+			   psaddr_t, void *, size_t);
+extern ps_err_e ps_ptwrite (struct ps_prochandle *,
+			    psaddr_t, const void *, size_t);
+
+
+/* Get and set the given LWP's general or FPU register set.  */
+extern ps_err_e ps_lgetregs (struct ps_prochandle *,
+			     lwpid_t, prgregset_t);
+extern ps_err_e ps_lsetregs (struct ps_prochandle *,
+			     lwpid_t, const prgregset_t);
+extern ps_err_e ps_lgetfpregs (struct ps_prochandle *,
+			       lwpid_t, prfpregset_t *);
+extern ps_err_e ps_lsetfpregs (struct ps_prochandle *,
+			       lwpid_t, const prfpregset_t *);
+
+/* Return the PID of the process.  */
+extern pid_t ps_getpid (struct ps_prochandle *);
+
+/* Fetch the special per-thread address associated with the given LWP.
+   This call is only used on a few platforms (most use a normal register).
+   The meaning of the `int' parameter is machine-dependent.  */
+extern ps_err_e ps_get_thread_area (struct ps_prochandle *,
+				    lwpid_t, int, psaddr_t *);
+
+
+/* Look up the named symbol in the named DSO in the symbol tables
+   associated with the process being debugged, filling in *SYM_ADDR
+   with the corresponding run-time address.  */
+extern ps_err_e ps_pglobal_lookup (struct ps_prochandle *,
+				   const char *object_name,
+				   const char *sym_name,
+				   psaddr_t *sym_addr);
+
+
+/* Stop or continue the entire process.  */
+extern ps_err_e ps_pstop (struct ps_prochandle *);
+extern ps_err_e ps_pcontinue (struct ps_prochandle *);
+
+/* Stop or continue the given LWP alone.  */
+extern ps_err_e ps_lstop (struct ps_prochandle *, lwpid_t);
+extern ps_err_e ps_lcontinue (struct ps_prochandle *, lwpid_t);
+
+__END_DECLS
+
+#endif /* proc_service.h */
diff --git a/REORG.TODO/nptl_db/shlib-versions b/REORG.TODO/nptl_db/shlib-versions
new file mode 100644
index 0000000000..cf5a9e9694
--- /dev/null
+++ b/REORG.TODO/nptl_db/shlib-versions
@@ -0,0 +1,2 @@
+# The thread debug library
+libthread_db=1
diff --git a/REORG.TODO/nptl_db/structs.def b/REORG.TODO/nptl_db/structs.def
new file mode 100644
index 0000000000..8a65afd658
--- /dev/null
+++ b/REORG.TODO/nptl_db/structs.def
@@ -0,0 +1,123 @@
+/* List of types and symbols in libpthread examined by libthread_db.
+   Copyright (C) 2003-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef DB_STRUCT_ARRAY_FIELD
+# define DB_STRUCT_ARRAY_FIELD(type, field) DB_STRUCT_FIELD (type, field)
+# define DB_ARRAY_VARIABLE(name) DB_VARIABLE (name)
+# define STRUCTS_DEF_DEFAULTS 1
+#endif
+
+#ifndef DB_RTLD_VARIABLE
+# define DB_RTLD_VARIABLE(name) DB_VARIABLE (name)
+#endif
+
+#ifndef DB_MAIN_VARIABLE
+# define DB_MAIN_VARIABLE(name) DB_VARIABLE (name)
+#endif
+
+#ifndef DB_RTLD_GLOBAL_FIELD
+# if !IS_IN (libpthread)
+#  define DB_RTLD_GLOBAL_FIELD(field)		\
+  DB_STRUCT_FIELD (rtld_global, _##field)	\
+  DB_MAIN_VARIABLE (_##field)
+# elif defined SHARED
+#  define DB_RTLD_GLOBAL_FIELD(field)		\
+  DB_STRUCT_FIELD (rtld_global, _##field)
+# else
+#  define DB_RTLD_GLOBAL_FIELD(field)		\
+  DB_MAIN_VARIABLE (_##field)
+# endif
+#endif /* DB_RTLD_GLOBAL_FIELD */
+
+DB_STRUCT (pthread)
+DB_STRUCT_FIELD (pthread, list)
+DB_STRUCT_FIELD (pthread, report_events)
+DB_STRUCT_FIELD (pthread, tid)
+DB_STRUCT_FIELD (pthread, start_routine)
+DB_STRUCT_FIELD (pthread, cancelhandling)
+DB_STRUCT_FIELD (pthread, schedpolicy)
+DB_STRUCT_FIELD (pthread, schedparam_sched_priority)
+DB_STRUCT_FIELD (pthread, specific)
+DB_STRUCT_FIELD (pthread, eventbuf)
+DB_STRUCT_FIELD (pthread, eventbuf_eventmask)
+DB_STRUCT_ARRAY_FIELD (pthread, eventbuf_eventmask_event_bits)
+DB_STRUCT_FIELD (pthread, nextevent)
+
+DB_STRUCT (list_t)
+DB_STRUCT_FIELD (list_t, next)
+DB_STRUCT_FIELD (list_t, prev)
+
+DB_STRUCT (td_thr_events_t)
+DB_STRUCT_ARRAY_FIELD (td_thr_events_t, event_bits)
+
+DB_STRUCT (td_eventbuf_t)
+DB_STRUCT_FIELD (td_eventbuf_t, eventnum)
+DB_STRUCT_FIELD (td_eventbuf_t, eventdata)
+
+DB_SYMBOL (stack_used)
+DB_SYMBOL (__stack_user)
+DB_SYMBOL (nptl_version)
+DB_FUNCTION (__nptl_create_event)
+DB_FUNCTION (__nptl_death_event)
+DB_SYMBOL (__nptl_threads_events)
+DB_VARIABLE (__nptl_nthreads)
+DB_VARIABLE (__nptl_last_event)
+DB_VARIABLE (__nptl_initial_report_events)
+
+DB_ARRAY_VARIABLE (__pthread_keys)
+DB_STRUCT (pthread_key_struct)
+DB_STRUCT_FIELD (pthread_key_struct, seq)
+DB_STRUCT_FIELD (pthread_key_struct, destr)
+
+DB_STRUCT (pthread_key_data)
+DB_STRUCT_FIELD (pthread_key_data, seq)
+DB_STRUCT_FIELD (pthread_key_data, data)
+DB_STRUCT (pthread_key_data_level2)
+DB_STRUCT_ARRAY_FIELD (pthread_key_data_level2, data)
+
+DB_STRUCT_FIELD (link_map, l_tls_modid)
+DB_STRUCT_FIELD (link_map, l_tls_offset)
+
+DB_STRUCT_ARRAY_FIELD (dtv, dtv)
+#define pointer_val pointer.val /* Field of anonymous struct in dtv_t.  */
+DB_STRUCT_FIELD (dtv_t, pointer_val)
+DB_STRUCT_FIELD (dtv_t, counter)
+#if !IS_IN (libpthread) || TLS_TCB_AT_TP
+DB_STRUCT_FIELD (pthread, dtvp)
+#endif
+
+#if !(IS_IN (libpthread) && !defined SHARED)
+DB_STRUCT (rtld_global)
+DB_RTLD_VARIABLE (_rtld_global)
+#endif
+DB_RTLD_GLOBAL_FIELD (dl_tls_dtv_slotinfo_list)
+
+DB_STRUCT (dtv_slotinfo_list)
+DB_STRUCT_FIELD (dtv_slotinfo_list, len)
+DB_STRUCT_FIELD (dtv_slotinfo_list, next)
+DB_STRUCT_ARRAY_FIELD (dtv_slotinfo_list, slotinfo)
+
+DB_STRUCT (dtv_slotinfo)
+DB_STRUCT_FIELD (dtv_slotinfo, gen)
+DB_STRUCT_FIELD (dtv_slotinfo, map)
+
+#ifdef STRUCTS_DEF_DEFAULTS
+# undef DB_STRUCT_ARRAY_FIELD
+# undef DB_ARRAY_VARIABLE
+# undef STRUCTS_DEF_DEFAULTS
+#endif
diff --git a/REORG.TODO/nptl_db/td_init.c b/REORG.TODO/nptl_db/td_init.c
new file mode 100644
index 0000000000..6fbd925810
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_init.c
@@ -0,0 +1,31 @@
+/* Initialization function of thread debugger support library.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+int __td_debug;
+
+
+td_err_e
+td_init (void)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_init");
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_log.c b/REORG.TODO/nptl_db/td_log.c
new file mode 100644
index 0000000000..c6c2b0f837
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_log.c
@@ -0,0 +1,31 @@
+/* Noop, left for historical reasons.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_log (void)
+{
+  /* This interface is deprecated in the Sun interface.  We provide it
+     for compatibility but don't do anything ourself.  We might in
+     future do some logging if this seems reasonable.  */
+  LOG ("td_log");
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_symbol_list.c b/REORG.TODO/nptl_db/td_symbol_list.c
new file mode 100644
index 0000000000..8d3f924bee
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_symbol_list.c
@@ -0,0 +1,51 @@
+/* Return list of symbols the library can request.
+   Copyright (C) 2001-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include "thread_dbP.h"
+
+static const char *symbol_list_arr[] =
+{
+# define DB_LOOKUP_NAME(idx, name)		[idx] = STRINGIFY (name),
+# define DB_LOOKUP_NAME_TH_UNIQUE(idx, name)	[idx] = STRINGIFY (name),
+# include "db-symbols.h"
+# undef	DB_LOOKUP_NAME
+# undef	DB_LOOKUP_NAME_TH_UNIQUE
+
+  [SYM_NUM_MESSAGES] = NULL
+};
+
+
+const char **
+td_symbol_list (void)
+{
+  return symbol_list_arr;
+}
+
+
+ps_err_e
+td_mod_lookup (struct ps_prochandle *ps, const char *mod,
+	       int idx, psaddr_t *sym_addr)
+{
+  ps_err_e result;
+  assert (idx >= 0 && idx < SYM_NUM_MESSAGES);
+  result = ps_pglobal_lookup (ps, mod, symbol_list_arr[idx], sym_addr);
+
+  return result;
+}
diff --git a/REORG.TODO/nptl_db/td_ta_clear_event.c b/REORG.TODO/nptl_db/td_ta_clear_event.c
new file mode 100644
index 0000000000..74b1d5875b
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_clear_event.c
@@ -0,0 +1,77 @@
+/* Globally disable events.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdint.h>
+#include "thread_dbP.h"
+
+
+td_err_e
+td_ta_clear_event (const td_thragent_t *ta_arg, td_thr_events_t *event)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  td_err_e err;
+  psaddr_t eventmask = 0;
+  void *copy = NULL;
+
+  LOG ("td_ta_clear_event");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* Fetch the old event mask from the inferior and modify it in place.  */
+  err = DB_GET_SYMBOL (eventmask, ta, __nptl_threads_events);
+  if (err == TD_OK)
+    err = DB_GET_STRUCT (copy, ta, eventmask, td_thr_events_t);
+  if (err == TD_OK)
+    {
+      uint32_t idx;
+      for (idx = 0; idx < TD_EVENTSIZE; ++idx)
+	{
+	  psaddr_t word;
+	  uint32_t mask;
+	  err = DB_GET_FIELD_LOCAL (word, ta, copy,
+				    td_thr_events_t, event_bits, idx);
+	  if (err != TD_OK)
+	    break;
+	  mask = (uintptr_t) word;
+	  mask &= ~event->event_bits[idx];
+	  word = (psaddr_t) (uintptr_t) mask;
+	  err = DB_PUT_FIELD_LOCAL (ta, copy,
+				    td_thr_events_t, event_bits, idx, word);
+	  if (err != TD_OK)
+	    break;
+	}
+      if (err == TD_NOAPLIC)
+	{
+	  err = TD_OK;
+	  while (idx < TD_EVENTSIZE)
+	    if (event->event_bits[idx++] != 0)
+	      {
+		err = TD_NOEVENT;
+		break;
+	      }
+	}
+      if (err == TD_OK)
+	/* Now write it back to the inferior.  */
+	err = DB_PUT_STRUCT (ta, eventmask, td_thr_events_t, copy);
+    }
+
+  return err;
+}
diff --git a/REORG.TODO/nptl_db/td_ta_delete.c b/REORG.TODO/nptl_db/td_ta_delete.c
new file mode 100644
index 0000000000..0c9ee91d8b
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_delete.c
@@ -0,0 +1,41 @@
+/* Detach to target process.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdlib.h>
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_ta_delete (td_thragent_t *ta)
+{
+  LOG ("td_ta_delete");
+
+  /* Safety check.  Note that the test will also fail for TA == NULL.  */
+  if (!ta_ok (ta))
+    return TD_BADTA;
+
+  /* Remove the handle from the list.  */
+  list_del (&ta->list);
+
+  /* The handle was allocated in `td_ta_new'.  */
+  free (ta);
+
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_ta_enable_stats.c b/REORG.TODO/nptl_db/td_ta_enable_stats.c
new file mode 100644
index 0000000000..9b8832ec2d
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_enable_stats.c
@@ -0,0 +1,34 @@
+/* Enable collection of statistics for process.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_ta_enable_stats (const td_thragent_t *ta, int enable)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_ta_enable_stats");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_ta_event_addr.c b/REORG.TODO/nptl_db/td_ta_event_addr.c
new file mode 100644
index 0000000000..912069dead
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_event_addr.c
@@ -0,0 +1,60 @@
+/* Get event address.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_ta_event_addr (const td_thragent_t *ta_arg,
+		  td_event_e event, td_notify_t *addr)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  td_err_e err;
+  psaddr_t taddr;
+
+  LOG ("td_ta_event_addr");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  switch (event)
+    {
+    case TD_CREATE:
+      err = DB_GET_SYMBOL (taddr, ta, __nptl_create_event);
+      break;
+
+    case TD_DEATH:
+      err = DB_GET_SYMBOL (taddr, ta, __nptl_death_event);
+      break;
+
+    default:
+      /* Event cannot be handled.  */
+      return TD_NOEVENT;
+    }
+
+  if (err == TD_OK)
+    {
+      /* Success, we got the address.  */
+      addr->type = NOTIFY_BPT;
+      addr->u.bptaddr = taddr;
+    }
+
+  return err;
+}
diff --git a/REORG.TODO/nptl_db/td_ta_event_getmsg.c b/REORG.TODO/nptl_db/td_ta_event_getmsg.c
new file mode 100644
index 0000000000..52e9b91abd
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_event_getmsg.c
@@ -0,0 +1,104 @@
+/* Retrieve event.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+#include <string.h>
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_ta_event_getmsg (const td_thragent_t *ta_arg, td_event_msg_t *msg)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  td_err_e err;
+  psaddr_t eventbuf, eventnum, eventdata;
+  psaddr_t thp, next;
+  void *copy;
+
+  /* XXX I cannot think of another way but using a static variable.  */
+  /* XXX Use at least __thread once it is possible.  */
+  static td_thrhandle_t th;
+
+  LOG ("td_thr_event_getmsg");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* Get the pointer to the thread descriptor with the last event.  */
+  err = DB_GET_VALUE (thp, ta, __nptl_last_event, 0);
+  if (err != TD_OK)
+    return err;
+
+  if (thp == 0)
+    /* Nothing waiting.  */
+    return TD_NOMSG;
+
+  /* Copy the event message buffer in from the inferior.  */
+  err = DB_GET_FIELD_ADDRESS (eventbuf, ta, thp, pthread, eventbuf, 0);
+  if (err == TD_OK)
+    err = DB_GET_STRUCT (copy, ta, eventbuf, td_eventbuf_t);
+  if (err != TD_OK)
+    return err;
+
+  /* Read the event details from the target thread.  */
+  err = DB_GET_FIELD_LOCAL (eventnum, ta, copy, td_eventbuf_t, eventnum, 0);
+  if (err != TD_OK)
+    return err;
+  /* If the structure is on the list there better be an event recorded.  */
+  if ((int) (uintptr_t) eventnum == TD_EVENT_NONE)
+    return TD_DBERR;
+
+  /* Fill the user's data structure.  */
+  err = DB_GET_FIELD_LOCAL (eventdata, ta, copy, td_eventbuf_t, eventdata, 0);
+  if (err != TD_OK)
+    return err;
+
+  /* Generate the thread descriptor.  */
+  th.th_ta_p = (td_thragent_t *) ta;
+  th.th_unique = thp;
+
+  /* Fill the user's data structure.  */
+  msg->msg.data = (uintptr_t) eventdata;
+  msg->event = (uintptr_t) eventnum;
+  msg->th_p = &th;
+
+  /* And clear the event message in the target.  */
+  memset (copy, 0, ta->ta_sizeof_td_eventbuf_t);
+  err = DB_PUT_STRUCT (ta, eventbuf, td_eventbuf_t, copy);
+  if (err != TD_OK)
+    return err;
+
+  /* Get the pointer to the next descriptor with an event.  */
+  err = DB_GET_FIELD (next, ta, thp, pthread, nextevent, 0);
+  if (err != TD_OK)
+    return err;
+
+  /* Store the pointer in the list head variable.  */
+  err = DB_PUT_VALUE (ta, __nptl_last_event, 0, next);
+  if (err != TD_OK)
+    return err;
+
+  if (next != 0)
+    /* Clear the next pointer in the current descriptor.  */
+    err = DB_PUT_FIELD (ta, thp, pthread, nextevent, 0, 0);
+
+  return err;
+}
diff --git a/REORG.TODO/nptl_db/td_ta_get_nthreads.c b/REORG.TODO/nptl_db/td_ta_get_nthreads.c
new file mode 100644
index 0000000000..f7213855d7
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_get_nthreads.c
@@ -0,0 +1,41 @@
+/* Get the number of threads in the process.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+td_err_e
+td_ta_get_nthreads (const td_thragent_t *ta_arg, int *np)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  td_err_e err;
+  psaddr_t n;
+
+  LOG ("td_ta_get_nthreads");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* Access the variable in the inferior that tells us.  */
+  err = DB_GET_VALUE (n, ta, __nptl_nthreads, 0);
+  if (err == TD_OK)
+    *np = (uintptr_t) n;
+
+  return err;
+}
diff --git a/REORG.TODO/nptl_db/td_ta_get_ph.c b/REORG.TODO/nptl_db/td_ta_get_ph.c
new file mode 100644
index 0000000000..9d09540b31
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_get_ph.c
@@ -0,0 +1,35 @@
+/* Get external process handle.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_ta_get_ph (const td_thragent_t *ta, struct ps_prochandle **ph)
+{
+  LOG ("td_ta_get_ph");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  *ph = ta->ph;
+
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_ta_get_stats.c b/REORG.TODO/nptl_db/td_ta_get_stats.c
new file mode 100644
index 0000000000..b1905008c2
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_get_stats.c
@@ -0,0 +1,34 @@
+/* Retrieve statistics for process.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_ta_get_stats (const td_thragent_t *ta, td_ta_stats_t *statsp)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_ta_get_stats");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_ta_map_id2thr.c b/REORG.TODO/nptl_db/td_ta_map_id2thr.c
new file mode 100644
index 0000000000..f112f97236
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_map_id2thr.c
@@ -0,0 +1,37 @@
+/* Map thread ID to thread handle.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_ta_map_id2thr (const td_thragent_t *ta, pthread_t pt, td_thrhandle_t *th)
+{
+  LOG ("td_ta_map_id2thr");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* Create the `td_thrhandle_t' object.  */
+  th->th_ta_p = (td_thragent_t *) ta;
+  th->th_unique = (psaddr_t) pt;
+
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_ta_map_lwp2thr.c b/REORG.TODO/nptl_db/td_ta_map_lwp2thr.c
new file mode 100644
index 0000000000..d34711dffc
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_map_lwp2thr.c
@@ -0,0 +1,208 @@
+/* Which thread is running on an LWP?
+   Copyright (C) 2003-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+#include <stdlib.h>
+#include <byteswap.h>
+#include <sys/procfs.h>
+
+
+td_err_e
+__td_ta_lookup_th_unique (const td_thragent_t *ta_arg,
+			  lwpid_t lwpid, td_thrhandle_t *th)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  ps_err_e err;
+  td_err_e terr;
+  prgregset_t regs;
+  psaddr_t addr;
+
+  if (ta->ta_howto == ta_howto_unknown)
+    {
+      /* We need to read in from the inferior the instructions what to do.  */
+      psaddr_t howto;
+
+      err = td_lookup (ta->ph, SYM_TH_UNIQUE_CONST_THREAD_AREA, &howto);
+      if (err == PS_OK)
+	{
+	  err = ps_pdread (ta->ph, howto,
+			   &ta->ta_howto_data.const_thread_area,
+ 			   sizeof ta->ta_howto_data.const_thread_area);
+	  if (err != PS_OK)
+	    return TD_ERR;
+	  ta->ta_howto = ta_howto_const_thread_area;
+	  if (ta->ta_howto_data.const_thread_area & 0xff000000U)
+	    ta->ta_howto_data.const_thread_area
+	      = bswap_32 (ta->ta_howto_data.const_thread_area);
+	}
+      else
+	{
+	  switch (sizeof (regs[0]))
+	    {
+	    case 8:
+	      err = td_lookup (ta->ph, SYM_TH_UNIQUE_REGISTER64, &howto);
+	      if (err == PS_OK)
+		ta->ta_howto = ta_howto_reg;
+	      else if (err == PS_NOSYM)
+		{
+		  err = td_lookup (ta->ph,
+				   SYM_TH_UNIQUE_REGISTER64_THREAD_AREA,
+				   &howto);
+		  if (err == PS_OK)
+		    ta->ta_howto = ta_howto_reg_thread_area;
+		}
+	      break;
+
+	    case 4:
+	      err = td_lookup (ta->ph, SYM_TH_UNIQUE_REGISTER32, &howto);
+	      if (err == PS_OK)
+		ta->ta_howto = ta_howto_reg;
+	      else if (err == PS_NOSYM)
+		{
+		  err = td_lookup (ta->ph,
+				   SYM_TH_UNIQUE_REGISTER32_THREAD_AREA,
+				   &howto);
+		  if (err == PS_OK)
+		    ta->ta_howto = ta_howto_reg_thread_area;
+		}
+	      break;
+
+	    default:
+	      abort ();
+	      return TD_DBERR;
+	    }
+
+	  if (err != PS_OK)
+	    return TD_DBERR;
+
+	  /* For either of these methods we read in the same descriptor.  */
+	  err = ps_pdread (ta->ph, howto,
+			   ta->ta_howto_data.reg, DB_SIZEOF_DESC);
+	  if (err != PS_OK)
+	    return TD_ERR;
+	  if (DB_DESC_SIZE (ta->ta_howto_data.reg) == 0)
+	    return TD_DBERR;
+	  if (DB_DESC_SIZE (ta->ta_howto_data.reg) & 0xff000000U)
+	    {
+	      /* Byte-swap these words, though we leave the size word
+		 in native order as the handy way to distinguish.  */
+	      DB_DESC_OFFSET (ta->ta_howto_data.reg)
+		= bswap_32 (DB_DESC_OFFSET (ta->ta_howto_data.reg));
+	      DB_DESC_NELEM (ta->ta_howto_data.reg)
+		= bswap_32 (DB_DESC_NELEM (ta->ta_howto_data.reg));
+	    }
+	}
+    }
+
+  switch (ta->ta_howto)
+    {
+    default:
+      return TD_DBERR;
+
+    case ta_howto_reg:
+      /* On most machines, we are just looking at a register.  */
+      if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
+	return TD_ERR;
+      terr = _td_fetch_value_local (ta, ta->ta_howto_data.reg, -1,
+				    0, regs, &addr);
+      if (terr != TD_OK)
+	return terr;
+
+      /* In this descriptor the nelem word is overloaded as the bias.  */
+      addr += (int32_t) DB_DESC_NELEM (ta->ta_howto_data.reg);
+      th->th_unique = addr;
+      break;
+
+    case ta_howto_const_thread_area:
+      /* Some hosts don't have this call and this case won't be used.  */
+# pragma weak ps_get_thread_area
+      if (&ps_get_thread_area == NULL)
+	return TD_NOCAPAB;
+
+      /* A la x86-64, there is a magic index for get_thread_area.  */
+      if (ps_get_thread_area (ta->ph, lwpid,
+			      ta->ta_howto_data.const_thread_area,
+			      &th->th_unique) != PS_OK)
+	return TD_ERR;	/* XXX Other error value?  */
+      break;
+
+    case ta_howto_reg_thread_area:
+      if (&ps_get_thread_area == NULL)
+	return TD_NOCAPAB;
+
+      /* A la i386, a register holds the index for get_thread_area.  */
+      if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK)
+	return TD_ERR;
+      terr = _td_fetch_value_local (ta, ta->ta_howto_data.reg_thread_area,
+				    -1, 0, regs, &addr);
+      if (terr != TD_OK)
+	return terr;
+      /* In this descriptor the nelem word is overloaded as scale factor.  */
+      if (ps_get_thread_area
+	  (ta->ph, lwpid,
+	   ((addr - (psaddr_t) 0)
+	    >> DB_DESC_NELEM (ta->ta_howto_data.reg_thread_area)),
+	   &th->th_unique) != PS_OK)
+	return TD_ERR;	/* XXX Other error value?  */
+      break;
+    }
+
+  /* Found it.  Now complete the `td_thrhandle_t' object.  */
+  th->th_ta_p = ta;
+
+  return TD_OK;
+}
+
+td_err_e
+td_ta_map_lwp2thr (const td_thragent_t *ta_arg,
+		   lwpid_t lwpid, td_thrhandle_t *th)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+
+  LOG ("td_ta_map_lwp2thr");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* We cannot rely on thread registers and such information at all
+     before __pthread_initialize_minimal has gotten far enough.  They
+     sometimes contain garbage that would confuse us, left by the kernel
+     at exec.  So if it looks like initialization is incomplete, we only
+     fake a special descriptor for the initial thread.  */
+
+  psaddr_t list;
+  td_err_e err = DB_GET_SYMBOL (list, ta, __stack_user);
+  if (err != TD_OK)
+    return err;
+
+  err = DB_GET_FIELD (list, ta, list, list_t, next, 0);
+  if (err != TD_OK)
+    return err;
+
+  if (list == 0)
+    {
+      if (ps_getpid (ta->ph) != lwpid)
+	return TD_ERR;
+      th->th_ta_p = ta;
+      th->th_unique = 0;
+      return TD_OK;
+    }
+
+  return __td_ta_lookup_th_unique (ta_arg, lwpid, th);
+}
diff --git a/REORG.TODO/nptl_db/td_ta_new.c b/REORG.TODO/nptl_db/td_ta_new.c
new file mode 100644
index 0000000000..aec23563be
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_new.c
@@ -0,0 +1,64 @@
+/* Attach to target process.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <version.h>
+
+#include "thread_dbP.h"
+
+
+/* Datatype for the list of known thread agents.  Normally there will
+   be exactly one so we don't spend much though on making it fast.  */
+LIST_HEAD (__td_agent_list);
+
+
+td_err_e
+td_ta_new (struct ps_prochandle *ps, td_thragent_t **ta)
+{
+  psaddr_t versaddr;
+  char versbuf[sizeof (VERSION)];
+
+  LOG ("td_ta_new");
+
+  /* Check whether the versions match.  */
+  if (td_lookup (ps, SYM_nptl_version, &versaddr) != PS_OK)
+    return TD_NOLIBTHREAD;
+  if (ps_pdread (ps, versaddr, versbuf, sizeof (versbuf)) != PS_OK)
+    return TD_ERR;
+
+  if (memcmp (versbuf, VERSION, sizeof VERSION) != 0)
+    /* Not the right version.  */
+    return TD_VERSION;
+
+  /* Fill in the appropriate information.  */
+  *ta = (td_thragent_t *) calloc (1, sizeof (td_thragent_t));
+  if (*ta == NULL)
+    return TD_MALLOC;
+
+  /* Store the proc handle which we will pass to the callback functions
+     back into the debugger.  */
+  (*ta)->ph = ps;
+
+  /* Now add the new agent descriptor to the list.  */
+  list_add (&(*ta)->list, &__td_agent_list);
+
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_ta_reset_stats.c b/REORG.TODO/nptl_db/td_ta_reset_stats.c
new file mode 100644
index 0000000000..f9728ab306
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_reset_stats.c
@@ -0,0 +1,34 @@
+/* Reset statistics.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_ta_reset_stats (const td_thragent_t *ta)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_ta_reset_stats");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_ta_set_event.c b/REORG.TODO/nptl_db/td_ta_set_event.c
new file mode 100644
index 0000000000..f91b7d986d
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_set_event.c
@@ -0,0 +1,77 @@
+/* Globally enable events.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdint.h>
+#include "thread_dbP.h"
+
+
+td_err_e
+td_ta_set_event (const td_thragent_t *ta_arg, td_thr_events_t *event)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  td_err_e err;
+  psaddr_t eventmask = 0;
+  void *copy = NULL;
+
+  LOG ("td_ta_set_event");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* Fetch the old event mask from the inferior and modify it in place.  */
+  err = DB_GET_SYMBOL (eventmask, ta, __nptl_threads_events);
+  if (err == TD_OK)
+    err = DB_GET_STRUCT (copy, ta, eventmask, td_thr_events_t);
+  if (err == TD_OK)
+    {
+      uint32_t idx;
+      for (idx = 0; idx < TD_EVENTSIZE; ++idx)
+	{
+	  psaddr_t word;
+	  uint32_t mask;
+	  err = DB_GET_FIELD_LOCAL (word, ta, copy,
+				    td_thr_events_t, event_bits, idx);
+	  if (err != TD_OK)
+	    break;
+	  mask = (uintptr_t) word;
+	  mask |= event->event_bits[idx];
+	  word = (psaddr_t) (uintptr_t) mask;
+	  err = DB_PUT_FIELD_LOCAL (ta, copy,
+				    td_thr_events_t, event_bits, idx, word);
+	  if (err != TD_OK)
+	    break;
+	}
+      if (err == TD_NOAPLIC)
+	{
+	  err = TD_OK;
+	  while (idx < TD_EVENTSIZE)
+	    if (event->event_bits[idx++] != 0)
+	      {
+		err = TD_NOEVENT;
+		break;
+	      }
+	}
+      if (err == TD_OK)
+	/* Now write it back to the inferior.  */
+	err = DB_PUT_STRUCT (ta, eventmask, td_thr_events_t, copy);
+    }
+
+  return err;
+}
diff --git a/REORG.TODO/nptl_db/td_ta_setconcurrency.c b/REORG.TODO/nptl_db/td_ta_setconcurrency.c
new file mode 100644
index 0000000000..daac04c41e
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_setconcurrency.c
@@ -0,0 +1,34 @@
+/* Set suggested concurrency level for process.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_ta_setconcurrency (const td_thragent_t *ta, int level)
+{
+  /* This is something LinuxThreads does not need to support.  */
+  LOG ("td_ta_setconcurrency");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  return TD_NOCAPAB;
+}
diff --git a/REORG.TODO/nptl_db/td_ta_thr_iter.c b/REORG.TODO/nptl_db/td_ta_thr_iter.c
new file mode 100644
index 0000000000..cc3d1e7611
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_thr_iter.c
@@ -0,0 +1,150 @@
+/* Iterate over a process's threads.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+static td_err_e
+iterate_thread_list (td_thragent_t *ta, td_thr_iter_f *callback,
+		     void *cbdata_p, td_thr_state_e state, int ti_pri,
+		     psaddr_t head, bool fake_empty, pid_t match_pid)
+{
+  td_err_e err;
+  psaddr_t next, ofs;
+  void *copy;
+
+  /* Test the state.
+     XXX This is incomplete.  Normally this test should be in the loop.  */
+  if (state != TD_THR_ANY_STATE)
+    return TD_OK;
+
+  err = DB_GET_FIELD (next, ta, head, list_t, next, 0);
+  if (err != TD_OK)
+    return err;
+
+  if (next == 0 && fake_empty)
+    {
+      /* __pthread_initialize_minimal has not run.  There is just the main
+	 thread to return.  We cannot rely on its thread register.  They
+	 sometimes contain garbage that would confuse us, left by the
+	 kernel at exec.  So if it looks like initialization is incomplete,
+	 we only fake a special descriptor for the initial thread.  */
+      td_thrhandle_t th = { ta, 0 };
+      return callback (&th, cbdata_p) != 0 ? TD_DBERR : TD_OK;
+    }
+
+  /* Cache the offset from struct pthread to its list_t member.  */
+  err = DB_GET_FIELD_ADDRESS (ofs, ta, 0, pthread, list, 0);
+  if (err != TD_OK)
+    return err;
+
+  if (ta->ta_sizeof_pthread == 0)
+    {
+      err = _td_check_sizeof (ta, &ta->ta_sizeof_pthread, SYM_SIZEOF_pthread);
+      if (err != TD_OK)
+	return err;
+    }
+  copy = __alloca (ta->ta_sizeof_pthread);
+
+  while (next != head)
+    {
+      psaddr_t addr, schedpolicy, schedprio;
+
+      addr = next - (ofs - (psaddr_t) 0);
+      if (next == 0 || addr == 0) /* Sanity check.  */
+	return TD_DBERR;
+
+      /* Copy the whole descriptor in once so we can access the several
+	 fields locally.  Excess copying in one go is much better than
+	 multiple ps_pdread calls.  */
+      if (ps_pdread (ta->ph, addr, copy, ta->ta_sizeof_pthread) != PS_OK)
+	return TD_ERR;
+
+      err = DB_GET_FIELD_LOCAL (schedpolicy, ta, copy, pthread,
+				schedpolicy, 0);
+      if (err != TD_OK)
+	break;
+      err = DB_GET_FIELD_LOCAL (schedprio, ta, copy, pthread,
+				schedparam_sched_priority, 0);
+      if (err != TD_OK)
+	break;
+
+      /* Now test whether this thread matches the specified conditions.  */
+
+      /* Only if the priority level is as high or higher.  */
+      int descr_pri = ((uintptr_t) schedpolicy == SCHED_OTHER
+		       ? 0 : (uintptr_t) schedprio);
+      if (descr_pri >= ti_pri)
+	{
+	  /* Yep, it matches.  Call the callback function.  */
+	  td_thrhandle_t th;
+	  th.th_ta_p = (td_thragent_t *) ta;
+	  th.th_unique = addr;
+	  if (callback (&th, cbdata_p) != 0)
+	    return TD_DBERR;
+	}
+
+      /* Get the pointer to the next element.  */
+      err = DB_GET_FIELD_LOCAL (next, ta, copy + (ofs - (psaddr_t) 0), list_t,
+				next, 0);
+      if (err != TD_OK)
+	break;
+    }
+
+  return err;
+}
+
+
+td_err_e
+td_ta_thr_iter (const td_thragent_t *ta_arg, td_thr_iter_f *callback,
+		void *cbdata_p, td_thr_state_e state, int ti_pri,
+		sigset_t *ti_sigmask_p, unsigned int ti_user_flags)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  td_err_e err;
+  psaddr_t list = 0;
+
+  LOG ("td_ta_thr_iter");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* The thread library keeps two lists for the running threads.  One
+     list contains the thread which are using user-provided stacks
+     (this includes the main thread) and the other includes the
+     threads for which the thread library allocated the stacks.  We
+     have to iterate over both lists separately.  We start with the
+     list of threads with user-defined stacks.  */
+
+  pid_t pid = ps_getpid (ta->ph);
+  err = DB_GET_SYMBOL (list, ta, __stack_user);
+  if (err == TD_OK)
+    err = iterate_thread_list (ta, callback, cbdata_p, state, ti_pri,
+			       list, true, pid);
+
+  /* And the threads with stacks allocated by the implementation.  */
+  if (err == TD_OK)
+    err = DB_GET_SYMBOL (list, ta, stack_used);
+  if (err == TD_OK)
+    err = iterate_thread_list (ta, callback, cbdata_p, state, ti_pri,
+			       list, false, pid);
+
+  return err;
+}
diff --git a/REORG.TODO/nptl_db/td_ta_tsd_iter.c b/REORG.TODO/nptl_db/td_ta_tsd_iter.c
new file mode 100644
index 0000000000..33fd53d6c1
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_ta_tsd_iter.c
@@ -0,0 +1,81 @@
+/* Iterate over a process's thread-specific data.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdint.h>
+#include "thread_dbP.h"
+#include <alloca.h>
+
+td_err_e
+td_ta_tsd_iter (const td_thragent_t *ta_arg, td_key_iter_f *callback,
+		void *cbdata_p)
+{
+  td_thragent_t *const ta = (td_thragent_t *) ta_arg;
+  td_err_e err;
+  void *keys;
+  size_t keys_nb, keys_elemsize;
+  psaddr_t addr;
+  uint32_t idx;
+
+  LOG ("td_ta_tsd_iter");
+
+  /* Test whether the TA parameter is ok.  */
+  if (! ta_ok (ta))
+    return TD_BADTA;
+
+  /* This makes sure we have the size information on hand.  */
+  addr = 0;
+  err = _td_locate_field (ta,
+			  ta->ta_var___pthread_keys, SYM_DESC___pthread_keys,
+			  (psaddr_t) 0 + 1, &addr);
+  if (err != TD_OK)
+    return err;
+
+  /* Now copy in the entire array of key descriptors.  */
+  keys_elemsize = (addr - (psaddr_t) 0) / 8;
+  keys_nb = keys_elemsize * DB_DESC_NELEM (ta->ta_var___pthread_keys);
+  keys = __alloca (keys_nb);
+  err = DB_GET_SYMBOL (addr, ta, __pthread_keys);
+  if (err != TD_OK)
+    return err;
+  if (ps_pdread (ta->ph, addr, keys, keys_nb) != PS_OK)
+    return TD_ERR;
+
+  /* Now get all descriptors, one after the other.  */
+  for (idx = 0; idx < DB_DESC_NELEM (ta->ta_var___pthread_keys); ++idx)
+    {
+      psaddr_t seq, destr;
+      err = DB_GET_FIELD_LOCAL (seq, ta, keys, pthread_key_struct, seq, 0);
+      if (err != TD_OK)
+	return err;
+      if (((uintptr_t) seq) & 1)
+	{
+	  err = DB_GET_FIELD_LOCAL (destr, ta, keys, pthread_key_struct,
+				    destr, 0);
+	  if (err != TD_OK)
+	    return err;
+	  /* Return with an error if the callback returns a nonzero value.  */
+	  if (callback ((thread_key_t) idx, destr, cbdata_p) != 0)
+	    return TD_DBERR;
+	}
+      /* Advance to the next element in the copied array.  */
+      keys += keys_elemsize;
+    }
+
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_clear_event.c b/REORG.TODO/nptl_db/td_thr_clear_event.c
new file mode 100644
index 0000000000..e12385023f
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_clear_event.c
@@ -0,0 +1,75 @@
+/* Disable specific event for thread.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_clear_event (const td_thrhandle_t *th, td_thr_events_t *event)
+{
+  td_err_e err;
+  psaddr_t eventmask;
+  void *copy;
+
+  LOG ("td_thr_clear_event");
+
+  /* Fetch the old event mask from the inferior and modify it in place.  */
+  err = DB_GET_FIELD_ADDRESS (eventmask, th->th_ta_p,
+			      th->th_unique, pthread, eventbuf_eventmask, 0);
+  if (err == TD_OK)
+    err = DB_GET_STRUCT (copy, th->th_ta_p, eventmask, td_thr_events_t);
+  if (err == TD_OK)
+    {
+      uint32_t idx;
+      for (idx = 0; idx < TD_EVENTSIZE; ++idx)
+	{
+	  psaddr_t word;
+	  uint32_t mask;
+	  err = DB_GET_FIELD_LOCAL (word, th->th_ta_p, copy,
+				    td_thr_events_t, event_bits, idx);
+	  if (err != TD_OK)
+	    break;
+	  mask = (uintptr_t) word;
+	  mask &= ~event->event_bits[idx];
+	  word = (psaddr_t) (uintptr_t) mask;
+	  err = DB_PUT_FIELD_LOCAL (th->th_ta_p, copy,
+				    td_thr_events_t, event_bits, idx, word);
+	  if (err != TD_OK)
+	    break;
+	}
+      if (err == TD_NOAPLIC)
+	{
+	  err = TD_OK;
+	  while (idx < TD_EVENTSIZE)
+	    if (event->event_bits[idx++] != 0)
+	      {
+		err = TD_NOEVENT;
+		break;
+	      }
+	}
+      if (err == TD_OK)
+	/* Now write it back to the inferior.  */
+	err = DB_PUT_STRUCT (th->th_ta_p, eventmask, td_thr_events_t, copy);
+    }
+
+  return err;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_dbresume.c b/REORG.TODO/nptl_db/td_thr_dbresume.c
new file mode 100644
index 0000000000..a3037bc835
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_dbresume.c
@@ -0,0 +1,29 @@
+/* Resume execution of given thread.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_dbresume (const td_thrhandle_t *th)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_thr_dbresume");
+  return TD_NOCAPAB;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_dbsuspend.c b/REORG.TODO/nptl_db/td_thr_dbsuspend.c
new file mode 100644
index 0000000000..e46edb3b1e
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_dbsuspend.c
@@ -0,0 +1,29 @@
+/* Suspend execution of given thread.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_dbsuspend (const td_thrhandle_t *th)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_thr_dbsuspend");
+  return TD_NOCAPAB;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_event_enable.c b/REORG.TODO/nptl_db/td_thr_event_enable.c
new file mode 100644
index 0000000000..295560d6e5
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_event_enable.c
@@ -0,0 +1,49 @@
+/* Enable event process-wide.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_event_enable (const td_thrhandle_t *th, int onoff)
+{
+  LOG ("td_thr_event_enable");
+
+  if (th->th_unique != 0)
+    {
+      /* Write the new value into the thread data structure.  */
+      td_err_e err = DB_PUT_FIELD (th->th_ta_p, th->th_unique, pthread,
+				   report_events, 0,
+				   (psaddr_t) 0 + (onoff != 0));
+      if (err != TD_OK)
+	return err;
+
+      /* Just in case we are in the window between initializing __stack_user
+	 and copying from __nptl_initial_report_events, we set it too.
+	 It doesn't hurt to do this for non-initial threads, since it
+	 won't be consulted again anyway.  It would take another fetch
+	 to get the tid and determine this isn't the initial thread,
+	 so just do it always.  */
+    }
+
+  /* We are faking it for the initial thread before its thread
+     descriptor is set up.  */
+  return DB_PUT_VALUE (th->th_ta_p, __nptl_initial_report_events, 0,
+		       (psaddr_t) 0 + (onoff != 0));
+}
diff --git a/REORG.TODO/nptl_db/td_thr_event_getmsg.c b/REORG.TODO/nptl_db/td_thr_event_getmsg.c
new file mode 100644
index 0000000000..9ff8b2dbbe
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_event_getmsg.c
@@ -0,0 +1,118 @@
+/* Retrieve event.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+#include <assert.h>
+
+
+td_err_e
+td_thr_event_getmsg (const td_thrhandle_t *th, td_event_msg_t *msg)
+{
+  td_err_e err;
+  psaddr_t eventbuf, eventnum, eventdata;
+  psaddr_t thp, prevp;
+  void *copy;
+
+  LOG ("td_thr_event_getmsg");
+
+  /* Copy the event message buffer in from the inferior.  */
+  err = DB_GET_FIELD_ADDRESS (eventbuf, th->th_ta_p, th->th_unique, pthread,
+			      eventbuf, 0);
+  if (err == TD_OK)
+    err = DB_GET_STRUCT (copy, th->th_ta_p, eventbuf, td_eventbuf_t);
+  if (err != TD_OK)
+    return err;
+
+  /* Check whether an event occurred.  */
+  err = DB_GET_FIELD_LOCAL (eventnum, th->th_ta_p, copy,
+			    td_eventbuf_t, eventnum, 0);
+  if (err != TD_OK)
+    return err;
+  if ((int) (uintptr_t) eventnum == TD_EVENT_NONE)
+    /* Nothing.  */
+    return TD_NOMSG;
+
+  /* Fill the user's data structure.  */
+  err = DB_GET_FIELD_LOCAL (eventdata, th->th_ta_p, copy,
+			    td_eventbuf_t, eventdata, 0);
+  if (err != TD_OK)
+    return err;
+
+  msg->msg.data = (uintptr_t) eventdata;
+  msg->event = (uintptr_t) eventnum;
+  msg->th_p = th;
+
+  /* And clear the event message in the target.  */
+  memset (copy, 0, th->th_ta_p->ta_sizeof_td_eventbuf_t);
+  err = DB_PUT_STRUCT (th->th_ta_p, eventbuf, td_eventbuf_t, copy);
+  if (err != TD_OK)
+    return err;
+
+  /* Get the pointer to the thread descriptor with the last event.
+     If it doesn't match TH, then walk down the list until we find it.
+     We must splice it out of the list so that there is no dangling
+     pointer to it later when it dies.  */
+  err = DB_GET_SYMBOL (prevp, th->th_ta_p, __nptl_last_event);
+  if (err != TD_OK)
+    return err;
+  err = DB_GET_VALUE (thp, th->th_ta_p, __nptl_last_event, 0);
+  if (err != TD_OK)
+    return err;
+
+  while (thp != 0)
+    {
+      psaddr_t next;
+      err = DB_GET_FIELD (next, th->th_ta_p, th->th_unique, pthread,
+			  nextevent, 0);
+      if (err != TD_OK)
+	return err;
+
+      if (next == thp)
+	return TD_DBERR;
+
+      if (thp == th->th_unique)
+	{
+	  /* PREVP points at this thread, splice it out.  */
+	  psaddr_t next_nextp;
+	  err = DB_GET_FIELD_ADDRESS (next_nextp, th->th_ta_p, next, pthread,
+				      nextevent, 0);
+	  assert (err == TD_OK); /* We used this field before.  */
+	  if (prevp == next_nextp)
+	    return TD_DBERR;
+
+	  err = _td_store_value (th->th_ta_p,
+				 th->th_ta_p->ta_var___nptl_last_event, -1,
+				 0, prevp, next);
+	  if (err != TD_OK)
+	    return err;
+
+	  /* Now clear this thread's own next pointer so it's not dangling
+	     when the thread resumes and then chains on for its next event.  */
+	  return DB_PUT_FIELD (th->th_ta_p, thp, pthread, nextevent, 0, 0);
+	}
+
+      err = DB_GET_FIELD_ADDRESS (prevp, th->th_ta_p, thp, pthread,
+				  nextevent, 0);
+      assert (err == TD_OK); /* We used this field before.  */
+      thp = next;
+    }
+
+  /* Ack!  This should not happen.  */
+  return TD_DBERR;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_get_info.c b/REORG.TODO/nptl_db/td_thr_get_info.c
new file mode 100644
index 0000000000..48979b8e28
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_get_info.c
@@ -0,0 +1,126 @@
+/* Get thread information.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+#include <string.h>
+#include <stdint.h>
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_get_info (const td_thrhandle_t *th, td_thrinfo_t *infop)
+{
+  td_err_e err;
+  void *copy;
+  psaddr_t tls, schedpolicy, schedprio, cancelhandling, tid, report_events;
+
+  LOG ("td_thr_get_info");
+
+  if (th->th_unique == 0)
+    {
+      /* Special case for the main thread before initialization.  */
+      copy = NULL;
+      tls = 0;
+      cancelhandling = 0;
+      schedpolicy = SCHED_OTHER;
+      schedprio = 0;
+      tid = 0;
+      err = DB_GET_VALUE (report_events, th->th_ta_p,
+			  __nptl_initial_report_events, 0);
+    }
+  else
+    {
+      /* Copy the whole descriptor in once so we can access the several
+	 fields locally.  Excess copying in one go is much better than
+	 multiple ps_pdread calls.  */
+      err = DB_GET_STRUCT (copy, th->th_ta_p, th->th_unique, pthread);
+      if (err != TD_OK)
+	return err;
+
+      err = DB_GET_FIELD_ADDRESS (tls, th->th_ta_p, th->th_unique,
+				  pthread, specific, 0);
+      if (err != TD_OK)
+	return err;
+
+      err = DB_GET_FIELD_LOCAL (schedpolicy, th->th_ta_p, copy, pthread,
+				schedpolicy, 0);
+      if (err != TD_OK)
+	return err;
+      err = DB_GET_FIELD_LOCAL (schedprio, th->th_ta_p, copy, pthread,
+				schedparam_sched_priority, 0);
+      if (err != TD_OK)
+	return err;
+      err = DB_GET_FIELD_LOCAL (tid, th->th_ta_p, copy, pthread, tid, 0);
+      if (err != TD_OK)
+	return err;
+      err = DB_GET_FIELD_LOCAL (cancelhandling, th->th_ta_p, copy, pthread,
+				cancelhandling, 0);
+      if (err != TD_OK)
+	return err;
+      err = DB_GET_FIELD_LOCAL (report_events, th->th_ta_p, copy, pthread,
+				report_events, 0);
+    }
+  if (err != TD_OK)
+    return err;
+
+  /* Fill in information.  Clear first to provide reproducable
+     results for the fields we do not fill in.  */
+  memset (infop, '\0', sizeof (td_thrinfo_t));
+
+  infop->ti_tid = (thread_t) th->th_unique;
+  infop->ti_tls = (char *) tls;
+  infop->ti_pri = ((uintptr_t) schedpolicy == SCHED_OTHER
+		   ? 0 : (uintptr_t) schedprio);
+  infop->ti_type = TD_THR_USER;
+
+  if ((((int) (uintptr_t) cancelhandling) & EXITING_BITMASK) == 0)
+    /* XXX For now there is no way to get more information.  */
+    infop->ti_state = TD_THR_ACTIVE;
+  else if ((((int) (uintptr_t) cancelhandling) & TERMINATED_BITMASK) == 0)
+    infop->ti_state = TD_THR_ZOMBIE;
+  else
+    infop->ti_state = TD_THR_UNKNOWN;
+
+  /* Initialization which are the same in both cases.  */
+  infop->ti_ta_p = th->th_ta_p;
+  infop->ti_lid = tid == 0 ? ps_getpid (th->th_ta_p->ph) : (uintptr_t) tid;
+  infop->ti_traceme = report_events != 0;
+
+  if (copy != NULL)
+    err = DB_GET_FIELD_LOCAL (infop->ti_startfunc, th->th_ta_p, copy, pthread,
+			      start_routine, 0);
+  if (copy != NULL && err == TD_OK)
+    {
+      uint32_t idx;
+      for (idx = 0; idx < TD_EVENTSIZE; ++idx)
+	{
+	  psaddr_t word;
+	  err = DB_GET_FIELD_LOCAL (word, th->th_ta_p, copy, pthread,
+				    eventbuf_eventmask_event_bits, idx);
+	  if (err != TD_OK)
+	    break;
+	  infop->ti_events.event_bits[idx] = (uintptr_t) word;
+	}
+      if (err == TD_NOAPLIC)
+	memset (&infop->ti_events.event_bits[idx], 0,
+		(TD_EVENTSIZE - idx) * sizeof infop->ti_events.event_bits[0]);
+    }
+
+  return err;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_getfpregs.c b/REORG.TODO/nptl_db/td_thr_getfpregs.c
new file mode 100644
index 0000000000..3c5462c43f
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_getfpregs.c
@@ -0,0 +1,57 @@
+/* Get a thread's floating-point register set.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_getfpregs (const td_thrhandle_t *th, prfpregset_t *regset)
+{
+  psaddr_t cancelhandling, tid;
+  td_err_e err;
+
+  LOG ("td_thr_getfpregs");
+
+  if (th->th_unique == 0)
+    /* Special case for the main thread before initialization.  */
+    return ps_lgetfpregs (th->th_ta_p->ph, ps_getpid (th->th_ta_p->ph),
+			  regset) != PS_OK ? TD_ERR : TD_OK;
+
+  /* We have to get the state and the PID for this thread.  */
+  err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread,
+		      cancelhandling, 0);
+  if (err != TD_OK)
+    return err;
+
+  /* If the thread already terminated we return all zeroes.  */
+  if (((int) (uintptr_t) cancelhandling) & TERMINATED_BITMASK)
+    memset (regset, '\0', sizeof (*regset));
+  /* Otherwise get the register content through the callback.  */
+  else
+    {
+      err = DB_GET_FIELD (tid, th->th_ta_p, th->th_unique, pthread, tid, 0);
+      if (err != TD_OK)
+	return err;
+
+      if (ps_lgetfpregs (th->th_ta_p->ph, (uintptr_t) tid, regset) != PS_OK)
+	return TD_ERR;
+    }
+
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_getgregs.c b/REORG.TODO/nptl_db/td_thr_getgregs.c
new file mode 100644
index 0000000000..61ffa120ee
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_getgregs.c
@@ -0,0 +1,57 @@
+/* Get a thread's general register set.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_getgregs (const td_thrhandle_t *th, prgregset_t regset)
+{
+  psaddr_t cancelhandling, tid;
+  td_err_e err;
+
+  LOG ("td_thr_getgregs");
+
+  if (th->th_unique == 0)
+    /* Special case for the main thread before initialization.  */
+    return ps_lgetregs (th->th_ta_p->ph, ps_getpid (th->th_ta_p->ph),
+			regset) != PS_OK ? TD_ERR : TD_OK;
+
+  /* We have to get the state and the PID for this thread.  */
+  err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread,
+		      cancelhandling, 0);
+  if (err != TD_OK)
+    return err;
+
+  /* If the thread already terminated we return all zeroes.  */
+  if (((int) (uintptr_t) cancelhandling) & TERMINATED_BITMASK)
+    memset (regset, '\0', sizeof (*regset));
+  /* Otherwise get the register content through the callback.  */
+  else
+    {
+      err = DB_GET_FIELD (tid, th->th_ta_p, th->th_unique, pthread, tid, 0);
+      if (err != TD_OK)
+	return err;
+
+      if (ps_lgetregs (th->th_ta_p->ph, (uintptr_t) tid, regset) != PS_OK)
+	return TD_ERR;
+    }
+
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_getxregs.c b/REORG.TODO/nptl_db/td_thr_getxregs.c
new file mode 100644
index 0000000000..fdb9da79f0
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_getxregs.c
@@ -0,0 +1,29 @@
+/* Get a thread's extra state register set.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_getxregs (const td_thrhandle_t *th, void *xregs)
+{
+  /* XXX This might be platform specific.  */
+  LOG ("td_thr_getxregs");
+  return TD_NOXREGS;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_getxregsize.c b/REORG.TODO/nptl_db/td_thr_getxregsize.c
new file mode 100644
index 0000000000..58739d05a9
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_getxregsize.c
@@ -0,0 +1,29 @@
+/* Get the size of the extra state register set for this architecture.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_getxregsize (const td_thrhandle_t *th, int *sizep)
+{
+  /* XXX This might be platform specific.  */
+  LOG ("td_thr_getxregsize");
+  return TD_NOXREGS;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_set_event.c b/REORG.TODO/nptl_db/td_thr_set_event.c
new file mode 100644
index 0000000000..9be09058cb
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_set_event.c
@@ -0,0 +1,75 @@
+/* Enable specific event for thread.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_set_event (const td_thrhandle_t *th, td_thr_events_t *event)
+{
+  td_err_e err;
+  psaddr_t eventmask;
+  void *copy;
+
+  LOG ("td_thr_set_event");
+
+  /* Fetch the old event mask from the inferior and modify it in place.  */
+  err = DB_GET_FIELD_ADDRESS (eventmask, th->th_ta_p,
+			      th->th_unique, pthread, eventbuf_eventmask, 0);
+  if (err == TD_OK)
+    err = DB_GET_STRUCT (copy, th->th_ta_p, eventmask, td_thr_events_t);
+  if (err == TD_OK)
+    {
+      uint32_t idx;
+      for (idx = 0; idx < TD_EVENTSIZE; ++idx)
+	{
+	  psaddr_t word;
+	  uint32_t mask;
+	  err = DB_GET_FIELD_LOCAL (word, th->th_ta_p, copy,
+				    td_thr_events_t, event_bits, idx);
+	  if (err != TD_OK)
+	    break;
+	  mask = (uintptr_t) word;
+	  mask |= event->event_bits[idx];
+	  word = (psaddr_t) (uintptr_t) mask;
+	  err = DB_PUT_FIELD_LOCAL (th->th_ta_p, copy,
+				    td_thr_events_t, event_bits, idx, word);
+	  if (err != TD_OK)
+	    break;
+	}
+      if (err == TD_NOAPLIC)
+	{
+	  err = TD_OK;
+	  while (idx < TD_EVENTSIZE)
+	    if (event->event_bits[idx++] != 0)
+	      {
+		err = TD_NOEVENT;
+		break;
+	      }
+	}
+      if (err == TD_OK)
+	/* Now write it back to the inferior.  */
+	err = DB_PUT_STRUCT (th->th_ta_p, eventmask, td_thr_events_t, copy);
+    }
+
+  return err;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_setfpregs.c b/REORG.TODO/nptl_db/td_thr_setfpregs.c
new file mode 100644
index 0000000000..092fc1a0e0
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_setfpregs.c
@@ -0,0 +1,54 @@
+/* Set a thread's floating-point register set.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_setfpregs (const td_thrhandle_t *th, const prfpregset_t *fpregs)
+{
+  psaddr_t cancelhandling, tid;
+  td_err_e err;
+
+  LOG ("td_thr_setfpregs");
+
+  if (th->th_unique == 0)
+    /* Special case for the main thread before initialization.  */
+    return ps_lsetfpregs (th->th_ta_p->ph, ps_getpid (th->th_ta_p->ph),
+			  fpregs) != PS_OK ? TD_ERR : TD_OK;
+
+  /* We have to get the state and the PID for this thread.  */
+  err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread,
+		      cancelhandling, 0);
+  if (err != TD_OK)
+    return err;
+
+  /* Only set the registers if the thread hasn't yet terminated.  */
+  if ((((int) (uintptr_t) cancelhandling) & TERMINATED_BITMASK) == 0)
+    {
+      err = DB_GET_FIELD (tid, th->th_ta_p, th->th_unique, pthread, tid, 0);
+      if (err != TD_OK)
+	return err;
+
+      if (ps_lsetfpregs (th->th_ta_p->ph, (uintptr_t) tid, fpregs) != PS_OK)
+	return TD_ERR;
+    }
+
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_setgregs.c b/REORG.TODO/nptl_db/td_thr_setgregs.c
new file mode 100644
index 0000000000..a927119d53
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_setgregs.c
@@ -0,0 +1,54 @@
+/* Set a thread's general register set.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_setgregs (const td_thrhandle_t *th, prgregset_t gregs)
+{
+  psaddr_t cancelhandling, tid;
+  td_err_e err;
+
+  LOG ("td_thr_setgregs");
+
+  if (th->th_unique == 0)
+    /* Special case for the main thread before initialization.  */
+    return ps_lsetregs (th->th_ta_p->ph, ps_getpid (th->th_ta_p->ph),
+			gregs) != PS_OK ? TD_ERR : TD_OK;
+
+  /* We have to get the state and the PID for this thread.  */
+  err = DB_GET_FIELD (cancelhandling, th->th_ta_p, th->th_unique, pthread,
+		      cancelhandling, 0);
+  if (err != TD_OK)
+    return err;
+
+  /* Only set the registers if the thread hasn't yet terminated.  */
+  if ((((int) (uintptr_t) cancelhandling) & TERMINATED_BITMASK) == 0)
+    {
+      err = DB_GET_FIELD (tid, th->th_ta_p, th->th_unique, pthread, tid, 0);
+      if (err != TD_OK)
+	return err;
+
+      if (ps_lsetregs (th->th_ta_p->ph, tid - (psaddr_t) 0, gregs) != PS_OK)
+	return TD_ERR;
+    }
+
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_setprio.c b/REORG.TODO/nptl_db/td_thr_setprio.c
new file mode 100644
index 0000000000..1cbe827f59
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_setprio.c
@@ -0,0 +1,29 @@
+/* Set a thread's priority.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_setprio (const td_thrhandle_t *th, int prio)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_thr_setprio");
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_setsigpending.c b/REORG.TODO/nptl_db/td_thr_setsigpending.c
new file mode 100644
index 0000000000..c83da3221a
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_setsigpending.c
@@ -0,0 +1,30 @@
+/* Raise a signal for a thread.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_setsigpending (const td_thrhandle_t *th, unsigned char n,
+		      const sigset_t *ss)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_thr_setsigpending");
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_setxregs.c b/REORG.TODO/nptl_db/td_thr_setxregs.c
new file mode 100644
index 0000000000..e2fdd6c254
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_setxregs.c
@@ -0,0 +1,29 @@
+/* Set a thread's extra state register set.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_setxregs (const td_thrhandle_t *ta, const void *addr)
+{
+  /* XXX This might have to be platform specific.  */
+  LOG ("td_thr_setxregs");
+  return TD_NOXREGS;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_sigsetmask.c b/REORG.TODO/nptl_db/td_thr_sigsetmask.c
new file mode 100644
index 0000000000..9e2a240455
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_sigsetmask.c
@@ -0,0 +1,29 @@
+/* Set a thread's signal mask.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_sigsetmask (const td_thrhandle_t *th, const sigset_t *ss)
+{
+  /* XXX We have to figure out what has to be done.  */
+  LOG ("td_thr_sigsetmask");
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_tls_get_addr.c b/REORG.TODO/nptl_db/td_thr_tls_get_addr.c
new file mode 100644
index 0000000000..5bc5ecd497
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_tls_get_addr.c
@@ -0,0 +1,42 @@
+/* Get address of thread local variable.
+   Copyright (C) 2002-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <link.h>
+#include "thread_dbP.h"
+
+td_err_e
+td_thr_tls_get_addr (const td_thrhandle_t *th,
+		     psaddr_t map_address, size_t offset, psaddr_t *address)
+{
+  td_err_e err;
+  psaddr_t modid;
+
+  /* Get the TLS module ID from the `struct link_map' in the inferior.  */
+  err = DB_GET_FIELD (modid, th->th_ta_p, map_address, link_map,
+		      l_tls_modid, 0);
+  if (err == TD_NOCAPAB)
+    return TD_NOAPLIC;
+  if (err == TD_OK)
+    {
+      err = td_thr_tlsbase (th, (uintptr_t) modid, address);
+      if (err == TD_OK)
+	*address += offset;
+    }
+  return err;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_tlsbase.c b/REORG.TODO/nptl_db/td_thr_tlsbase.c
new file mode 100644
index 0000000000..11d7ad3a1c
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_tlsbase.c
@@ -0,0 +1,243 @@
+/* Locate TLS data for a thread.
+   Copyright (C) 2003-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+#include <link.h>
+
+/* Get the DTV slotinfo list head entry from the dynamic loader state
+   into *LISTHEAD.  */
+static td_err_e
+dtv_slotinfo_list (td_thragent_t *ta,
+		   psaddr_t *listhead)
+{
+  td_err_e err;
+  psaddr_t head;
+
+  if (ta->ta_addr__rtld_global == 0
+      && td_mod_lookup (ta->ph, LD_SO, SYM__rtld_global,
+			&ta->ta_addr__rtld_global) != PS_OK)
+    ta->ta_addr__rtld_global = (void*)-1;
+
+  if (ta->ta_addr__rtld_global != (void*)-1)
+    {
+      err = DB_GET_FIELD (head, ta, ta->ta_addr__rtld_global,
+			  rtld_global, _dl_tls_dtv_slotinfo_list, 0);
+      if (err != TD_OK)
+	return err;
+    }
+  else
+    {
+      if (ta->ta_addr__dl_tls_dtv_slotinfo_list == 0
+	  && td_mod_lookup (ta->ph, NULL, SYM__dl_tls_dtv_slotinfo_list,
+			    &ta->ta_addr__dl_tls_dtv_slotinfo_list) != PS_OK)
+	return TD_ERR;
+
+      err = _td_fetch_value (ta, ta->ta_var__dl_tls_dtv_slotinfo_list,
+			     SYM_DESC__dl_tls_dtv_slotinfo_list,
+			     0, ta->ta_addr__dl_tls_dtv_slotinfo_list, &head);
+      if (err != TD_OK)
+	return err;
+    }
+
+  *listhead = head;
+  return TD_OK;
+}
+
+/* Get the address of the DTV slotinfo entry for MODID into
+   *DTVSLOTINFO.  */
+static td_err_e
+dtv_slotinfo (td_thragent_t *ta,
+	      unsigned long int modid,
+	      psaddr_t *dtvslotinfo)
+{
+  td_err_e err;
+  psaddr_t slot, temp;
+  size_t slbase = 0;
+
+  err = dtv_slotinfo_list (ta, &slot);
+  if (err != TD_OK)
+    return err;
+
+  while (slot)
+    {
+      /* Get the number of entries in this list entry's array.  */
+      err = DB_GET_FIELD (temp, ta, slot, dtv_slotinfo_list, len, 0);
+      if (err != TD_OK)
+	return err;
+      size_t len = (uintptr_t)temp;
+
+      /* Did we find the list entry for modid?  */
+      if (modid < slbase + len)
+	break;
+
+      /* We didn't, so get the next list entry.  */
+      slbase += len;
+      err = DB_GET_FIELD (temp, ta, slot, dtv_slotinfo_list,
+			  next, 0);
+      if (err != TD_OK)
+	return err;
+      slot = temp;
+    }
+
+  /* We reached the end of the list and found nothing.  */
+  if (!slot)
+    return TD_ERR;
+
+  /* Take the slotinfo for modid from the list entry.  */
+  err = DB_GET_FIELD_ADDRESS (temp, ta, slot, dtv_slotinfo_list,
+			      slotinfo, modid - slbase);
+  if (err != TD_OK)
+    return err;
+  slot = temp;
+
+  *dtvslotinfo = slot;
+  return TD_OK;
+}
+
+/* Return in *BASE the base address of the TLS block for MODID within
+   TH.
+
+   It should return success and yield the correct pointer in any
+   circumstance where the TLS block for the module and thread
+   requested has already been initialized.
+
+   It should fail with TD_TLSDEFER only when the thread could not
+   possibly have observed any values in that TLS block.  That way, the
+   debugger can fall back to showing initial values from the PT_TLS
+   segment (and refusing attempts to mutate) for the TD_TLSDEFER case,
+   and never fail to make the values the program will actually see
+   available to the user of the debugger.  */
+td_err_e
+td_thr_tlsbase (const td_thrhandle_t *th,
+		unsigned long int modid,
+		psaddr_t *base)
+{
+  td_err_e err;
+  psaddr_t dtv, dtvslot, dtvptr, temp;
+
+  if (modid < 1)
+    return TD_NOTLS;
+
+  psaddr_t pd = th->th_unique;
+  if (pd == 0)
+    {
+      /* This is the fake handle for the main thread before libpthread
+	 initialization.  We are using 0 for its th_unique because we can't
+	 trust that its thread register has been initialized.  But we need
+	 a real pointer to have any TLS access work.  In case of dlopen'd
+	 libpthread, initialization might not be for quite some time.  So
+	 try looking up the thread register now.  Worst case, it's nonzero
+	 uninitialized garbage and we get bogus results for TLS access
+	 attempted too early.  Tough.  */
+
+      td_thrhandle_t main_th;
+      err = __td_ta_lookup_th_unique (th->th_ta_p, ps_getpid (th->th_ta_p->ph),
+				      &main_th);
+      if (err == 0)
+	pd = main_th.th_unique;
+      if (pd == 0)
+	return TD_TLSDEFER;
+    }
+
+  err = dtv_slotinfo (th->th_ta_p, modid, &temp);
+  if (err != TD_OK)
+    return err;
+
+  psaddr_t slot;
+  err = DB_GET_STRUCT (slot, th->th_ta_p, temp, dtv_slotinfo);
+  if (err != TD_OK)
+    return err;
+
+  /* Take the link_map from the slotinfo.  */
+  psaddr_t map;
+  err = DB_GET_FIELD_LOCAL (map, th->th_ta_p, slot, dtv_slotinfo, map, 0);
+  if (err != TD_OK)
+    return err;
+  if (!map)
+    return TD_ERR;
+
+  /* Ok, the modid is good, now find out what DTV generation it
+     requires.  */
+  err = DB_GET_FIELD_LOCAL (temp, th->th_ta_p, slot, dtv_slotinfo, gen, 0);
+  if (err != TD_OK)
+    return err;
+  size_t modgen = (uintptr_t)temp;
+
+  /* Get the DTV pointer from the thread descriptor.  */
+  err = DB_GET_FIELD (dtv, th->th_ta_p, pd, pthread, dtvp, 0);
+  if (err != TD_OK)
+    return err;
+
+  psaddr_t dtvgenloc;
+  /* Get the DTV generation count at dtv[0].counter.  */
+  err = DB_GET_FIELD_ADDRESS (dtvgenloc, th->th_ta_p, dtv, dtv, dtv, 0);
+  if (err != TD_OK)
+    return err;
+  err = DB_GET_FIELD (temp, th->th_ta_p, dtvgenloc, dtv_t, counter, 0);
+  if (err != TD_OK)
+    return err;
+  size_t dtvgen = (uintptr_t)temp;
+
+  /* Is the DTV current enough?  */
+  if (dtvgen < modgen)
+    {
+    try_static_tls:
+      /* If the module uses Static TLS, we're still good.  */
+      err = DB_GET_FIELD (temp, th->th_ta_p, map, link_map, l_tls_offset, 0);
+      if (err != TD_OK)
+	return err;
+      ptrdiff_t tlsoff = (uintptr_t)temp;
+
+      if (tlsoff != FORCED_DYNAMIC_TLS_OFFSET
+	  && tlsoff != NO_TLS_OFFSET)
+	{
+	  psaddr_t tp = pd;
+
+#if TLS_TCB_AT_TP
+	  dtvptr = tp - tlsoff;
+#elif TLS_DTV_AT_TP
+	  dtvptr = tp + tlsoff + TLS_PRE_TCB_SIZE;
+#else
+# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
+#endif
+
+	  *base = dtvptr;
+	  return TD_OK;
+	}
+
+      return TD_TLSDEFER;
+    }
+
+  /* Find the corresponding entry in the DTV.  */
+  err = DB_GET_FIELD_ADDRESS (dtvslot, th->th_ta_p, dtv, dtv, dtv, modid);
+  if (err != TD_OK)
+    return err;
+
+  /* Extract the TLS block address from that DTV slot.  */
+  err = DB_GET_FIELD (dtvptr, th->th_ta_p, dtvslot, dtv_t, pointer_val, 0);
+  if (err != TD_OK)
+    return err;
+
+  /* It could be that the memory for this module is not allocated for
+     the given thread.  */
+  if ((uintptr_t) dtvptr & 1)
+    goto try_static_tls;
+
+  *base = dtvptr;
+  return TD_OK;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_tsd.c b/REORG.TODO/nptl_db/td_thr_tsd.c
new file mode 100644
index 0000000000..6fe7ae9a0f
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_tsd.c
@@ -0,0 +1,96 @@
+/* Get a thread-specific data pointer for a thread.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdint.h>
+#include "thread_dbP.h"
+
+
+td_err_e
+td_thr_tsd (const td_thrhandle_t *th, const thread_key_t tk, void **data)
+{
+  td_err_e err;
+  psaddr_t tk_seq, level1, level2, seq, value;
+  void *copy;
+  uint32_t pthread_key_2ndlevel_size, idx1st, idx2nd;
+
+  LOG ("td_thr_tsd");
+
+  /* Get the key entry.  */
+  err = DB_GET_VALUE (tk_seq, th->th_ta_p, __pthread_keys, tk);
+  if (err == TD_NOAPLIC)
+    return TD_BADKEY;
+  if (err != TD_OK)
+    return err;
+
+  /* Fail if this key is not at all used.  */
+  if (((uintptr_t) tk_seq & 1) == 0)
+    return TD_BADKEY;
+
+  /* This makes sure we have the size information on hand.  */
+  err = DB_GET_FIELD_ADDRESS (level2, th->th_ta_p, 0, pthread_key_data_level2,
+			      data, 1);
+  if (err != TD_OK)
+    return err;
+
+  /* Compute the indeces.  */
+  pthread_key_2ndlevel_size
+    = DB_DESC_NELEM (th->th_ta_p->ta_field_pthread_key_data_level2_data);
+  idx1st = tk / pthread_key_2ndlevel_size;
+  idx2nd = tk % pthread_key_2ndlevel_size;
+
+  /* Now fetch the first level pointer.  */
+  err = DB_GET_FIELD (level1, th->th_ta_p, th->th_unique, pthread,
+		      specific, idx1st);
+  if (err == TD_NOAPLIC)
+    return TD_DBERR;
+  if (err != TD_OK)
+    return err;
+
+  /* Check the pointer to the second level array.  */
+  if (level1 == 0)
+    return TD_NOTSD;
+
+  /* Locate the element within the second level array.  */
+  err = DB_GET_FIELD_ADDRESS (level2, th->th_ta_p,
+			      level1, pthread_key_data_level2, data, idx2nd);
+  if (err == TD_NOAPLIC)
+    return TD_DBERR;
+  if (err != TD_OK)
+    return err;
+
+  /* Now copy in that whole structure.  */
+  err = DB_GET_STRUCT (copy, th->th_ta_p, level2, pthread_key_data);
+  if (err != TD_OK)
+    return err;
+
+  /* Check whether the data is valid.  */
+  err = DB_GET_FIELD_LOCAL (seq, th->th_ta_p, copy, pthread_key_data, seq, 0);
+  if (err != TD_OK)
+    return err;
+  if (seq != tk_seq)
+    return TD_NOTSD;
+
+  /* Finally, fetch the value.  */
+  err = DB_GET_FIELD_LOCAL (value, th->th_ta_p, copy, pthread_key_data,
+			    data, 0);
+  if (err == TD_OK)
+    *data = value;
+
+  return err;
+}
diff --git a/REORG.TODO/nptl_db/td_thr_validate.c b/REORG.TODO/nptl_db/td_thr_validate.c
new file mode 100644
index 0000000000..645fab479c
--- /dev/null
+++ b/REORG.TODO/nptl_db/td_thr_validate.c
@@ -0,0 +1,84 @@
+/* Validate a thread handle.
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "thread_dbP.h"
+#include <stdbool.h>
+
+static td_err_e
+check_thread_list (const td_thrhandle_t *th, psaddr_t head, bool *uninit)
+{
+  td_err_e err;
+  psaddr_t next, ofs;
+
+  err = DB_GET_FIELD (next, th->th_ta_p, head, list_t, next, 0);
+  if (err == TD_OK)
+    {
+      if (next == 0)
+	{
+	  *uninit = true;
+	  return TD_NOTHR;
+	}
+      err = DB_GET_FIELD_ADDRESS (ofs, th->th_ta_p, 0, pthread, list, 0);
+    }
+
+  while (err == TD_OK)
+    {
+      if (next == head)
+	return TD_NOTHR;
+
+      if (next - (ofs - (psaddr_t) 0) == th->th_unique)
+	return TD_OK;
+
+      err = DB_GET_FIELD (next, th->th_ta_p, next, list_t, next, 0);
+    }
+
+  return err;
+}
+
+
+td_err_e
+td_thr_validate (const td_thrhandle_t *th)
+{
+  td_err_e err;
+  psaddr_t list;
+
+  LOG ("td_thr_validate");
+
+  /* First check the list with threads using user allocated stacks.  */
+  bool uninit = false;
+  err = DB_GET_SYMBOL (list, th->th_ta_p, __stack_user);
+  if (err == TD_OK)
+    err = check_thread_list (th, list, &uninit);
+
+  /* If our thread is not on this list search the list with stack
+     using implementation allocated stacks.  */
+  if (err == TD_NOTHR)
+    {
+      err = DB_GET_SYMBOL (list, th->th_ta_p, stack_used);
+      if (err == TD_OK)
+	err = check_thread_list (th, list, &uninit);
+
+      if (err == TD_NOTHR && uninit && th->th_unique == 0)
+	/* __pthread_initialize_minimal has not run yet.
+	   There is only the special case thread handle.  */
+	err = TD_OK;
+    }
+
+  return err;
+}
diff --git a/REORG.TODO/nptl_db/thread_db.h b/REORG.TODO/nptl_db/thread_db.h
new file mode 100644
index 0000000000..d8e82b747f
--- /dev/null
+++ b/REORG.TODO/nptl_db/thread_db.h
@@ -0,0 +1,458 @@
+/* thread_db.h -- interface to libthread_db.so library for debugging -lpthread
+   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _THREAD_DB_H
+#define _THREAD_DB_H	1
+
+/* This is the debugger interface for the NPTL library.  It is
+   modelled closely after the interface with same names in Solaris
+   with the goal to share the same code in the debugger.  */
+#include <pthread.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/procfs.h>
+
+
+/* Error codes of the library.  */
+typedef enum
+{
+  TD_OK,	  /* No error.  */
+  TD_ERR,	  /* No further specified error.  */
+  TD_NOTHR,	  /* No matching thread found.  */
+  TD_NOSV,	  /* No matching synchronization handle found.  */
+  TD_NOLWP,	  /* No matching light-weighted process found.  */
+  TD_BADPH,	  /* Invalid process handle.  */
+  TD_BADTH,	  /* Invalid thread handle.  */
+  TD_BADSH,	  /* Invalid synchronization handle.  */
+  TD_BADTA,	  /* Invalid thread agent.  */
+  TD_BADKEY,	  /* Invalid key.  */
+  TD_NOMSG,	  /* No event available.  */
+  TD_NOFPREGS,	  /* No floating-point register content available.  */
+  TD_NOLIBTHREAD, /* Application not linked with thread library.  */
+  TD_NOEVENT,	  /* Requested event is not supported.  */
+  TD_NOCAPAB,	  /* Capability not available.  */
+  TD_DBERR,	  /* Internal debug library error.  */
+  TD_NOAPLIC,	  /* Operation is not applicable.  */
+  TD_NOTSD,	  /* No thread-specific data available.  */
+  TD_MALLOC,	  /* Out of memory.  */
+  TD_PARTIALREG,  /* Not entire register set was read or written.  */
+  TD_NOXREGS,	  /* X register set not available for given thread.  */
+  TD_TLSDEFER,	  /* Thread has not yet allocated TLS for given module.  */
+  TD_NOTALLOC = TD_TLSDEFER,
+  TD_VERSION,	  /* Version if libpthread and libthread_db do not match.  */
+  TD_NOTLS	  /* There is no TLS segment in the given module.  */
+} td_err_e;
+
+
+/* Possible thread states.  TD_THR_ANY_STATE is a pseudo-state used to
+   select threads regardless of state in td_ta_thr_iter().  */
+typedef enum
+{
+  TD_THR_ANY_STATE,
+  TD_THR_UNKNOWN,
+  TD_THR_STOPPED,
+  TD_THR_RUN,
+  TD_THR_ACTIVE,
+  TD_THR_ZOMBIE,
+  TD_THR_SLEEP,
+  TD_THR_STOPPED_ASLEEP
+} td_thr_state_e;
+
+/* Thread type: user or system.  TD_THR_ANY_TYPE is a pseudo-type used
+   to select threads regardless of type in td_ta_thr_iter().  */
+typedef enum
+{
+  TD_THR_ANY_TYPE,
+  TD_THR_USER,
+  TD_THR_SYSTEM
+} td_thr_type_e;
+
+
+/* Types of the debugging library.  */
+
+/* Handle for a process.  This type is opaque.  */
+typedef struct td_thragent td_thragent_t;
+
+/* The actual thread handle type.  This is also opaque.  */
+typedef struct td_thrhandle
+{
+  td_thragent_t *th_ta_p;
+  psaddr_t th_unique;
+} td_thrhandle_t;
+
+
+/* Forward declaration of a type defined by and for the dynamic linker.  */
+struct link_map;
+
+
+/* Flags for `td_ta_thr_iter'.  */
+#define TD_THR_ANY_USER_FLAGS	0xffffffff
+#define TD_THR_LOWEST_PRIORITY	-20
+#define TD_SIGNO_MASK		NULL
+
+
+#define TD_EVENTSIZE	2
+#define BT_UISHIFT	5 /* log base 2 of BT_NBIPUI, to extract word index */
+#define BT_NBIPUI	(1 << BT_UISHIFT)       /* n bits per unsigned int */
+#define BT_UIMASK	(BT_NBIPUI - 1)         /* to extract bit index */
+
+/* Bitmask of enabled events. */
+typedef struct td_thr_events
+{
+  uint32_t event_bits[TD_EVENTSIZE];
+} td_thr_events_t;
+
+/* Event set manipulation macros. */
+#define __td_eventmask(n) \
+  (UINT32_C (1) << (((n) - 1) & BT_UIMASK))
+#define __td_eventword(n) \
+  ((UINT32_C ((n) - 1)) >> BT_UISHIFT)
+
+#define td_event_emptyset(setp) \
+  do {									      \
+    int __i;								      \
+    for (__i = TD_EVENTSIZE; __i > 0; --__i)				      \
+      (setp)->event_bits[__i - 1] = 0;					      \
+  } while (0)
+
+#define td_event_fillset(setp) \
+  do {									      \
+    int __i;								      \
+    for (__i = TD_EVENTSIZE; __i > 0; --__i)				      \
+      (setp)->event_bits[__i - 1] = UINT32_C (0xffffffff);		      \
+  } while (0)
+
+#define td_event_addset(setp, n) \
+  (((setp)->event_bits[__td_eventword (n)]) |= __td_eventmask (n))
+#define td_event_delset(setp, n) \
+  (((setp)->event_bits[__td_eventword (n)]) &= ~__td_eventmask (n))
+#define td_eventismember(setp, n) \
+  (__td_eventmask (n) & ((setp)->event_bits[__td_eventword (n)]))
+#if TD_EVENTSIZE == 2
+# define td_eventisempty(setp) \
+  (!((setp)->event_bits[0]) && !((setp)->event_bits[1]))
+#else
+# error "td_eventisempty must be changed to match TD_EVENTSIZE"
+#endif
+
+/* Events reportable by the thread implementation.  */
+typedef enum
+{
+  TD_ALL_EVENTS,		 /* Pseudo-event number.  */
+  TD_EVENT_NONE = TD_ALL_EVENTS, /* Depends on context.  */
+  TD_READY,			 /* Is executable now. */
+  TD_SLEEP,			 /* Blocked in a synchronization obj.  */
+  TD_SWITCHTO,			 /* Now assigned to a process.  */
+  TD_SWITCHFROM,		 /* Not anymore assigned to a process.  */
+  TD_LOCK_TRY,			 /* Trying to get an unavailable lock.  */
+  TD_CATCHSIG,			 /* Signal posted to the thread.  */
+  TD_IDLE,			 /* Process getting idle.  */
+  TD_CREATE,			 /* New thread created.  */
+  TD_DEATH,			 /* Thread terminated.  */
+  TD_PREEMPT,			 /* Preempted.  */
+  TD_PRI_INHERIT,		 /* Inherited elevated priority.  */
+  TD_REAP,			 /* Reaped.  */
+  TD_CONCURRENCY,		 /* Number of processes changing.  */
+  TD_TIMEOUT,			 /* Conditional variable wait timed out.  */
+  TD_MIN_EVENT_NUM = TD_READY,
+  TD_MAX_EVENT_NUM = TD_TIMEOUT,
+  TD_EVENTS_ENABLE = 31		/* Event reporting enabled.  */
+} td_event_e;
+
+/* Values representing the different ways events are reported.  */
+typedef enum
+{
+  NOTIFY_BPT,			/* User must insert breakpoint at u.bptaddr. */
+  NOTIFY_AUTOBPT,		/* Breakpoint at u.bptaddr is automatically
+				   inserted.  */
+  NOTIFY_SYSCALL		/* System call u.syscallno will be invoked.  */
+} td_notify_e;
+
+/* Description how event type is reported.  */
+typedef struct td_notify
+{
+  td_notify_e type;		/* Way the event is reported.  */
+  union
+  {
+    psaddr_t bptaddr;		/* Address of breakpoint.  */
+    int syscallno;		/* Number of system call used.  */
+  } u;
+} td_notify_t;
+
+/* Structure used to report event.  */
+typedef struct td_event_msg
+{
+  td_event_e event;		/* Event type being reported.  */
+  const td_thrhandle_t *th_p;	/* Thread reporting the event.  */
+  union
+  {
+# if 0
+    td_synchandle_t *sh;	/* Handle of synchronization object.  */
+#endif
+    uintptr_t data;		/* Event specific data.  */
+  } msg;
+} td_event_msg_t;
+
+/* Structure containing event data available in each thread structure.  */
+typedef struct
+{
+  td_thr_events_t eventmask;	/* Mask of enabled events.  */
+  td_event_e eventnum;		/* Number of last event.  */
+  void *eventdata;		/* Data associated with event.  */
+} td_eventbuf_t;
+
+
+/* Gathered statistics about the process.  */
+typedef struct td_ta_stats
+{
+  int nthreads;       		/* Total number of threads in use.  */
+  int r_concurrency;		/* Concurrency level requested by user.  */
+  int nrunnable_num;		/* Average runnable threads, numerator.  */
+  int nrunnable_den;		/* Average runnable threads, denominator.  */
+  int a_concurrency_num;	/* Achieved concurrency level, numerator.  */
+  int a_concurrency_den;	/* Achieved concurrency level, denominator.  */
+  int nlwps_num;		/* Average number of processes in use,
+				   numerator.  */
+  int nlwps_den;		/* Average number of processes in use,
+				   denominator.  */
+  int nidle_num;		/* Average number of idling processes,
+				   numerator.  */
+  int nidle_den;		/* Average number of idling processes,
+				   denominator.  */
+} td_ta_stats_t;
+
+
+/* Since Sun's library is based on Solaris threads we have to define a few
+   types to map them to POSIX threads.  */
+typedef pthread_t thread_t;
+typedef pthread_key_t thread_key_t;
+
+
+/* Callback for iteration over threads.  */
+typedef int td_thr_iter_f (const td_thrhandle_t *, void *);
+
+/* Callback for iteration over thread local data.  */
+typedef int td_key_iter_f (thread_key_t, void (*) (void *), void *);
+
+
+
+/* Forward declaration.  This has to be defined by the user.  */
+struct ps_prochandle;
+
+
+/* Information about the thread.  */
+typedef struct td_thrinfo
+{
+  td_thragent_t *ti_ta_p;		/* Process handle.  */
+  unsigned int ti_user_flags;		/* Unused.  */
+  thread_t ti_tid;			/* Thread ID returned by
+					   pthread_create().  */
+  char *ti_tls;				/* Pointer to thread-local data.  */
+  psaddr_t ti_startfunc;		/* Start function passed to
+					   pthread_create().  */
+  psaddr_t ti_stkbase;			/* Base of thread's stack.  */
+  long int ti_stksize;			/* Size of thread's stack.  */
+  psaddr_t ti_ro_area;			/* Unused.  */
+  int ti_ro_size;			/* Unused.  */
+  td_thr_state_e ti_state;		/* Thread state.  */
+  unsigned char ti_db_suspended;	/* Nonzero if suspended by debugger. */
+  td_thr_type_e ti_type;		/* Type of the thread (system vs
+					   user thread).  */
+  intptr_t ti_pc;			/* Unused.  */
+  intptr_t ti_sp;			/* Unused.  */
+  short int ti_flags;			/* Unused.  */
+  int ti_pri;				/* Thread priority.  */
+  lwpid_t ti_lid;			/* Kernel PID for this thread.  */
+  sigset_t ti_sigmask;			/* Signal mask.  */
+  unsigned char ti_traceme;		/* Nonzero if event reporting
+					   enabled.  */
+  unsigned char ti_preemptflag;		/* Unused.  */
+  unsigned char ti_pirecflag;		/* Unused.  */
+  sigset_t ti_pending;			/* Set of pending signals.  */
+  td_thr_events_t ti_events;		/* Set of enabled events.  */
+} td_thrinfo_t;
+
+
+
+/* Prototypes for exported library functions.  */
+
+/* Initialize the thread debug support library.  */
+extern td_err_e td_init (void);
+
+/* Historical relict.  Should not be used anymore.  */
+extern td_err_e td_log (void);
+
+/* Return list of symbols the library can request.  */
+extern const char **td_symbol_list (void);
+
+/* Generate new thread debug library handle for process PS.  */
+extern td_err_e td_ta_new (struct ps_prochandle *__ps, td_thragent_t **__ta);
+
+/* Free resources allocated for TA.  */
+extern td_err_e td_ta_delete (td_thragent_t *__ta);
+
+/* Get number of currently running threads in process associated with TA.  */
+extern td_err_e td_ta_get_nthreads (const td_thragent_t *__ta, int *__np);
+
+/* Return process handle passed in `td_ta_new' for process associated with
+   TA.  */
+extern td_err_e td_ta_get_ph (const td_thragent_t *__ta,
+			      struct ps_prochandle **__ph);
+
+/* Map thread library handle PT to thread debug library handle for process
+   associated with TA and store result in *TH.  */
+extern td_err_e td_ta_map_id2thr (const td_thragent_t *__ta, pthread_t __pt,
+				  td_thrhandle_t *__th);
+
+/* Map process ID LWPID to thread debug library handle for process
+   associated with TA and store result in *TH.  */
+extern td_err_e td_ta_map_lwp2thr (const td_thragent_t *__ta, lwpid_t __lwpid,
+				   td_thrhandle_t *__th);
+
+
+/* Call for each thread in a process associated with TA the callback function
+   CALLBACK.  */
+extern td_err_e td_ta_thr_iter (const td_thragent_t *__ta,
+				td_thr_iter_f *__callback, void *__cbdata_p,
+				td_thr_state_e __state, int __ti_pri,
+				sigset_t *__ti_sigmask_p,
+				unsigned int __ti_user_flags);
+
+/* Call for each defined thread local data entry the callback function KI.  */
+extern td_err_e td_ta_tsd_iter (const td_thragent_t *__ta, td_key_iter_f *__ki,
+				void *__p);
+
+
+/* Get event address for EVENT.  */
+extern td_err_e td_ta_event_addr (const td_thragent_t *__ta,
+				  td_event_e __event, td_notify_t *__ptr);
+
+/* Enable EVENT in global mask.  */
+extern td_err_e td_ta_set_event (const td_thragent_t *__ta,
+				 td_thr_events_t *__event);
+
+/* Disable EVENT in global mask.  */
+extern td_err_e td_ta_clear_event (const td_thragent_t *__ta,
+				   td_thr_events_t *__event);
+
+/* Return information about last event.  */
+extern td_err_e td_ta_event_getmsg (const td_thragent_t *__ta,
+				    td_event_msg_t *__msg);
+
+
+/* Set suggested concurrency level for process associated with TA.  */
+extern td_err_e td_ta_setconcurrency (const td_thragent_t *__ta, int __level);
+
+
+/* Enable collecting statistics for process associated with TA.  */
+extern td_err_e td_ta_enable_stats (const td_thragent_t *__ta, int __enable);
+
+/* Reset statistics.  */
+extern td_err_e td_ta_reset_stats (const td_thragent_t *__ta);
+
+/* Retrieve statistics from process associated with TA.  */
+extern td_err_e td_ta_get_stats (const td_thragent_t *__ta,
+				 td_ta_stats_t *__statsp);
+
+
+/* Validate that TH is a thread handle.  */
+extern td_err_e td_thr_validate (const td_thrhandle_t *__th);
+
+/* Return information about thread TH.  */
+extern td_err_e td_thr_get_info (const td_thrhandle_t *__th,
+				 td_thrinfo_t *__infop);
+
+/* Retrieve floating-point register contents of process running thread TH.  */
+extern td_err_e td_thr_getfpregs (const td_thrhandle_t *__th,
+				  prfpregset_t *__regset);
+
+/* Retrieve general register contents of process running thread TH.  */
+extern td_err_e td_thr_getgregs (const td_thrhandle_t *__th,
+				 prgregset_t __gregs);
+
+/* Retrieve extended register contents of process running thread TH.  */
+extern td_err_e td_thr_getxregs (const td_thrhandle_t *__th, void *__xregs);
+
+/* Get size of extended register set of process running thread TH.  */
+extern td_err_e td_thr_getxregsize (const td_thrhandle_t *__th, int *__sizep);
+
+/* Set floating-point register contents of process running thread TH.  */
+extern td_err_e td_thr_setfpregs (const td_thrhandle_t *__th,
+				  const prfpregset_t *__fpregs);
+
+/* Set general register contents of process running thread TH.  */
+extern td_err_e td_thr_setgregs (const td_thrhandle_t *__th,
+				 prgregset_t __gregs);
+
+/* Set extended register contents of process running thread TH.  */
+extern td_err_e td_thr_setxregs (const td_thrhandle_t *__th,
+				 const void *__addr);
+
+
+/* Get address of the given module's TLS storage area for the given thread.  */
+extern td_err_e td_thr_tlsbase (const td_thrhandle_t *__th,
+				unsigned long int __modid,
+				psaddr_t *__base);
+
+/* Get address of thread local variable.  */
+extern td_err_e td_thr_tls_get_addr (const td_thrhandle_t *__th,
+				     psaddr_t __map_address, size_t __offset,
+				     psaddr_t *__address);
+
+
+/* Enable reporting for EVENT for thread TH.  */
+extern td_err_e td_thr_event_enable (const td_thrhandle_t *__th, int __event);
+
+/* Enable EVENT for thread TH.  */
+extern td_err_e td_thr_set_event (const td_thrhandle_t *__th,
+				  td_thr_events_t *__event);
+
+/* Disable EVENT for thread TH.  */
+extern td_err_e td_thr_clear_event (const td_thrhandle_t *__th,
+				    td_thr_events_t *__event);
+
+/* Get event message for thread TH.  */
+extern td_err_e td_thr_event_getmsg (const td_thrhandle_t *__th,
+				     td_event_msg_t *__msg);
+
+
+/* Set priority of thread TH.  */
+extern td_err_e td_thr_setprio (const td_thrhandle_t *__th, int __prio);
+
+
+/* Set pending signals for thread TH.  */
+extern td_err_e td_thr_setsigpending (const td_thrhandle_t *__th,
+				      unsigned char __n, const sigset_t *__ss);
+
+/* Set signal mask for thread TH.  */
+extern td_err_e td_thr_sigsetmask (const td_thrhandle_t *__th,
+				   const sigset_t *__ss);
+
+
+/* Return thread local data associated with key TK in thread TH.  */
+extern td_err_e td_thr_tsd (const td_thrhandle_t *__th,
+			    const thread_key_t __tk, void **__data);
+
+
+/* Suspend execution of thread TH.  */
+extern td_err_e td_thr_dbsuspend (const td_thrhandle_t *__th);
+
+/* Resume execution of thread TH.  */
+extern td_err_e td_thr_dbresume (const td_thrhandle_t *__th);
+
+#endif	/* thread_db.h */
diff --git a/REORG.TODO/nptl_db/thread_dbP.h b/REORG.TODO/nptl_db/thread_dbP.h
new file mode 100644
index 0000000000..c88ee2923f
--- /dev/null
+++ b/REORG.TODO/nptl_db/thread_dbP.h
@@ -0,0 +1,268 @@
+/* Private header for thread debug library
+   Copyright (C) 2003-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _THREAD_DBP_H
+#define _THREAD_DBP_H	1
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include "proc_service.h"
+#include "thread_db.h"
+#include "../nptl/pthreadP.h"  	/* This is for *_BITMASK only.  */
+#include <list.h>
+#include <gnu/lib-names.h>
+#include <libc-diag.h>
+
+/* Indeces for the symbol names.  */
+enum
+  {
+# define DB_STRUCT(type)		SYM_SIZEOF_##type,
+# define DB_STRUCT_FIELD(type, field)	SYM_##type##_FIELD_##field,
+# define DB_SYMBOL(name)		SYM_##name,
+# define DB_FUNCTION(name)		SYM_##name,
+# define DB_VARIABLE(name)		SYM_##name, SYM_DESC_##name,
+# include "structs.def"
+# undef DB_STRUCT
+# undef DB_STRUCT_FIELD
+# undef DB_SYMBOL
+# undef DB_FUNCTION
+# undef DB_VARIABLE
+
+    SYM_TH_UNIQUE_CONST_THREAD_AREA,
+    SYM_TH_UNIQUE_REGISTER64,
+    SYM_TH_UNIQUE_REGISTER32,
+    SYM_TH_UNIQUE_REGISTER64_THREAD_AREA,
+    SYM_TH_UNIQUE_REGISTER32_THREAD_AREA,
+
+    SYM_NUM_MESSAGES
+  };
+
+
+/* Comment out the following for less verbose output.  */
+#ifndef NDEBUG
+# define LOG(c) if (__td_debug) write (2, c "\n", strlen (c "\n"))
+extern int __td_debug attribute_hidden;
+#else
+# define LOG(c)
+#endif
+
+
+#define DB_DESC_SIZE(desc)	((desc)[0])
+#define DB_DESC_NELEM(desc)	((desc)[1])
+#define DB_DESC_OFFSET(desc)	((desc)[2])
+#define DB_SIZEOF_DESC		(3 * sizeof (uint32_t))
+#define DB_DEFINE_DESC(name, size, nelem, offset) \
+  const uint32_t name[3] = { (size), (nelem), (offset) }
+typedef uint32_t db_desc_t[3];
+
+
+/* Handle for a process.  This type is opaque.  */
+struct td_thragent
+{
+  /* Chain on the list of all agent structures.  */
+  list_t list;
+
+  /* Delivered by the debugger and we have to pass it back in the
+     proc callbacks.  */
+  struct ps_prochandle *ph;
+
+  /* Cached values read from the inferior.  */
+# define DB_STRUCT(type) \
+  uint32_t ta_sizeof_##type;
+# define DB_STRUCT_FIELD(type, field) \
+  db_desc_t ta_field_##type##_##field;
+# define DB_SYMBOL(name) \
+  psaddr_t ta_addr_##name;
+# define DB_FUNCTION(name) \
+  psaddr_t ta_addr_##name;
+# define DB_VARIABLE(name) \
+  psaddr_t ta_addr_##name; \
+  db_desc_t ta_var_##name;
+# include "structs.def"
+# undef DB_STRUCT
+# undef DB_STRUCT_FIELD
+# undef DB_FUNCTION
+# undef DB_SYMBOL
+# undef DB_VARIABLE
+
+  /* The method of locating a thread's th_unique value.  */
+  enum
+    {
+      ta_howto_unknown,
+      ta_howto_reg,
+      ta_howto_reg_thread_area,
+      ta_howto_const_thread_area
+    } ta_howto;
+  union
+  {
+    uint32_t const_thread_area;	/* Constant argument to ps_get_thread_area.  */
+    /* These are as if the descriptor of the field in prregset_t,
+       but DB_DESC_NELEM is overloaded as follows: */
+    db_desc_t reg;		/* Signed bias applied to register value.  */
+    db_desc_t reg_thread_area;	/* Bits to scale down register value.  */
+  } ta_howto_data;
+};
+
+
+/* List of all known descriptors.  */
+extern list_t __td_agent_list attribute_hidden;
+
+
+/* Function used to test for correct thread agent pointer.  */
+static inline bool
+ta_ok (const td_thragent_t *ta)
+{
+  list_t *runp;
+
+  list_for_each (runp, &__td_agent_list)
+    if (list_entry (runp, td_thragent_t, list) == ta)
+      return true;
+
+  return false;
+}
+
+
+/* Internal wrappers around ps_pglobal_lookup.  */
+extern ps_err_e td_mod_lookup (struct ps_prochandle *ps, const char *modname,
+			       int idx, psaddr_t *sym_addr) attribute_hidden;
+#define td_lookup(ps, idx, sym_addr) \
+  td_mod_lookup ((ps), LIBPTHREAD_SO, (idx), (sym_addr))
+
+
+/* Store in psaddr_t VAR the address of inferior's symbol NAME.  */
+#define DB_GET_SYMBOL(var, ta, name)					      \
+  (((ta)->ta_addr_##name == 0						      \
+    && td_lookup ((ta)->ph, SYM_##name, &(ta)->ta_addr_##name) != PS_OK)      \
+   ? TD_ERR : ((var) = (ta)->ta_addr_##name, TD_OK))
+
+/* Store in psaddr_t VAR the value of ((TYPE) PTR)->FIELD[IDX] in the inferior.
+   A target field smaller than psaddr_t is zero-extended.  */
+#define DB_GET_FIELD(var, ta, ptr, type, field, idx) \
+  _td_fetch_value ((ta), (ta)->ta_field_##type##_##field, \
+		   SYM_##type##_FIELD_##field, \
+		   (psaddr_t) 0 + (idx), (ptr), &(var))
+
+/* With GCC 5.3 when compiling with -Os the compiler emits a warning
+   that slot may be used uninitialized.  This is never the case since
+   the dynamic loader initializes the slotinfo list and
+   dtv_slotinfo_list will point slot at the first entry.  Therefore
+   when DB_GET_FIELD_ADDRESS is called with a slot for ptr, the slot is
+   always initialized.  */
+DIAG_PUSH_NEEDS_COMMENT;
+DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
+#define DB_GET_FIELD_ADDRESS(var, ta, ptr, type, field, idx) \
+  ((var) = (ptr), _td_locate_field ((ta), (ta)->ta_field_##type##_##field, \
+				    SYM_##type##_FIELD_##field, \
+				    (psaddr_t) 0 + (idx), &(var)))
+DIAG_POP_NEEDS_COMMENT;
+
+extern td_err_e _td_locate_field (td_thragent_t *ta,
+				  db_desc_t desc, int descriptor_name,
+				  psaddr_t idx,
+				  psaddr_t *address) attribute_hidden;
+
+
+/* Like DB_GET_FIELD, but PTR is a local pointer to a structure that
+   has already been copied in from the inferior.  */
+#define DB_GET_FIELD_LOCAL(var, ta, ptr, type, field, idx) \
+  _td_fetch_value_local ((ta), (ta)->ta_field_##type##_##field, \
+		         SYM_##type##_FIELD_##field, \
+			 (psaddr_t) 0 + (idx), (ptr), &(var))
+
+/* Store in psaddr_t VAR the value of variable NAME[IDX] in the inferior.
+   A target value smaller than psaddr_t is zero-extended.  */
+#define DB_GET_VALUE(var, ta, name, idx)				      \
+  (((ta)->ta_addr_##name == 0						      \
+    && td_lookup ((ta)->ph, SYM_##name, &(ta)->ta_addr_##name) != PS_OK)      \
+   ? TD_ERR								      \
+   : _td_fetch_value ((ta), (ta)->ta_var_##name, SYM_DESC_##name, 	      \
+		      (psaddr_t) 0 + (idx), (ta)->ta_addr_##name, &(var)))
+
+/* Helper functions for those.  */
+extern td_err_e _td_fetch_value (td_thragent_t *ta,
+				 db_desc_t field, int descriptor_name,
+				 psaddr_t idx, psaddr_t address,
+				 psaddr_t *result) attribute_hidden;
+extern td_err_e _td_fetch_value_local (td_thragent_t *ta,
+				       db_desc_t field,
+				       int descriptor_name,
+				       psaddr_t idx, void *address,
+				       psaddr_t *result) attribute_hidden;
+
+/* Store psaddr_t VALUE in ((TYPE) PTR)->FIELD[IDX] in the inferior.
+   A target field smaller than psaddr_t is zero-extended.  */
+#define DB_PUT_FIELD(ta, ptr, type, field, idx, value) \
+  _td_store_value ((ta), (ta)->ta_field_##type##_##field, \
+		   SYM_##type##_FIELD_##field, \
+		   (psaddr_t) 0 + (idx), (ptr), (value))
+
+#define DB_PUT_FIELD_LOCAL(ta, ptr, type, field, idx, value) \
+  _td_store_value_local ((ta), (ta)->ta_field_##type##_##field, \
+			 SYM_##type##_FIELD_##field, \
+			 (psaddr_t) 0 + (idx), (ptr), (value))
+
+/* Store psaddr_t VALUE in variable NAME[IDX] in the inferior.
+   A target field smaller than psaddr_t is zero-extended.  */
+#define DB_PUT_VALUE(ta, name, idx, value)				      \
+  (((ta)->ta_addr_##name == 0						      \
+    && td_lookup ((ta)->ph, SYM_##name, &(ta)->ta_addr_##name) != PS_OK)      \
+   ? TD_ERR								      \
+   : _td_store_value ((ta), (ta)->ta_var_##name, SYM_DESC_##name, 	      \
+		      (psaddr_t) 0 + (idx), (ta)->ta_addr_##name, (value)))
+
+/* Helper functions for those.  */
+extern td_err_e _td_store_value (td_thragent_t *ta,
+				 db_desc_t field, int descriptor_name,
+				 psaddr_t idx, psaddr_t address,
+				 psaddr_t value) attribute_hidden;
+extern td_err_e _td_store_value_local (td_thragent_t *ta,
+				       db_desc_t field, int descriptor_name,
+				       psaddr_t idx, void *address,
+				       psaddr_t value) attribute_hidden;
+
+#define DB_GET_STRUCT(var, ta, ptr, type)				      \
+  ({ td_err_e _err = TD_OK;						      \
+     if ((ta)->ta_sizeof_##type == 0)					      \
+       _err = _td_check_sizeof ((ta), &(ta)->ta_sizeof_##type,		      \
+				      SYM_SIZEOF_##type);		      \
+     if (_err == TD_OK)							      \
+       _err = ps_pdread ((ta)->ph, (ptr),				      \
+			 (var) = __alloca ((ta)->ta_sizeof_##type),	      \
+			 (ta)->ta_sizeof_##type)			      \
+	 == PS_OK ? TD_OK : TD_ERR;					      \
+     else								      \
+       (var) = NULL; 							      \
+     _err;								      \
+  })
+#define DB_PUT_STRUCT(ta, ptr, type, copy)				      \
+  ({ assert ((ta)->ta_sizeof_##type != 0);				      \
+     ps_pdwrite ((ta)->ph, (ptr), (copy), (ta)->ta_sizeof_##type)	      \
+       == PS_OK ? TD_OK : TD_ERR;					      \
+  })
+
+extern td_err_e _td_check_sizeof (td_thragent_t *ta, uint32_t *sizep,
+				  int sizep_name) attribute_hidden;
+
+extern td_err_e __td_ta_lookup_th_unique (const td_thragent_t *ta,
+					  lwpid_t lwpid, td_thrhandle_t *th);
+
+#endif /* thread_dbP.h */