/* Copyright (C) 1992, 1993, 1994, 1997, 1998, 1999, 2000, 2003, 2004, 2005,
   2007, 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 "observer.h"
#include "gdbcmd.h"
#include "target.h"
#include "ada-lang.h"
#include "gdbcore.h"
#include "inferior.h"
#include "gdbthread.h"
#include "progspace.h"
#include "objfiles.h"

/* The name of the array in the GNAT runtime where the Ada Task Control
   Block of each task is stored.  */
#define KNOWN_TASKS_NAME "system__tasking__debug__known_tasks"

/* The maximum number of tasks known to the Ada runtime.  */
static const int MAX_NUMBER_OF_KNOWN_TASKS = 1000;

/* The name of the variable in the GNAT runtime where the head of a task
   chain is saved.  This is an alternate mechanism to find the list of known
   tasks.  */
#define KNOWN_TASKS_LIST "system__tasking__debug__first_task"

enum task_states
{
  Unactivated,
  Runnable,
  Terminated,
  Activator_Sleep,
  Acceptor_Sleep,
  Entry_Caller_Sleep,
  Async_Select_Sleep,
  Delay_Sleep,
  Master_Completion_Sleep,
  Master_Phase_2_Sleep,
  Interrupt_Server_Idle_Sleep,
  Interrupt_Server_Blocked_Interrupt_Sleep,
  Timer_Server_Sleep,
  AST_Server_Sleep,
  Asynchronous_Hold,
  Interrupt_Server_Blocked_On_Event_Flag,
  Activating,
  Acceptor_Delay_Sleep
};

/* A short description corresponding to each possible task state.  */
static const char *task_states[] = {
  N_("Unactivated"),
  N_("Runnable"),
  N_("Terminated"),
  N_("Child Activation Wait"),
  N_("Accept or Select Term"),
  N_("Waiting on entry call"),
  N_("Async Select Wait"),
  N_("Delay Sleep"),
  N_("Child Termination Wait"),
  N_("Wait Child in Term Alt"),
  "",
  "",
  "",
  "",
  N_("Asynchronous Hold"),
  "",
  N_("Activating"),
  N_("Selective Wait")
};

/* A longer description corresponding to each possible task state.  */
static const char *long_task_states[] = {
  N_("Unactivated"),
  N_("Runnable"),
  N_("Terminated"),
  N_("Waiting for child activation"),
  N_("Blocked in accept or select with terminate"),
  N_("Waiting on entry call"),
  N_("Asynchronous Selective Wait"),
  N_("Delay Sleep"),
  N_("Waiting for children termination"),
  N_("Waiting for children in terminate alternative"),
  "",
  "",
  "",
  "",
  N_("Asynchronous Hold"),
  "",
  N_("Activating"),
  N_("Blocked in selective wait statement")
};

/* The index of certain important fields in the Ada Task Control Block
   record and sub-records.  */

struct atcb_fieldnos
{
  /* Fields in record Ada_Task_Control_Block.  */
  int common;
  int entry_calls;
  int atc_nesting_level;

  /* Fields in record Common_ATCB.  */
  int state;
  int parent;
  int priority;
  int image;
  int image_len;     /* This field may be missing.  */
  int activation_link;
  int call;
  int ll;

  /* Fields in Task_Primitives.Private_Data.  */
  int ll_thread;
  int ll_lwp;        /* This field may be missing.  */

  /* Fields in Common_ATCB.Call.all.  */
  int call_self;
};

/* This module's per-program-space data.  */

struct ada_tasks_pspace_data
{
  /* Nonzero if the data has been initialized.  If set to zero,
     it means that the data has either not been initialized, or
     has potentially become stale.  */
  int initialized_p;

  /* The ATCB record type.  */
  struct type *atcb_type;

  /* The ATCB "Common" component type.  */
  struct type *atcb_common_type;

  /* The type of the "ll" field, from the atcb_common_type.  */
  struct type *atcb_ll_type;

  /* The type of the "call" field, from the atcb_common_type.  */
  struct type *atcb_call_type;

  /* The index of various fields in the ATCB record and sub-records.  */
  struct atcb_fieldnos atcb_fieldno;
};

/* Key to our per-program-space data.  */
static const struct program_space_data *ada_tasks_pspace_data_handle;

typedef struct ada_task_info ada_task_info_s;
DEF_VEC_O(ada_task_info_s);

/* The kind of data structure used by the runtime to store the list
   of Ada tasks.  */

enum ada_known_tasks_kind
{
  /* Use this value when we haven't determined which kind of structure
     is being used, or when we need to recompute it.

     We set the value of this enumerate to zero on purpose: This allows
     us to use this enumerate in a structure where setting all fields
     to zero will result in this kind being set to unknown.  */
  ADA_TASKS_UNKNOWN = 0,

  /* This value means that we did not find any task list.  Unless
     there is a bug somewhere, this means that the inferior does not
     use tasking.  */
  ADA_TASKS_NOT_FOUND,

  /* This value means that the task list is stored as an array.
     This is the usual method, as it causes very little overhead.
     But this method is not always used, as it does use a certain
     amount of memory, which might be scarse in certain environments.  */
  ADA_TASKS_ARRAY,

  /* This value means that the task list is stored as a linked list.
     This has more runtime overhead than the array approach, but
     also require less memory when the number of tasks is small.  */
  ADA_TASKS_LIST,
};

/* This module's per-inferior data.  */

struct ada_tasks_inferior_data
{
  /* The type of data structure used by the runtime to store
     the list of Ada tasks.  The value of this field influences
     the interpretation of the known_tasks_addr field below:
       - ADA_TASKS_UNKNOWN: The value of known_tasks_addr hasn't
         been determined yet;
       - ADA_TASKS_NOT_FOUND: The program probably does not use tasking
         and the known_tasks_addr is irrelevant;
       - ADA_TASKS_ARRAY: The known_tasks is an array;
       - ADA_TASKS_LIST: The known_tasks is a list.  */
  enum ada_known_tasks_kind known_tasks_kind;

  /* The address of the known_tasks structure.  This is where
     the runtime stores the information for all Ada tasks.
     The interpretation of this field depends on KNOWN_TASKS_KIND
     above.  */
  CORE_ADDR known_tasks_addr;

  /* When nonzero, this flag indicates that the task_list field
     below is up to date.  When set to zero, the list has either
     not been initialized, or has potentially become stale.  */
  int task_list_valid_p;

  /* The list of Ada tasks.

     Note: To each task we associate a number that the user can use to
     reference it - this number is printed beside each task in the tasks
     info listing displayed by "info tasks".  This number is equal to
     its index in the vector + 1.  Reciprocally, to compute the index
     of a task in the vector, we need to substract 1 from its number.  */
  VEC(ada_task_info_s) *task_list;
};

/* Key to our per-inferior data.  */
static const struct inferior_data *ada_tasks_inferior_data_handle;

/* Return the ada-tasks module's data for the given program space (PSPACE).
   If none is found, add a zero'ed one now.

   This function always returns a valid object.  */

static struct ada_tasks_pspace_data *
get_ada_tasks_pspace_data (struct program_space *pspace)
{
  struct ada_tasks_pspace_data *data;

  data = program_space_data (pspace, ada_tasks_pspace_data_handle);
  if (data == NULL)
    {
      data = XZALLOC (struct ada_tasks_pspace_data);
      set_program_space_data (pspace, ada_tasks_pspace_data_handle, data);
    }

  return data;
}

/* Return the ada-tasks module's data for the given inferior (INF).
   If none is found, add a zero'ed one now.

   This function always returns a valid object.

   Note that we could use an observer of the inferior-created event
   to make sure that the ada-tasks per-inferior data always exists.
   But we prefered this approach, as it avoids this entirely as long
   as the user does not use any of the tasking features.  This is
   quite possible, particularly in the case where the inferior does
   not use tasking.  */

static struct ada_tasks_inferior_data *
get_ada_tasks_inferior_data (struct inferior *inf)
{
  struct ada_tasks_inferior_data *data;

  data = inferior_data (inf, ada_tasks_inferior_data_handle);
  if (data == NULL)
    {
      data = XZALLOC (struct ada_tasks_inferior_data);
      set_inferior_data (inf, ada_tasks_inferior_data_handle, data);
    }

  return data;
}

/* Return the task number of the task whose ptid is PTID, or zero
   if the task could not be found.  */

int
ada_get_task_number (ptid_t ptid)
{
  int i;
  struct inferior *inf = find_inferior_pid (ptid_get_pid (ptid));
  struct ada_tasks_inferior_data *data;

  gdb_assert (inf != NULL);
  data = get_ada_tasks_inferior_data (inf);

  for (i = 0; i < VEC_length (ada_task_info_s, data->task_list); i++)
    if (ptid_equal (VEC_index (ada_task_info_s, data->task_list, i)->ptid,
		    ptid))
      return i + 1;

  return 0;  /* No matching task found.  */
}

/* Return the task number of the task running in inferior INF which
   matches TASK_ID , or zero if the task could not be found.  */
 
static int
get_task_number_from_id (CORE_ADDR task_id, struct inferior *inf)
{
  struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf);
  int i;

  for (i = 0; i < VEC_length (ada_task_info_s, data->task_list); i++)
    {
      struct ada_task_info *task_info =
        VEC_index (ada_task_info_s, data->task_list, i);

      if (task_info->task_id == task_id)
        return i + 1;
    }

  /* Task not found.  Return 0.  */
  return 0;
}

/* Return non-zero if TASK_NUM is a valid task number.  */

int
valid_task_id (int task_num)
{
  struct ada_tasks_inferior_data *data;

  ada_build_task_list ();
  data = get_ada_tasks_inferior_data (current_inferior ());
  return (task_num > 0
          && task_num <= VEC_length (ada_task_info_s, data->task_list));
}

/* Return non-zero iff the task STATE corresponds to a non-terminated
   task state.  */

static int
ada_task_is_alive (struct ada_task_info *task_info)
{
  return (task_info->state != Terminated);
}

/* Call the ITERATOR function once for each Ada task that hasn't been
   terminated yet.  */

void
iterate_over_live_ada_tasks (ada_task_list_iterator_ftype *iterator)
{
  int i, nb_tasks;
  struct ada_task_info *task;
  struct ada_tasks_inferior_data *data;

  ada_build_task_list ();
  data = get_ada_tasks_inferior_data (current_inferior ());
  nb_tasks = VEC_length (ada_task_info_s, data->task_list);

  for (i = 0; i < nb_tasks; i++)
    {
      task = VEC_index (ada_task_info_s, data->task_list, i);
      if (!ada_task_is_alive (task))
        continue;
      iterator (task);
    }
}

/* Extract the contents of the value as a string whose length is LENGTH,
   and store the result in DEST.  */

static void
value_as_string (char *dest, struct value *val, int length)
{
  memcpy (dest, value_contents (val), length);
  dest[length] = '\0';
}

/* Extract the string image from the fat string corresponding to VAL,
   and store it in DEST.  If the string length is greater than MAX_LEN,
   then truncate the result to the first MAX_LEN characters of the fat
   string.  */

static void
read_fat_string_value (char *dest, struct value *val, int max_len)
{
  struct value *array_val;
  struct value *bounds_val;
  int len;

  /* The following variables are made static to avoid recomputing them
     each time this function is called.  */
  static int initialize_fieldnos = 1;
  static int array_fieldno;
  static int bounds_fieldno;
  static int upper_bound_fieldno;

  /* Get the index of the fields that we will need to read in order
     to extract the string from the fat string.  */
  if (initialize_fieldnos)
    {
      struct type *type = value_type (val);
      struct type *bounds_type;

      array_fieldno = ada_get_field_index (type, "P_ARRAY", 0);
      bounds_fieldno = ada_get_field_index (type, "P_BOUNDS", 0);

      bounds_type = TYPE_FIELD_TYPE (type, bounds_fieldno);
      if (TYPE_CODE (bounds_type) == TYPE_CODE_PTR)
        bounds_type = TYPE_TARGET_TYPE (bounds_type);
      if (TYPE_CODE (bounds_type) != TYPE_CODE_STRUCT)
        error (_("Unknown task name format. Aborting"));
      upper_bound_fieldno = ada_get_field_index (bounds_type, "UB0", 0);

      initialize_fieldnos = 0;
    }

  /* Get the size of the task image by checking the value of the bounds.
     The lower bound is always 1, so we only need to read the upper bound.  */
  bounds_val = value_ind (value_field (val, bounds_fieldno));
  len = value_as_long (value_field (bounds_val, upper_bound_fieldno));

  /* Make sure that we do not read more than max_len characters...  */
  if (len > max_len)
    len = max_len;

  /* Extract LEN characters from the fat string.  */
  array_val = value_ind (value_field (val, array_fieldno));
  read_memory (value_address (array_val), dest, len);

  /* Add the NUL character to close the string.  */
  dest[len] = '\0';
}

/* Get from the debugging information the type description of all types
   related to the Ada Task Control Block that will be needed in order to
   read the list of known tasks in the Ada runtime.  Also return the
   associated ATCB_FIELDNOS.

   Error handling:  Any data missing from the debugging info will cause
   an error to be raised, and none of the return values to be set.
   Users of this function can depend on the fact that all or none of the
   return values will be set.  */

static void
get_tcb_types_info (void)
{
  struct type *type;
  struct type *common_type;
  struct type *ll_type;
  struct type *call_type;
  struct atcb_fieldnos fieldnos;
  struct ada_tasks_pspace_data *pspace_data;

  const char *atcb_name = "system__tasking__ada_task_control_block___XVE";
  const char *atcb_name_fixed = "system__tasking__ada_task_control_block";
  const char *common_atcb_name = "system__tasking__common_atcb";
  const char *private_data_name = "system__task_primitives__private_data";
  const char *entry_call_record_name = "system__tasking__entry_call_record";

  /* ATCB symbols may be found in several compilation units.  As we
     are only interested in one instance, use standard (literal,
     C-like) lookups to get the first match.  */

  struct symbol *atcb_sym =
    lookup_symbol_in_language (atcb_name, NULL, VAR_DOMAIN,
			       language_c, NULL);
  const struct symbol *common_atcb_sym =
    lookup_symbol_in_language (common_atcb_name, NULL, VAR_DOMAIN,
			       language_c, NULL);
  const struct symbol *private_data_sym =
    lookup_symbol_in_language (private_data_name, NULL, VAR_DOMAIN,
			       language_c, NULL);
  const struct symbol *entry_call_record_sym =
    lookup_symbol_in_language (entry_call_record_name, NULL, VAR_DOMAIN,
			       language_c, NULL);

  if (atcb_sym == NULL || atcb_sym->type == NULL)
    {
      /* In Ravenscar run-time libs, the  ATCB does not have a dynamic
         size, so the symbol name differs.  */
      atcb_sym = lookup_symbol_in_language (atcb_name_fixed, NULL, VAR_DOMAIN,
					    language_c, NULL);

      if (atcb_sym == NULL || atcb_sym->type == NULL)
        error (_("Cannot find Ada_Task_Control_Block type. Aborting"));

      type = atcb_sym->type;
    }
  else
    {
      /* Get a static representation of the type record
         Ada_Task_Control_Block.  */
      type = atcb_sym->type;
      type = ada_template_to_fixed_record_type_1 (type, NULL, 0, NULL, 0);
    }

  if (common_atcb_sym == NULL || common_atcb_sym->type == NULL)
    error (_("Cannot find Common_ATCB type. Aborting"));
  if (private_data_sym == NULL || private_data_sym->type == NULL)
    error (_("Cannot find Private_Data type. Aborting"));
  if (entry_call_record_sym == NULL || entry_call_record_sym->type == NULL)
    error (_("Cannot find Entry_Call_Record type. Aborting"));

  /* Get the type for Ada_Task_Control_Block.Common.  */
  common_type = common_atcb_sym->type;

  /* Get the type for Ada_Task_Control_Bloc.Common.Call.LL.  */
  ll_type = private_data_sym->type;

  /* Get the type for Common_ATCB.Call.all.  */
  call_type = entry_call_record_sym->type;

  /* Get the field indices.  */
  fieldnos.common = ada_get_field_index (type, "common", 0);
  fieldnos.entry_calls = ada_get_field_index (type, "entry_calls", 1);
  fieldnos.atc_nesting_level =
    ada_get_field_index (type, "atc_nesting_level", 1);
  fieldnos.state = ada_get_field_index (common_type, "state", 0);
  fieldnos.parent = ada_get_field_index (common_type, "parent", 1);
  fieldnos.priority = ada_get_field_index (common_type, "base_priority", 0);
  fieldnos.image = ada_get_field_index (common_type, "task_image", 1);
  fieldnos.image_len = ada_get_field_index (common_type, "task_image_len", 1);
  fieldnos.activation_link = ada_get_field_index (common_type,
                                                  "activation_link", 1);
  fieldnos.call = ada_get_field_index (common_type, "call", 1);
  fieldnos.ll = ada_get_field_index (common_type, "ll", 0);
  fieldnos.ll_thread = ada_get_field_index (ll_type, "thread", 0);
  fieldnos.ll_lwp = ada_get_field_index (ll_type, "lwp", 1);
  fieldnos.call_self = ada_get_field_index (call_type, "self", 0);

  /* On certain platforms such as x86-windows, the "lwp" field has been
     named "thread_id".  This field will likely be renamed in the future,
     but we need to support both possibilities to avoid an unnecessary
     dependency on a recent compiler.  We therefore try locating the
     "thread_id" field in place of the "lwp" field if we did not find
     the latter.  */
  if (fieldnos.ll_lwp < 0)
    fieldnos.ll_lwp = ada_get_field_index (ll_type, "thread_id", 1);

  /* Set all the out parameters all at once, now that we are certain
     that there are no potential error() anymore.  */
  pspace_data = get_ada_tasks_pspace_data (current_program_space);
  pspace_data->initialized_p = 1;
  pspace_data->atcb_type = type;
  pspace_data->atcb_common_type = common_type;
  pspace_data->atcb_ll_type = ll_type;
  pspace_data->atcb_call_type = call_type;
  pspace_data->atcb_fieldno = fieldnos;
}

/* Build the PTID of the task from its COMMON_VALUE, which is the "Common"
   component of its ATCB record.  This PTID needs to match the PTID used
   by the thread layer.  */

static ptid_t
ptid_from_atcb_common (struct value *common_value)
{
  long thread = 0;
  CORE_ADDR lwp = 0;
  struct value *ll_value;
  ptid_t ptid;
  const struct ada_tasks_pspace_data *pspace_data
    = get_ada_tasks_pspace_data (current_program_space);

  ll_value = value_field (common_value, pspace_data->atcb_fieldno.ll);

  if (pspace_data->atcb_fieldno.ll_lwp >= 0)
    lwp = value_as_address (value_field (ll_value,
					 pspace_data->atcb_fieldno.ll_lwp));
  thread = value_as_long (value_field (ll_value,
				       pspace_data->atcb_fieldno.ll_thread));

  ptid = target_get_ada_task_ptid (lwp, thread);

  return ptid;
}

/* Read the ATCB data of a given task given its TASK_ID (which is in practice
   the address of its assocated ATCB record), and store the result inside
   TASK_INFO.  */

static void
read_atcb (CORE_ADDR task_id, struct ada_task_info *task_info)
{
  struct value *tcb_value;
  struct value *common_value;
  struct value *atc_nesting_level_value;
  struct value *entry_calls_value;
  struct value *entry_calls_value_element;
  int called_task_fieldno = -1;
  static const char ravenscar_task_name[] = "Ravenscar task";
  const struct ada_tasks_pspace_data *pspace_data
    = get_ada_tasks_pspace_data (current_program_space);

  if (!pspace_data->initialized_p)
    get_tcb_types_info ();

  tcb_value = value_from_contents_and_address (pspace_data->atcb_type,
					       NULL, task_id);
  common_value = value_field (tcb_value, pspace_data->atcb_fieldno.common);

  /* Fill in the task_id.  */

  task_info->task_id = task_id;

  /* Compute the name of the task.

     Depending on the GNAT version used, the task image is either a fat
     string, or a thin array of characters.  Older versions of GNAT used
     to use fat strings, and therefore did not need an extra field in
     the ATCB to store the string length.  For efficiency reasons, newer
     versions of GNAT replaced the fat string by a static buffer, but this
     also required the addition of a new field named "Image_Len" containing
     the length of the task name.  The method used to extract the task name
     is selected depending on the existence of this field.

     In some run-time libs (e.g. Ravenscar), the name is not in the ATCB;
     we may want to get it from the first user frame of the stack.  For now,
     we just give a dummy name.  */

  if (pspace_data->atcb_fieldno.image_len == -1)
    {
      if (pspace_data->atcb_fieldno.image >= 0)
        read_fat_string_value (task_info->name,
                               value_field (common_value,
					    pspace_data->atcb_fieldno.image),
                               sizeof (task_info->name) - 1);
      else
	{
	  struct minimal_symbol *msym;

	  msym = lookup_minimal_symbol_by_pc (task_id);
	  if (msym)
	    {
	      const char *full_name = SYMBOL_LINKAGE_NAME (msym);
	      const char *task_name = full_name;
	      const char *p;

	      /* Strip the prefix.  */
	      for (p = full_name; *p; p++)
		if (p[0] == '_' && p[1] == '_')
		  task_name = p + 2;

	      /* Copy the task name.  */
	      strncpy (task_info->name, task_name, sizeof (task_info->name));
	      task_info->name[sizeof (task_info->name) - 1] = 0;
	    }
	  else
	    {
	      /* No symbol found.  Use a default name.  */
	      strcpy (task_info->name, ravenscar_task_name);
	    }
	}
    }
  else
    {
      int len = value_as_long
		  (value_field (common_value,
				pspace_data->atcb_fieldno.image_len));

      value_as_string (task_info->name,
                       value_field (common_value,
				    pspace_data->atcb_fieldno.image),
		       len);
    }

  /* Compute the task state and priority.  */

  task_info->state =
    value_as_long (value_field (common_value,
				pspace_data->atcb_fieldno.state));
  task_info->priority =
    value_as_long (value_field (common_value,
				pspace_data->atcb_fieldno.priority));

  /* If the ATCB contains some information about the parent task,
     then compute it as well.  Otherwise, zero.  */

  if (pspace_data->atcb_fieldno.parent >= 0)
    task_info->parent =
      value_as_address (value_field (common_value,
				     pspace_data->atcb_fieldno.parent));
  else
    task_info->parent = 0;
  

  /* If the ATCB contains some information about entry calls, then
     compute the "called_task" as well.  Otherwise, zero.  */

  if (pspace_data->atcb_fieldno.atc_nesting_level > 0
      && pspace_data->atcb_fieldno.entry_calls > 0)
    {
      /* Let My_ATCB be the Ada task control block of a task calling the
         entry of another task; then the Task_Id of the called task is
         in My_ATCB.Entry_Calls (My_ATCB.ATC_Nesting_Level).Called_Task.  */
      atc_nesting_level_value =
        value_field (tcb_value, pspace_data->atcb_fieldno.atc_nesting_level);
      entry_calls_value =
        ada_coerce_to_simple_array_ptr
	  (value_field (tcb_value, pspace_data->atcb_fieldno.entry_calls));
      entry_calls_value_element =
        value_subscript (entry_calls_value,
			 value_as_long (atc_nesting_level_value));
      called_task_fieldno =
        ada_get_field_index (value_type (entry_calls_value_element),
                             "called_task", 0);
      task_info->called_task =
        value_as_address (value_field (entry_calls_value_element,
                                       called_task_fieldno));
    }
  else
    {
      task_info->called_task = 0;
    }

  /* If the ATCB cotnains some information about RV callers,
     then compute the "caller_task".  Otherwise, zero.  */

  task_info->caller_task = 0;
  if (pspace_data->atcb_fieldno.call >= 0)
    {
      /* Get the ID of the caller task from Common_ATCB.Call.all.Self.
         If Common_ATCB.Call is null, then there is no caller.  */
      const CORE_ADDR call =
        value_as_address (value_field (common_value,
				       pspace_data->atcb_fieldno.call));
      struct value *call_val;

      if (call != 0)
        {
          call_val =
            value_from_contents_and_address (pspace_data->atcb_call_type,
					     NULL, call);
          task_info->caller_task =
            value_as_address
	      (value_field (call_val, pspace_data->atcb_fieldno.call_self));
        }
    }

  /* And finally, compute the task ptid.  Note that there are situations
     where this cannot be determined:
       - The task is no longer alive - the ptid is irrelevant;
       - We are debugging a core file - the thread is not always
         completely preserved for us to link back a task to its
         underlying thread.  Since we do not support task switching
         when debugging core files anyway, we don't need to compute
         that task ptid.
     In either case, we don't need that ptid, and it is just good enough
     to set it to null_ptid.  */

  if (target_has_execution && ada_task_is_alive (task_info))
    task_info->ptid = ptid_from_atcb_common (common_value);
  else
    task_info->ptid = null_ptid;
}

/* Read the ATCB info of the given task (identified by TASK_ID), and
   add the result to the given inferior's TASK_LIST.  */

static void
add_ada_task (CORE_ADDR task_id, struct inferior *inf)
{
  struct ada_task_info task_info;
  struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf);

  read_atcb (task_id, &task_info);
  VEC_safe_push (ada_task_info_s, data->task_list, &task_info);
}

/* Read the Known_Tasks array from the inferior memory, and store
   it in the current inferior's TASK_LIST.  Return non-zero upon success.  */

static int
read_known_tasks_array (CORE_ADDR known_tasks_addr)
{
  const int target_ptr_byte =
    gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT;
  const int known_tasks_size = target_ptr_byte * MAX_NUMBER_OF_KNOWN_TASKS;
  gdb_byte *known_tasks = alloca (known_tasks_size);
  int i;

  /* Build a new list by reading the ATCBs from the Known_Tasks array
     in the Ada runtime.  */
  read_memory (known_tasks_addr, known_tasks, known_tasks_size);
  for (i = 0; i < MAX_NUMBER_OF_KNOWN_TASKS; i++)
    {
      struct type *data_ptr_type =
        builtin_type (target_gdbarch)->builtin_data_ptr;
      CORE_ADDR task_id =
        extract_typed_address (known_tasks + i * target_ptr_byte,
			       data_ptr_type);

      if (task_id != 0)
        add_ada_task (task_id, current_inferior ());
    }

  return 1;
}

/* Read the known tasks from the inferior memory, and store it in
   the current inferior's TASK_LIST.  Return non-zero upon success.  */

static int
read_known_tasks_list (CORE_ADDR known_tasks_addr)
{
  const int target_ptr_byte =
    gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT;
  gdb_byte *known_tasks = alloca (target_ptr_byte);
  struct type *data_ptr_type =
    builtin_type (target_gdbarch)->builtin_data_ptr;
  CORE_ADDR task_id;
  const struct ada_tasks_pspace_data *pspace_data
    = get_ada_tasks_pspace_data (current_program_space);

  /* Sanity check.  */
  if (pspace_data->atcb_fieldno.activation_link < 0)
    return 0;

  /* Build a new list by reading the ATCBs.  Read head of the list.  */
  read_memory (known_tasks_addr, known_tasks, target_ptr_byte);
  task_id = extract_typed_address (known_tasks, data_ptr_type);
  while (task_id != 0)
    {
      struct value *tcb_value;
      struct value *common_value;

      add_ada_task (task_id, current_inferior ());

      /* Read the chain.  */
      tcb_value = value_from_contents_and_address (pspace_data->atcb_type,
						   NULL, task_id);
      common_value = value_field (tcb_value, pspace_data->atcb_fieldno.common);
      task_id = value_as_address
		  (value_field (common_value,
                                pspace_data->atcb_fieldno.activation_link));
    }

  return 1;
}

/* Return the address of the variable NAME that contains all the known
   tasks maintained in the Ada Runtime.  Return NULL if the variable
   could not be found, meaning that the inferior program probably does
   not use tasking.  */

static CORE_ADDR
get_known_tasks_addr (const char *name)
{
  struct minimal_symbol *msym;

  msym = lookup_minimal_symbol (name, NULL, NULL);
  if (msym == NULL)
    return 0;

  return SYMBOL_VALUE_ADDRESS (msym);
}

/* Assuming DATA is the ada-tasks' data for the current inferior,
   set the known_tasks_kind and known_tasks_addr fields.  Do nothing
   if those fields are already set and still up to date.  */

static void
ada_set_current_inferior_known_tasks_addr (struct ada_tasks_inferior_data *data)
{
  CORE_ADDR known_tasks_addr;

  if (data->known_tasks_kind != ADA_TASKS_UNKNOWN)
    return;

  known_tasks_addr = get_known_tasks_addr (KNOWN_TASKS_NAME);
  if (known_tasks_addr != 0)
    {
      data->known_tasks_kind = ADA_TASKS_ARRAY;
      data->known_tasks_addr = known_tasks_addr;
      return;
    }

  known_tasks_addr = get_known_tasks_addr (KNOWN_TASKS_LIST);
  if (known_tasks_addr != 0)
    {
      data->known_tasks_kind = ADA_TASKS_LIST;
      data->known_tasks_addr = known_tasks_addr;
      return;
    }

  data->known_tasks_kind = ADA_TASKS_NOT_FOUND;
  data->known_tasks_addr = 0;
}

/* Read the known tasks from the current inferior's memory, and store it
   in the current inferior's data TASK_LIST.
   Return non-zero upon success.  */

static int
read_known_tasks (void)
{
  struct ada_tasks_inferior_data *data =
    get_ada_tasks_inferior_data (current_inferior ());

  /* Step 1: Clear the current list, if necessary.  */
  VEC_truncate (ada_task_info_s, data->task_list, 0);

  /* Step 2: do the real work.
     If the application does not use task, then no more needs to be done.
     It is important to have the task list cleared (see above) before we
     return, as we don't want a stale task list to be used...  This can
     happen for instance when debugging a non-multitasking program after
     having debugged a multitasking one.  */
  ada_set_current_inferior_known_tasks_addr (data);
  gdb_assert (data->known_tasks_kind != ADA_TASKS_UNKNOWN);

  switch (data->known_tasks_kind)
    {
      case ADA_TASKS_NOT_FOUND: /* Tasking not in use in inferior.  */
        return 0;
      case ADA_TASKS_ARRAY:
        return read_known_tasks_array (data->known_tasks_addr);
      case ADA_TASKS_LIST:
        return read_known_tasks_list (data->known_tasks_addr);
    }

  /* Step 3: Set task_list_valid_p, to avoid re-reading the Known_Tasks
     array unless needed.  Then report a success.  */
  data->task_list_valid_p = 1;

  return 1;
}

/* Build the task_list by reading the Known_Tasks array from
   the inferior, and return the number of tasks in that list
   (zero means that the program is not using tasking at all).  */

int
ada_build_task_list (void)
{
  struct ada_tasks_inferior_data *data;

  if (!target_has_stack)
    error (_("Cannot inspect Ada tasks when program is not running"));

  data = get_ada_tasks_inferior_data (current_inferior ());
  if (!data->task_list_valid_p)
    read_known_tasks ();

  return VEC_length (ada_task_info_s, data->task_list);
}

/* Print a table providing a short description of all Ada tasks
   running inside inferior INF.  If ARG_STR is set, it will be
   interpreted as a task number, and the table will be limited to
   that task only.  */

void
print_ada_task_info (struct ui_out *uiout,
		     char *arg_str,
		     struct inferior *inf)
{
  struct ada_tasks_inferior_data *data;
  int taskno, nb_tasks;
  int taskno_arg = 0;
  struct cleanup *old_chain;
  int nb_columns;

  if (ada_build_task_list () == 0)
    {
      ui_out_message (uiout, 0,
		      _("Your application does not use any Ada tasks.\n"));
      return;
    }

  if (arg_str != NULL && arg_str[0] != '\0')
    taskno_arg = value_as_long (parse_and_eval (arg_str));

  if (ui_out_is_mi_like_p (uiout))
    /* In GDB/MI mode, we want to provide the thread ID corresponding
       to each task.  This allows clients to quickly find the thread
       associated to any task, which is helpful for commands that
       take a --thread argument.  However, in order to be able to
       provide that thread ID, the thread list must be up to date
       first.  */
    target_find_new_threads ();

  data = get_ada_tasks_inferior_data (inf);

  /* Compute the number of tasks that are going to be displayed
     in the output.  If an argument was given, there will be
     at most 1 entry.  Otherwise, there will be as many entries
     as we have tasks.  */
  if (taskno_arg)
    {
      if (taskno_arg > 0
	  && taskno_arg <= VEC_length (ada_task_info_s, data->task_list))
	nb_tasks = 1;
      else
	nb_tasks = 0;
    }
  else
    nb_tasks = VEC_length (ada_task_info_s, data->task_list);

  nb_columns = ui_out_is_mi_like_p (uiout) ? 8 : 7;
  old_chain = make_cleanup_ui_out_table_begin_end (uiout, nb_columns,
						   nb_tasks, "tasks");
  ui_out_table_header (uiout, 1, ui_left, "current", "");
  ui_out_table_header (uiout, 3, ui_right, "id", "ID");
  ui_out_table_header (uiout, 9, ui_right, "task-id", "TID");
  /* The following column is provided in GDB/MI mode only because
     it is only really useful in that mode, and also because it
     allows us to keep the CLI output shorter and more compact.  */
  if (ui_out_is_mi_like_p (uiout))
    ui_out_table_header (uiout, 4, ui_right, "thread-id", "");
  ui_out_table_header (uiout, 4, ui_right, "parent-id", "P-ID");
  ui_out_table_header (uiout, 3, ui_right, "priority", "Pri");
  ui_out_table_header (uiout, 22, ui_left, "state", "State");
  /* Use ui_noalign for the last column, to prevent the CLI uiout
     from printing an extra space at the end of each row.  This
     is a bit of a hack, but does get the job done.  */
  ui_out_table_header (uiout, 1, ui_noalign, "name", "Name");
  ui_out_table_body (uiout);

  for (taskno = 1;
       taskno <= VEC_length (ada_task_info_s, data->task_list);
       taskno++)
    {
      const struct ada_task_info *const task_info =
	VEC_index (ada_task_info_s, data->task_list, taskno - 1);
      int parent_id;
      struct cleanup *chain2;

      gdb_assert (task_info != NULL);

      /* If the user asked for the output to be restricted
	 to one task only, and this is not the task, skip
	 to the next one.  */
      if (taskno_arg && taskno != taskno_arg)
        continue;

      chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);

      /* Print a star if this task is the current task (or the task
         currently selected).  */
      if (ptid_equal (task_info->ptid, inferior_ptid))
	ui_out_field_string (uiout, "current", "*");
      else
	ui_out_field_skip (uiout, "current");

      /* Print the task number.  */
      ui_out_field_int (uiout, "id", taskno);

      /* Print the Task ID.  */
      ui_out_field_fmt (uiout, "task-id", "%9lx", (long) task_info->task_id);

      /* Print the associated Thread ID.  */
      if (ui_out_is_mi_like_p (uiout))
        {
	  const int thread_id = pid_to_thread_id (task_info->ptid);

	  if (thread_id != 0)
	    ui_out_field_int (uiout, "thread-id", thread_id);
	  else
	    /* This should never happen unless there is a bug somewhere,
	       but be resilient when that happens.  */
	    ui_out_field_skip (uiout, "thread-id");
	}

      /* Print the ID of the parent task.  */
      parent_id = get_task_number_from_id (task_info->parent, inf);
      if (parent_id)
        ui_out_field_int (uiout, "parent-id", parent_id);
      else
        ui_out_field_skip (uiout, "parent-id");

      /* Print the base priority of the task.  */
      ui_out_field_int (uiout, "priority", task_info->priority);

      /* Print the task current state.  */
      if (task_info->caller_task)
	ui_out_field_fmt (uiout, "state",
			  _("Accepting RV with %-4d"),
			  get_task_number_from_id (task_info->caller_task,
						   inf));
      else if (task_info->state == Entry_Caller_Sleep
	       && task_info->called_task)
	ui_out_field_fmt (uiout, "state",
			  _("Waiting on RV with %-3d"),
			  get_task_number_from_id (task_info->called_task,
						   inf));
      else
	ui_out_field_string (uiout, "state", task_states[task_info->state]);

      /* Finally, print the task name.  */
      ui_out_field_fmt (uiout, "name",
			"%s",
			task_info->name[0] != '\0' ? task_info->name
						   : _("<no name>"));

      ui_out_text (uiout, "\n");
      do_cleanups (chain2);
    }

  do_cleanups (old_chain);
}

/* Print a detailed description of the Ada task whose ID is TASKNO_STR
   for the given inferior (INF).  */

static void
info_task (struct ui_out *uiout, char *taskno_str, struct inferior *inf)
{
  const int taskno = value_as_long (parse_and_eval (taskno_str));
  struct ada_task_info *task_info;
  int parent_taskno = 0;
  struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf);

  if (ada_build_task_list () == 0)
    {
      ui_out_message (uiout, 0,
		      _("Your application does not use any Ada tasks.\n"));
      return;
    }

  if (taskno <= 0 || taskno > VEC_length (ada_task_info_s, data->task_list))
    error (_("Task ID %d not known.  Use the \"info tasks\" command to\n"
             "see the IDs of currently known tasks"), taskno);
  task_info = VEC_index (ada_task_info_s, data->task_list, taskno - 1);

  /* Print the Ada task ID.  */
  printf_filtered (_("Ada Task: %s\n"),
		   paddress (target_gdbarch, task_info->task_id));

  /* Print the name of the task.  */
  if (task_info->name[0] != '\0')
    printf_filtered (_("Name: %s\n"), task_info->name);
  else
    printf_filtered (_("<no name>\n"));

  /* Print the TID and LWP.  */
  printf_filtered (_("Thread: %#lx\n"), ptid_get_tid (task_info->ptid));
  printf_filtered (_("LWP: %#lx\n"), ptid_get_lwp (task_info->ptid));

  /* Print who is the parent (if any).  */
  if (task_info->parent != 0)
    parent_taskno = get_task_number_from_id (task_info->parent, inf);
  if (parent_taskno)
    {
      struct ada_task_info *parent =
        VEC_index (ada_task_info_s, data->task_list, parent_taskno - 1);

      printf_filtered (_("Parent: %d"), parent_taskno);
      if (parent->name[0] != '\0')
        printf_filtered (" (%s)", parent->name);
      printf_filtered ("\n");
    }
  else
    printf_filtered (_("No parent\n"));

  /* Print the base priority.  */
  printf_filtered (_("Base Priority: %d\n"), task_info->priority);

  /* print the task current state.  */
  {
    int target_taskno = 0;

    if (task_info->caller_task)
      {
        target_taskno = get_task_number_from_id (task_info->caller_task, inf);
        printf_filtered (_("State: Accepting rendezvous with %d"),
                         target_taskno);
      }
    else if (task_info->state == Entry_Caller_Sleep && task_info->called_task)
      {
        target_taskno = get_task_number_from_id (task_info->called_task, inf);
        printf_filtered (_("State: Waiting on task %d's entry"),
                         target_taskno);
      }
    else
      printf_filtered (_("State: %s"), _(long_task_states[task_info->state]));

    if (target_taskno)
      {
        struct ada_task_info *target_task_info =
          VEC_index (ada_task_info_s, data->task_list, target_taskno - 1);

        if (target_task_info->name[0] != '\0')
          printf_filtered (" (%s)", target_task_info->name);
      }

    printf_filtered ("\n");
  }
}

/* If ARG is empty or null, then print a list of all Ada tasks.
   Otherwise, print detailed information about the task whose ID
   is ARG.
   
   Does nothing if the program doesn't use Ada tasking.  */

static void
info_tasks_command (char *arg, int from_tty)
{
  struct ui_out *uiout = current_uiout;

  if (arg == NULL || *arg == '\0')
    print_ada_task_info (uiout, NULL, current_inferior ());
  else
    info_task (uiout, arg, current_inferior ());
}

/* Print a message telling the user id of the current task.
   This function assumes that tasking is in use in the inferior.  */

static void
display_current_task_id (void)
{
  const int current_task = ada_get_task_number (inferior_ptid);

  if (current_task == 0)
    printf_filtered (_("[Current task is unknown]\n"));
  else
    printf_filtered (_("[Current task is %d]\n"), current_task);
}

/* Parse and evaluate TIDSTR into a task id, and try to switch to
   that task.  Print an error message if the task switch failed.  */

static void
task_command_1 (char *taskno_str, int from_tty, struct inferior *inf)
{
  const int taskno = value_as_long (parse_and_eval (taskno_str));
  struct ada_task_info *task_info;
  struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf);

  if (taskno <= 0 || taskno > VEC_length (ada_task_info_s, data->task_list))
    error (_("Task ID %d not known.  Use the \"info tasks\" command to\n"
             "see the IDs of currently known tasks"), taskno);
  task_info = VEC_index (ada_task_info_s, data->task_list, taskno - 1);

  if (!ada_task_is_alive (task_info))
    error (_("Cannot switch to task %d: Task is no longer running"), taskno);
   
  /* On some platforms, the thread list is not updated until the user
     performs a thread-related operation (by using the "info threads"
     command, for instance).  So this thread list may not be up to date
     when the user attempts this task switch.  Since we cannot switch
     to the thread associated to our task if GDB does not know about
     that thread, we need to make sure that any new threads gets added
     to the thread list.  */
  target_find_new_threads ();

  /* Verify that the ptid of the task we want to switch to is valid
     (in other words, a ptid that GDB knows about).  Otherwise, we will
     cause an assertion failure later on, when we try to determine
     the ptid associated thread_info data.  We should normally never
     encounter such an error, but the wrong ptid can actually easily be
     computed if target_get_ada_task_ptid has not been implemented for
     our target (yet).  Rather than cause an assertion error in that case,
     it's nicer for the user to just refuse to perform the task switch.  */
  if (!find_thread_ptid (task_info->ptid))
    error (_("Unable to compute thread ID for task %d.\n"
             "Cannot switch to this task."),
           taskno);

  switch_to_thread (task_info->ptid);
  ada_find_printable_frame (get_selected_frame (NULL));
  printf_filtered (_("[Switching to task %d]\n"), taskno);
  print_stack_frame (get_selected_frame (NULL),
                     frame_relative_level (get_selected_frame (NULL)), 1);
}


/* Print the ID of the current task if TASKNO_STR is empty or NULL.
   Otherwise, switch to the task indicated by TASKNO_STR.  */

static void
task_command (char *taskno_str, int from_tty)
{
  struct ui_out *uiout = current_uiout;

  if (ada_build_task_list () == 0)
    {
      ui_out_message (uiout, 0,
		      _("Your application does not use any Ada tasks.\n"));
      return;
    }

  if (taskno_str == NULL || taskno_str[0] == '\0')
    display_current_task_id ();
  else
    {
      /* Task switching in core files doesn't work, either because:
           1. Thread support is not implemented with core files
           2. Thread support is implemented, but the thread IDs created
              after having read the core file are not the same as the ones
              that were used during the program life, before the crash.
              As a consequence, there is no longer a way for the debugger
              to find the associated thead ID of any given Ada task.
         So, instead of attempting a task switch without giving the user
         any clue as to what might have happened, just error-out with
         a message explaining that this feature is not supported.  */
      if (!target_has_execution)
        error (_("\
Task switching not supported when debugging from core files\n\
(use thread support instead)"));
      task_command_1 (taskno_str, from_tty, current_inferior ());
    }
}

/* Indicate that the given inferior's task list may have changed,
   so invalidate the cache.  */

static void
ada_task_list_changed (struct inferior *inf)
{
  struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf);

  data->task_list_valid_p = 0;
}

/* Invalidate the per-program-space data.  */

static void
ada_tasks_invalidate_pspace_data (struct program_space *pspace)
{
  get_ada_tasks_pspace_data (pspace)->initialized_p = 0;
}

/* Invalidate the per-inferior data.  */

static void
ada_tasks_invalidate_inferior_data (struct inferior *inf)
{
  struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf);

  data->known_tasks_kind = ADA_TASKS_UNKNOWN;
  data->task_list_valid_p = 0;
}

/* The 'normal_stop' observer notification callback.  */

static void
ada_normal_stop_observer (struct bpstats *unused_args, int unused_args2)
{
  /* The inferior has been resumed, and just stopped. This means that
     our task_list needs to be recomputed before it can be used again.  */
  ada_task_list_changed (current_inferior ());
}

/* A routine to be called when the objfiles have changed.  */

static void
ada_new_objfile_observer (struct objfile *objfile)
{
  struct inferior *inf;

  /* Invalidate the relevant data in our program-space data.  */

  if (objfile == NULL)
    {
      /* All objfiles are being cleared, so we should clear all
	 our caches for all program spaces.  */
      struct program_space *pspace;

      for (pspace = program_spaces; pspace != NULL; pspace = pspace->next)
        ada_tasks_invalidate_pspace_data (pspace);
    }
  else
    {
      /* The associated program-space data might have changed after
	 this objfile was added.  Invalidate all cached data.  */
      ada_tasks_invalidate_pspace_data (objfile->pspace);
    }

  /* Invalidate the per-inferior cache for all inferiors using
     this objfile (or, in other words, for all inferiors who have
     the same program-space as the objfile's program space).
     If all objfiles are being cleared (OBJFILE is NULL), then
     clear the caches for all inferiors.  */

  for (inf = inferior_list; inf != NULL; inf = inf->next)
    if (objfile == NULL || inf->pspace == objfile->pspace)
      ada_tasks_invalidate_inferior_data (inf);
}

/* Provide a prototype to silence -Wmissing-prototypes.  */
extern initialize_file_ftype _initialize_tasks;

void
_initialize_tasks (void)
{
  ada_tasks_pspace_data_handle = register_program_space_data ();
  ada_tasks_inferior_data_handle = register_inferior_data ();

  /* Attach various observers.  */
  observer_attach_normal_stop (ada_normal_stop_observer);
  observer_attach_new_objfile (ada_new_objfile_observer);

  /* Some new commands provided by this module.  */
  add_info ("tasks", info_tasks_command,
            _("Provide information about all known Ada tasks"));
  add_cmd ("task", class_run, task_command,
           _("Use this command to switch between Ada tasks.\n\
Without argument, this command simply prints the current task ID"),
           &cmdlist);
}

