diff --git a/linuxthreads_db/Makefile b/linuxthreads_db/Makefile index 1265a7864e..53e46f7758 100644 --- a/linuxthreads_db/Makefile +++ b/linuxthreads_db/Makefile @@ -39,7 +39,8 @@ libthread_db-routines = td_init td_log td_ta_delete td_ta_get_nthreads \ 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_tls_get_addr + td_ta_clear_event td_symbol_list \ + td_thr_tlsbase td_thr_tls_get_addr libthread_db-inhibit-o = $(filter-out .os,$(object-suffixes)) diff --git a/linuxthreads_db/Versions b/linuxthreads_db/Versions index 4ca8042c12..063493c676 100644 --- a/linuxthreads_db/Versions +++ b/linuxthreads_db/Versions @@ -18,4 +18,7 @@ libthread_db { GLIBC_2.3 { td_thr_tls_get_addr; } + GLIBC_2.3.3 { + td_thr_tlsbase; + } } diff --git a/linuxthreads_db/td_thr_tls_get_addr.c b/linuxthreads_db/td_thr_tls_get_addr.c index 223fa663fc..c900cac8e0 100644 --- a/linuxthreads_db/td_thr_tls_get_addr.c +++ b/linuxthreads_db/td_thr_tls_get_addr.c @@ -18,14 +18,9 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include #include #include "thread_dbP.h" -/* Value used for dtv entries for which the allocation is delayed. */ -# define TLS_DTV_UNALLOCATED ((void *) -1l) - - td_err_e td_thr_tls_get_addr (const td_thrhandle_t *th __attribute__ ((unused)), void *map_address __attribute__ ((unused)), @@ -33,44 +28,17 @@ td_thr_tls_get_addr (const td_thrhandle_t *th __attribute__ ((unused)), void **address __attribute__ ((unused))) { #if USE_TLS - size_t modid; - union dtv pdtv, *dtvp; - - LOG ("td_thr_tls_get_addr"); - - psaddr_t dtvpp = th->th_unique; -#if TLS_TCB_AT_TP - dtvpp += offsetof (struct _pthread_descr_struct, p_header.data.dtvp); -#elif TLS_DTV_AT_TP - dtvpp += TLS_PRE_TCB_SIZE + offsetof (tcbhead_t, dtv); -#else -# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined." -#endif - - /* Get the DTV pointer from the thread descriptor. */ - if (ps_pdread (th->th_ta_p->ph, dtvpp, &dtvp, sizeof dtvp) != PS_OK) - return TD_ERR; /* XXX Other error value? */ - /* Read the module ID from the link_map. */ + size_t modid; if (ps_pdread (th->th_ta_p->ph, &((struct link_map *) map_address)->l_tls_modid, &modid, sizeof modid) != PS_OK) return TD_ERR; /* XXX Other error value? */ - /* Get the corresponding entry in the DTV. */ - if (ps_pdread (th->th_ta_p->ph, dtvp + modid, - &pdtv, sizeof (union dtv)) != PS_OK) - return TD_ERR; /* XXX Other error value? */ - - /* It could be that the memory for this module is not allocated for - the given thread. */ - if (pdtv.pointer == TLS_DTV_UNALLOCATED) - /* There is not much we can do. */ - return TD_NOTALLOC; - - *address = (char *) pdtv.pointer + offset; - - return TD_OK; + td_err_e result = td_thr_tlsbase (th, modid, address); + if (result == TD_OK) + *address += offset; + return result; #else return TD_ERR; #endif diff --git a/linuxthreads_db/td_thr_tlsbase.c b/linuxthreads_db/td_thr_tlsbase.c new file mode 100644 index 0000000000..bcf06539e9 --- /dev/null +++ b/linuxthreads_db/td_thr_tlsbase.c @@ -0,0 +1,67 @@ +/* Locate TLS data for a thread. + 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" + +/* Value used for dtv entries for which the allocation is delayed. */ +# define TLS_DTV_UNALLOCATED ((void *) -1l) + +td_err_e +td_thr_tlsbase (const td_thrhandle_t *th, + unsigned long int modid, + psaddr_t *base) +{ + if (modid < 1) + return TD_NOTLS; + +#if USE_TLS + union dtv pdtv, *dtvp; + + LOG ("td_thr_tlsbase"); + + psaddr_t dtvpp = th->th_unique; +#if TLS_TCB_AT_TP + dtvpp += offsetof (struct _pthread_descr_struct, p_header.data.dtvp); +#elif TLS_DTV_AT_TP + dtvpp += TLS_PRE_TCB_SIZE + offsetof (tcbhead_t, dtv); +#else +# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined." +#endif + + /* Get the DTV pointer from the thread descriptor. */ + if (ps_pdread (th->th_ta_p->ph, dtvpp, &dtvp, sizeof dtvp) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Get the corresponding entry in the DTV. */ + if (ps_pdread (th->th_ta_p->ph, dtvp + modid, + &pdtv, sizeof (union dtv)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* It could be that the memory for this module is not allocated for + the given thread. */ + if (pdtv.pointer == TLS_DTV_UNALLOCATED) + return TD_TLSDEFER; + + *base = (char *) pdtv.pointer; + + return TD_OK; +#else + return TD_ERR; +#endif +} diff --git a/linuxthreads_db/thread_db.h b/linuxthreads_db/thread_db.h index f0d9aa7c37..c115399a32 100644 --- a/linuxthreads_db/thread_db.h +++ b/linuxthreads_db/thread_db.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. +/* thread_db.h -- interface to libthread_db.so library for debugging -lpthread + Copyright (C) 1999,2001,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 @@ -52,8 +53,10 @@ typedef enum TD_MALLOC, /* Out of memory. */ TD_PARTIALREG, /* Not entire register set was read or written. */ TD_NOXREGS, /* X register set not available for given thread. */ - TD_NOTALLOC, /* TLS memory not yet allocated. */ - TD_VERSION /* Version if libpthread and libthread_db do not match. */ + TD_TLSDEFER, /* Thread has not yet allocated TLS for given module. */ + TD_NOTALLOC = TD_TLSDEFER, + TD_VERSION, /* Version if libpthread and libthread_db do not match. */ + TD_NOTLS /* There is TLS segment in the given module. */ } td_err_e; @@ -402,6 +405,11 @@ extern td_err_e td_thr_setxregs (const td_thrhandle_t *__th, const void *__addr); +/* Get address of the given module's TLS storage area for the given thread. */ +extern td_err_e td_thr_tlsbase (const td_thrhandle_t *__th, + unsigned long int __modid, + psaddr_t *__base); + /* Get address of thread local variable. */ extern td_err_e td_thr_tls_get_addr (const td_thrhandle_t *__th, void *__map_address, size_t __offset, diff --git a/nptl_db/Makefile b/nptl_db/Makefile index 4e6d1ea236..d6dcec5aea 100644 --- a/nptl_db/Makefile +++ b/nptl_db/Makefile @@ -41,9 +41,8 @@ libthread_db-routines = td_init td_log td_ta_new td_ta_delete \ 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_tls_get_addr - - + td_ta_clear_event td_symbol_list \ + td_thr_tlsbase td_thr_tls_get_addr libthread_db-inhibit-o = $(filter-out .os,$(object-suffixes)) diff --git a/nptl_db/Versions b/nptl_db/Versions index 4ca8042c12..063493c676 100644 --- a/nptl_db/Versions +++ b/nptl_db/Versions @@ -18,4 +18,7 @@ libthread_db { GLIBC_2.3 { td_thr_tls_get_addr; } + GLIBC_2.3.3 { + td_thr_tlsbase; + } } diff --git a/nptl_db/td_thr_tls_get_addr.c b/nptl_db/td_thr_tls_get_addr.c index d1e29da8b9..c900cac8e0 100644 --- a/nptl_db/td_thr_tls_get_addr.c +++ b/nptl_db/td_thr_tls_get_addr.c @@ -1,7 +1,7 @@ /* Get address of thread local variable. - Copyright (C) 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2002,2003 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 2002. + Contributed by Ulrich Drepper , 2002. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -18,15 +18,9 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include #include #include "thread_dbP.h" - -/* Value used for dtv entries for which the allocation is delayed. */ -# define TLS_DTV_UNALLOCATED ((void *) -1l) - - td_err_e td_thr_tls_get_addr (const td_thrhandle_t *th __attribute__ ((unused)), void *map_address __attribute__ ((unused)), @@ -34,44 +28,17 @@ td_thr_tls_get_addr (const td_thrhandle_t *th __attribute__ ((unused)), void **address __attribute__ ((unused))) { #if USE_TLS - size_t modid; - union dtv pdtv, *dtvp; - - LOG ("td_thr_tls_get_addr"); - - psaddr_t dtvpp = th->th_unique; -#if TLS_TCB_AT_TP - dtvpp += offsetof (struct pthread, header.dtv); -#elif TLS_DTV_AT_TP - dtvpp += TLS_PRE_TCB_SIZE + offsetof (tcbhead_t, dtv); -#else -# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined." -#endif - - /* Get the DTV pointer from the thread descriptor. */ - if (ps_pdread (th->th_ta_p->ph, dtvpp, &dtvp, sizeof dtvp) != PS_OK) - return TD_ERR; /* XXX Other error value? */ - /* Read the module ID from the link_map. */ + size_t modid; if (ps_pdread (th->th_ta_p->ph, &((struct link_map *) map_address)->l_tls_modid, &modid, sizeof modid) != PS_OK) return TD_ERR; /* XXX Other error value? */ - /* Get the corresponding entry in the DTV. */ - if (ps_pdread (th->th_ta_p->ph, dtvp + modid, - &pdtv, sizeof (union dtv)) != PS_OK) - return TD_ERR; /* XXX Other error value? */ - - /* It could be that the memory for this module is not allocated for - the given thread. */ - if (pdtv.pointer == TLS_DTV_UNALLOCATED) - /* There is not much we can do. */ - return TD_NOTALLOC; - - *address = (char *) pdtv.pointer + offset; - - return TD_OK; + td_err_e result = td_thr_tlsbase (th, modid, address); + if (result == TD_OK) + *address += offset; + return result; #else return TD_ERR; #endif diff --git a/nptl_db/td_thr_tlsbase.c b/nptl_db/td_thr_tlsbase.c new file mode 100644 index 0000000000..ff8f1c7504 --- /dev/null +++ b/nptl_db/td_thr_tlsbase.c @@ -0,0 +1,67 @@ +/* Locate TLS data for a thread. + 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" + +/* Value used for dtv entries for which the allocation is delayed. */ +# define TLS_DTV_UNALLOCATED ((void *) -1l) + +td_err_e +td_thr_tlsbase (const td_thrhandle_t *th, + unsigned long int modid, + psaddr_t *base) +{ + if (modid < 1) + return TD_NOTLS; + +#if USE_TLS + union dtv pdtv, *dtvp; + + LOG ("td_thr_tlsbase"); + + psaddr_t dtvpp = th->th_unique; +#if TLS_TCB_AT_TP + dtvpp += offsetof (struct pthread, header.dtv); +#elif TLS_DTV_AT_TP + dtvpp += TLS_PRE_TCB_SIZE + offsetof (tcbhead_t, dtv); +#else +# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined." +#endif + + /* Get the DTV pointer from the thread descriptor. */ + if (ps_pdread (th->th_ta_p->ph, dtvpp, &dtvp, sizeof dtvp) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* Get the corresponding entry in the DTV. */ + if (ps_pdread (th->th_ta_p->ph, dtvp + modid, + &pdtv, sizeof (union dtv)) != PS_OK) + return TD_ERR; /* XXX Other error value? */ + + /* It could be that the memory for this module is not allocated for + the given thread. */ + if (pdtv.pointer == TLS_DTV_UNALLOCATED) + return TD_TLSDEFER; + + *base = (char *) pdtv.pointer; + + return TD_OK; +#else + return TD_ERR; +#endif +} diff --git a/nptl_db/thread_db.h b/nptl_db/thread_db.h index ee7179c6dc..6328e16e76 100644 --- a/nptl_db/thread_db.h +++ b/nptl_db/thread_db.h @@ -1,4 +1,5 @@ -/* Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. +/* thread_db.h -- interface to libthread_db.so library for debugging -lpthread + Copyright (C) 1999,2001,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 @@ -52,8 +53,10 @@ typedef enum TD_MALLOC, /* Out of memory. */ TD_PARTIALREG, /* Not entire register set was read or written. */ TD_NOXREGS, /* X register set not available for given thread. */ - TD_NOTALLOC, /* TLS memory not yet allocated. */ - TD_VERSION /* Version if libpthread and libthread_db do not match. */ + TD_TLSDEFER, /* Thread has not yet allocated TLS for given module. */ + TD_NOTALLOC = TD_TLSDEFER, + TD_VERSION, /* Version if libpthread and libthread_db do not match. */ + TD_NOTLS /* There is TLS segment in the given module. */ } td_err_e; @@ -402,6 +405,11 @@ extern td_err_e td_thr_setxregs (const td_thrhandle_t *__th, const void *__addr); +/* Get address of the given module's TLS storage area for the given thread. */ +extern td_err_e td_thr_tlsbase (const td_thrhandle_t *__th, + unsigned long int __modid, + psaddr_t *__base); + /* Get address of thread local variable. */ extern td_err_e td_thr_tls_get_addr (const td_thrhandle_t *__th, void *__map_address, size_t __offset,