/* Ada Ravenscar thread support.

   Copyright (C) 2004-2017 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 const 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 const 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 const 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);
  ptid_t ptid = regcache_get_ptid (regcache);

  if (!ravenscar_runtime_initialized ()
      || ptid_equal (ptid, base_magic_null_ptid)
      || ptid_equal (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);
  ptid_t ptid = regcache_get_ptid (regcache);

  if (!ravenscar_runtime_initialized ()
      || ptid_equal (ptid, base_magic_null_ptid)
      || ptid_equal (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);
  ptid_t ptid = regcache_get_ptid (regcache);

  if (!ravenscar_runtime_initialized ()
      || ptid_equal (ptid, base_magic_null_ptid)
      || ptid_equal (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);
}
