/* Ada Ravenscar thread support.

   Copyright (C) 2004-2016 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 "gdbcore.h"
#include "gdbthread.h"
#include "ada-lang.h"
#include "target.h"
#include "inferior.h"
#include "command.h"
#include "ravenscar-thread.h"
#include "observer.h"
#include "gdbcmd.h"
#include "top.h"
#include "regcache.h"
#include "objfiles.h"

/* If non-null, ravenscar task support is enabled.  */
static int ravenscar_task_support = 1;

/* This module's target-specific operations.  */
static struct target_ops ravenscar_ops;

/* Some base target uses a special value for the null PID (exempli gratia
   remote).  */
static ptid_t base_magic_null_ptid;

/* Ptid of the inferior as seen by the process stratum.  */
static ptid_t base_ptid;

static const char running_thread_name[] = "__gnat_running_thread_table";

static const char known_tasks_name[] = "system__tasking__debug__known_tasks";
static const char first_task_name[] = "system__tasking__debug__first_task";

static const char ravenscar_runtime_initializer[] =
  "system__bb__threads__initialize";

static void ravenscar_update_thread_list (struct target_ops *ops);
static ptid_t ravenscar_running_thread (void);
static char *ravenscar_extra_thread_info (struct target_ops *self,
					  struct thread_info *tp);
static int ravenscar_thread_alive (struct target_ops *ops, ptid_t ptid);
static void ravenscar_fetch_registers (struct target_ops *ops,
                                       struct regcache *regcache, int regnum);
static void ravenscar_store_registers (struct target_ops *ops,
                                       struct regcache *regcache, int regnum);
static void ravenscar_prepare_to_store (struct target_ops *self,
					struct regcache *regcache);
static void ravenscar_resume (struct target_ops *ops, ptid_t ptid, int step,
			      enum gdb_signal siggnal);
static void ravenscar_mourn_inferior (struct target_ops *ops);
static void ravenscar_update_inferior_ptid (void);
static int has_ravenscar_runtime (void);
static int ravenscar_runtime_initialized (void);
static void ravenscar_inferior_created (struct target_ops *target,
					int from_tty);

/* Fetch the ravenscar running thread from target memory and
   update inferior_ptid accordingly.  */

static void
ravenscar_update_inferior_ptid (void)
{
  base_ptid = inferior_ptid;

  /* If the runtime has not been initialized yet, the inferior_ptid is
     the only ptid that there is.  */
  if (!ravenscar_runtime_initialized ())
    return;

  /* Make sure we set base_ptid before calling ravenscar_running_thread
     as the latter relies on it.  */
  inferior_ptid = ravenscar_running_thread ();
  gdb_assert (!ptid_equal (inferior_ptid, null_ptid));

  /* The running thread may not have been added to
     system.tasking.debug's list yet; so ravenscar_update_thread_list
     may not always add it to the thread list.  Add it here.  */
  if (!find_thread_ptid (inferior_ptid))
    add_thread (inferior_ptid);
}

/* The Ravenscar Runtime exports a symbol which contains the ID of
   the thread that is currently running.  Try to locate that symbol
   and return its associated minimal symbol.
   Return NULL if not found.  */

static struct bound_minimal_symbol
get_running_thread_msymbol (void)
{
  struct bound_minimal_symbol msym;

  msym = lookup_minimal_symbol (running_thread_name, NULL, NULL);
  if (!msym.minsym)
    /* Older versions of the GNAT runtime were using a different
       (less ideal) name for the symbol where the active thread ID
       is stored.  If we couldn't find the symbol using the latest
       name, then try the old one.  */
    msym = lookup_minimal_symbol ("running_thread", NULL, NULL);

  return msym;
}

/* Return True if the Ada Ravenscar run-time can be found in the
   application.  */

static int
has_ravenscar_runtime (void)
{
  struct bound_minimal_symbol msym_ravenscar_runtime_initializer =
    lookup_minimal_symbol (ravenscar_runtime_initializer, NULL, NULL);
  struct bound_minimal_symbol msym_known_tasks =
    lookup_minimal_symbol (known_tasks_name, NULL, NULL);
  struct bound_minimal_symbol msym_first_task =
    lookup_minimal_symbol (first_task_name, NULL, NULL);
  struct bound_minimal_symbol msym_running_thread
    = get_running_thread_msymbol ();

  return (msym_ravenscar_runtime_initializer.minsym
	  && (msym_known_tasks.minsym || msym_first_task.minsym)
	  && msym_running_thread.minsym);
}

/* Return True if the Ada Ravenscar run-time can be found in the
   application, and if it has been initialized on target.  */

static int
ravenscar_runtime_initialized (void)
{
  return (!(ptid_equal (ravenscar_running_thread (), null_ptid)));
}

/* Return the ID of the thread that is currently running.
   Return 0 if the ID could not be determined.  */

static CORE_ADDR
get_running_thread_id (void)
{
  struct bound_minimal_symbol object_msym = get_running_thread_msymbol ();
  int object_size;
  int buf_size;
  gdb_byte *buf;
  CORE_ADDR object_addr;
  struct type *builtin_type_void_data_ptr =
    builtin_type (target_gdbarch ())->builtin_data_ptr;

  if (!object_msym.minsym)
    return 0;

  object_addr = BMSYMBOL_VALUE_ADDRESS (object_msym);
  object_size = TYPE_LENGTH (builtin_type_void_data_ptr);
  buf_size = object_size;
  buf = (gdb_byte *) alloca (buf_size);
  read_memory (object_addr, buf, buf_size);
  return extract_typed_address (buf, builtin_type_void_data_ptr);
}

static void
ravenscar_resume (struct target_ops *ops, ptid_t ptid, int step,
		  enum gdb_signal siggnal)
{
  struct target_ops *beneath = find_target_beneath (ops);

  inferior_ptid = base_ptid;
  beneath->to_resume (beneath, base_ptid, step, siggnal);
}

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

  inferior_ptid = base_ptid;
  beneath->to_wait (beneath, base_ptid, status, 0);
  /* Find any new threads that might have been created, and update
     inferior_ptid to the active thread.

     Only do it if the program is still alive, though.  Otherwise,
     this causes problems when debugging through the remote protocol,
     because we might try switching threads (and thus sending packets)
     after the remote has disconnected.  */
  if (status->kind != TARGET_WAITKIND_EXITED
      && status->kind != TARGET_WAITKIND_SIGNALLED)
    {
      ravenscar_update_thread_list (ops);
      ravenscar_update_inferior_ptid ();
    }
  return inferior_ptid;
}

/* Add the thread associated to the given TASK to the thread list
   (if the thread has already been added, this is a no-op).  */

static void
ravenscar_add_thread (struct ada_task_info *task)
{
  if (find_thread_ptid (task->ptid) == NULL)
    add_thread (task->ptid);
}

static void
ravenscar_update_thread_list (struct target_ops *ops)
{
  ada_build_task_list ();

  /* Do not clear the thread list before adding the Ada task, to keep
     the thread that the process stratum has included into it
     (base_ptid) and the running thread, that may not have been included
     to system.tasking.debug's list yet.  */

  iterate_over_live_ada_tasks (ravenscar_add_thread);
}

static ptid_t
ravenscar_running_thread (void)
{
  CORE_ADDR tid = get_running_thread_id ();

  if (tid == 0)
    return null_ptid;
  else
    return ptid_build (ptid_get_pid (base_ptid), 0, tid);
}

static char *
ravenscar_extra_thread_info (struct target_ops *self, struct thread_info *tp)
{
  return "Ravenscar task";
}

static int
ravenscar_thread_alive (struct target_ops *ops, ptid_t ptid)
{
  /* Ravenscar tasks are non-terminating.  */
  return 1;
}

static char *
ravenscar_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
  static char buf[30];

  snprintf (buf, sizeof (buf), "Thread %#x", (int) ptid_get_tid (ptid));
  return buf;
}

static void
ravenscar_fetch_registers (struct target_ops *ops,
                           struct regcache *regcache, int regnum)
{
  struct target_ops *beneath = find_target_beneath (ops);

  if (!ravenscar_runtime_initialized ()
      || ptid_equal (inferior_ptid, base_magic_null_ptid)
      || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
    beneath->to_fetch_registers (beneath, regcache, regnum);
  else
    {
      struct gdbarch *gdbarch = get_regcache_arch (regcache);
      struct ravenscar_arch_ops *arch_ops
	= gdbarch_ravenscar_ops (gdbarch);

      arch_ops->to_fetch_registers (regcache, regnum);
    }
}

static void
ravenscar_store_registers (struct target_ops *ops,
                           struct regcache *regcache, int regnum)
{
  struct target_ops *beneath = find_target_beneath (ops);

  if (!ravenscar_runtime_initialized ()
      || ptid_equal (inferior_ptid, base_magic_null_ptid)
      || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
    beneath->to_store_registers (beneath, regcache, regnum);
  else
    {
      struct gdbarch *gdbarch = get_regcache_arch (regcache);
      struct ravenscar_arch_ops *arch_ops
	= gdbarch_ravenscar_ops (gdbarch);

      arch_ops->to_store_registers (regcache, regnum);
    }
}

static void
ravenscar_prepare_to_store (struct target_ops *self,
			    struct regcache *regcache)
{
  struct target_ops *beneath = find_target_beneath (self);

  if (!ravenscar_runtime_initialized ()
      || ptid_equal (inferior_ptid, base_magic_null_ptid)
      || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
    beneath->to_prepare_to_store (beneath, regcache);
  else
    {
      struct gdbarch *gdbarch = get_regcache_arch (regcache);
      struct ravenscar_arch_ops *arch_ops
	= gdbarch_ravenscar_ops (gdbarch);

      arch_ops->to_prepare_to_store (regcache);
    }
}

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

  base_ptid = null_ptid;
  beneath->to_mourn_inferior (beneath);
  unpush_target (&ravenscar_ops);
}

/* Observer on inferior_created: push ravenscar thread stratum if needed.  */

static void
ravenscar_inferior_created (struct target_ops *target, int from_tty)
{

  if (!ravenscar_task_support
      || gdbarch_ravenscar_ops (target_gdbarch ()) == NULL
      || !has_ravenscar_runtime ())
    return;

  base_magic_null_ptid = inferior_ptid;
  ravenscar_update_inferior_ptid ();
  push_target (&ravenscar_ops);
}

static ptid_t
ravenscar_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
{
  return ptid_build (ptid_get_pid (base_ptid), 0, thread);
}

static void
init_ravenscar_thread_ops (void)
{
  ravenscar_ops.to_shortname = "ravenscar";
  ravenscar_ops.to_longname = "Ravenscar tasks.";
  ravenscar_ops.to_doc = "Ravenscar tasks support.";
  ravenscar_ops.to_resume = ravenscar_resume;
  ravenscar_ops.to_wait = ravenscar_wait;
  ravenscar_ops.to_fetch_registers = ravenscar_fetch_registers;
  ravenscar_ops.to_store_registers = ravenscar_store_registers;
  ravenscar_ops.to_prepare_to_store = ravenscar_prepare_to_store;
  ravenscar_ops.to_thread_alive = ravenscar_thread_alive;
  ravenscar_ops.to_update_thread_list = ravenscar_update_thread_list;
  ravenscar_ops.to_pid_to_str = ravenscar_pid_to_str;
  ravenscar_ops.to_extra_thread_info = ravenscar_extra_thread_info;
  ravenscar_ops.to_get_ada_task_ptid = ravenscar_get_ada_task_ptid;
  ravenscar_ops.to_mourn_inferior = ravenscar_mourn_inferior;
  ravenscar_ops.to_has_all_memory = default_child_has_all_memory;
  ravenscar_ops.to_has_memory = default_child_has_memory;
  ravenscar_ops.to_has_stack = default_child_has_stack;
  ravenscar_ops.to_has_registers = default_child_has_registers;
  ravenscar_ops.to_has_execution = default_child_has_execution;
  ravenscar_ops.to_stratum = thread_stratum;
  ravenscar_ops.to_magic = OPS_MAGIC;
}

/* Command-list for the "set/show ravenscar" prefix command.  */
static struct cmd_list_element *set_ravenscar_list;
static struct cmd_list_element *show_ravenscar_list;

/* Implement the "set ravenscar" prefix command.  */

static void
set_ravenscar_command (char *arg, int from_tty)
{
  printf_unfiltered (_(\
"\"set ravenscar\" must be followed by the name of a setting.\n"));
  help_list (set_ravenscar_list, "set ravenscar ", all_commands, gdb_stdout);
}

/* Implement the "show ravenscar" prefix command.  */

static void
show_ravenscar_command (char *args, int from_tty)
{
  cmd_show_list (show_ravenscar_list, from_tty, "");
}

/* Implement the "show ravenscar task-switching" command.  */

static void
show_ravenscar_task_switching_command (struct ui_file *file, int from_tty,
				       struct cmd_list_element *c,
				       const char *value)
{
  if (ravenscar_task_support)
    fprintf_filtered (file, _("\
Support for Ravenscar task/thread switching is enabled\n"));
  else
    fprintf_filtered (file, _("\
Support for Ravenscar task/thread switching is disabled\n"));
}

/* Provide a prototype to silence -Wmissing-prototypes.  */
extern void _initialize_ravenscar (void);

/* Module startup initialization function, automagically called by
   init.c.  */

void
_initialize_ravenscar (void)
{
  init_ravenscar_thread_ops ();
  base_ptid = null_ptid;

  /* Notice when the inferior is created in order to push the
     ravenscar ops if needed.  */
  observer_attach_inferior_created (ravenscar_inferior_created);

  complete_target_initialization (&ravenscar_ops);

  add_prefix_cmd ("ravenscar", no_class, set_ravenscar_command,
                  _("Prefix command for changing Ravenscar-specific settings"),
                  &set_ravenscar_list, "set ravenscar ", 0, &setlist);

  add_prefix_cmd ("ravenscar", no_class, show_ravenscar_command,
                  _("Prefix command for showing Ravenscar-specific settings"),
                  &show_ravenscar_list, "show ravenscar ", 0, &showlist);

  add_setshow_boolean_cmd ("task-switching", class_obscure,
                           &ravenscar_task_support, _("\
Enable or disable support for GNAT Ravenscar tasks"), _("\
Show whether support for GNAT Ravenscar tasks is enabled"),
                           _("\
Enable or disable support for task/thread switching with the GNAT\n\
Ravenscar run-time library for bareboard configuration."),
			   NULL, show_ravenscar_task_switching_command,
			   &set_ravenscar_list, &show_ravenscar_list);
}
