/* Program and address space management, for GDB, the GNU debugger.

   Copyright (C) 2009-2020 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 "gdbcmd.h"
#include "objfiles.h"
#include "arch-utils.h"
#include "gdbcore.h"
#include "solib.h"
#include "solist.h"
#include "gdbthread.h"
#include "inferior.h"
#include <algorithm>

/* The last program space number assigned.  */
int last_program_space_num = 0;

/* The head of the program spaces list.  */
struct program_space *program_spaces;

/* Pointer to the current program space.  */
struct program_space *current_program_space;

/* The last address space number assigned.  */
static int highest_address_space_num;



/* Keep a registry of per-program_space data-pointers required by other GDB
   modules.  */

DEFINE_REGISTRY (program_space, REGISTRY_ACCESS_FIELD)

/* Keep a registry of per-address_space data-pointers required by other GDB
   modules.  */

DEFINE_REGISTRY (address_space, REGISTRY_ACCESS_FIELD)



/* Create a new address space object, and add it to the list.  */

struct address_space *
new_address_space (void)
{
  struct address_space *aspace;

  aspace = XCNEW (struct address_space);
  aspace->num = ++highest_address_space_num;
  address_space_alloc_data (aspace);

  return aspace;
}

/* Maybe create a new address space object, and add it to the list, or
   return a pointer to an existing address space, in case inferiors
   share an address space on this target system.  */

struct address_space *
maybe_new_address_space (void)
{
  int shared_aspace = gdbarch_has_shared_address_space (target_gdbarch ());

  if (shared_aspace)
    {
      /* Just return the first in the list.  */
      return program_spaces->aspace;
    }

  return new_address_space ();
}

static void
free_address_space (struct address_space *aspace)
{
  address_space_free_data (aspace);
  xfree (aspace);
}

int
address_space_num (struct address_space *aspace)
{
  return aspace->num;
}

/* Start counting over from scratch.  */

static void
init_address_spaces (void)
{
  highest_address_space_num = 0;
}



/* Adds a new empty program space to the program space list, and binds
   it to ASPACE.  Returns the pointer to the new object.  */

program_space::program_space (address_space *aspace_)
: num (++last_program_space_num), aspace (aspace_)
{
  program_space_alloc_data (this);

  if (program_spaces == NULL)
    program_spaces = this;
  else
    {
      struct program_space *last;

      for (last = program_spaces; last->next != NULL; last = last->next)
	;
      last->next = this;
    }
}

/* Releases program space PSPACE, and all its contents (shared
   libraries, objfiles, and any other references to the PSPACE in
   other modules).  It is an internal error to call this when PSPACE
   is the current program space, since there should always be a
   program space.  */

program_space::~program_space ()
{
  gdb_assert (this != current_program_space);

  scoped_restore_current_program_space restore_pspace;

  set_current_program_space (this);

  breakpoint_program_space_exit (this);
  no_shared_libraries (NULL, 0);
  exec_close ();
  free_all_objfiles ();
  /* Defer breakpoint re-set because we don't want to create new
     locations for this pspace which we're tearing down.  */
  clear_symtab_users (SYMFILE_DEFER_BP_RESET);
  if (!gdbarch_has_shared_address_space (target_gdbarch ()))
    free_address_space (this->aspace);
  clear_section_table (&this->target_sections);
  clear_program_space_solib_cache (this);
    /* Discard any data modules have associated with the PSPACE.  */
  program_space_free_data (this);
}

/* See progspace.h.  */

void
program_space::free_all_objfiles ()
{
  struct so_list *so;

  /* Any objfile reference would become stale.  */
  for (so = master_so_list (); so; so = so->next)
    gdb_assert (so->objfile == NULL);

  while (!objfiles_list.empty ())
    objfiles_list.front ()->unlink ();
}

/* See progspace.h.  */

void
program_space::add_objfile (std::shared_ptr<objfile> &&objfile,
			    struct objfile *before)
{
  if (before == nullptr)
    objfiles_list.push_back (std::move (objfile));
  else
    {
      auto iter = std::find_if (objfiles_list.begin (), objfiles_list.end (),
				[=] (const std::shared_ptr<::objfile> &objf)
				{
				  return objf.get () == before;
				});
      gdb_assert (iter != objfiles_list.end ());
      objfiles_list.insert (iter, std::move (objfile));
    }
}

/* See progspace.h.  */

void
program_space::remove_objfile (struct objfile *objfile)
{
  auto iter = std::find_if (objfiles_list.begin (), objfiles_list.end (),
			    [=] (const std::shared_ptr<::objfile> &objf)
			    {
			      return objf.get () == objfile;
			    });
  gdb_assert (iter != objfiles_list.end ());
  objfiles_list.erase (iter);

  if (objfile == symfile_object_file)
    symfile_object_file = NULL;
}

/* Copies program space SRC to DEST.  Copies the main executable file,
   and the main symbol file.  Returns DEST.  */

struct program_space *
clone_program_space (struct program_space *dest, struct program_space *src)
{
  scoped_restore_current_program_space restore_pspace;

  set_current_program_space (dest);

  if (src->pspace_exec_filename != NULL)
    exec_file_attach (src->pspace_exec_filename, 0);

  if (src->symfile_object_file != NULL)
    symbol_file_add_main (objfile_name (src->symfile_object_file),
			  SYMFILE_DEFER_BP_RESET);

  return dest;
}

/* Sets PSPACE as the current program space.  It is the caller's
   responsibility to make sure that the currently selected
   inferior/thread matches the selected program space.  */

void
set_current_program_space (struct program_space *pspace)
{
  if (current_program_space == pspace)
    return;

  gdb_assert (pspace != NULL);

  current_program_space = pspace;

  /* Different symbols change our view of the frame chain.  */
  reinit_frame_cache ();
}

/* Returns true iff there's no inferior bound to PSPACE.  */

int
program_space_empty_p (struct program_space *pspace)
{
  if (find_inferior_for_program_space (pspace) != NULL)
      return 0;

  return 1;
}

/* Remove a program space from the program spaces list and release it.  It is
   an error to call this function while PSPACE is the current program space. */

void
delete_program_space (struct program_space *pspace)
{
  struct program_space *ss, **ss_link;
  gdb_assert (pspace != NULL);
  gdb_assert (pspace != current_program_space);

  ss = program_spaces;
  ss_link = &program_spaces;
  while (ss != NULL)
    {
      if (ss == pspace)
	{
	  *ss_link = ss->next;
	  break;
	}

      ss_link = &ss->next;
      ss = *ss_link;
    }

  delete pspace;
}

/* Prints the list of program spaces and their details on UIOUT.  If
   REQUESTED is not -1, it's the ID of the pspace that should be
   printed.  Otherwise, all spaces are printed.  */

static void
print_program_space (struct ui_out *uiout, int requested)
{
  struct program_space *pspace;
  int count = 0;

  /* Compute number of pspaces we will print.  */
  ALL_PSPACES (pspace)
    {
      if (requested != -1 && pspace->num != requested)
	continue;

      ++count;
    }

  /* There should always be at least one.  */
  gdb_assert (count > 0);

  ui_out_emit_table table_emitter (uiout, 3, count, "pspaces");
  uiout->table_header (1, ui_left, "current", "");
  uiout->table_header (4, ui_left, "id", "Id");
  uiout->table_header (17, ui_left, "exec", "Executable");
  uiout->table_body ();

  ALL_PSPACES (pspace)
    {
      struct inferior *inf;
      int printed_header;

      if (requested != -1 && requested != pspace->num)
	continue;

      ui_out_emit_tuple tuple_emitter (uiout, NULL);

      if (pspace == current_program_space)
	uiout->field_string ("current", "*");
      else
	uiout->field_skip ("current");

      uiout->field_signed ("id", pspace->num);

      if (pspace->pspace_exec_filename)
	uiout->field_string ("exec", pspace->pspace_exec_filename);
      else
	uiout->field_skip ("exec");

      /* Print extra info that doesn't really fit in tabular form.
	 Currently, we print the list of inferiors bound to a pspace.
	 There can be more than one inferior bound to the same pspace,
	 e.g., both parent/child inferiors in a vfork, or, on targets
	 that share pspaces between inferiors.  */
      printed_header = 0;
      for (inf = inferior_list; inf; inf = inf->next)
	if (inf->pspace == pspace)
	  {
	    if (!printed_header)
	      {
		printed_header = 1;
		printf_filtered ("\n\tBound inferiors: ID %d (%s)",
				 inf->num,
				 target_pid_to_str (ptid_t (inf->pid)).c_str ());
	      }
	    else
	      printf_filtered (", ID %d (%s)",
			       inf->num,
			       target_pid_to_str (ptid_t (inf->pid)).c_str ());
	  }

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

/* Boolean test for an already-known program space id.  */

static int
valid_program_space_id (int num)
{
  struct program_space *pspace;

  ALL_PSPACES (pspace)
    if (pspace->num == num)
      return 1;

  return 0;
}

/* If ARGS is NULL or empty, print information about all program
   spaces.  Otherwise, ARGS is a text representation of a LONG
   indicating which the program space to print information about.  */

static void
maintenance_info_program_spaces_command (const char *args, int from_tty)
{
  int requested = -1;

  if (args && *args)
    {
      requested = parse_and_eval_long (args);
      if (!valid_program_space_id (requested))
	error (_("program space ID %d not known."), requested);
    }

  print_program_space (current_uiout, requested);
}

/* Simply returns the count of program spaces.  */

int
number_of_program_spaces (void)
{
  struct program_space *pspace;
  int count = 0;

  ALL_PSPACES (pspace)
    count++;

  return count;
}

/* Update all program spaces matching to address spaces.  The user may
   have created several program spaces, and loaded executables into
   them before connecting to the target interface that will create the
   inferiors.  All that happens before GDB has a chance to know if the
   inferiors will share an address space or not.  Call this after
   having connected to the target interface and having fetched the
   target description, to fixup the program/address spaces mappings.

   It is assumed that there are no bound inferiors yet, otherwise,
   they'd be left with stale referenced to released aspaces.  */

void
update_address_spaces (void)
{
  int shared_aspace = gdbarch_has_shared_address_space (target_gdbarch ());
  struct program_space *pspace;
  struct inferior *inf;

  init_address_spaces ();

  if (shared_aspace)
    {
      struct address_space *aspace = new_address_space ();

      free_address_space (current_program_space->aspace);
      ALL_PSPACES (pspace)
	pspace->aspace = aspace;
    }
  else
    ALL_PSPACES (pspace)
      {
	free_address_space (pspace->aspace);
	pspace->aspace = new_address_space ();
      }

  for (inf = inferior_list; inf; inf = inf->next)
    if (gdbarch_has_global_solist (target_gdbarch ()))
      inf->aspace = maybe_new_address_space ();
    else
      inf->aspace = inf->pspace->aspace;
}



/* See progspace.h.  */

void
clear_program_space_solib_cache (struct program_space *pspace)
{
  pspace->added_solibs.clear ();
  pspace->deleted_solibs.clear ();
}



void
initialize_progspace (void)
{
  add_cmd ("program-spaces", class_maintenance,
	   maintenance_info_program_spaces_command,
	   _("Info about currently known program spaces."),
	   &maintenanceinfolist);

  /* There's always one program space.  Note that this function isn't
     an automatic _initialize_foo function, since other
     _initialize_foo routines may need to install their per-pspace
     data keys.  We can only allocate a progspace when all those
     modules have done that.  Do this before
     initialize_current_architecture, because that accesses exec_bfd,
     which in turn dereferences current_program_space.  */
  current_program_space = new program_space (new_address_space ());
}
