summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libpthread/nptl_db/ChangeLog207
-rw-r--r--libpthread/nptl_db/Makefile13
-rw-r--r--libpthread/nptl_db/Makefile.in71
-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.def88
-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.c87
-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.c55
-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.h258
49 files changed, 3964 insertions, 0 deletions
diff --git a/libpthread/nptl_db/ChangeLog b/libpthread/nptl_db/ChangeLog
new file mode 100644
index 000000000..52c849138
--- /dev/null
+++ b/libpthread/nptl_db/ChangeLog
@@ -0,0 +1,207 @@
+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/libpthread/nptl_db/Makefile b/libpthread/nptl_db/Makefile
new file mode 100644
index 000000000..f9100219a
--- /dev/null
+++ b/libpthread/nptl_db/Makefile
@@ -0,0 +1,13 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+top_srcdir=../../
+top_builddir=../../
+include $(top_builddir)Rules.mak
+all: libs
+include Makefile.in
+include $(top_srcdir)Makerules
diff --git a/libpthread/nptl_db/Makefile.in b/libpthread/nptl_db/Makefile.in
new file mode 100644
index 000000000..3eaded59f
--- /dev/null
+++ b/libpthread/nptl_db/Makefile.in
@@ -0,0 +1,71 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+
+subdirs += libpthread/nptl/nptl_db
+
+# Get the thread include dependencies and shared object name
+CFLAGS-nptl_db := -DLIBPTHREAD_SO="\"libpthread.so.$(MAJOR_VERSION)\""
+CFLAGS-nptl_db += -I$(top_srcdir)libpthread/nptl -D_GNU_SOURCE
+CFLAGS-nptl_db += -DIS_IN_libthread_db=1 -std=gnu99 -I$(top_srcdir)ldso/include
+
+LDFLAGS-libthread_db.so := $(LDFLAGS_NOSTRIP) -s --warn-unresolved-symbols
+
+LIBS-libthread_db.so := $(LIBS)
+
+libthread_db_FULL_NAME := libthread_db-$(VERSION).so
+
+libthread_db_DIR := $(top_srcdir)libpthread/nptl_db
+libthread_db_OUT := $(top_builddir)libpthread/nptl_db
+
+libthread_db_SRC := $(wildcard $(libthread_db_DIR)/td_*.c) \
+ $(libthread_db_DIR)/fetch-value.c
+
+libthread_db_OBJ := $(patsubst $(libthread_db_DIR)/%.c,$(libthread_db_OUT)/%.o,$(libthread_db_SRC))
+
+libthread_db-so-y := $(libthread_db_OBJ:.o=.oS)
+ifeq ($(DOPIC),y)
+libthread_db-a-y := $(libthread_db-so-y)
+else
+libthread_db-a-y := $(libthread_db_OBJ)
+endif
+
+libthread_db-multi-y := $(libthread_db_SRC)
+
+lib-a-$(PTHREADS_DEBUG_SUPPORT) += $(top_builddir)lib/libthread_db.a
+lib-so-$(PTHREADS_DEBUG_SUPPORT) += $(top_builddir)lib/libthread_db.so
+objclean-y += libthread_db_clean
+headers-$(PTHREADS_DEBUG_SUPPORT) += $(nptl_db_headers)
+headers_clean-y += nptl_db_headers_clean
+
+ifeq ($(DOPIC),y)
+$(top_builddir)lib/libthread_db.so: $(top_builddir)lib/libthread_db.a $(libc)
+else
+$(top_builddir)lib/libthread_db.so: $(libthread_db_OUT)/libthread_db_so.a $(libc)
+endif
+ $(call link.so,$(libthread_db_FULL_NAME),1)
+
+$(libthread_db_OUT)/libthread_db_so.a: $(libthread_db-so-y)
+ $(Q)$(RM) $@
+ $(do_strip)
+ $(do_ar)
+
+$(top_builddir)lib/libthread_db.a: $(libthread_db-a-y)
+ $(Q)$(INSTALL) -d $(dir $@)
+ $(Q)$(RM) $@
+ $(do_strip)
+ $(do_ar)
+
+$(top_builddir)include/thread_db.h:
+ $(do_ln) $(call rel_srcdir)$(PTDIR)_db/$(@F) $@
+
+nptl_db_headers:= $(top_builddir)include/thread_db.h
+
+nptl_db_headers_clean:
+ $(do_rm) $(nptl_db_headers)
+
+libthread_db_clean:
+ $(do_rm) $(addprefix $(libthread_db_OUT)/*., o oS a)
diff --git a/libpthread/nptl_db/db_info.c b/libpthread/nptl_db/db_info.c
new file mode 100644
index 000000000..5aec152d5
--- /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 defined(TLS_TCB_AT_TP)
+# define dtvp header.dtv
+#elif defined(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))
+ {
<