/* Helper routines for libthread_db.
   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 <byteswap.h>
#include <assert.h>
#include <stdint.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 && DB_DESC_NELEM (desc) != 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))
    {
      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;
}
