/* Copyright (C) 1992-1994, 1997-2000, 2003-2005, 2007-2012 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;

  /* Type of elements of the known task.  Usually a pointer.  */
  struct type *known_tasks_element;

  /* Number of elements in the known tasks array.  */
  unsigned int known_tasks_length;

  /* 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 (struct ada_tasks_inferior_data *data)
{
  const int target_ptr_byte = TYPE_LENGTH (data->known_tasks_element);
  const int known_tasks_size = target_ptr_byte * data->known_tasks_length;
  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 (data->known_tasks_addr, known_tasks, known_tasks_size);
  for (i = 0; i < data->known_tasks_length; i++)
    {
      CORE_ADDR task_id =
        extract_typed_address (known_tasks + i * target_ptr_byte,
			       data->known_tasks_element);

      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 (struct ada_tasks_inferior_data *data)
{
  const int target_ptr_byte = TYPE_LENGTH (data->known_tasks_element);
  gdb_byte *known_tasks = alloca (target_ptr_byte);
  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 (data->known_tasks_addr, known_tasks, target_ptr_byte);
  task_id = extract_typed_address (known_tasks, data->known_tasks_element);
  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;
}

/* Set all fields of the current inferior ada-tasks data pointed by DATA.
   Do nothing if those fields are already set and still up to date.  */

static void
ada_tasks_inferior_data_sniffer (struct ada_tasks_inferior_data *data)
{
  struct minimal_symbol *msym;
  struct symbol *sym;

  /* Return now if already set.  */
  if (data->known_tasks_kind != ADA_TASKS_UNKNOWN)
    return;

  /* Try array.  */

  msym = lookup_minimal_symbol (KNOWN_TASKS_NAME, NULL, NULL);
  if (msym != NULL)
    {
      data->known_tasks_kind = ADA_TASKS_ARRAY;
      data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym);

      /* Try to get pointer type and array length from the symtab.  */
      sym = lookup_symbol_in_language (KNOWN_TASKS_NAME, NULL, VAR_DOMAIN,
				       language_c, NULL);
      if (sym != NULL)
	{
	  /* Validate.  */
	  struct type *type = check_typedef (SYMBOL_TYPE (sym));
	  struct type *eltype = NULL;
	  struct type *idxtype = NULL;

	  if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
	    eltype = check_typedef (TYPE_TARGET_TYPE (type));
	  if (eltype != NULL
	      && TYPE_CODE (eltype) == TYPE_CODE_PTR)
	    idxtype = check_typedef (TYPE_INDEX_TYPE (type));
	  if (idxtype != NULL
	      && !TYPE_LOW_BOUND_UNDEFINED (idxtype)
	      && !TYPE_HIGH_BOUND_UNDEFINED (idxtype))
	    {
	      data->known_tasks_element = eltype;
	      data->known_tasks_length =
		TYPE_HIGH_BOUND (idxtype) - TYPE_LOW_BOUND (idxtype) + 1;
	      return;
	    }
	}

      /* Fallback to default values.  The runtime may have been stripped (as
	 in some distributions), but it is likely that the executable still
	 contains debug information on the task type (due to implicit with of
	 Ada.Tasking).  */
      data->known_tasks_element =
	builtin_type (target_gdbarch)->builtin_data_ptr;
      data->known_tasks_length = MAX_NUMBER_OF_KNOWN_TASKS;
      return;
    }


  /* Try list.  */

  msym = lookup_minimal_symbol (KNOWN_TASKS_LIST, NULL, NULL);
  if (msym != NULL)
    {
      data->known_tasks_kind = ADA_TASKS_LIST;
      data->known_tasks_addr = SYMBOL_VALUE_ADDRESS (msym);
      data->known_tasks_length = 1;

      sym = lookup_symbol_in_language (KNOWN_TASKS_LIST, NULL, VAR_DOMAIN,
				       language_c, NULL);
      if (sym != NULL && SYMBOL_VALUE_ADDRESS (sym) != 0)
	{
	  /* Validate.  */
	  struct type *type = check_typedef (SYMBOL_TYPE (sym));

	  if (TYPE_CODE (type) == TYPE_CODE_PTR)
	    {
	      data->known_tasks_element = type;
	      return;
	    }
	}

      /* Fallback to default values.  */
      data->known_tasks_element =
	builtin_type (target_gdbarch)->builtin_data_ptr;
      data->known_tasks_length = 1;
      return;
    }

  /* Can't find tasks.  */

  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_tasks_inferior_data_sniffer (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);
      case ADA_TASKS_LIST:
        return read_known_tasks_list (data);
    }

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

