/* Copyright (C) 2008-2014 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "command.h"
#include "gdbcmd.h"
#include "target.h"
#include "observer.h"
#include <sys/procfs.h>
#include "gregset.h"
#include "regcache.h"
#include "inferior.h"
#include "gdbthread.h"

#include <pthread_debug.h>

/* Print debugging traces if set to non-zero.  */
static int debug_dec_thread = 0;

/* Non-zero if the dec-thread layer is active.  */
static int dec_thread_active = 0;

/* The pthread_debug context.  */
pthreadDebugContext_t debug_context;

/* The dec-thread target_ops structure.  */
static struct target_ops dec_thread_ops;

/* Print a debug trace if DEBUG_DEC_THREAD is set (its value is adjusted
   by the user using "set debug dec-thread ...").  */

static void
debug (char *format, ...)
{
  if (debug_dec_thread)
    {
      va_list args;

      va_start (args, format);
      printf_unfiltered ("DEC Threads: ");
      vprintf_unfiltered (format, args);
      printf_unfiltered ("\n");
      va_end (args);
    }
}

/* pthread debug callbacks.  */

static int
suspend_clbk (void *caller_context)
{
  return ESUCCESS;
}

static int
resume_clbk (void *caller_context)
{
  return ESUCCESS;
} 

static int
hold_clbk (void *caller_context, pthreadDebugKId_t kernel_tid)
{ 
  return ESUCCESS;
}

static int
unhold_clbk (void *caller_context, pthreadDebugKId_t kernel_tid)
{
  return ESUCCESS;
}

static int
read_clbk (void *caller_context, void *address, void *buffer,
           unsigned long size)
{
  int status = target_read_memory ((CORE_ADDR) address, buffer, size);

  if (status != 0)
    return EINVAL;

  return ESUCCESS;
}

static int
write_clbk (void *caller_context, void *address, void *buffer,
            unsigned long size)
{
  int status = target_write_memory ((CORE_ADDR) address, buffer, size);
  
  if (status != 0)
    return EINVAL;

  return ESUCCESS;
}

/* Get integer regs.  */

static int
get_reg_clbk(void *caller_context, pthreadDebugGetRegRtn_t regs,
             pthreadDebugKId_t kernel_tid)
{
  debug ("get_reg_clbk");

  /* Not sure that we actually need to do anything in this callback.  */
  return ESUCCESS;
}

/* Set integer regs.  */

static int
set_reg_clbk(void *caller_context, const pthreadDebugRegs_t *regs,
             pthreadDebugKId_t kernel_tid)
{
  debug ("set_reg_clbk");

  /* Not sure that we actually need to do anything in this callback.  */
  return ESUCCESS;
}

static int
output_clbk (void *caller_context, char *line)
{
  printf_filtered ("%s\n", line);
  return ESUCCESS;
}

static int
error_clbk (void *caller_context, char *line)
{
  fprintf_filtered (gdb_stderr, "%s\n", line);
  return ESUCCESS;
}

/* Get floating-point regs.  */

static int
get_fpreg_clbk (void *caller_context, pthreadDebugFregs_p fregs,
                pthreadDebugKId_t kernel_tid)
{
  debug ("get_fpreg_clbk");

  /* Not sure that we actually need to do anything in this callback.  */
  return ESUCCESS;
}

/* Set floating-point regs.  */

static int
set_fpreg_clbk (void *caller_context, const pthreadDebugFregs_t *fregs,
                pthreadDebugKId_t kernel_tid)
{
  debug ("set_fpreg_clbk");

  /* Not sure that we actually need to do anything in this callback.  */
  return ESUCCESS;
}

static void *
malloc_clbk (void *caller_context, size_t size)
{
  return xmalloc (size);
}

static void
free_clbk (void *caller_context, void *address)
{
  xfree (address);
}

static int
kthdinfo_clbk (pthreadDebugClient_t caller_context,
               pthreadDebugKId_t kernel_tid,
               pthreadDebugKThreadInfo_p thread_info)
{
  return ENOTSUP;
}

static int
speckthd_clbk (pthreadDebugClient_t caller_context,
               pthreadDebugSpecialType_t type,
               pthreadDebugKId_t *kernel_tid)
{
  return ENOTSUP;
}

static pthreadDebugCallbacks_t debug_callbacks =
{
  PTHREAD_DEBUG_VERSION,
  (pthreadDebugGetMemRtn_t) read_clbk,
  (pthreadDebugSetMemRtn_t) write_clbk,
  suspend_clbk,
  resume_clbk,
  kthdinfo_clbk,
  hold_clbk,
  unhold_clbk,
  (pthreadDebugGetFregRtn_t) get_fpreg_clbk,
  (pthreadDebugSetFregRtn_t) set_fpreg_clbk,
  (pthreadDebugGetRegRtn_t) get_reg_clbk,
  (pthreadDebugSetRegRtn_t) set_reg_clbk,
  (pthreadDebugOutputRtn_t) output_clbk,
  (pthreadDebugOutputRtn_t) error_clbk,
  malloc_clbk,
  free_clbk,
  speckthd_clbk
};

/* Activate thread support if appropriate.  Do nothing if thread
   support is already active.  */

static void
enable_dec_thread (void)
{
  struct bound_minimal_symbol msym;
  void* caller_context;
  int status;

  /* If already active, nothing more to do.  */
  if (dec_thread_active)
    return;

  msym = lookup_minimal_symbol ("__pthread_dbg_symtable", NULL, NULL);
  if (msym.minsym == NULL)
    {
      debug ("enable_dec_thread: No __pthread_dbg_symtable");
      return;
    }

  status = pthreadDebugContextInit (&caller_context, &debug_callbacks,
                                    (void *) SYMBOL_VALUE_ADDRESS (msym.minsym),
                                    &debug_context);
  if (status != ESUCCESS)
    {
      debug ("enable_dec_thread: pthreadDebugContextInit -> %d",
             status);
      return;
    }

  push_target (&dec_thread_ops);
  dec_thread_active = 1;

  debug ("enable_dec_thread: Thread support enabled.");
}

/* Deactivate thread support.  Do nothing if thread support is
   already inactive.  */

static void
disable_dec_thread (void)
{
  if (!dec_thread_active)
    return;

  pthreadDebugContextDestroy (debug_context);
  unpush_target (&dec_thread_ops);
  dec_thread_active = 0;
}

/* A structure that contains a thread ID and is associated
   pthreadDebugThreadInfo_t data.  */

struct dec_thread_info
{
  pthreadDebugId_t thread;
  pthreadDebugThreadInfo_t info;
};
typedef struct dec_thread_info dec_thread_info_s;

/* The list of user threads.  */

DEF_VEC_O (dec_thread_info_s);
VEC(dec_thread_info_s) *dec_thread_list;

/* Release the memory used by the given VECP thread list pointer.
   Then set *VECP to NULL.  */

static void
free_dec_thread_info_vec (VEC(dec_thread_info_s) **vecp)
{
  int i;
  struct dec_thread_info *item;
  VEC(dec_thread_info_s) *vec = *vecp;

  for (i = 0; VEC_iterate (dec_thread_info_s, vec, i, item); i++)
     xfree (item);
  VEC_free (dec_thread_info_s, vec);
  *vecp = NULL;
}

/* Return a thread's ptid given its associated INFO.  */

static ptid_t
ptid_build_from_info (struct dec_thread_info info)
{
  int pid = ptid_get_pid (inferior_ptid);

  return ptid_build (pid, 0, (long) info.thread);
}

/* Return non-zero if PTID is still alive.

   Assumes that DEC_THREAD_LIST is up to date.  */
static int
dec_thread_ptid_is_alive (ptid_t ptid)
{
  pthreadDebugId_t tid = ptid_get_tid (ptid);
  int i;
  struct dec_thread_info *info;

  if (tid == 0)
    /* This is the thread corresponding to the process.  This ptid
       is always alive until the program exits.  */
    return 1;

  /* Search whether an entry with the same tid exists in the dec-thread
     list of threads.  If it does, then the thread is still alive.
     No match found means that the thread must be dead, now.  */
  for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info); i++)
    if (info->thread == tid)
      return 1;
  return 0;
}

/* Recompute the list of user threads and store the result in
   DEC_THREAD_LIST.  */

static void
update_dec_thread_list (void)
{
  pthreadDebugId_t thread;
  pthreadDebugThreadInfo_t info;
  int res;

  free_dec_thread_info_vec (&dec_thread_list);
  res = pthreadDebugThdSeqInit (debug_context, &thread);
  while (res == ESUCCESS)
    {

      res = pthreadDebugThdGetInfo (debug_context, thread, &info);
      if (res != ESUCCESS)
        warning (_("unable to get thread info, ignoring thread %ld"),
                   thread);
      else if (info.kind == PTHREAD_DEBUG_THD_KIND_INITIAL
               || info.kind == PTHREAD_DEBUG_THD_KIND_NORMAL)
        {
          struct dec_thread_info *item = 
            xmalloc (sizeof (struct dec_thread_info));

          item->thread = thread;
          item->info = info;
          VEC_safe_push (dec_thread_info_s, dec_thread_list, item);
        }
      res = pthreadDebugThdSeqNext (debug_context, &thread);
    }
  pthreadDebugThdSeqDestroy (debug_context);
}

/* A callback to count the number of threads known to GDB.  */

static int
dec_thread_count_gdb_threads (struct thread_info *ignored, void *context)
{
  int *count = (int *) context;

  *count = *count + 1;
  return 0;
}

/* A callback that saves the given thread INFO at the end of an
   array.  The end of the array is given in the CONTEXT and is
   incremented once the info has been added.  */

static int
dec_thread_add_gdb_thread (struct thread_info *info, void *context)
{
  struct thread_info ***listp = (struct thread_info ***) context;
  
  **listp = info;
  *listp = *listp + 1;
  return 0;
}

/* Implement the find_new_thread target_ops method.  */

static void
dec_thread_find_new_threads (struct target_ops *ops)
{
  int i;
  struct dec_thread_info *info;

  update_dec_thread_list ();
  for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info); i++)
    {
      ptid_t ptid = ptid_build_from_info (*info);

      if (!in_thread_list (ptid))
        add_thread (ptid);
    }
}

/* Resynchronize the list of threads known by GDB with the actual
   list of threads reported by libpthread_debug.  */

static void
resync_thread_list (struct target_ops *ops)
{
  int i;
  int num_gdb_threads = 0;
  struct thread_info **gdb_thread_list;
  struct thread_info **next_thread_info;

  /* Add new threads.  */
  dec_thread_find_new_threads (ops);

  /* Remove threads that no longer exist.  To help with the search,
     we build an array of GDB threads, and then iterate over this
     array.  */

  iterate_over_threads (dec_thread_count_gdb_threads,
                        (void *) &num_gdb_threads);
  gdb_thread_list = alloca (num_gdb_threads * sizeof (struct thread_info *));
  next_thread_info = gdb_thread_list;
  iterate_over_threads (dec_thread_add_gdb_thread, (void *) &next_thread_info);

  for (i = 0; i < num_gdb_threads; i++)
    if (!dec_thread_ptid_is_alive (gdb_thread_list[i]->ptid))
      delete_thread (gdb_thread_list[i]->ptid);
}

/* The "to_detach" method of the dec_thread_ops.  */

static void
dec_thread_detach (struct target_ops *ops, const char *args, int from_tty)
{   
  struct target_ops *beneath = find_target_beneath (ops);

  debug ("dec_thread_detach");

  disable_dec_thread ();
  beneath->to_detach (beneath, args, from_tty);
}

/* Return the ptid of the thread that is currently active.  */

static ptid_t
get_active_ptid (void)
{
  int i;
  struct dec_thread_info *info;

  for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info);
       i++)
    if (info->info.state == PTHREAD_DEBUG_STATE_RUNNING)
      return ptid_build_from_info (*info);

  /* No active thread found.  This can happen when the program
     has just exited.  */
  return null_ptid;
}

/* The "to_wait" method of the dec_thread_ops.  */

static ptid_t
dec_thread_wait (struct target_ops *ops,
		 ptid_t ptid, struct target_waitstatus *status, int options)
{
  ptid_t active_ptid;
  struct target_ops *beneath = find_target_beneath (ops);

  debug ("dec_thread_wait");

  ptid = beneath->to_wait (beneath, ptid, status, options);

  /* The ptid returned by the target beneath us is the ptid of the process.
     We need to find which thread is currently active and return its ptid.  */
  resync_thread_list (ops);
  active_ptid = get_active_ptid ();
  if (ptid_equal (active_ptid, null_ptid))
    return ptid;
  return active_ptid;
}

/* Fetch the general purpose and floating point registers for the given
   thread TID, and store the result in GREGSET and FPREGSET.  Return
   zero if successful.  */

static int
dec_thread_get_regsets (pthreadDebugId_t tid, gdb_gregset_t *gregset,
                        gdb_fpregset_t *fpregset)
{
  int res;
  pthreadDebugRegs_t regs;
  pthreadDebugFregs_t fregs;

  res = pthreadDebugThdGetReg (debug_context, tid, &regs);
  if (res != ESUCCESS)
    {
      debug ("dec_thread_get_regsets: pthreadDebugThdGetReg -> %d", res);
      return -1;
    }
  memcpy (gregset->regs, &regs, sizeof (regs));

  res = pthreadDebugThdGetFreg (debug_context, tid, &fregs);
  if (res != ESUCCESS)
    {
      debug ("dec_thread_get_regsets: pthreadDebugThdGetFreg -> %d", res);
      return -1;
    }
  memcpy (fpregset->regs, &fregs, sizeof (fregs));

  return 0;
}

/* The "to_fetch_registers" method of the dec_thread_ops.

   Because the dec-thread debug API doesn't allow us to fetch
   only one register, we simply ignore regno and fetch+supply all
   registers.  */

static void
dec_thread_fetch_registers (struct target_ops *ops,
                            struct regcache *regcache, int regno)
{
  pthreadDebugId_t tid = ptid_get_tid (inferior_ptid);
  gregset_t gregset;
  fpregset_t fpregset;
  int res;

  debug ("dec_thread_fetch_registers (tid=%ld, regno=%d)", tid, regno);


  if (tid == 0 || ptid_equal (inferior_ptid, get_active_ptid ()))
    {
      struct target_ops *beneath = find_target_beneath (ops);

      beneath->to_fetch_registers (beneath, regcache, regno);
      return;
    }

  res = dec_thread_get_regsets (tid, &gregset, &fpregset);
  if (res != 0)
    return;

  supply_gregset (regcache, &gregset);
  supply_fpregset (regcache, &fpregset);
}

/* Store the registers given in GREGSET and FPREGSET into the associated
   general purpose and floating point registers of thread TID.  Return
   zero if successful.  */

static int
dec_thread_set_regsets (pthreadDebugId_t tid, gdb_gregset_t gregset,
                        gdb_fpregset_t fpregset)
{
  int res;
  pthreadDebugRegs_t regs;
  pthreadDebugFregs_t fregs;

  memcpy (&regs, gregset.regs, sizeof (regs));
  res = pthreadDebugThdSetReg (debug_context, tid, &regs);
  if (res != ESUCCESS)
    {
      debug ("dec_thread_set_regsets: pthreadDebugThdSetReg -> %d", res);
      return -1;
    }

  memcpy (&fregs, fpregset.regs, sizeof (fregs));
  res = pthreadDebugThdSetFreg (debug_context, tid, &fregs);
  if (res != ESUCCESS)
    {
      debug ("dec_thread_set_regsets: pthreadDebugThdSetFreg -> %d", res);
      return -1;
    }

  return 0;
}

/* The "to_store_registers" method of the dec_thread_ops.

   Because the dec-thread debug API doesn't allow us to store
   just one register, we store all the registers.  */

static void
dec_thread_store_registers (struct target_ops *ops,
                            struct regcache *regcache, int regno)
{
  pthreadDebugId_t tid = ptid_get_tid (inferior_ptid);
  gregset_t gregset;
  fpregset_t fpregset;
  int res;

  debug ("dec_thread_store_registers (tid=%ld, regno=%d)", tid, regno);

  if (tid == 0 || ptid_equal (inferior_ptid, get_active_ptid ()))
    {
      struct target_ops *beneath = find_target_beneath (ops);

      beneath->to_store_registers (beneath, regcache, regno);
      return;
    }

  /* FIXME: brobecker/2008-05-28: I wonder if we could simply check
     in which register set the register is and then only store the
     registers for that register set, instead of storing both register
     sets.  */
  fill_gregset (regcache, &gregset, -1);
  fill_fpregset (regcache, &fpregset, -1);
  
  res = dec_thread_set_regsets (tid, gregset, fpregset);
  if (res != 0)
    warning (_("failed to store registers."));
}

/* The "to_mourn_inferior" method of the dec_thread_ops.  */

static void
dec_thread_mourn_inferior (struct target_ops *ops)
{
  struct target_ops *beneath = find_target_beneath (ops);

  debug ("dec_thread_mourn_inferior");

  disable_dec_thread ();
  beneath->to_mourn_inferior (beneath);
}

/* The "to_thread_alive" method of the dec_thread_ops.  */
static int
dec_thread_thread_alive (struct target_ops *ops, ptid_t ptid)
{
  debug ("dec_thread_thread_alive (tid=%ld)", ptid_get_tid (ptid));

  /* The thread list maintained by GDB is up to date, since we update
     it everytime we stop.   So check this list.  */
  return in_thread_list (ptid);
}

/* The "to_pid_to_str" method of the dec_thread_ops.  */

static char *
dec_thread_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
  static char *ret = NULL;

  if (ptid_get_tid (ptid) == 0)
    {
      struct target_ops *beneath = find_target_beneath (ops);

      return beneath->to_pid_to_str (beneath, ptid);
    }

  /* Free previous return value; a new one will be allocated by
     xstrprintf().  */
  xfree (ret);

  ret = xstrprintf (_("Thread %ld"), ptid_get_tid (ptid));
  return ret;
}

/* A "new-objfile" observer.  Used to activate/deactivate dec-thread
   support.  */

static void
dec_thread_new_objfile_observer (struct objfile *objfile)
{
  if (objfile != NULL)
     enable_dec_thread ();
  else
     disable_dec_thread ();
}

/* The "to_get_ada_task_ptid" method of the dec_thread_ops.  */

static ptid_t
dec_thread_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
{
  int i;
  struct dec_thread_info *info;

  debug ("dec_thread_get_ada_task_ptid (struct target_ops *self,"
	 " lwp=0x%lx, thread=0x%lx)",
         lwp, thread);

  for (i = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, i, info);
       i++)
    if (info->info.teb == (pthread_t) thread)
      return ptid_build_from_info (*info);

  warning (_("Could not find thread id from THREAD = 0x%lx"), thread);
  return inferior_ptid;
}

static void
init_dec_thread_ops (void)
{
  dec_thread_ops.to_shortname          = "dec-threads";
  dec_thread_ops.to_longname           = _("DEC threads support");
  dec_thread_ops.to_doc                = _("DEC threads support");
  dec_thread_ops.to_detach             = dec_thread_detach;
  dec_thread_ops.to_wait               = dec_thread_wait;
  dec_thread_ops.to_fetch_registers    = dec_thread_fetch_registers;
  dec_thread_ops.to_store_registers    = dec_thread_store_registers;
  dec_thread_ops.to_mourn_inferior     = dec_thread_mourn_inferior;
  dec_thread_ops.to_thread_alive       = dec_thread_thread_alive;
  dec_thread_ops.to_find_new_threads   = dec_thread_find_new_threads;
  dec_thread_ops.to_pid_to_str         = dec_thread_pid_to_str;
  dec_thread_ops.to_stratum            = thread_stratum;
  dec_thread_ops.to_get_ada_task_ptid  = dec_thread_get_ada_task_ptid;
  dec_thread_ops.to_magic              = OPS_MAGIC;
}

void
_initialize_dec_thread (void)
{
  init_dec_thread_ops ();
  complete_target_initialization (&dec_thread_ops);

  observer_attach_new_objfile (dec_thread_new_objfile_observer);

  add_setshow_boolean_cmd ("dec-thread", class_maintenance, &debug_dec_thread,
                            _("Set debugging of DEC threads module."),
                            _("Show debugging of DEC threads module."),
                            _("Enables debugging output (used to debug GDB)."),
                            NULL, NULL,
                            &setdebuglist, &showdebuglist);
}
