/* Program and address space management, for GDB, the GNU debugger.
- Copyright (C) 2009-2013 Free Software Foundation, Inc.
+ Copyright (C) 2009-2017 Free Software Foundation, Inc.
This file is part of GDB.
DEFINE_REGISTRY (program_space, REGISTRY_ACCESS_FIELD)
-\f
-
-/* An address space. Currently this is not used for much other than
- for comparing if pspaces/inferior/threads see the same address
+/* An address space. It is used for comparing if pspaces/inferior/threads
+ see the same address space and for associating caches to each address
space. */
struct address_space
{
int num;
+
+ /* Per aspace data-pointers required by other GDB modules. */
+ REGISTRY_FIELDS;
};
+/* Keep a registry of per-address_space data-pointers required by other GDB
+ modules. */
+
+DEFINE_REGISTRY (address_space, REGISTRY_ACCESS_FIELD)
+
+\f
+
/* Create a new address space object, and add it to the list. */
struct address_space *
{
struct address_space *aspace;
- aspace = XZALLOC (struct address_space);
+ aspace = XCNEW (struct address_space);
aspace->num = ++highest_address_space_num;
+ address_space_alloc_data (aspace);
return aspace;
}
static void
free_address_space (struct address_space *aspace)
{
+ address_space_free_data (aspace);
xfree (aspace);
}
{
struct program_space *pspace;
- pspace = XZALLOC (struct program_space);
+ pspace = XCNEW (struct program_space);
pspace->num = ++last_program_space_num;
pspace->aspace = aspace;
program_space_alloc_data (pspace);
- pspace->next = program_spaces;
- program_spaces = pspace;
+ if (program_spaces == NULL)
+ program_spaces = pspace;
+ else
+ {
+ struct program_space *last;
+
+ for (last = program_spaces; last->next != NULL; last = last->next)
+ ;
+ last->next = pspace;
+ }
return pspace;
}
free_all_objfiles ();
if (!gdbarch_has_shared_address_space (target_gdbarch ()))
free_address_space (pspace->aspace);
- resize_section_table (&pspace->target_sections,
- -resize_section_table (&pspace->target_sections, 0));
+ clear_section_table (&pspace->target_sections);
clear_program_space_solib_cache (pspace);
/* Discard any data modules have associated with the PSPACE. */
program_space_free_data (pspace);
do_cleanups (old_chain);
}
-/* Unlinks PSPACE from the pspace list, and releases it. */
-
-void
-remove_program_space (struct program_space *pspace)
-{
- struct program_space *ss, **ss_link;
-
- ss = program_spaces;
- ss_link = &program_spaces;
- while (ss)
- {
- if (ss != pspace)
- {
- ss_link = &ss->next;
- ss = *ss_link;
- continue;
- }
-
- *ss_link = ss->next;
- release_program_space (ss);
- ss = *ss_link;
- }
-}
-
/* Copies program space SRC to DEST. Copies the main executable file,
and the main symbol file. Returns DEST. */
static void
restore_program_space (void *arg)
{
- struct program_space *saved_pspace = arg;
+ struct program_space *saved_pspace = (struct program_space *) arg;
set_current_program_space (saved_pspace);
}
/* Returns true iff there's no inferior bound to PSPACE. */
-static int
-pspace_empty_p (struct program_space *pspace)
+int
+program_space_empty_p (struct program_space *pspace)
{
if (find_inferior_for_program_space (pspace) != NULL)
return 0;
return 1;
}
-/* Prune away automatically added program spaces that aren't required
- anymore. */
+/* 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
-prune_program_spaces (void)
+delete_program_space (struct program_space *pspace)
{
struct program_space *ss, **ss_link;
- struct program_space *current = current_program_space;
+ gdb_assert (pspace != NULL);
+ gdb_assert (pspace != current_program_space);
ss = program_spaces;
ss_link = &program_spaces;
- while (ss)
+ while (ss != NULL)
{
- if (ss == current || !pspace_empty_p (ss))
+ if (ss == pspace)
{
- ss_link = &ss->next;
- ss = *ss_link;
- continue;
+ *ss_link = ss->next;
+ break;
}
- *ss_link = ss->next;
- release_program_space (ss);
+ ss_link = &ss->next;
ss = *ss_link;
}
+
+ release_program_space (pspace);
}
/* Prints the list of program spaces and their details on UIOUT. If
int count = 0;
struct cleanup *old_chain;
- /* Might as well prune away unneeded ones, so the user doesn't even
- seem them. */
- prune_program_spaces ();
-
/* Compute number of pspaces we will print. */
ALL_PSPACES (pspace)
{
gdb_assert (count > 0);
old_chain = make_cleanup_ui_out_table_begin_end (uiout, 3, count, "pspaces");
- ui_out_table_header (uiout, 1, ui_left, "current", "");
- ui_out_table_header (uiout, 4, ui_left, "id", "Id");
- ui_out_table_header (uiout, 17, ui_left, "exec", "Executable");
- ui_out_table_body (uiout);
+ 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)
{
chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
if (pspace == current_program_space)
- ui_out_field_string (uiout, "current", "*");
+ uiout->field_string ("current", "*");
else
- ui_out_field_skip (uiout, "current");
+ uiout->field_skip ("current");
- ui_out_field_int (uiout, "id", pspace->num);
+ uiout->field_int ("id", pspace->num);
if (pspace->pspace_exec_filename)
- ui_out_field_string (uiout, "exec", pspace->pspace_exec_filename);
+ uiout->field_string ("exec", pspace->pspace_exec_filename);
else
- ui_out_field_skip (uiout, "exec");
+ 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.
target_pid_to_str (pid_to_ptid (inf->pid)));
}
- ui_out_text (uiout, "\n");
+ uiout->text ("\n");
do_cleanups (chain2);
}
return old_chain;
}
-/* Switches full context to program space PSPACE. Switches to the
- first thread found bound to PSPACE. */
+/* See progspace.h */
void
switch_to_program_space_and_thread (struct program_space *pspace)
struct inferior *inf;
inf = find_inferior_for_program_space (pspace);
- if (inf != NULL)
+ if (inf != NULL && inf->pid != 0)
{
struct thread_info *tp;