/* Copyright (C) 1992-2023 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 "observable.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"
#include "cli/cli-style.h"

static int ada_build_task_list ();

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

/* Return a string representing the task state.  */
static const char *
get_state (unsigned value)
{
  if (value >= 0 && value <= ARRAY_SIZE (task_states)
      && task_states[value][0] != '\0')
    return _ (task_states[value]);

  static char buffer[100];
  xsnprintf (buffer, sizeof (buffer), _ ("Unknown task state: %d"), value);
  return buffer;
}

/* A longer description corresponding to each possible task state.  */
static const char *const 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") };

/* Return a string representing the task state.  This uses the long
   descriptions.  */
static const char *
get_long_state (unsigned value)
{
  if (value >= 0 && value <= ARRAY_SIZE (long_task_states)
      && long_task_states[value][0] != '\0')
    return _ (long_task_states[value]);

  static char buffer[100];
  xsnprintf (buffer, sizeof (buffer), _ ("Unknown task state: %d"), value);
  return buffer;
}

/* 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;
  int base_cpu;

  /* 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 = 0;

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

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

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

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

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

  /* On some systems, gdbserver applies an offset to the CPU that is
     reported.  */
  unsigned int cpu_id_offset = 0;
};

/* Key to our per-program-space data.  */
static const registry<program_space>::key<ada_tasks_pspace_data>
  ada_tasks_pspace_data_handle;

/* 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 = ADA_TASKS_UNKNOWN;

  /* 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 = 0;

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

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

  /* 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.  */
  bool task_list_valid_p = false;

  /* 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.  */
  std::vector<ada_task_info> task_list;
};

/* Key to our per-inferior data.  */
static const registry<inferior>::key<ada_tasks_inferior_data>
  ada_tasks_inferior_data_handle;

/* Return a string with TASKNO followed by the task name if TASK_INFO
   contains a name.  */

static std::string
task_to_str (int taskno, const ada_task_info *task_info)
{
  if (task_info->name[0] == '\0')
    return string_printf ("%d", taskno);
  else
    return string_printf ("%d \"%s\"", taskno, task_info->name);
}

/* 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 = ada_tasks_pspace_data_handle.get (pspace);
  if (data == NULL)
    data = ada_tasks_pspace_data_handle.emplace (pspace);

  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 = ada_tasks_inferior_data_handle.get (inf);
  if (data == NULL)
    data = ada_tasks_inferior_data_handle.emplace (inf);

  return data;
}

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

int
ada_get_task_number (thread_info *thread)
{
  struct inferior *inf = thread->inf;
  struct ada_tasks_inferior_data *data;

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

  for (int i = 0; i < data->task_list.size (); i++)
    if (data->task_list[i].ptid == thread->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);

  for (int i = 0; i < data->task_list.size (); i++)
    {
      if (data->task_list[i].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 <= data->task_list.size ();
}

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

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

/* Search through the list of known tasks for the one whose ptid is
   PTID, and return it.  Return NULL if the task was not found.  */

struct ada_task_info *
ada_get_task_info_from_ptid (ptid_t ptid)
{
  struct ada_tasks_inferior_data *data;

  ada_build_task_list ();
  data = get_ada_tasks_inferior_data (current_inferior ());

  for (ada_task_info &task : data->task_list)
    {
      if (task.ptid == ptid)
	return &task;
    }

  return NULL;
}

/* 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)
{
  struct ada_tasks_inferior_data *data;

  ada_build_task_list ();
  data = get_ada_tasks_inferior_data (current_inferior ());

  for (ada_task_info &task : data->task_list)
    {
      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).data (), 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 (bounds_fieldno).type ();
      if (bounds_type->code () == TYPE_CODE_PTR)
	bounds_type = bounds_type->target_type ();
      if (bounds_type->code () != 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), (gdb_byte *) 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 are needed in order to
   read the list of known tasks in the Ada runtime.  If all of the info
   needed to do so is found, then save that info in the module's per-
   program-space data, and return NULL.  Otherwise, if any information
   cannot be found, leave the per-program-space data untouched, and
   return an error message explaining what was missing (that error
   message does NOT need to be deallocated).  */

const char *
ada_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, STRUCT_DOMAIN, language_c,
				 NULL)
	.symbol;
  const struct symbol *common_atcb_sym
    = lookup_symbol_in_language (common_atcb_name, NULL, STRUCT_DOMAIN,
				 language_c, NULL)
	.symbol;
  const struct symbol *private_data_sym
    = lookup_symbol_in_language (private_data_name, NULL, STRUCT_DOMAIN,
				 language_c, NULL)
	.symbol;
  const struct symbol *entry_call_record_sym
    = lookup_symbol_in_language (entry_call_record_name, NULL, STRUCT_DOMAIN,
				 language_c, NULL)
	.symbol;

  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,
					    STRUCT_DOMAIN, language_c, NULL)
		   .symbol;

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

      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)
    return _ ("Cannot find Common_ATCB type");
  if (private_data_sym == NULL || private_data_sym->type () == NULL)
    return _ ("Cannot find Private_Data type");
  if (entry_call_record_sym == NULL || entry_call_record_sym->type () == NULL)
    return _ ("Cannot find Entry_Call_Record type");

  /* 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.base_cpu = ada_get_field_index (common_type, "base_cpu", 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);

  /* Check for the CPU offset.  */
  bound_minimal_symbol first_id_sym
    = lookup_bound_minimal_symbol ("__gnat_gdb_cpu_first_id");
  unsigned int first_id = 0;
  if (first_id_sym.minsym != nullptr)
    {
      CORE_ADDR addr = first_id_sym.value_address ();
      /* This symbol always has type uint32_t.  */
      struct type *u32type = builtin_type (target_gdbarch ())->builtin_uint32;
      first_id = value_as_long (value_at (u32type, addr));
    }

  /* 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;
  pspace_data->cpu_id_offset = first_id;
  return NULL;
}

/* 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)
{
  ULONGEST thread;
  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 associated 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);

  /* Clear the whole structure to start with, so that everything
     is always initialized the same.  */
  memset (task_info, 0, sizeof (struct ada_task_info));

  if (!pspace_data->initialized_p)
    {
      const char *err_msg = ada_get_tcb_types_info ();

      if (err_msg != NULL)
	error (_ ("%s. Aborting"), err_msg);
    }

  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 bound_minimal_symbol msym;

	  msym = lookup_minimal_symbol_by_pc (task_id);
	  if (msym.minsym)
	    {
	      const char *full_name = msym.minsym->linkage_name ();
	      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) - 1);
	      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));

  /* If the task is in an entry call waiting for another task,
     then determine which task it is.  */

  if (task_info->state == Entry_Caller_Sleep
      && 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));
    }

  /* If the ATCB contains some information about RV callers, then
     compute the "caller_task".  Otherwise, leave it as zero.  */

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

  task_info->base_cpu
    = (pspace_data->cpu_id_offset
       + value_as_long (value_field (common_value,
				     pspace_data->atcb_fieldno.base_cpu)));

  /* And finally, compute the task ptid.  Note that there is not point
     in computing it if the task is no longer alive, in which case
     it is good enough to set its ptid to the null_ptid.  */
  if (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);
  data->task_list.push_back (task_info);
}

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

static bool
read_known_tasks_array (struct ada_tasks_inferior_data *data)
{
  const int target_ptr_byte = data->known_tasks_element->length ();
  const int known_tasks_size = target_ptr_byte * data->known_tasks_length;
  gdb_byte *known_tasks = (gdb_byte *) 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 true;
}

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

static bool
read_known_tasks_list (struct ada_tasks_inferior_data *data)
{
  const int target_ptr_byte = data->known_tasks_element->length ();
  gdb_byte *known_tasks = (gdb_byte *) 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 false;

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

/* 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 bound_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.minsym != NULL)
    {
      data->known_tasks_kind = ADA_TASKS_ARRAY;
      data->known_tasks_addr = msym.value_address ();

      /* 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)
	      .symbol;
      if (sym != NULL)
	{
	  /* Validate.  */
	  struct type *type = check_typedef (sym->type ());
	  struct type *eltype = NULL;
	  struct type *idxtype = NULL;

	  if (type->code () == TYPE_CODE_ARRAY)
	    eltype = check_typedef (type->target_type ());
	  if (eltype != NULL && eltype->code () == TYPE_CODE_PTR)
	    idxtype = check_typedef (type->index_type ());
	  if (idxtype != NULL
	      && idxtype->bounds ()->low.kind () != PROP_UNDEFINED
	      && idxtype->bounds ()->high.kind () != PROP_UNDEFINED)
	    {
	      data->known_tasks_element = eltype;
	      data->known_tasks_length
		= (idxtype->bounds ()->high.const_val ()
		   - idxtype->bounds ()->low.const_val () + 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.minsym != NULL)
    {
      data->known_tasks_kind = ADA_TASKS_LIST;
      data->known_tasks_addr = msym.value_address ();
      data->known_tasks_length = 1;

      sym = lookup_symbol_in_language (KNOWN_TASKS_LIST, NULL, VAR_DOMAIN,
				       language_c, NULL)
	      .symbol;
      if (sym != NULL && sym->value_address () != 0)
	{
	  /* Validate.  */
	  struct type *type = check_typedef (sym->type ());

	  if (type->code () == 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.  */

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

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

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

  /* Step 3: Set task_list_valid_p, to avoid re-reading the Known_Tasks
     array unless needed.  */
  switch (data->known_tasks_kind)
    {
    case ADA_TASKS_NOT_FOUND: /* Tasking not in use in inferior.  */
      break;
    case ADA_TASKS_ARRAY:
      data->task_list_valid_p = read_known_tasks_array (data);
      break;
    case ADA_TASKS_LIST:
      data->task_list_valid_p = read_known_tasks_list (data);
      break;
    }
}

/* 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).  */

static int
ada_build_task_list ()
{
  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 data->task_list.size ();
}

/* 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, const char *arg_str,
		     struct inferior *inf)
{
  struct ada_tasks_inferior_data *data;
  int taskno, nb_tasks;
  int taskno_arg = 0;
  int nb_columns;

  if (ada_build_task_list () == 0)
    {
      uiout->message (_ ("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 (uiout->is_mi_like_p ())
    /* 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_update_thread_list ();

  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 <= data->task_list.size ())
	nb_tasks = 1;
      else
	nb_tasks = 0;
    }
  else
    nb_tasks = data->task_list.size ();

  nb_columns = uiout->is_mi_like_p () ? 8 : 7;
  ui_out_emit_table table_emitter (uiout, nb_columns, nb_tasks, "tasks");
  uiout->table_header (1, ui_left, "current", "");
  uiout->table_header (3, ui_right, "id", "ID");
  {
    size_t tid_width = 9;
    /* Grown below in case the largest entry is bigger.  */

    if (!uiout->is_mi_like_p ())
      {
	for (taskno = 1; taskno <= data->task_list.size (); taskno++)
	  {
	    const struct ada_task_info *const task_info
	      = &data->task_list[taskno - 1];

	    gdb_assert (task_info != NULL);

	    tid_width = std::max (
	      tid_width,
	      1 + strlen (phex_nz (task_info->task_id, sizeof (CORE_ADDR))));
	  }
      }
    uiout->table_header (tid_width, 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 (uiout->is_mi_like_p ())
    uiout->table_header (4, ui_right, "thread-id", "");
  uiout->table_header (4, ui_right, "parent-id", "P-ID");
  uiout->table_header (3, ui_right, "priority", "Pri");
  uiout->table_header (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.  */
  uiout->table_header (1, ui_noalign, "name", "Name");
  uiout->table_body ();

  for (taskno = 1; taskno <= data->task_list.size (); taskno++)
    {
      const struct ada_task_info *const task_info
	= &data->task_list[taskno - 1];
      int parent_id;

      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;

      ui_out_emit_tuple tuple_emitter (uiout, NULL);

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

      /* Print the task number.  */
      uiout->field_signed ("id", taskno);

      /* Print the Task ID.  */
      uiout->field_string ("task-id",
			   phex_nz (task_info->task_id, sizeof (CORE_ADDR)));

      /* Print the associated Thread ID.  */
      if (uiout->is_mi_like_p ())
	{
	  thread_info *thread = (ada_task_is_alive (task_info)
				   ? find_thread_ptid (inf, task_info->ptid)
				   : nullptr);

	  if (thread != NULL)
	    uiout->field_signed ("thread-id", thread->global_num);
	  else
	    {
	      /* This can happen if the thread is no longer alive.  */
	      uiout->field_skip ("thread-id");
	    }
	}

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

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

      /* Print the task current state.  */
      if (task_info->caller_task)
	uiout->field_fmt ("state", _ ("Accepting RV with %-4d"),
			  get_task_number_from_id (task_info->caller_task,
						   inf));
      else if (task_info->called_task)
	uiout->field_fmt ("state", _ ("Waiting on RV with %-3d"),
			  get_task_number_from_id (task_info->called_task,
						   inf));
      else
	uiout->field_string ("state", get_state (task_info->state));

      /* Finally, print the task name, without quotes around it, as mi like
	 is not expecting quotes, and in non mi-like no need for quotes
	 as there is a specific column for the name.  */
      uiout->field_fmt ("name",
			(task_info->name[0] != '\0' ? ui_file_style ()
						    : metadata_style.style ()),
			"%s",
			(task_info->name[0] != '\0' ? task_info->name
						    : _ ("<no name>")));

      uiout->text ("\n");
    }
}

/* 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, const 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)
    {
      uiout->message (_ ("Your application does not use any Ada tasks.\n"));
      return;
    }

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

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

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

  /* Print the TID and LWP.  */
  gdb_printf (_ ("Thread: 0x%s\n"),
	      phex_nz (task_info->ptid.tid (), sizeof (ULONGEST)));
  gdb_printf (_ ("LWP: %#lx\n"), task_info->ptid.lwp ());

  /* If set, print the base CPU.  */
  if (task_info->base_cpu != 0)
    gdb_printf (_ ("Base CPU: %d\n"), task_info->base_cpu);

  /* 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 = &data->task_list[parent_taskno - 1];

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

  /* Print the base priority.  */
  gdb_printf (_ ("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);
	gdb_printf (_ ("State: Accepting rendezvous with %d"), target_taskno);
      }
    else if (task_info->called_task)
      {
	target_taskno = get_task_number_from_id (task_info->called_task, inf);
	gdb_printf (_ ("State: Waiting on task %d's entry"), target_taskno);
      }
    else
      gdb_printf (_ ("State: %s"), get_long_state (task_info->state));

    if (target_taskno)
      {
	ada_task_info *target_task_info = &data->task_list[target_taskno - 1];

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

    gdb_printf ("\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 (const 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_thread ());

  if (current_task == 0)
    gdb_printf (_ ("[Current task is unknown]\n"));
  else
    {
      struct ada_tasks_inferior_data *data
	= get_ada_tasks_inferior_data (current_inferior ());
      struct ada_task_info *task_info = &data->task_list[current_task - 1];

      gdb_printf (_ ("[Current task is %s]\n"),
		  task_to_str (current_task, task_info).c_str ());
    }
}

/* 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 (const 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 > data->task_list.size ())
    error (_ ("Task ID %d not known.  Use the \"info tasks\" command to\n"
	      "see the IDs of currently known tasks"),
	   taskno);
  task_info = &data->task_list[taskno - 1];

  if (!ada_task_is_alive (task_info))
    error (_ ("Cannot switch to task %s: Task is no longer running"),
	   task_to_str (taskno, task_info).c_str ());

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

  /* 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.  */
  thread_info *tp = find_thread_ptid (inf, task_info->ptid);
  if (tp == NULL)
    error (_ ("Unable to compute thread ID for task %s.\n"
	      "Cannot switch to this task."),
	   task_to_str (taskno, task_info).c_str ());

  switch_to_thread (tp);
  ada_find_printable_frame (get_selected_frame (NULL));
  gdb_printf (_ ("[Switching to task %s]\n"),
	      task_to_str (taskno, task_info).c_str ());
  print_stack_frame (get_selected_frame (NULL),
		     frame_relative_level (get_selected_frame (NULL)),
		     SRC_AND_LOC, 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 (const char *taskno_str, int from_tty)
{
  struct ui_out *uiout = current_uiout;

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

  if (taskno_str == NULL || taskno_str[0] == '\0')
    display_current_task_id ();
  else
    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 = false;
}

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

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

static void
ada_tasks_normal_stop_observer (struct bpstat *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_tasks_new_objfile_observer (struct objfile *objfile)
{
  /* 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.  */
      for (struct program_space *pspace : program_spaces)
	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 (inferior *inf : all_inferiors ())
    if (objfile == NULL || inf->pspace == objfile->pspace)
      ada_tasks_invalidate_inferior_data (inf);
}

/* The qcs command line flags for the "task apply" commands.  Keep
   this in sync with the "frame apply" commands.  */

using qcs_flag_option_def = gdb::option::flag_option_def<qcs_flags>;

static const gdb::option::option_def task_qcs_flags_option_defs[] = {
  qcs_flag_option_def {
    "q",
    [] (qcs_flags *opt) { return &opt->quiet; },
    N_ ("Disables printing the task information."),
  },

  qcs_flag_option_def {
    "c",
    [] (qcs_flags *opt) { return &opt->cont; },
    N_ ("Print any error raised by COMMAND and continue."),
  },

  qcs_flag_option_def {
    "s",
    [] (qcs_flags *opt) { return &opt->silent; },
    N_ ("Silently ignore any errors or empty output produced by COMMAND."),
  },
};

/* Create an option_def_group for the "task apply all" options, with
   FLAGS as context.  */

static inline std::array<gdb::option::option_def_group, 1>
make_task_apply_all_options_def_group (qcs_flags *flags)
{
  return { {
    { { task_qcs_flags_option_defs }, flags },
  } };
}

/* Create an option_def_group for the "task apply" options, with
   FLAGS as context.  */

static inline gdb::option::option_def_group
make_task_apply_options_def_group (qcs_flags *flags)
{
  return { { task_qcs_flags_option_defs }, flags };
}

/* Implementation of 'task apply all'.  */

static void
task_apply_all_command (const char *cmd, int from_tty)
{
  qcs_flags flags;

  auto group = make_task_apply_all_options_def_group (&flags);
  gdb::option::process_options (
    &cmd, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group);

  validate_flags_qcs ("task apply all", &flags);

  if (cmd == nullptr || *cmd == '\0')
    error (_ ("Please specify a command at the end of 'task apply all'"));

  update_thread_list ();
  ada_build_task_list ();

  inferior *inf = current_inferior ();
  struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf);

  /* Save a copy of the thread list and increment each thread's
     refcount while executing the command in the context of each
     thread, in case the command affects this.  */
  std::vector<std::pair<int, thread_info_ref>> thr_list_cpy;

  for (int i = 1; i <= data->task_list.size (); ++i)
    {
      ada_task_info &task = data->task_list[i - 1];
      if (!ada_task_is_alive (&task))
	continue;

      thread_info *tp = find_thread_ptid (inf, task.ptid);
      if (tp == nullptr)
	warning (_ ("Unable to compute thread ID for task %s.\n"
		    "Cannot switch to this task."),
		 task_to_str (i, &task).c_str ());
      else
	thr_list_cpy.emplace_back (i, thread_info_ref::new_reference (tp));
    }

  scoped_restore_current_thread restore_thread;

  for (const auto &info : thr_list_cpy)
    if (switch_to_thread_if_alive (info.second.get ()))
      thread_try_catch_cmd (info.second.get (), info.first, cmd, from_tty,
			    flags);
}

/* Implementation of 'task apply'.  */

static void
task_apply_command (const char *tidlist, int from_tty)
{
  if (tidlist == nullptr || *tidlist == '\0')
    error (_ ("Please specify a task ID list"));

  update_thread_list ();
  ada_build_task_list ();

  inferior *inf = current_inferior ();
  struct ada_tasks_inferior_data *data = get_ada_tasks_inferior_data (inf);

  /* Save a copy of the thread list and increment each thread's
     refcount while executing the command in the context of each
     thread, in case the command affects this.  */
  std::vector<std::pair<int, thread_info_ref>> thr_list_cpy;

  number_or_range_parser parser (tidlist);
  while (!parser.finished ())
    {
      int num = parser.get_number ();

      if (num < 1 || num - 1 >= data->task_list.size ())
	warning (_ ("no Ada Task with number %d"), num);
      else
	{
	  ada_task_info &task = data->task_list[num - 1];
	  if (!ada_task_is_alive (&task))
	    continue;

	  thread_info *tp = find_thread_ptid (inf, task.ptid);
	  if (tp == nullptr)
	    warning (_ ("Unable to compute thread ID for task %s.\n"
			"Cannot switch to this task."),
		     task_to_str (num, &task).c_str ());
	  else
	    thr_list_cpy.emplace_back (num,
				       thread_info_ref::new_reference (tp));
	}
    }

  qcs_flags flags;
  const char *cmd = parser.cur_tok ();

  auto group = make_task_apply_options_def_group (&flags);
  gdb::option::process_options (
    &cmd, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group);

  validate_flags_qcs ("task apply", &flags);

  if (*cmd == '\0')
    error (_ ("Please specify a command following the task ID list"));

  scoped_restore_current_thread restore_thread;

  for (const auto &info : thr_list_cpy)
    if (switch_to_thread_if_alive (info.second.get ()))
      thread_try_catch_cmd (info.second.get (), info.first, cmd, from_tty,
			    flags);
}

void _initialize_tasks ();

void
_initialize_tasks ()
{
  /* Attach various observers.  */
  gdb::observers::normal_stop.attach (ada_tasks_normal_stop_observer,
				      "ada-tasks");
  gdb::observers::new_objfile.attach (ada_tasks_new_objfile_observer,
				      "ada-tasks");

  static struct cmd_list_element *task_cmd_list;
  static struct cmd_list_element *task_apply_list;

  /* Some new commands provided by this module.  */
  add_info ("tasks", info_tasks_command,
	    _ ("Provide information about all known Ada tasks."));

  add_prefix_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."),
		  &task_cmd_list, 1, &cmdlist);

#define TASK_APPLY_OPTION_HELP \
  "\
Prints per-inferior task number followed by COMMAND output.\n\
\n\
By default, an error raised during the execution of COMMAND\n\
aborts \"task apply\".\n\
\n\
Options:\n\
%OPTIONS%"

  static const auto task_apply_opts
    = make_task_apply_options_def_group (nullptr);

  static std::string task_apply_help
    = gdb::option::build_help (_ ("\
Apply a command to a list of tasks.\n\
Usage: task apply ID... [OPTION]... COMMAND\n\
ID is a space-separated list of IDs of tasks to apply COMMAND on.\n" TASK_APPLY_OPTION_HELP),
			       task_apply_opts);

  add_prefix_cmd ("apply", class_run, task_apply_command,
		  task_apply_help.c_str (), &task_apply_list, 1,
		  &task_cmd_list);

  static const auto task_apply_all_opts
    = make_task_apply_all_options_def_group (nullptr);

  static std::string task_apply_all_help
    = gdb::option::build_help (_ ("\
Apply a command to all tasks in the current inferior.\n\
\n\
Usage: task apply all [OPTION]... COMMAND\n" TASK_APPLY_OPTION_HELP),
			       task_apply_all_opts);

  add_cmd ("all", class_run, task_apply_all_command,
	   task_apply_all_help.c_str (), &task_apply_list);
}
