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

   Copyright (C) 2009-2025 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 "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.  */

bool
program_space::multi_objfile_p () const
{
  return (!m_objfiles_list.empty ()
	  && std::next (m_objfiles_list.begin ()) != m_objfiles_list.end ());
}

/* 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 (!m_objfiles_list.empty ())
    this->remove_objfile (&m_objfiles_list.front ());
}

/* See progspace.h.  */

void
program_space::add_objfile (std::unique_ptr<objfile> &&objfile,
			    struct objfile *before)
{
  if (before == nullptr)
    m_objfiles_list.push_back (std::move (objfile));
  else
    {
      gdb_assert (before->is_linked ());
      m_objfiles_list.insert (m_objfiles_list.iterator_to (*before),
			      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 ();

  if (objfile == symfile_object_file)
    symfile_object_file = NULL;

  gdb_assert (objfile->is_linked ());
  m_objfiles_list.erase (m_objfiles_list.iterator_to (*objfile));
}

/* 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.  We
	 move it to another ref_ptr instead of saving it to a raw
	 pointer to avoid it looking like possible use-after-free.  */
      gdb_bfd_ref_ptr saved_ebfd = std::move (ebfd);
      ebfd.reset (nullptr);
      ebfd_mtime = 0;

      remove_target_sections (saved_ebfd.get ());

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