/* Copyright (C) 2008, 2009, 2010, 2011 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 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 == NULL)
    {
      debug ("enable_dec_thread: No __pthread_dbg_symtable");
      return;
    }

  status = pthreadDebugContextInit (&caller_context, &debug_callbacks,
                                    (void *) SYMBOL_VALUE_ADDRESS (msym),
                                    &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, 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 (long lwp, long thread)
{
  int i;
  struct dec_thread_info *info;

  debug ("dec_thread_get_ada_task_ptid (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 ();
  add_target (&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);
}
