Back to index

glibc  2.9
td_thr_tlsbase.c
Go to the documentation of this file.
00001 /* Locate TLS data for a thread.
00002    Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include "thread_dbP.h"
00021 
00022 /* Value used for dtv entries for which the allocation is delayed.  */
00023 # define TLS_DTV_UNALLOCATED       ((void *) -1l)
00024 
00025 td_err_e
00026 td_thr_tlsbase (const td_thrhandle_t *th,
00027               unsigned long int modid,
00028               psaddr_t *base)
00029 {
00030   if (modid < 1)
00031     return TD_NOTLS;
00032 
00033 #if USE_TLS
00034   union dtv pdtv, *dtvp;
00035 
00036   LOG ("td_thr_tlsbase");
00037 
00038   psaddr_t dtvpp = th->th_unique;
00039 #if TLS_TCB_AT_TP
00040   dtvpp += offsetof (struct _pthread_descr_struct, p_header.data.dtvp);
00041 #elif TLS_DTV_AT_TP
00042 /* Special case hack.  If TLS_TCB_SIZE == 0 (on PowerPC), there is no TCB
00043    containing the DTV at the TP, but actually the TCB lies behind the TP,
00044    i.e. at the very end of the area covered by TLS_PRE_TCB_SIZE.  */
00045   dtvpp += TLS_PRE_TCB_SIZE + offsetof (tcbhead_t, dtv)
00046           - (TLS_TCB_SIZE == 0 ? sizeof (tcbhead_t) : 0);
00047 #else
00048 # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined."
00049 #endif
00050 
00051   /* Get the DTV pointer from the thread descriptor.  */
00052   if (ps_pdread (th->th_ta_p->ph, dtvpp, &dtvp, sizeof dtvp) != PS_OK)
00053     return TD_ERR;   /* XXX Other error value?  */
00054 
00055   /* Get the corresponding entry in the DTV.  */
00056   if (ps_pdread (th->th_ta_p->ph, dtvp + modid,
00057                &pdtv, sizeof (union dtv)) != PS_OK)
00058     return TD_ERR;   /* XXX Other error value?  */
00059 
00060   /* It could be that the memory for this module is not allocated for
00061      the given thread.  */
00062   if (pdtv.pointer.val == TLS_DTV_UNALLOCATED)
00063     return TD_TLSDEFER;
00064 
00065   *base = (char *) pdtv.pointer.val;
00066 
00067   return TD_OK;
00068 #else
00069   return TD_ERR;
00070 #endif
00071 }