X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fprogspace.c;h=a0b14a6d2eb7cfec0af972e0343a57c11d3f3201;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=98ce5a57bdd7618a664525276a1c052c88571b14;hpb=7b6bb8daaceb9ecf3f42dea57ae82733d6a3b2f6;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/progspace.c b/gdb/progspace.c index 98ce5a57bd..a0b14a6d2e 100644 --- a/gdb/progspace.c +++ b/gdb/progspace.c @@ -1,6 +1,6 @@ /* Program and address space management, for GDB, the GNU debugger. - Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. + Copyright (C) 2009-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -23,13 +23,16 @@ #include "arch-utils.h" #include "gdbcore.h" #include "solib.h" +#include "solist.h" #include "gdbthread.h" +#include "inferior.h" +#include /* The last program space number assigned. */ int last_program_space_num = 0; /* The head of the program spaces list. */ -struct program_space *program_spaces; +std::vector program_spaces; /* Pointer to the current program space. */ struct program_space *current_program_space; @@ -37,20 +40,19 @@ struct program_space *current_program_space; /* The last address space number assigned. */ static int highest_address_space_num; -/* Prototypes for local functions */ - -static void program_space_alloc_data (struct program_space *); -static void program_space_free_data (struct program_space *); -/* An address space. Currently this is not used for much other than - for comparing if pspaces/inferior/threads see the same address - space. */ +/* Keep a registry of per-program_space data-pointers required by other GDB + modules. */ -struct address_space -{ - int num; -}; +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. */ @@ -59,8 +61,9 @@ new_address_space (void) { 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; } @@ -72,12 +75,12 @@ new_address_space (void) struct address_space * maybe_new_address_space (void) { - int shared_aspace = gdbarch_has_shared_address_space (target_gdbarch); + 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 program_spaces[0]->aspace; } return new_address_space (); @@ -86,6 +89,7 @@ maybe_new_address_space (void) static void free_address_space (struct address_space *aspace) { + address_space_free_data (aspace); xfree (aspace); } @@ -105,100 +109,132 @@ init_address_spaces (void) -/* Adds a new empty program space to the program space list, and binds - it to ASPACE. Returns the pointer to the new object. */ +/* Remove a program space from the program spaces list. */ -struct program_space * -add_program_space (struct address_space *aspace) +static void +remove_program_space (program_space *pspace) { - struct program_space *pspace; - - pspace = XZALLOC (struct program_space); + gdb_assert (pspace != NULL); - pspace->num = ++last_program_space_num; - pspace->aspace = aspace; + auto iter = std::find (program_spaces.begin (), program_spaces.end (), + pspace); + gdb_assert (iter != program_spaces.end ()); + program_spaces.erase (iter); +} - program_space_alloc_data (pspace); +/* See progspace.h. */ - pspace->next = program_spaces; - program_spaces = pspace; +program_space::program_space (address_space *aspace_) + : num (++last_program_space_num), + aspace (aspace_) +{ + program_space_alloc_data (this); - return pspace; + program_spaces.push_back (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. */ +/* See progspace.h. */ -static void -release_program_space (struct program_space *pspace) +program_space::~program_space () { - struct cleanup *old_chain = save_current_program_space (); + gdb_assert (this != current_program_space); + + remove_program_space (this); - gdb_assert (pspace != current_program_space); + scoped_restore_current_program_space restore_pspace; - set_current_program_space (pspace); + set_current_program_space (this); - breakpoint_program_space_exit (pspace); + breakpoint_program_space_exit (this); no_shared_libraries (NULL, 0); exec_close (); 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)); + /* 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 (pspace); - xfree (pspace); - - do_cleanups (old_chain); + program_space_free_data (this); } -/* Unlinks PSPACE from the pspace list, and releases it. */ +/* See progspace.h. */ void -remove_program_space (struct program_space *pspace) +program_space::free_all_objfiles () { - struct program_space *ss, **ss_link; + /* Any objfile reference would become stale. */ + for (struct so_list *so : current_program_space->solibs ()) + gdb_assert (so->objfile == NULL); + + while (!objfiles_list.empty ()) + objfiles_list.front ()->unlink (); +} + +/* See progspace.h. */ - ss = program_spaces; - ss_link = &program_spaces; - while (ss) +void +program_space::add_objfile (std::shared_ptr &&objfile, + struct objfile *before) +{ + if (before == nullptr) + objfiles_list.push_back (std::move (objfile)); + else { - if (ss != pspace) - { - ss_link = &ss->next; - ss = *ss_link; - continue; - } - - *ss_link = ss->next; - release_program_space (ss); - ss = *ss_link; + 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; +} + +/* See progspace.h. */ + +next_adapter +program_space::solibs () const +{ + return next_adapter (this->so_list); +} + /* 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) { - struct cleanup *old_chain; - - old_chain = save_current_program_space (); + scoped_restore_current_program_space restore_pspace; set_current_program_space (dest); - if (src->ebfd != NULL) - exec_file_attach (bfd_get_filename (src->ebfd), 0); + if (src->pspace_exec_filename != NULL) + exec_file_attach (src->pspace_exec_filename, 0); if (src->symfile_object_file != NULL) - symbol_file_add_main (src->symfile_object_file->name, 0); + symbol_file_add_main (objfile_name (src->symfile_object_file), + SYMFILE_DEFER_BP_RESET); - do_cleanups (old_chain); return dest; } @@ -220,34 +256,10 @@ set_current_program_space (struct program_space *pspace) reinit_frame_cache (); } -/* A cleanups callback, helper for save_current_program_space - below. */ - -static void -restore_program_space (void *arg) -{ - struct program_space *saved_pspace = arg; - - set_current_program_space (saved_pspace); -} - -/* Save the current program space so that it may be restored by a later - call to do_cleanups. Returns the struct cleanup pointer needed for - later doing the cleanup. */ - -struct cleanup * -save_current_program_space (void) -{ - struct cleanup *old_chain = make_cleanup (restore_program_space, - current_program_space); - - return old_chain; -} - /* 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; @@ -255,32 +267,6 @@ pspace_empty_p (struct program_space *pspace) return 1; } -/* Prune away automatically added program spaces that aren't required - anymore. */ - -void -prune_program_spaces (void) -{ - struct program_space *ss, **ss_link; - struct program_space *current = current_program_space; - - ss = program_spaces; - ss_link = &program_spaces; - while (ss) - { - if (ss == current || !pspace_empty_p (ss)) - { - ss_link = &ss->next; - ss = *ss_link; - continue; - } - - *ss_link = ss->next; - release_program_space (ss); - ss = *ss_link; - } -} - /* 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. */ @@ -288,16 +274,10 @@ prune_program_spaces (void) static void print_program_space (struct ui_out *uiout, int requested) { - struct program_space *pspace; 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) + for (struct program_space *pspace : program_spaces) { if (requested != -1 && pspace->num != requested) continue; @@ -308,35 +288,33 @@ print_program_space (struct ui_out *uiout, int requested) /* There should always be at least one. */ 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); + 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) + for (struct program_space *pspace : program_spaces) { - struct cleanup *chain2; struct inferior *inf; int printed_header; if (requested != -1 && requested != pspace->num) continue; - chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); + ui_out_emit_tuple tuple_emitter (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_signed ("id", pspace->num); - if (pspace->ebfd) - ui_out_field_string (uiout, "exec", - bfd_get_filename (pspace->ebfd)); + if (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. @@ -352,19 +330,16 @@ print_program_space (struct ui_out *uiout, int requested) printed_header = 1; printf_filtered ("\n\tBound inferiors: ID %d (%s)", inf->num, - target_pid_to_str (pid_to_ptid (inf->pid))); + target_pid_to_str (ptid_t (inf->pid)).c_str ()); } else printf_filtered (", ID %d (%s)", inf->num, - target_pid_to_str (pid_to_ptid (inf->pid))); + target_pid_to_str (ptid_t (inf->pid)).c_str ()); } - ui_out_text (uiout, "\n"); - do_cleanups (chain2); + uiout->text ("\n"); } - - do_cleanups (old_chain); } /* Boolean test for an already-known program space id. */ @@ -372,9 +347,7 @@ print_program_space (struct ui_out *uiout, int requested) static int valid_program_space_id (int num) { - struct program_space *pspace; - - ALL_PSPACES (pspace) + for (struct program_space *pspace : program_spaces) if (pspace->num == num) return 1; @@ -386,7 +359,7 @@ valid_program_space_id (int num) indicating which the program space to print information about. */ static void -maintenance_info_program_spaces_command (char *args, int from_tty) +maintenance_info_program_spaces_command (const char *args, int from_tty) { int requested = -1; @@ -397,21 +370,7 @@ maintenance_info_program_spaces_command (char *args, int from_tty) error (_("program space ID %d not known."), requested); } - print_program_space (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; + print_program_space (current_uiout, requested); } /* Update all program spaces matching to address spaces. The user may @@ -428,8 +387,7 @@ number_of_program_spaces (void) void update_address_spaces (void) { - int shared_aspace = gdbarch_has_shared_address_space (target_gdbarch); - struct program_space *pspace; + int shared_aspace = gdbarch_has_shared_address_space (target_gdbarch ()); struct inferior *inf; init_address_spaces (); @@ -439,167 +397,32 @@ update_address_spaces (void) struct address_space *aspace = new_address_space (); free_address_space (current_program_space->aspace); - ALL_PSPACES (pspace) + for (struct program_space *pspace : program_spaces) pspace->aspace = aspace; } else - ALL_PSPACES (pspace) + for (struct program_space *pspace : program_spaces) { 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)) + if (gdbarch_has_global_solist (target_gdbarch ())) inf->aspace = maybe_new_address_space (); else inf->aspace = inf->pspace->aspace; } -/* Save the current program space so that it may be restored by a later - call to do_cleanups. Returns the struct cleanup pointer needed for - later doing the cleanup. */ - -struct cleanup * -save_current_space_and_thread (void) -{ - struct cleanup *old_chain; - - /* If restoring to null thread, we need to restore the pspace as - well, hence, we need to save the current program space first. */ - old_chain = save_current_program_space (); - save_current_inferior (); - make_cleanup_restore_current_thread (); - - return old_chain; -} - -/* Switches full context to program space PSPACE. Switches to the - first thread found bound to PSPACE. */ - -void -switch_to_program_space_and_thread (struct program_space *pspace) -{ - struct inferior *inf; - - inf = find_inferior_for_program_space (pspace); - if (inf != NULL) - { - struct thread_info *tp; - - tp = any_live_thread_of_process (inf->pid); - if (tp != NULL) - { - switch_to_thread (tp->ptid); - /* Switching thread switches pspace implicitly. We're - done. */ - return; - } - } - - switch_to_thread (null_ptid); - set_current_program_space (pspace); -} - -/* Keep a registry of per-program_space data-pointers required by other GDB - modules. */ - -struct program_space_data -{ - unsigned index; - void (*cleanup) (struct program_space *, void *); -}; - -struct program_space_data_registration -{ - struct program_space_data *data; - struct program_space_data_registration *next; -}; - -struct program_space_data_registry -{ - struct program_space_data_registration *registrations; - unsigned num_registrations; -}; - -static struct program_space_data_registry program_space_data_registry - = { NULL, 0 }; - -const struct program_space_data * -register_program_space_data_with_cleanup - (void (*cleanup) (struct program_space *, void *)) -{ - struct program_space_data_registration **curr; - - /* Append new registration. */ - for (curr = &program_space_data_registry.registrations; - *curr != NULL; curr = &(*curr)->next); - - *curr = XMALLOC (struct program_space_data_registration); - (*curr)->next = NULL; - (*curr)->data = XMALLOC (struct program_space_data); - (*curr)->data->index = program_space_data_registry.num_registrations++; - (*curr)->data->cleanup = cleanup; - - return (*curr)->data; -} - -const struct program_space_data * -register_program_space_data (void) -{ - return register_program_space_data_with_cleanup (NULL); -} - -static void -program_space_alloc_data (struct program_space *pspace) -{ - gdb_assert (pspace->data == NULL); - pspace->num_data = program_space_data_registry.num_registrations; - pspace->data = XCALLOC (pspace->num_data, void *); -} - -static void -program_space_free_data (struct program_space *pspace) -{ - gdb_assert (pspace->data != NULL); - clear_program_space_data (pspace); - xfree (pspace->data); - pspace->data = NULL; -} - -void -clear_program_space_data (struct program_space *pspace) -{ - struct program_space_data_registration *registration; - int i; - - gdb_assert (pspace->data != NULL); - - for (registration = program_space_data_registry.registrations, i = 0; - i < pspace->num_data; - registration = registration->next, i++) - if (pspace->data[i] != NULL && registration->data->cleanup) - registration->data->cleanup (pspace, pspace->data[i]); - - memset (pspace->data, 0, pspace->num_data * sizeof (void *)); -} +/* See progspace.h. */ void -set_program_space_data (struct program_space *pspace, - const struct program_space_data *data, - void *value) -{ - gdb_assert (data->index < pspace->num_data); - pspace->data[data->index] = value; -} - -void * -program_space_data (struct program_space *pspace, const struct program_space_data *data) +clear_program_space_solib_cache (struct program_space *pspace) { - gdb_assert (data->index < pspace->num_data); - return pspace->data[data->index]; + pspace->added_solibs.clear (); + pspace->deleted_solibs.clear (); } @@ -608,8 +431,8 @@ void initialize_progspace (void) { add_cmd ("program-spaces", class_maintenance, - maintenance_info_program_spaces_command, _("\ -Info about currently known program spaces."), + maintenance_info_program_spaces_command, + _("Info about currently known program spaces."), &maintenanceinfolist); /* There's always one program space. Note that this function isn't @@ -619,5 +442,5 @@ Info about currently known program spaces."), 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 = add_program_space (new_address_space ()); + current_program_space = new program_space (new_address_space ()); }