/* Copyright (C) 2008, 2009 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 is 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);
}

/* 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++;
  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++;
  return 0;
}

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

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

  update_dec_thread_list ();

  /* Add new threads.  */

  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);
    }

  /* 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++)
    {
      int j;

      for (j = 0; VEC_iterate (dec_thread_info_s, dec_thread_list, j, info);
           j++)
        if (ptid_equal (gdb_thread_list[i]->ptid,
                         ptid_build_from_info (*info)))
          break;
      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 ();
  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\n"), 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_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);
}
