summaryrefslogtreecommitdiff
path: root/libpthread/nptl_db
diff options
context:
space:
mode:
author"Steven J. Hill" <sjhill@realitydiluted.com>2005-05-07 02:04:55 +0000
committer"Steven J. Hill" <sjhill@realitydiluted.com>2005-05-07 02:04:55 +0000
commit0b3366f6a93ac0f7e2028745ea557c0acd8722c6 (patch)
tree2a87cb353c106eb55a44437d3b4d5e0d60af1d36 /libpthread/nptl_db
parent2274f6b2ddc7d7ea919a8fa1f9c54ef1920cb180 (diff)
Import in NPTL code from glibc. For further information please
consult the 'README.NPTL' file.
Diffstat (limited to 'libpthread/nptl_db')
-rw-r--r--libpthread/nptl_db/Makefile60
-rw-r--r--libpthread/nptl_db/Versions24
-rw-r--r--libpthread/nptl_db/db_info.c103
-rw-r--r--libpthread/nptl_db/fetch-value.c284
-rw-r--r--libpthread/nptl_db/proc_service.h87
-rw-r--r--libpthread/nptl_db/structs.def86
-rw-r--r--libpthread/nptl_db/td_init.c32
-rw-r--r--libpthread/nptl_db/td_log.c32
-rw-r--r--libpthread/nptl_db/td_symbol_list.c85
-rw-r--r--libpthread/nptl_db/td_ta_clear_event.c79
-rw-r--r--libpthread/nptl_db/td_ta_delete.c42
-rw-r--r--libpthread/nptl_db/td_ta_enable_stats.c35
-rw-r--r--libpthread/nptl_db/td_ta_event_addr.c61
-rw-r--r--libpthread/nptl_db/td_ta_event_getmsg.c105
-rw-r--r--libpthread/nptl_db/td_ta_get_nthreads.c42
-rw-r--r--libpthread/nptl_db/td_ta_get_ph.c36
-rw-r--r--libpthread/nptl_db/td_ta_get_stats.c35
-rw-r--r--libpthread/nptl_db/td_ta_map_id2thr.c38
-rw-r--r--libpthread/nptl_db/td_ta_map_lwp2thr.c178
-rw-r--r--libpthread/nptl_db/td_ta_new.c65
-rw-r--r--libpthread/nptl_db/td_ta_reset_stats.c35
-rw-r--r--libpthread/nptl_db/td_ta_set_event.c79
-rw-r--r--libpthread/nptl_db/td_ta_setconcurrency.c35
-rw-r--r--libpthread/nptl_db/td_ta_thr_iter.c148
-rw-r--r--libpthread/nptl_db/td_ta_tsd_iter.c81
-rw-r--r--libpthread/nptl_db/td_thr_clear_event.c77
-rw-r--r--libpthread/nptl_db/td_thr_dbresume.c30
-rw-r--r--libpthread/nptl_db/td_thr_dbsuspend.c30
-rw-r--r--libpthread/nptl_db/td_thr_event_enable.c34
-rw-r--r--libpthread/nptl_db/td_thr_event_getmsg.c119
-rw-r--r--libpthread/nptl_db/td_thr_get_info.c110
-rw-r--r--libpthread/nptl_db/td_thr_getfpregs.c53
-rw-r--r--libpthread/nptl_db/td_thr_getgregs.c53
-rw-r--r--libpthread/nptl_db/td_thr_getxregs.c30
-rw-r--r--libpthread/nptl_db/td_thr_getxregsize.c30
-rw-r--r--libpthread/nptl_db/td_thr_set_event.c77
-rw-r--r--libpthread/nptl_db/td_thr_setfpregs.c50
-rw-r--r--libpthread/nptl_db/td_thr_setgregs.c50
-rw-r--r--libpthread/nptl_db/td_thr_setprio.c30
-rw-r--r--libpthread/nptl_db/td_thr_setsigpending.c31
-rw-r--r--libpthread/nptl_db/td_thr_setxregs.c30
-rw-r--r--libpthread/nptl_db/td_thr_sigsetmask.c30
-rw-r--r--libpthread/nptl_db/td_thr_tls_get_addr.c43
-rw-r--r--libpthread/nptl_db/td_thr_tlsbase.c50
-rw-r--r--libpthread/nptl_db/td_thr_tsd.c96
-rw-r--r--libpthread/nptl_db/td_thr_validate.c91
-rw-r--r--libpthread/nptl_db/thread_db.h459
-rw-r--r--libpthread/nptl_db/thread_dbP.h254
48 files changed, 3744 insertions, 0 deletions
diff --git a/libpthread/nptl_db/Makefile b/libpthread/nptl_db/Makefile
new file mode 100644
index 000000000..5c73ff28f
--- /dev/null
+++ b/libpthread/nptl_db/Makefile
@@ -0,0 +1,60 @@
+# Copyright (C) 2002, 2003 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, write to the Free
+# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+# 02111-1307 USA.
+
+# Makefile for NPTL debug library subdirectory of GNU C Library.
+
+subdir := nptl_db
+
+nptl_db-version = 1.0
+
+extra-libs = libthread_db
+extra-libs-others := $(extra-libs)
+
+headers = thread_db.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
+
+distribute = thread_dbP.h shlib-versions proc_service.h db_info.c structs.def
+include ../Rules
+
+# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
+# This ensures they will load libc.so for needed symbols if loaded by
+# a statically-linked program that hasn't already loaded it.
+$(objpfx)libthread_db.so: $(common-objpfx)libc.so \
+ $(common-objpfx)libc_nonshared.a
diff --git a/libpthread/nptl_db/Versions b/libpthread/nptl_db/Versions
new file mode 100644
index 000000000..063493c67
--- /dev/null
+++ b/libpthread/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/libpthread/nptl_db/db_info.c b/libpthread/nptl_db/db_info.c
new file mode 100644
index 000000000..5000b99ba
--- /dev/null
+++ b/libpthread/nptl_db/db_info.c
@@ -0,0 +1,103 @@
+/* This file is included by pthread_create.c to define in libpthread
+ all the magic symbols required by libthread_db.
+
+ Copyright (C) 2003, 2004 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "thread_dbP.h"
+#include <tls.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;
+
+
+#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/libpthread/nptl_db/fetch-value.c b/libpthread/nptl_db/fetch-value.c
new file mode 100644
index 000000000..0d9bb0eb8
--- /dev/null
+++ b/libpthread/nptl_db/fetch-value.c
@@ -0,0 +1,284 @@
+/* Helper routines for libthread_db.
+ Copyright (C) 2003, 2004 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include "thread_dbP.h"
+#include <byteswap.h>
+#include <assert.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 && 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/libpthread/nptl_db/proc_service.h b/libpthread/nptl_db/proc_service.h
new file mode 100644
index 000000000..d49e87ab3
--- /dev/null
+++ b/libpthread/nptl_db/proc_service.h
@@ -0,0 +1,87 @@
+/* Callback interface for libthread_db, functions users must define.
+ Copyright (C) 1999,2002,2003 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* The definitions in this file must correspond to those in the debugger. */
+#include <sys/procfs.h>
+
+/* 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 (const 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 (const struct ps_prochandle *);
+extern ps_err_e ps_pcontinue (const struct ps_prochandle *);
+
+/* Stop or continue the given LWP alone. */
+extern ps_err_e ps_lstop (const struct ps_prochandle *, lwpid_t);
+extern ps_err_e ps_lcontinue (const struct ps_prochandle *, lwpid_t);
diff --git a/libpthread/nptl_db/structs.def b/libpthread/nptl_db/structs.def
new file mode 100644
index 000000000..b17a628e0
--- /dev/null
+++ b/libpthread/nptl_db/structs.def
@@ -0,0 +1,86 @@
+/* List of types and symbols in libpthread examined by libthread_db.
+ Copyright (C) 2003 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#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
+
+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_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)
+
+#if USE_TLS
+DB_STRUCT_FIELD (link_map, l_tls_modid)
+#endif
+
+#if !defined IS_IN_libpthread || USE_TLS
+DB_STRUCT_ARRAY_FIELD (dtv, dtv)