/* Locate TLS data for a thread.
   Copyright (C) 2003-2018 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, see
   <http://www.gnu.org/licenses/>.  */

#include "thread_dbP.h"
#include <link.h>

/* Get the DTV slotinfo list head entry from the dynamic loader state
   into *LISTHEAD.  */
static td_err_e
dtv_slotinfo_list (td_thragent_t *ta,
		   psaddr_t *listhead)
{
  td_err_e err;
  psaddr_t head;

  if (ta->ta_addr__rtld_global == 0
      && td_mod_lookup (ta->ph, LD_SO, SYM__rtld_global,
			&ta->ta_addr__rtld_global) != PS_OK)
    ta->ta_addr__rtld_global = (void*)-1;

  if (ta->ta_addr__rtld_global != (void*)-1)
    {
      err = DB_GET_FIELD (head, ta, ta->ta_addr__rtld_global,
			  rtld_global, _dl_tls_dtv_slotinfo_list, 0);
      if (err != TD_OK)
	return err;
    }
  else
    {
      if (ta->ta_addr__dl_tls_dtv_slotinfo_list == 0
	  && td_mod_lookup (ta->ph, NULL, SYM__dl_tls_dtv_slotinfo_list,
			    &ta->ta_addr__dl_tls_dtv_slotinfo_list) != PS_OK)
	return TD_ERR;

      err = _td_fetch_value (ta, ta->ta_var__dl_tls_dtv_slotinfo_list,
			     SYM_DESC__dl_tls_dtv_slotinfo_list,
			     0, ta->ta_addr__dl_tls_dtv_slotinfo_list, &head);
      if (err != TD_OK)
	return err;
    }

  *listhead = head;
  return TD_OK;
}

/* Get the address of the DTV slotinfo entry for MODID into
   *DTVSLOTINFO.  */
static td_err_e
dtv_slotinfo (td_thragent_t *ta,
	      unsigned long int modid,
	      psaddr_t *dtvslotinfo)
{
  td_err_e err;
  psaddr_t slot, temp;
  size_t slbase = 0;

  err = dtv_slotinfo_list (ta, &slot);
  if (err != TD_OK)
    return err;

  while (slot)
    {
      /* Get the number of entries in this list entry's array.  */
      err = DB_GET_FIELD (temp, ta, slot, dtv_slotinfo_list, len, 0);
      if (err != TD_OK)
	return err;
      size_t len = (uintptr_t)temp;

      /* Did we find the list entry for modid?  */
      if (modid < slbase + len)
	break;

      /* We didn't, so get the next list entry.  */
      slbase += len;
      err = DB_GET_FIELD (temp, ta, slot, dtv_slotinfo_list,
			  next, 0);
      if (err != TD_OK)
	return err;
      slot = temp;
    }

  /* We reached the end of the list and found nothing.  */
  if (!slot)
    return TD_ERR;

  /* Take the slotinfo for modid from the list entry.  */
  err = DB_GET_FIELD_ADDRESS (temp, ta, slot, dtv_slotinfo_list,
			      slotinfo, modid - slbase);
  if (err != TD_OK)
    return err;
  slot = temp;

  *dtvslotinfo = slot;
  return TD_OK;
}

/* Return in *BASE the base address of the TLS block for MODID within
   TH.

   It should return success and yield the correct pointer in any
   circumstance where the TLS block for the module and thread
   requested has already been initialized.

   It should fail with TD_TLSDEFER only when the thread could not
   possibly have observed any values in that TLS block.  That way, the
   debugger can fall back to showing initial values from the PT_TLS
   segment (and refusing attempts to mutate) for the TD_TLSDEFER case,
   and never fail to make the values the program will actually see
   available to the user of the debugger.  */
td_err_e
td_thr_tlsbase (const td_thrhandle_t *th,
		unsigned long int modid,
		psaddr_t *base)
{
  td_err_e err;
  psaddr_t dtv, dtvslot, dtvptr, temp;

  if (modid < 1)
    return TD_NOTLS;

  psaddr_t pd = th->th_unique;
  if (pd == 0)
    {
      /* This is the fake handle for the main thread before libpthread
	 initialization.  We are using 0 for its th_unique because we can't
	 trust that its thread register has been initialized.  But we need
	 a real pointer to have any TLS access work.  In case of dlopen'd
	 libpthread, initialization might not be for quite some time.  So
	 try looking up the thread register now.  Worst case, it's nonzero
	 uninitialized garbage and we get bogus results for TLS access
	 attempted too early.  Tough.  */

      td_thrhandle_t main_th;
      err = __td_ta_lookup_th_unique (th->th_ta_p, ps_getpid (th->th_ta_p->ph),
				      &main_th);
      if (err == 0)
	pd = main_th.th_unique;
      if (pd == 0)
	return TD_TLSDEFER;
    }

  err = dtv_slotinfo (th->th_ta_p, modid, &temp);
  if (err != TD_OK)
    return err;

  psaddr_t slot;
  err = DB_GET_STRUCT (slot, th->th_ta_p, temp, dtv_slotinfo);
  if (err != TD_OK)
    return err;

  /* Take the link_map from the slotinfo.  */
  psaddr_t map;
  err = DB_GET_FIELD_LOCAL (map, th->th_ta_p, slot, dtv_slotinfo, map, 0);
  if (err != TD_OK)
    return err;
  if (!map)
    return TD_ERR;

  /* Ok, the modid is good, now find out what DTV generation it
     requires.  */
  err = DB_GET_FIELD_LOCAL (temp, th->th_ta_p, slot, dtv_slotinfo, gen, 0);
  if (err != TD_OK)
    return err;
  size_t modgen = (uintptr_t)temp;

  /* Get the DTV pointer from the thread descriptor.  */
  err = DB_GET_FIELD (dtv, th->th_ta_p, pd, pthread, dtvp, 0);
  if (err != TD_OK)
    return err;

  psaddr_t dtvgenloc;
  /* Get the DTV generation count at dtv[0].counter.  */
  err = DB_GET_FIELD_ADDRESS (dtvgenloc, th->th_ta_p, dtv, dtv, dtv, 0);
  if (err != TD_OK)
    return err;
  err = DB_GET_FIELD (temp, th->th_ta_p, dtvgenloc, dtv_t, counter, 0);
  if (err != TD_OK)
    return err;
  size_t dtvgen = (uintptr_t)temp;

  /* Is the DTV current enough?  */
  if (dtvgen < modgen)
    {
    try_static_tls:
      /* If the module uses Static TLS, we're still good.  */
      err = DB_GET_FIELD (temp, th->th_ta_p, map, link_map, l_tls_offset, 0);
      if (err != TD_OK)
	return err;
      ptrdiff_t tlsoff = (uintptr_t)temp;

      if (tlsoff != FORCED_DYNAMIC_TLS_OFFSET
	  && tlsoff != NO_TLS_OFFSET)
	{
	  psaddr_t tp = pd;

#if TLS_TCB_AT_TP
	  dtvptr = tp - tlsoff;
#elif TLS_DTV_AT_TP
	  dtvptr = tp + tlsoff + TLS_PRE_TCB_SIZE;
#else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif

	  *base = dtvptr;
	  return TD_OK;
	}

      return TD_TLSDEFER;
    }

  /* Find the corresponding entry in the DTV.  */
  err = DB_GET_FIELD_ADDRESS (dtvslot, th->th_ta_p, dtv, dtv, dtv, modid);
  if (err != TD_OK)
    return err;

  /* Extract the TLS block address from that DTV slot.  */
  err = DB_GET_FIELD (dtvptr, th->th_ta_p, dtvslot, dtv_t, pointer_val, 0);
  if (err != TD_OK)
    return err;

  /* It could be that the memory for this module is not allocated for
     the given thread.  */
  if ((uintptr_t) dtvptr & 1)
    goto try_static_tls;

  *base = dtvptr;
  return TD_OK;
}
