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

   Copyright (C) 2009-2024 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 "cli/cli-cmds.h"
#include "objfiles.h"
#include "gdbcore.h"
#include "solib.h"
#include "solist.h"
#include "gdbthread.h"
#include "inferior.h"
#include <algorithm>
#include "cli/cli-style.h"
#include "observable.h"

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

/* The head of the program spaces list.  */
std::vector<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;



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

address_space::address_space ()
  : m_num (++highest_address_space_num)
{
}

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

address_space_ref_ptr
maybe_new_address_space ()
{
  int shared_aspace
    = gdbarch_has_shared_address_space (current_inferior ()->arch ());

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

  return new_address_space ();
}

/* Start counting over from scratch.  */

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



/* Remove a program space from the program spaces list.  */

static void
remove_program_space (program_space *pspace)
{
  gdb_assert (pspace != NULL);

  auto iter = std::find (program_spaces.begin (), program_spaces.end (),
			 pspace);
  gdb_assert (iter != program_spaces.end ());
  program_spaces.erase (iter);
}

/* See progspace.h.  */

program_space::program_space (address_space_ref_ptr aspace_)
  : num (++last_program_space_num),
    aspace (std::move (aspace_))
{
  program_spaces.push_back (this);
  gdb::observers::new_program_space.notify (this);
}

/* See progspace.h.  */

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

  gdb::observers::free_program_space.notify (this);
  remove_program_space (this);

  scoped_restore_current_program_space restore_pspace;

  set_current_program_space (this);

  breakpoint_program_space_exit (this);
  no_shared_libraries (this);
  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);
}

/* See progspace.h.  */

void
program_space::free_all_objfiles ()
{
  /* Any objfile reference would become stale.  */
  for (const solib &so : this->solibs ())
    gdb_assert (so.objfile == NULL);

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

/* See progspace.h.  */

void
program_space::add_objfile (std::unique_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::unique_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)
{
  /* Removing an objfile from the objfile list invalidates any frame
     that was built using frame info found in the objfile.  Reinit the
     frame cache to get rid of any frame that might otherwise
     reference stale info.  */
  reinit_frame_cache ();

  auto iter = std::find_if (objfiles_list.begin (), objfiles_list.end (),
			    [=] (const std::unique_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;
}

/* See progspace.h.  */

struct objfile *
program_space::objfile_for_address (CORE_ADDR address)
{
  for (auto iter : objfiles ())
    {
      /* Don't check separate debug objfiles.  */
      if (iter->separate_debug_objfile_backlink != nullptr)
	continue;
      if (is_addr_in_objfile (address, iter))
	return iter;
    }
  return nullptr;
}

/* See progspace.h.  */

void
program_space::exec_close ()
{
  if (ebfd != nullptr)
    {
      /* Removing target sections may close the exec_ops target.
	 Clear ebfd before doing so to prevent recursion.  */
      bfd *saved_ebfd = ebfd.get ();
      ebfd.reset (nullptr);
      ebfd_mtime = 0;

      remove_target_sections (saved_ebfd);

      m_exec_filename.reset ();
    }
}

/* 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->exec_filename () != nullptr)
    exec_file_attach (src->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.  */

bool
program_space::empty ()
{
  return find_inferior_for_program_space (this) == nullptr;
}

/* 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)
{
  int count = 0;

  /* Start with a minimum width of 17 for the executable name column.  */
  size_t longest_exec_name = 17;

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

      if (pspace->exec_filename () != nullptr)
	longest_exec_name = std::max (strlen (pspace->exec_filename ()),
				      longest_exec_name);

      ++count;
    }

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

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

  for (struct program_space *pspace : program_spaces)
    {
      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->exec_filename () != nullptr)
	uiout->field_string ("exec", pspace->exec_filename (),
			     file_name_style.style ());
      else
	uiout->field_skip ("exec");

      if (pspace->cbfd != nullptr)
	uiout->field_string ("core", bfd_get_filename (pspace->cbfd.get ()),
			     file_name_style.style ());
      else
	uiout->field_skip ("core");

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

      /* We're going to switch inferiors.  */
      scoped_restore_current_thread restore_thread;

      for (inferior *inf : all_inferiors ())
	if (inf->pspace == pspace)
	  {
	    /* Switch to inferior in order to call target methods.  */
	    switch_to_inferior_no_thread (inf);

	    if (!printed_header)
	      {
		printed_header = 1;
		gdb_printf ("\n\tBound inferiors: ID %d (%s)",
			    inf->num,
			    target_pid_to_str (ptid_t (inf->pid)).c_str ());
	      }
	    else
	      gdb_printf (", 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)
{
  for (struct program_space *pspace : program_spaces)
    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);
}

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

  init_address_spaces ();

  if (shared_aspace)
    {
      address_space_ref_ptr aspace = new_address_space ();

      for (struct program_space *pspace : program_spaces)
	pspace->aspace = aspace;
    }
  else
    for (struct program_space *pspace : program_spaces)
      pspace->aspace = new_address_space ();

  for (inferior *inf : all_inferiors ())
    if (gdbarch_has_global_solist (current_inferior ()->arch ()))
      inf->aspace = maybe_new_address_space ();
    else
      inf->aspace = inf->pspace->aspace;
}



/* See progspace.h.  */

void
program_space::clear_solib_cache ()
{
  added_solibs.clear ();
  deleted_solibs.clear ();
}

/* See progspace.h.  */

void
initialize_progspace ()
{
  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 the ebfd
     of current_program_space.  */
  current_program_space = new program_space (new_address_space ());
}
