From 7f08f55a9f88d23fcfbf1fed00f4d5a094e5fffc Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 9 Sep 2003 07:01:01 +0000 Subject: * sysdeps/unix/sysv/linux/speed.c (cfsetospeed): Only set c_ospeed under [_HAVE_STRUCT_TERMIOS_C_OSPEED]. (cfsetispeed): Only set c_ispeed under [_HAVE_STRUCT_TERMIOS_C_ISPEED]. * sysdeps/unix/sysv/linux/bits/termios.h (_HAVE_STRUCT_TERMIOS_C_ISPEED, _HAVE_STRUCT_TERMIOS_C_OSPEED): Define. * sysdeps/unix/sysv/linux/alpha/bits/termios.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/bits/termios.h: Likewise. --- ChangeLog | 10 ++ nptl/ChangeLog | 24 +++ nptl/pthread_create.c | 7 +- nptl/pthread_key_create.c | 6 - nptl/sysdeps/alpha/td_ta_map_lwp2thr.c | 46 ----- nptl/sysdeps/alpha/tls.h | 4 + nptl/sysdeps/generic/td_ta_map_lwp2thr.c | 45 ----- nptl/sysdeps/i386/td_ta_map_lwp2thr.c | 48 ------ nptl/sysdeps/i386/tls.h | 5 + nptl/sysdeps/ia64/td_ta_map_lwp2thr.c | 44 ----- nptl/sysdeps/ia64/tls.h | 3 + nptl/sysdeps/powerpc/td_ta_map_lwp2thr.c | 44 ----- nptl/sysdeps/powerpc/tls.h | 7 + nptl/sysdeps/s390/td_ta_map_lwp2thr.c | 45 ----- nptl/sysdeps/s390/tls.h | 3 + nptl/sysdeps/sh/td_ta_map_lwp2thr.c | 44 ----- nptl/sysdeps/sh/tls.h | 3 + nptl/sysdeps/sparc/td_ta_map_lwp2thr.c | 44 ----- nptl/sysdeps/sparc/tls.h | 5 + nptl/sysdeps/x86_64/td_ta_map_lwp2thr.c | 43 ----- nptl/sysdeps/x86_64/tls.h | 3 + nptl_db/ChangeLog | 61 +++++++ nptl_db/Makefile | 5 +- nptl_db/db_info.c | 98 +++++++++++ nptl_db/fetch-value.c | 283 +++++++++++++++++++++++++++++++ nptl_db/proc_service.h | 100 ++++++----- nptl_db/structs.def | 86 ++++++++++ nptl_db/td_symbol_list.c | 33 ++-- nptl_db/td_ta_clear_event.c | 65 ++++--- nptl_db/td_ta_event_addr.c | 36 ++-- nptl_db/td_ta_event_getmsg.c | 91 +++++----- nptl_db/td_ta_get_nthreads.c | 21 +-- nptl_db/td_ta_map_lwp2thr.c | 179 +++++++++++++++++++ nptl_db/td_ta_new.c | 60 +------ nptl_db/td_ta_set_event.c | 65 ++++--- nptl_db/td_ta_thr_iter.c | 137 ++++++++------- nptl_db/td_ta_tsd_iter.c | 60 +++++-- nptl_db/td_thr_clear_event.c | 67 +++++--- nptl_db/td_thr_event_enable.c | 12 +- nptl_db/td_thr_event_getmsg.c | 92 +++++----- nptl_db/td_thr_get_info.c | 80 +++++++-- nptl_db/td_thr_getfpregs.c | 23 +-- nptl_db/td_thr_getgregs.c | 27 +-- nptl_db/td_thr_set_event.c | 67 +++++--- nptl_db/td_thr_setfpregs.c | 23 +-- nptl_db/td_thr_setgregs.c | 23 +-- nptl_db/td_thr_tls_get_addr.c | 34 ++-- nptl_db/td_thr_tlsbase.c | 39 ++--- nptl_db/td_thr_tsd.c | 81 ++++++--- nptl_db/td_thr_validate.c | 62 ++++--- nptl_db/thread_db.h | 6 +- nptl_db/thread_dbP.h | 239 +++++++++++++++++++++----- 52 files changed, 1718 insertions(+), 1020 deletions(-) delete mode 100644 nptl/sysdeps/alpha/td_ta_map_lwp2thr.c delete mode 100644 nptl/sysdeps/generic/td_ta_map_lwp2thr.c delete mode 100644 nptl/sysdeps/i386/td_ta_map_lwp2thr.c delete mode 100644 nptl/sysdeps/ia64/td_ta_map_lwp2thr.c delete mode 100644 nptl/sysdeps/powerpc/td_ta_map_lwp2thr.c delete mode 100644 nptl/sysdeps/s390/td_ta_map_lwp2thr.c delete mode 100644 nptl/sysdeps/sh/td_ta_map_lwp2thr.c delete mode 100644 nptl/sysdeps/sparc/td_ta_map_lwp2thr.c delete mode 100644 nptl/sysdeps/x86_64/td_ta_map_lwp2thr.c create mode 100644 nptl_db/db_info.c create mode 100644 nptl_db/fetch-value.c create mode 100644 nptl_db/structs.def create mode 100644 nptl_db/td_ta_map_lwp2thr.c diff --git a/ChangeLog b/ChangeLog index fc7f671a55..41acb7f98f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2003-09-08 Roland McGrath + + * sysdeps/unix/sysv/linux/speed.c + (cfsetospeed): Only set c_ospeed under [_HAVE_STRUCT_TERMIOS_C_OSPEED]. + (cfsetispeed): Only set c_ispeed under [_HAVE_STRUCT_TERMIOS_C_ISPEED]. + * sysdeps/unix/sysv/linux/bits/termios.h + (_HAVE_STRUCT_TERMIOS_C_ISPEED, _HAVE_STRUCT_TERMIOS_C_OSPEED): Define. + * sysdeps/unix/sysv/linux/alpha/bits/termios.h: Likewise. + * sysdeps/unix/sysv/linux/powerpc/bits/termios.h: Likewise. + 2003-09-08 Ulrich Drepper * sysdeps/unix/sysv/linux/x86_64/register-dump.h: Undo last change. diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 0b16c02fa9..dba84a4e7f 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,27 @@ +2003-09-05 Roland McGrath + + * pthread_create.c (__pthread_pthread_sizeof_descr): Removed. + Instead, include ../nptl_db/db_info.c to do its magic. + * pthread_key_create.c (__pthread_pthread_keys_max): Removed. + (__pthread_pthread_key_2ndlevel_size): Likewise. + * sysdeps/alpha/tls.h (DB_THREAD_SELF): New macro. + * sysdeps/i386/tls.h (DB_THREAD_SELF): New macro. + * sysdeps/ia64/tls.h (DB_THREAD_SELF): New macro. + * sysdeps/powerpc/tls.h (DB_THREAD_SELF): New macro. + * sysdeps/s390/tls.h (DB_THREAD_SELF): New macro. + * sysdeps/sh/tls.h (DB_THREAD_SELF): New macro. + * sysdeps/sparc/tls.h (DB_THREAD_SELF): New macro. + * sysdeps/x86_64/tls.h (DB_THREAD_SELF): New macro. + * sysdeps/alpha/td_ta_map_lwp2thr.c: File removed. + * sysdeps/generic/td_ta_map_lwp2thr.c: File removed. + * sysdeps/i386/td_ta_map_lwp2thr.c: File removed. + * sysdeps/ia64/td_ta_map_lwp2thr.c: File removed. + * sysdeps/powerpc/td_ta_map_lwp2thr.c: File removed. + * sysdeps/s390/td_ta_map_lwp2thr.c: File removed. + * sysdeps/sh/td_ta_map_lwp2thr.c: File removed. + * sysdeps/sparc/td_ta_map_lwp2thr.c: File removed. + * sysdeps/x86_64/td_ta_map_lwp2thr.c: File removed. + 2003-09-08 Ulrich Drepper * sysdeps/unix/sysv/linux/x86_64/bits/pthreadtypes.h: Change type diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index 49825f093e..f8ab269bdd 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -60,9 +60,6 @@ struct pthread_key_struct __pthread_keys[PTHREAD_KEYS_MAX] __attribute__ ((nocommon)); hidden_data_def (__pthread_keys) -/* This is for libthread_db only. */ -const int __pthread_pthread_sizeof_descr = sizeof (struct pthread); - struct pthread * internal_function __find_in_stack_list (pd) @@ -475,3 +472,7 @@ __pthread_create_2_0 (newthread, attr, start_routine, arg) compat_symbol (libpthread, __pthread_create_2_0, pthread_create, GLIBC_2_0); #endif + +/* Information for libthread_db. */ + +#include "../nptl_db/db_info.c" diff --git a/nptl/pthread_key_create.c b/nptl/pthread_key_create.c index 7827d9affc..cf35bc8776 100644 --- a/nptl/pthread_key_create.c +++ b/nptl/pthread_key_create.c @@ -24,12 +24,6 @@ /* Internal mutex for __pthread_keys table handling. */ lll_lock_t __pthread_keys_lock = LLL_LOCK_INITIALIZER; - -/* For debugging purposes put the maximum number of keys in a variable. */ -const int __pthread_pthread_keys_max = PTHREAD_KEYS_MAX; -const int __pthread_pthread_key_2ndlevel_size = PTHREAD_KEY_2NDLEVEL_SIZE; - - int __pthread_key_create (key, destr) pthread_key_t *key; diff --git a/nptl/sysdeps/alpha/td_ta_map_lwp2thr.c b/nptl/sysdeps/alpha/td_ta_map_lwp2thr.c deleted file mode 100644 index b30b10b123..0000000000 --- a/nptl/sysdeps/alpha/td_ta_map_lwp2thr.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Which thread is running on an LWP? PowerPC version. - 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. */ - -#include "thread_dbP.h" -#include - - -td_err_e -td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th) -{ - LOG ("td_ta_map_lwp2thr"); - - /* Test whether the TA parameter is ok. */ - if (! ta_ok (ta)) - return TD_BADTA; - - prgregset_t regs; - if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK) - return TD_ERR; - - /* The uniq value is stored in slot 33 in recent gdb; it isn't stored - anywhere otherwise. */ - th->th_unique = ((void *) regs[32] - - TLS_TCB_OFFSET - TLS_TCB_SIZE - TLS_PRE_TCB_SIZE); - - /* Found it. Now complete the `td_thrhandle_t' object. */ - th->th_ta_p = (td_thragent_t *) ta; - - return TD_OK; -} diff --git a/nptl/sysdeps/alpha/tls.h b/nptl/sysdeps/alpha/tls.h index 1718b3e466..8f61bb7409 100644 --- a/nptl/sysdeps/alpha/tls.h +++ b/nptl/sysdeps/alpha/tls.h @@ -118,6 +118,10 @@ typedef struct ((struct pthread *) (__builtin_thread_pointer () \ - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)) +/* Magic for libthread_db to know how to do THREAD_SELF. */ +# define DB_THREAD_SELF \ + REGISTER (64, 32 * 8, - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) + /* Identifier for the current thread. THREAD_SELF is usable but sometimes more expensive than necessary as in this case. */ # define THREAD_ID (__builtin_thread_pointer ()) diff --git a/nptl/sysdeps/generic/td_ta_map_lwp2thr.c b/nptl/sysdeps/generic/td_ta_map_lwp2thr.c deleted file mode 100644 index 126673e9af..0000000000 --- a/nptl/sysdeps/generic/td_ta_map_lwp2thr.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Which thread is running on an LWP? Stub version. - Copyright (C) 2002 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 -#include - - -td_err_e -td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th) -{ - LOG ("td_ta_map_lwp2thr"); - - /* Test whether the TA parameter is ok. */ - if (! ta_ok (ta)) - return TD_BADTA; - - prgregset_t regs; - if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK) - return TD_ERR; - -# error port this file - // th->th_unique = thread register; - - /* Found it. Now complete the `td_thrhandle_t' object. */ - th->th_ta_p = (td_thragent_t *) ta; - - return TD_OK; -} diff --git a/nptl/sysdeps/i386/td_ta_map_lwp2thr.c b/nptl/sysdeps/i386/td_ta_map_lwp2thr.c deleted file mode 100644 index 94f6d34987..0000000000 --- a/nptl/sysdeps/i386/td_ta_map_lwp2thr.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Which thread is running on an LWP? i386 version. - Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include "thread_dbP.h" -#include -#include - - -td_err_e -td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th) -{ - LOG ("td_ta_map_lwp2thr"); - - /* Test whether the TA parameter is ok. */ - if (! ta_ok (ta)) - return TD_BADTA; - - prgregset_t regs; - if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK) - return TD_ERR; - - /* Get the thread area for the addressed thread. */ - if (ps_get_thread_area (ta->ph, lwpid, regs[GS] >> 3, &th->th_unique) - != PS_OK) - return TD_ERR; /* XXX Other error value? */ - - /* Found it. Now complete the `td_thrhandle_t' object. */ - th->th_ta_p = (td_thragent_t *) ta; - - return TD_OK; -} diff --git a/nptl/sysdeps/i386/tls.h b/nptl/sysdeps/i386/tls.h index 85d6473380..873467ca77 100644 --- a/nptl/sysdeps/i386/tls.h +++ b/nptl/sysdeps/i386/tls.h @@ -251,6 +251,11 @@ union user_desc_init : "i" (offsetof (struct pthread, header.self))); \ __self;}) +/* Magic for libthread_db to know how to do THREAD_SELF. */ +# define DB_THREAD_SELF \ + REGISTER_THREAD_AREA (32, offsetof (struct user_regs_struct, xgs), 3) \ + REGISTER_THREAD_AREA (64, 26 * 8, 3) /* x86-64's user_regs_struct->gs */ + /* Read member of the thread descriptor directly. */ # define THREAD_GETMEM(descr, member) \ diff --git a/nptl/sysdeps/ia64/td_ta_map_lwp2thr.c b/nptl/sysdeps/ia64/td_ta_map_lwp2thr.c deleted file mode 100644 index b9f32eb8a1..0000000000 --- a/nptl/sysdeps/ia64/td_ta_map_lwp2thr.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Which thread is running on an LWP? IA-64 version. - 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. */ - -#include "thread_dbP.h" -#include - - -td_err_e -td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th) -{ - LOG ("td_ta_map_lwp2thr"); - - /* Test whether the TA parameter is ok. */ - if (! ta_ok (ta)) - return TD_BADTA; - - prgregset_t regs; - if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK) - return TD_ERR; - - /* IA-64 thread register is r13. */ - th->th_unique = (void *) (((struct pthread *) regs[13]) - 1); - - /* Found it. Now complete the `td_thrhandle_t' object. */ - th->th_ta_p = (td_thragent_t *) ta; - - return TD_OK; -} diff --git a/nptl/sysdeps/ia64/tls.h b/nptl/sysdeps/ia64/tls.h index 8a13a59d30..b6b20c0f50 100644 --- a/nptl/sysdeps/ia64/tls.h +++ b/nptl/sysdeps/ia64/tls.h @@ -113,6 +113,9 @@ register struct pthread *__thread_self __asm__("r13"); /* Return the thread descriptor for the current thread. */ # define THREAD_SELF (__thread_self - 1) +/* Magic for libthread_db to know how to do THREAD_SELF. */ +# define DB_THREAD_SELF REGISTER (64, 13 * 8, -sizeof (struct pthread)) + /* Access to data in the thread descriptor is easy. */ #define THREAD_GETMEM(descr, member) \ descr->member diff --git a/nptl/sysdeps/powerpc/td_ta_map_lwp2thr.c b/nptl/sysdeps/powerpc/td_ta_map_lwp2thr.c deleted file mode 100644 index d1a93681a3..0000000000 --- a/nptl/sysdeps/powerpc/td_ta_map_lwp2thr.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Which thread is running on an LWP? PowerPC version. - 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. */ - -#include "thread_dbP.h" -#include - - -td_err_e -td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th) -{ - LOG ("td_ta_map_lwp2thr"); - - /* Test whether the TA parameter is ok. */ - if (! ta_ok (ta)) - return TD_BADTA; - - prgregset_t regs; - if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK) - return TD_ERR; - - th->th_unique = ((void *) regs[PT_THREAD_POINTER] - - TLS_TCB_OFFSET - TLS_TCB_SIZE - TLS_PRE_TCB_SIZE); - - /* Found it. Now complete the `td_thrhandle_t' object. */ - th->th_ta_p = (td_thragent_t *) ta; - - return TD_OK; -} diff --git a/nptl/sysdeps/powerpc/tls.h b/nptl/sysdeps/powerpc/tls.h index 6573bb6b04..02595637c7 100644 --- a/nptl/sysdeps/powerpc/tls.h +++ b/nptl/sysdeps/powerpc/tls.h @@ -129,6 +129,13 @@ register void *__thread_register __asm__ ("r13"); ((struct pthread *) (__thread_register \ - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE)) +/* Magic for libthread_db to know how to do THREAD_SELF. */ +# define DB_THREAD_SELF \ + REGISTER (32, PT_THREAD_POINTER * 4, \ + - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) \ + REGISTER (64, PT_THREAD_POINTER * 8, \ + - TLS_TCB_OFFSET - TLS_PRE_TCB_SIZE) + /* Read member of the thread descriptor directly. */ # define THREAD_GETMEM(descr, member) ((void)(descr), (THREAD_SELF)->member) diff --git a/nptl/sysdeps/s390/td_ta_map_lwp2thr.c b/nptl/sysdeps/s390/td_ta_map_lwp2thr.c deleted file mode 100644 index 5b0bf840d8..0000000000 --- a/nptl/sysdeps/s390/td_ta_map_lwp2thr.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Which thread is running on an LWP? i386 version. - Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Martin Schwidefsky , 2003. - - 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 - - -td_err_e -td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th) -{ - LOG ("td_ta_map_lwp2thr"); - - /* Test whether the TA parameter is ok. */ - if (! ta_ok (ta)) - return TD_BADTA; - - prgregset_t regs; - if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK) - return TD_ERR; - - /* S390 thread register is ACR0, aka register 18. */ - th->th_unique = (void *) regs[18]; - - /* Found it. Now complete the `td_thrhandle_t' object. */ - th->th_ta_p = (td_thragent_t *) ta; - - return TD_OK; -} diff --git a/nptl/sysdeps/s390/tls.h b/nptl/sysdeps/s390/tls.h index 06237ae15b..7b38e3389d 100644 --- a/nptl/sysdeps/s390/tls.h +++ b/nptl/sysdeps/s390/tls.h @@ -137,6 +137,9 @@ typedef struct /* Return the thread descriptor for the current thread. */ # define THREAD_SELF ((struct pthread *) __builtin_thread_pointer ()) +/* Magic for libthread_db to know how to do THREAD_SELF. */ +# define DB_THREAD_SELF REGISTER (32, 18 * 4, 0) REGISTER (64, 18 * 8, 0) + /* Access to data in the thread descriptor is easy. */ #define THREAD_GETMEM(descr, member) \ descr->member diff --git a/nptl/sysdeps/sh/td_ta_map_lwp2thr.c b/nptl/sysdeps/sh/td_ta_map_lwp2thr.c deleted file mode 100644 index 75853009da..0000000000 --- a/nptl/sysdeps/sh/td_ta_map_lwp2thr.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Which thread is running on an LWP? Stub version. - 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. */ - -#include "thread_dbP.h" -#include -#include - - -td_err_e -td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th) -{ - LOG ("td_ta_map_lwp2thr"); - - /* Test whether the TA parameter is ok. */ - if (! ta_ok (ta)) - return TD_BADTA; - - prgregset_t regs; - if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK) - return TD_ERR; - - th->th_unique = regs[REG_GBR]; - - /* Found it. Now complete the `td_thrhandle_t' object. */ - th->th_ta_p = (td_thragent_t *) ta; - - return TD_OK; -} diff --git a/nptl/sysdeps/sh/tls.h b/nptl/sysdeps/sh/tls.h index 1e27b987e0..b6d8428bf6 100644 --- a/nptl/sysdeps/sh/tls.h +++ b/nptl/sysdeps/sh/tls.h @@ -117,6 +117,9 @@ typedef struct __asm ("stc gbr,%0" : "=r" (__self)); \ __self - 1;}) +/* Magic for libthread_db to know how to do THREAD_SELF. */ +# define DB_THREAD_SELF REGISTER (32, REG_GBR * 4, 0) + /* Read member of the thread descriptor directly. */ # define THREAD_GETMEM(descr, member) (descr->member) diff --git a/nptl/sysdeps/sparc/td_ta_map_lwp2thr.c b/nptl/sysdeps/sparc/td_ta_map_lwp2thr.c deleted file mode 100644 index f120b96e73..0000000000 --- a/nptl/sysdeps/sparc/td_ta_map_lwp2thr.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Which thread is running on an LWP? SPARC version. - 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. */ - -#include "thread_dbP.h" -#include - - -td_err_e -td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th) -{ - LOG ("td_ta_map_lwp2thr"); - - /* Test whether the TA parameter is ok. */ - if (! ta_ok (ta)) - return TD_BADTA; - - prgregset_t regs; - if (ps_lgetregs (ta->ph, lwpid, regs) != PS_OK) - return TD_ERR; - - /* SPARC thread register is %g7. */ - th->th_unique = (void *) regs[7]; - - /* Found it. Now complete the `td_thrhandle_t' object. */ - th->th_ta_p = (td_thragent_t *) ta; - - return TD_OK; -} diff --git a/nptl/sysdeps/sparc/tls.h b/nptl/sysdeps/sparc/tls.h index 87255941c1..8c4264f24f 100644 --- a/nptl/sysdeps/sparc/tls.h +++ b/nptl/sysdeps/sparc/tls.h @@ -104,6 +104,11 @@ register struct pthread *__thread_self __asm__("%g7"); /* Return the thread descriptor for the current thread. */ #define THREAD_SELF __thread_self +/* Magic for libthread_db to know how to do THREAD_SELF. */ +# define DB_THREAD_SELF_INCLUDE +# define DB_THREAD_SELF \ + REGISTER (32, REG_G7 * 4, 0) REGISTER (64, REG_G7 * 8, 0) + /* Access to data in the thread descriptor is easy. */ #define THREAD_GETMEM(descr, member) \ descr->member diff --git a/nptl/sysdeps/x86_64/td_ta_map_lwp2thr.c b/nptl/sysdeps/x86_64/td_ta_map_lwp2thr.c deleted file mode 100644 index d49d00c277..0000000000 --- a/nptl/sysdeps/x86_64/td_ta_map_lwp2thr.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Which thread is running on an LWP? x86-64 version. - Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include "thread_dbP.h" -#include -#include - - -td_err_e -td_ta_map_lwp2thr (const td_thragent_t *ta, lwpid_t lwpid, td_thrhandle_t *th) -{ - LOG ("td_ta_map_lwp2thr"); - - /* Test whether the TA parameter is ok. */ - if (! ta_ok (ta)) - return TD_BADTA; - - /* Get the %fs segment register base address for the addressed thread. */ - if (ps_get_thread_area (ta->ph, lwpid, FS, &th->th_unique) != PS_OK) - return TD_ERR; /* XXX Other error value? */ - - /* Found it. Now complete the `td_thrhandle_t' object. */ - th->th_ta_p = (td_thragent_t *) ta; - - return TD_OK; -} diff --git a/nptl/sysdeps/x86_64/tls.h b/nptl/sysdeps/x86_64/tls.h index 999c3aa55a..3d6111f4e3 100644 --- a/nptl/sysdeps/x86_64/tls.h +++ b/nptl/sysdeps/x86_64/tls.h @@ -161,6 +161,9 @@ typedef struct : "i" (offsetof (struct pthread, header.self))); \ __self;}) +/* Magic for libthread_db to know how to do THREAD_SELF. */ +# define DB_THREAD_SELF_INCLUDE /* For the FS constant. */ +# define DB_THREAD_SELF CONST_THREAD_AREA (64, FS) /* Read member of the thread descriptor directly. */ # define THREAD_GETMEM(descr, member) \ diff --git a/nptl_db/ChangeLog b/nptl_db/ChangeLog index 32781ec6f8..da38cee035 100644 --- a/nptl_db/ChangeLog +++ b/nptl_db/ChangeLog @@ -1,3 +1,64 @@ +2003-09-08 Roland McGrath + + * td_thr_get_info.c (td_thr_get_info): Cast th_unique to thread_t. + +2003-08-22 Roland McGrath + + * 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 + + * 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 + + * thread_dbP.h (td_lookup): Add attribute_hidden to decl. + +2003-08-04 Roland McGrath + + * td_ta_clear_event.c (td_ta_clear_event): Fix sizes in ps_* calls. + +2003-06-23 Roland McGrath + + * proc_service.h: Cosmetic and comment fixes. + 2003-06-19 Roland McGrath * td_thr_event_enable.c (td_thr_event_enable): Use proper type `bool' diff --git a/nptl_db/Makefile b/nptl_db/Makefile index d6dcec5aea..5c73ff28f2 100644 --- a/nptl_db/Makefile +++ b/nptl_db/Makefile @@ -42,14 +42,15 @@ libthread_db-routines = td_init td_log td_ta_new td_ta_delete \ 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 + 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 +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. diff --git a/nptl_db/db_info.c b/nptl_db/db_info.c new file mode 100644 index 0000000000..aa485369b2 --- /dev/null +++ b/nptl_db/db_info.c @@ -0,0 +1,98 @@ +/* This file is included by pthread_create.c to define in libpthread + all the magic symbols required 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. */ + +#include "thread_dbP.h" +#include + +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. */ +DESC (_thread_db_pthread_dtvp, + TLS_PRE_TCB_SIZE + offsetof (tcbhead_t, dtv), 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. */ +#include "structs.def" +#undef DB_STRUCT +#undef DB_STRUCT_FIELD +#undef DB_SYMBOL +#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, regofs, bias) \ + DB_DEFINE_DESC (_thread_db_register##bits, bits, (uint32_t)(bias), (regofs)); + +DB_THREAD_SELF +#endif diff --git a/nptl_db/fetch-value.c b/nptl_db/fetch-value.c new file mode 100644 index 0000000000..9d40b61691 --- /dev/null +++ b/nptl_db/fetch-value.c @@ -0,0 +1,283 @@ +/* Helper routines for 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. */ + +#include "thread_dbP.h" +#include +#include + +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 += DB_DESC_OFFSET (desc) + (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/nptl_db/proc_service.h b/nptl_db/proc_service.h index 9963c3aecd..d49e87ab30 100644 --- a/nptl_db/proc_service.h +++ b/nptl_db/proc_service.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1999, 2002 Free Software Foundation, Inc. +/* 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 @@ -19,55 +20,68 @@ /* The definitions in this file must correspond to those in the debugger. */ #include +/* Functions in this interface return one of these status codes. */ typedef enum { - PS_OK, /* generic "call succeeded" */ - PS_ERR, /* generic. */ - PS_BADPID, /* bad process handle */ - PS_BADLID, /* bad lwp identifier */ - PS_BADADDR, /* bad address */ - PS_NOSYM, /* p_lookup() could not find given symbol */ - PS_NOFREGS - /* - * FPU register set not available for given - * lwp - */ -} ps_err_e; - - -struct ps_prochandle; /* user defined. */ - - -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); - -extern ps_err_e ps_pglobal_lookup(struct ps_prochandle *, - const char *object_name, const char *sym_name, psaddr_t *sym_addr); - - -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 *); - + 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); - -extern ps_err_e ps_get_thread_area (const struct ps_prochandle *, lwpid_t, - int, psaddr_t *); diff --git a/nptl_db/structs.def b/nptl_db/structs.def new file mode 100644 index 0000000000..c8b31bb7f5 --- /dev/null +++ b/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_SYMBOL (__nptl_create_event) +DB_SYMBOL (__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) +#endif +#if !defined IS_IN_libpthread || TLS_TCB_AT_TP +DB_STRUCT_FIELD (pthread, dtvp) +#endif + +#ifdef STRUCTS_DEF_DEFAULTS +# undef DB_STRUCT_ARRAY_FIELD +# undef DB_ARRAY_VARIABLE +# undef STRUCTS_DEF_DEFAULTS +#endif diff --git a/nptl_db/td_symbol_list.c b/nptl_db/td_symbol_list.c index 252faa418d..061767eb74 100644 --- a/nptl_db/td_symbol_list.c +++ b/nptl_db/td_symbol_list.c @@ -25,17 +25,26 @@ static const char *symbol_list_arr[] = { - [SYM_PTHREAD_THREADS_EVENTS] = "__nptl_threads_events", - [SYM_PTHREAD_LAST_EVENT] = "__nptl_last_event", - [SYM_PTHREAD_NTHREADS] = "__nptl_nthreads", - [SYM_PTHREAD_STACK_USED] = "stack_used", - [SYM_PTHREAD_STACK_USER] = "__stack_user", - [SYM_PTHREAD_KEYS] = "__pthread_keys", - [SYM_PTHREAD_KEYS_MAX] = "__pthread_pthread_keys_max", - [SYM_PTHREAD_SIZEOF_DESCR] = "__pthread_pthread_sizeof_descr", - [SYM_PTHREAD_CREATE_EVENT] = "__nptl_create_event", - [SYM_PTHREAD_DEATH_EVENT] = "__nptl_death_event", - [SYM_PTHREAD_VERSION] = "nptl_version", +# define DB_STRUCT(type) \ + [SYM_SIZEOF_##type] = "_thread_db_sizeof_" #type, +# define DB_STRUCT_FIELD(type, field) \ + [SYM_##type##_FIELD_##field] = "_thread_db_" #type "_" #field, +# define DB_SYMBOL(name) \ + [SYM_##name] = #name, +# define DB_VARIABLE(name) \ + [SYM_##name] = #name, \ + [SYM_DESC_##name] = "_thread_db_" #name, +# include "structs.def" +# undef DB_STRUCT +# undef DB_SYMBOL +# undef DB_VARIABLE + + [SYM_TH_UNIQUE_CONST_THREAD_AREA] = "_thread_db_const_thread_area", + [SYM_TH_UNIQUE_REGISTER64] = "_thread_db_register64", + [SYM_TH_UNIQUE_REGISTER32] = "_thread_db_register32", + [SYM_TH_UNIQUE_REGISTER32_THREAD_AREA] = "_thread_db_register32_thread_area", + [SYM_TH_UNIQUE_REGISTER64_THREAD_AREA] = "_thread_db_register64_thread_area", + [SYM_NUM_MESSAGES] = NULL }; @@ -47,7 +56,7 @@ td_symbol_list (void) } -int +ps_err_e td_lookup (struct ps_prochandle *ps, int idx, psaddr_t *sym_addr) { assert (idx >= 0 && idx < SYM_NUM_MESSAGES); diff --git a/nptl_db/td_ta_clear_event.c b/nptl_db/td_ta_clear_event.c index 611281fbaa..d45d75ba83 100644 --- a/nptl_db/td_ta_clear_event.c +++ b/nptl_db/td_ta_clear_event.c @@ -1,5 +1,5 @@ /* Globally disable events. - Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1999. @@ -22,31 +22,58 @@ td_err_e -td_ta_clear_event (ta, event) - const td_thragent_t *ta; +td_ta_clear_event (ta_arg, 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; + void *copy; + LOG ("td_ta_clear_event"); /* Test whether the TA parameter is ok. */ if (! ta_ok (ta)) return TD_BADTA; - /* Write the new value into the thread data structure. */ - td_thr_events_t old_event; - if (ps_pdread (ta->ph, ta->pthread_threads_eventsp, - &old_event, sizeof (td_thrhandle_t)) != PS_OK) - return TD_ERR; /* XXX Other error value? */ - - /* Remove the set bits in. */ - int i; - for (i = 0; i < TD_EVENTSIZE; ++i) - old_event.event_bits[i] &= ~event->event_bits[i]; - - /* Write the new value into the thread data structure. */ - if (ps_pdwrite (ta->ph, ta->pthread_threads_eventsp, - &old_event, sizeof (td_thrhandle_t)) != PS_OK) - return TD_ERR; /* XXX Other error value? */ + /* 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 TD_OK; + return err; } diff --git a/nptl_db/td_ta_event_addr.c b/nptl_db/td_ta_event_addr.c index 906835dc73..37196e643f 100644 --- a/nptl_db/td_ta_event_addr.c +++ b/nptl_db/td_ta_event_addr.c @@ -1,5 +1,5 @@ /* Get event address. - Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1999,2001,2002,2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1999. @@ -22,10 +22,12 @@ td_err_e -td_ta_event_addr (const td_thragent_t *ta, td_event_e event, td_notify_t *addr) +td_ta_event_addr (const td_thragent_t *ta_arg, + td_event_e event, td_notify_t *addr) { - td_err_e res = TD_NOEVENT; - int idx = -1; + td_thragent_t *const ta = (td_thragent_t *) ta_arg; + td_err_e err; + psaddr_t taddr; LOG ("td_ta_event_addr"); @@ -36,34 +38,24 @@ td_ta_event_addr (const td_thragent_t *ta, td_event_e event, td_notify_t *addr) switch (event) { case TD_CREATE: - idx = SYM_PTHREAD_CREATE_EVENT; + err = DB_GET_SYMBOL (taddr, ta, __nptl_create_event); break; case TD_DEATH: - idx = SYM_PTHREAD_DEATH_EVENT; + err = DB_GET_SYMBOL (taddr, ta, __nptl_death_event); break; default: /* Event cannot be handled. */ - break; + return TD_NOEVENT; } - /* Now get the address. */ - if (idx != -1) + if (err == TD_OK) { - psaddr_t taddr; - - if (td_lookup (ta->ph, idx, &taddr) == PS_OK) - { - /* Success, we got the address. */ - addr->type = NOTIFY_BPT; - addr->u.bptaddr = taddr; - - res = TD_OK; - } - else - res = TD_ERR; + /* Success, we got the address. */ + addr->type = NOTIFY_BPT; + addr->u.bptaddr = taddr; } - return res; + return err; } diff --git a/nptl_db/td_ta_event_getmsg.c b/nptl_db/td_ta_event_getmsg.c index bab44cddda..6e68ff4ff2 100644 --- a/nptl_db/td_ta_event_getmsg.c +++ b/nptl_db/td_ta_event_getmsg.c @@ -25,76 +25,81 @@ td_err_e -td_ta_event_getmsg (const td_thragent_t *ta, td_event_msg_t *msg) +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_ta_event_getmsg"); + 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. */ - psaddr_t addr; - if (ps_pdread (ta->ph, ta->pthread_last_event, - &addr, sizeof (struct pthread *)) != PS_OK) - return TD_ERR; /* XXX Other error value? */ + err = DB_GET_VALUE (thp, ta, __nptl_last_event, 0); + if (err != TD_OK) + return err; - if (addr == 0) + if (thp == 0) /* Nothing waiting. */ return TD_NOMSG; - /* Read the event structure from the target. */ - td_eventbuf_t event; - if (ps_pdread (ta->ph, (char *) addr + offsetof (struct pthread, eventbuf), - &event, sizeof (td_eventbuf_t)) != PS_OK) - return TD_ERR; /* XXX Other error value? */ - + /* 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 (event.eventnum == TD_EVENT_NONE) + 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 = addr; + th.th_unique = thp; /* Fill the user's data structure. */ - msg->event = event.eventnum; + msg->msg.data = (uintptr_t) eventdata; + msg->event = (uintptr_t) eventnum; msg->th_p = &th; - msg->msg.data = (uintptr_t) event.eventdata; /* And clear the event message in the target. */ - memset (&event, '\0', sizeof (td_eventbuf_t)); - if (ps_pdwrite (ta->ph, (char *) addr + offsetof (struct pthread, eventbuf), - &event, sizeof (td_eventbuf_t)) != PS_OK) - return TD_ERR; /* XXX Other error value? */ + 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. */ - psaddr_t next; - if (ps_pdread (ta->ph, (char *) addr + offsetof (struct pthread, nextevent), - &next, sizeof (struct pthread *)) != PS_OK) - return TD_ERR; /* XXX Other error value? */ - - if (next == addr) - return TD_DBERR; + err = DB_GET_FIELD (next, ta, thp, pthread, nextevent, 0); + if (err != TD_OK) + return err; /* Store the pointer in the list head variable. */ - if (ps_pdwrite (ta->ph, ta->pthread_last_event, - &next, sizeof (struct pthread *)) != PS_OK) - return TD_ERR; /* XXX Other error value? */ - - if (next != NULL) - { - /* Clear the next pointer in the current descriptor. */ - next = NULL; - if (ps_pdwrite (ta->ph, - (char *) addr + offsetof (struct pthread, nextevent), - &next, sizeof (struct pthread *)) != PS_OK) - return TD_ERR; /* XXX Other error value? */ - } - - return TD_OK; + 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/nptl_db/td_ta_get_nthreads.c b/nptl_db/td_ta_get_nthreads.c index cfe93d1b19..ffe78bd57e 100644 --- a/nptl_db/td_ta_get_nthreads.c +++ b/nptl_db/td_ta_get_nthreads.c @@ -1,5 +1,5 @@ /* Get the number of threads in the process. - Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1999,2001,2002,2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1999. @@ -21,21 +21,22 @@ #include "thread_dbP.h" td_err_e -td_ta_get_nthreads (const td_thragent_t *ta, int *np) +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 `__pthread_handles_num'. */ - psaddr_t addr; - if (td_lookup (ta->ph, SYM_PTHREAD_NTHREADS, &addr) != PS_OK) - return TD_ERR; /* XXX Other error value? */ - - if (ps_pdread (ta->ph, addr, np, sizeof (int)) != PS_OK) - return TD_ERR; /* XXX Other error value? */ + /* 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 TD_OK; + return err; } diff --git a/nptl_db/td_ta_map_lwp2thr.c b/nptl_db/td_ta_map_lwp2thr.c new file mode 100644 index 0000000000..1e47528314 --- /dev/null +++ b/nptl_db/td_ta_map_lwp2thr.c @@ -0,0 +1,179 @@ +/* Which thread is running on an LWP? + 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. */ + +#include "thread_dbP.h" +#include +#include +#include + + +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; + ps_err_e err; + td_err_e terr; + prgregset_t regs; + psaddr_t addr; + + LOG ("td_ta_map_lwp2thr"); + + /* Test whether the TA parameter is ok. */ + if (! ta_ok (ta)) + return TD_BADTA; + + 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.co