1cf7f2e2dSJohn Marino /* Program and address space management, for GDB, the GNU debugger. 2cf7f2e2dSJohn Marino 3*ef5ccd6cSJohn Marino Copyright (C) 2009-2013 Free Software Foundation, Inc. 4cf7f2e2dSJohn Marino 5cf7f2e2dSJohn Marino This file is part of GDB. 6cf7f2e2dSJohn Marino 7cf7f2e2dSJohn Marino This program is free software; you can redistribute it and/or modify 8cf7f2e2dSJohn Marino it under the terms of the GNU General Public License as published by 9cf7f2e2dSJohn Marino the Free Software Foundation; either version 3 of the License, or 10cf7f2e2dSJohn Marino (at your option) any later version. 11cf7f2e2dSJohn Marino 12cf7f2e2dSJohn Marino This program is distributed in the hope that it will be useful, 13cf7f2e2dSJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of 14cf7f2e2dSJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15cf7f2e2dSJohn Marino GNU General Public License for more details. 16cf7f2e2dSJohn Marino 17cf7f2e2dSJohn Marino You should have received a copy of the GNU General Public License 18cf7f2e2dSJohn Marino along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19cf7f2e2dSJohn Marino 20cf7f2e2dSJohn Marino #include "defs.h" 21cf7f2e2dSJohn Marino #include "gdbcmd.h" 22cf7f2e2dSJohn Marino #include "objfiles.h" 23cf7f2e2dSJohn Marino #include "arch-utils.h" 24cf7f2e2dSJohn Marino #include "gdbcore.h" 25cf7f2e2dSJohn Marino #include "solib.h" 26cf7f2e2dSJohn Marino #include "gdbthread.h" 27cf7f2e2dSJohn Marino 28cf7f2e2dSJohn Marino /* The last program space number assigned. */ 29cf7f2e2dSJohn Marino int last_program_space_num = 0; 30cf7f2e2dSJohn Marino 31cf7f2e2dSJohn Marino /* The head of the program spaces list. */ 32cf7f2e2dSJohn Marino struct program_space *program_spaces; 33cf7f2e2dSJohn Marino 34cf7f2e2dSJohn Marino /* Pointer to the current program space. */ 35cf7f2e2dSJohn Marino struct program_space *current_program_space; 36cf7f2e2dSJohn Marino 37cf7f2e2dSJohn Marino /* The last address space number assigned. */ 38cf7f2e2dSJohn Marino static int highest_address_space_num; 39cf7f2e2dSJohn Marino 40*ef5ccd6cSJohn Marino 41cf7f2e2dSJohn Marino 42*ef5ccd6cSJohn Marino /* Keep a registry of per-program_space data-pointers required by other GDB 43*ef5ccd6cSJohn Marino modules. */ 44*ef5ccd6cSJohn Marino 45*ef5ccd6cSJohn Marino DEFINE_REGISTRY (program_space, REGISTRY_ACCESS_FIELD) 46*ef5ccd6cSJohn Marino 47cf7f2e2dSJohn Marino 48cf7f2e2dSJohn Marino 49cf7f2e2dSJohn Marino /* An address space. Currently this is not used for much other than 50cf7f2e2dSJohn Marino for comparing if pspaces/inferior/threads see the same address 51cf7f2e2dSJohn Marino space. */ 52cf7f2e2dSJohn Marino 53cf7f2e2dSJohn Marino struct address_space 54cf7f2e2dSJohn Marino { 55cf7f2e2dSJohn Marino int num; 56cf7f2e2dSJohn Marino }; 57cf7f2e2dSJohn Marino 58cf7f2e2dSJohn Marino /* Create a new address space object, and add it to the list. */ 59cf7f2e2dSJohn Marino 60cf7f2e2dSJohn Marino struct address_space * 61cf7f2e2dSJohn Marino new_address_space (void) 62cf7f2e2dSJohn Marino { 63cf7f2e2dSJohn Marino struct address_space *aspace; 64cf7f2e2dSJohn Marino 65cf7f2e2dSJohn Marino aspace = XZALLOC (struct address_space); 66cf7f2e2dSJohn Marino aspace->num = ++highest_address_space_num; 67cf7f2e2dSJohn Marino 68cf7f2e2dSJohn Marino return aspace; 69cf7f2e2dSJohn Marino } 70cf7f2e2dSJohn Marino 71cf7f2e2dSJohn Marino /* Maybe create a new address space object, and add it to the list, or 72cf7f2e2dSJohn Marino return a pointer to an existing address space, in case inferiors 73cf7f2e2dSJohn Marino share an address space on this target system. */ 74cf7f2e2dSJohn Marino 75cf7f2e2dSJohn Marino struct address_space * 76cf7f2e2dSJohn Marino maybe_new_address_space (void) 77cf7f2e2dSJohn Marino { 78*ef5ccd6cSJohn Marino int shared_aspace = gdbarch_has_shared_address_space (target_gdbarch ()); 79cf7f2e2dSJohn Marino 80cf7f2e2dSJohn Marino if (shared_aspace) 81cf7f2e2dSJohn Marino { 82cf7f2e2dSJohn Marino /* Just return the first in the list. */ 83cf7f2e2dSJohn Marino return program_spaces->aspace; 84cf7f2e2dSJohn Marino } 85cf7f2e2dSJohn Marino 86cf7f2e2dSJohn Marino return new_address_space (); 87cf7f2e2dSJohn Marino } 88cf7f2e2dSJohn Marino 89cf7f2e2dSJohn Marino static void 90cf7f2e2dSJohn Marino free_address_space (struct address_space *aspace) 91cf7f2e2dSJohn Marino { 92cf7f2e2dSJohn Marino xfree (aspace); 93cf7f2e2dSJohn Marino } 94cf7f2e2dSJohn Marino 95cf7f2e2dSJohn Marino int 96cf7f2e2dSJohn Marino address_space_num (struct address_space *aspace) 97cf7f2e2dSJohn Marino { 98cf7f2e2dSJohn Marino return aspace->num; 99cf7f2e2dSJohn Marino } 100cf7f2e2dSJohn Marino 101cf7f2e2dSJohn Marino /* Start counting over from scratch. */ 102cf7f2e2dSJohn Marino 103cf7f2e2dSJohn Marino static void 104cf7f2e2dSJohn Marino init_address_spaces (void) 105cf7f2e2dSJohn Marino { 106cf7f2e2dSJohn Marino highest_address_space_num = 0; 107cf7f2e2dSJohn Marino } 108cf7f2e2dSJohn Marino 109cf7f2e2dSJohn Marino 110cf7f2e2dSJohn Marino 111cf7f2e2dSJohn Marino /* Adds a new empty program space to the program space list, and binds 112cf7f2e2dSJohn Marino it to ASPACE. Returns the pointer to the new object. */ 113cf7f2e2dSJohn Marino 114cf7f2e2dSJohn Marino struct program_space * 115cf7f2e2dSJohn Marino add_program_space (struct address_space *aspace) 116cf7f2e2dSJohn Marino { 117cf7f2e2dSJohn Marino struct program_space *pspace; 118cf7f2e2dSJohn Marino 119cf7f2e2dSJohn Marino pspace = XZALLOC (struct program_space); 120cf7f2e2dSJohn Marino 121cf7f2e2dSJohn Marino pspace->num = ++last_program_space_num; 122cf7f2e2dSJohn Marino pspace->aspace = aspace; 123cf7f2e2dSJohn Marino 124cf7f2e2dSJohn Marino program_space_alloc_data (pspace); 125cf7f2e2dSJohn Marino 126cf7f2e2dSJohn Marino pspace->next = program_spaces; 127cf7f2e2dSJohn Marino program_spaces = pspace; 128cf7f2e2dSJohn Marino 129cf7f2e2dSJohn Marino return pspace; 130cf7f2e2dSJohn Marino } 131cf7f2e2dSJohn Marino 132cf7f2e2dSJohn Marino /* Releases program space PSPACE, and all its contents (shared 133cf7f2e2dSJohn Marino libraries, objfiles, and any other references to the PSPACE in 134cf7f2e2dSJohn Marino other modules). It is an internal error to call this when PSPACE 135cf7f2e2dSJohn Marino is the current program space, since there should always be a 136cf7f2e2dSJohn Marino program space. */ 137cf7f2e2dSJohn Marino 138cf7f2e2dSJohn Marino static void 139cf7f2e2dSJohn Marino release_program_space (struct program_space *pspace) 140cf7f2e2dSJohn Marino { 141cf7f2e2dSJohn Marino struct cleanup *old_chain = save_current_program_space (); 142cf7f2e2dSJohn Marino 143cf7f2e2dSJohn Marino gdb_assert (pspace != current_program_space); 144cf7f2e2dSJohn Marino 145cf7f2e2dSJohn Marino set_current_program_space (pspace); 146cf7f2e2dSJohn Marino 147cf7f2e2dSJohn Marino breakpoint_program_space_exit (pspace); 148cf7f2e2dSJohn Marino no_shared_libraries (NULL, 0); 149cf7f2e2dSJohn Marino exec_close (); 150cf7f2e2dSJohn Marino free_all_objfiles (); 151*ef5ccd6cSJohn Marino if (!gdbarch_has_shared_address_space (target_gdbarch ())) 152cf7f2e2dSJohn Marino free_address_space (pspace->aspace); 153cf7f2e2dSJohn Marino resize_section_table (&pspace->target_sections, 154cf7f2e2dSJohn Marino -resize_section_table (&pspace->target_sections, 0)); 155*ef5ccd6cSJohn Marino clear_program_space_solib_cache (pspace); 156cf7f2e2dSJohn Marino /* Discard any data modules have associated with the PSPACE. */ 157cf7f2e2dSJohn Marino program_space_free_data (pspace); 158cf7f2e2dSJohn Marino xfree (pspace); 159cf7f2e2dSJohn Marino 160cf7f2e2dSJohn Marino do_cleanups (old_chain); 161cf7f2e2dSJohn Marino } 162cf7f2e2dSJohn Marino 163cf7f2e2dSJohn Marino /* Unlinks PSPACE from the pspace list, and releases it. */ 164cf7f2e2dSJohn Marino 165cf7f2e2dSJohn Marino void 166cf7f2e2dSJohn Marino remove_program_space (struct program_space *pspace) 167cf7f2e2dSJohn Marino { 168cf7f2e2dSJohn Marino struct program_space *ss, **ss_link; 169cf7f2e2dSJohn Marino 170cf7f2e2dSJohn Marino ss = program_spaces; 171cf7f2e2dSJohn Marino ss_link = &program_spaces; 172cf7f2e2dSJohn Marino while (ss) 173cf7f2e2dSJohn Marino { 174cf7f2e2dSJohn Marino if (ss != pspace) 175cf7f2e2dSJohn Marino { 176cf7f2e2dSJohn Marino ss_link = &ss->next; 177cf7f2e2dSJohn Marino ss = *ss_link; 178cf7f2e2dSJohn Marino continue; 179cf7f2e2dSJohn Marino } 180cf7f2e2dSJohn Marino 181cf7f2e2dSJohn Marino *ss_link = ss->next; 182cf7f2e2dSJohn Marino release_program_space (ss); 183cf7f2e2dSJohn Marino ss = *ss_link; 184cf7f2e2dSJohn Marino } 185cf7f2e2dSJohn Marino } 186cf7f2e2dSJohn Marino 187cf7f2e2dSJohn Marino /* Copies program space SRC to DEST. Copies the main executable file, 188cf7f2e2dSJohn Marino and the main symbol file. Returns DEST. */ 189cf7f2e2dSJohn Marino 190cf7f2e2dSJohn Marino struct program_space * 191cf7f2e2dSJohn Marino clone_program_space (struct program_space *dest, struct program_space *src) 192cf7f2e2dSJohn Marino { 193cf7f2e2dSJohn Marino struct cleanup *old_chain; 194cf7f2e2dSJohn Marino 195cf7f2e2dSJohn Marino old_chain = save_current_program_space (); 196cf7f2e2dSJohn Marino 197cf7f2e2dSJohn Marino set_current_program_space (dest); 198cf7f2e2dSJohn Marino 199*ef5ccd6cSJohn Marino if (src->pspace_exec_filename != NULL) 200*ef5ccd6cSJohn Marino exec_file_attach (src->pspace_exec_filename, 0); 201cf7f2e2dSJohn Marino 202cf7f2e2dSJohn Marino if (src->symfile_object_file != NULL) 203cf7f2e2dSJohn Marino symbol_file_add_main (src->symfile_object_file->name, 0); 204cf7f2e2dSJohn Marino 205cf7f2e2dSJohn Marino do_cleanups (old_chain); 206cf7f2e2dSJohn Marino return dest; 207cf7f2e2dSJohn Marino } 208cf7f2e2dSJohn Marino 209cf7f2e2dSJohn Marino /* Sets PSPACE as the current program space. It is the caller's 210cf7f2e2dSJohn Marino responsibility to make sure that the currently selected 211cf7f2e2dSJohn Marino inferior/thread matches the selected program space. */ 212cf7f2e2dSJohn Marino 213cf7f2e2dSJohn Marino void 214cf7f2e2dSJohn Marino set_current_program_space (struct program_space *pspace) 215cf7f2e2dSJohn Marino { 216cf7f2e2dSJohn Marino if (current_program_space == pspace) 217cf7f2e2dSJohn Marino return; 218cf7f2e2dSJohn Marino 219cf7f2e2dSJohn Marino gdb_assert (pspace != NULL); 220cf7f2e2dSJohn Marino 221cf7f2e2dSJohn Marino current_program_space = pspace; 222cf7f2e2dSJohn Marino 223cf7f2e2dSJohn Marino /* Different symbols change our view of the frame chain. */ 224cf7f2e2dSJohn Marino reinit_frame_cache (); 225cf7f2e2dSJohn Marino } 226cf7f2e2dSJohn Marino 227cf7f2e2dSJohn Marino /* A cleanups callback, helper for save_current_program_space 228cf7f2e2dSJohn Marino below. */ 229cf7f2e2dSJohn Marino 230cf7f2e2dSJohn Marino static void 231cf7f2e2dSJohn Marino restore_program_space (void *arg) 232cf7f2e2dSJohn Marino { 233cf7f2e2dSJohn Marino struct program_space *saved_pspace = arg; 234cf7f2e2dSJohn Marino 235cf7f2e2dSJohn Marino set_current_program_space (saved_pspace); 236cf7f2e2dSJohn Marino } 237cf7f2e2dSJohn Marino 238cf7f2e2dSJohn Marino /* Save the current program space so that it may be restored by a later 239cf7f2e2dSJohn Marino call to do_cleanups. Returns the struct cleanup pointer needed for 240cf7f2e2dSJohn Marino later doing the cleanup. */ 241cf7f2e2dSJohn Marino 242cf7f2e2dSJohn Marino struct cleanup * 243cf7f2e2dSJohn Marino save_current_program_space (void) 244cf7f2e2dSJohn Marino { 245cf7f2e2dSJohn Marino struct cleanup *old_chain = make_cleanup (restore_program_space, 246cf7f2e2dSJohn Marino current_program_space); 247cf7f2e2dSJohn Marino 248cf7f2e2dSJohn Marino return old_chain; 249cf7f2e2dSJohn Marino } 250cf7f2e2dSJohn Marino 251cf7f2e2dSJohn Marino /* Returns true iff there's no inferior bound to PSPACE. */ 252cf7f2e2dSJohn Marino 253cf7f2e2dSJohn Marino static int 254cf7f2e2dSJohn Marino pspace_empty_p (struct program_space *pspace) 255cf7f2e2dSJohn Marino { 256cf7f2e2dSJohn Marino if (find_inferior_for_program_space (pspace) != NULL) 257cf7f2e2dSJohn Marino return 0; 258cf7f2e2dSJohn Marino 259cf7f2e2dSJohn Marino return 1; 260cf7f2e2dSJohn Marino } 261cf7f2e2dSJohn Marino 262cf7f2e2dSJohn Marino /* Prune away automatically added program spaces that aren't required 263cf7f2e2dSJohn Marino anymore. */ 264cf7f2e2dSJohn Marino 265cf7f2e2dSJohn Marino void 266cf7f2e2dSJohn Marino prune_program_spaces (void) 267cf7f2e2dSJohn Marino { 268cf7f2e2dSJohn Marino struct program_space *ss, **ss_link; 269cf7f2e2dSJohn Marino struct program_space *current = current_program_space; 270cf7f2e2dSJohn Marino 271cf7f2e2dSJohn Marino ss = program_spaces; 272cf7f2e2dSJohn Marino ss_link = &program_spaces; 273cf7f2e2dSJohn Marino while (ss) 274cf7f2e2dSJohn Marino { 275cf7f2e2dSJohn Marino if (ss == current || !pspace_empty_p (ss)) 276cf7f2e2dSJohn Marino { 277cf7f2e2dSJohn Marino ss_link = &ss->next; 278cf7f2e2dSJohn Marino ss = *ss_link; 279cf7f2e2dSJohn Marino continue; 280cf7f2e2dSJohn Marino } 281cf7f2e2dSJohn Marino 282cf7f2e2dSJohn Marino *ss_link = ss->next; 283cf7f2e2dSJohn Marino release_program_space (ss); 284cf7f2e2dSJohn Marino ss = *ss_link; 285cf7f2e2dSJohn Marino } 286cf7f2e2dSJohn Marino } 287cf7f2e2dSJohn Marino 288cf7f2e2dSJohn Marino /* Prints the list of program spaces and their details on UIOUT. If 289cf7f2e2dSJohn Marino REQUESTED is not -1, it's the ID of the pspace that should be 290cf7f2e2dSJohn Marino printed. Otherwise, all spaces are printed. */ 291cf7f2e2dSJohn Marino 292cf7f2e2dSJohn Marino static void 293cf7f2e2dSJohn Marino print_program_space (struct ui_out *uiout, int requested) 294cf7f2e2dSJohn Marino { 295cf7f2e2dSJohn Marino struct program_space *pspace; 296cf7f2e2dSJohn Marino int count = 0; 297cf7f2e2dSJohn Marino struct cleanup *old_chain; 298cf7f2e2dSJohn Marino 299cf7f2e2dSJohn Marino /* Might as well prune away unneeded ones, so the user doesn't even 300cf7f2e2dSJohn Marino seem them. */ 301cf7f2e2dSJohn Marino prune_program_spaces (); 302cf7f2e2dSJohn Marino 303cf7f2e2dSJohn Marino /* Compute number of pspaces we will print. */ 304cf7f2e2dSJohn Marino ALL_PSPACES (pspace) 305cf7f2e2dSJohn Marino { 306cf7f2e2dSJohn Marino if (requested != -1 && pspace->num != requested) 307cf7f2e2dSJohn Marino continue; 308cf7f2e2dSJohn Marino 309cf7f2e2dSJohn Marino ++count; 310cf7f2e2dSJohn Marino } 311cf7f2e2dSJohn Marino 312cf7f2e2dSJohn Marino /* There should always be at least one. */ 313cf7f2e2dSJohn Marino gdb_assert (count > 0); 314cf7f2e2dSJohn Marino 315cf7f2e2dSJohn Marino old_chain = make_cleanup_ui_out_table_begin_end (uiout, 3, count, "pspaces"); 316cf7f2e2dSJohn Marino ui_out_table_header (uiout, 1, ui_left, "current", ""); 317cf7f2e2dSJohn Marino ui_out_table_header (uiout, 4, ui_left, "id", "Id"); 318cf7f2e2dSJohn Marino ui_out_table_header (uiout, 17, ui_left, "exec", "Executable"); 319cf7f2e2dSJohn Marino ui_out_table_body (uiout); 320cf7f2e2dSJohn Marino 321cf7f2e2dSJohn Marino ALL_PSPACES (pspace) 322cf7f2e2dSJohn Marino { 323cf7f2e2dSJohn Marino struct cleanup *chain2; 324cf7f2e2dSJohn Marino struct inferior *inf; 325cf7f2e2dSJohn Marino int printed_header; 326cf7f2e2dSJohn Marino 327cf7f2e2dSJohn Marino if (requested != -1 && requested != pspace->num) 328cf7f2e2dSJohn Marino continue; 329cf7f2e2dSJohn Marino 330cf7f2e2dSJohn Marino chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); 331cf7f2e2dSJohn Marino 332cf7f2e2dSJohn Marino if (pspace == current_program_space) 333cf7f2e2dSJohn Marino ui_out_field_string (uiout, "current", "*"); 334cf7f2e2dSJohn Marino else 335cf7f2e2dSJohn Marino ui_out_field_skip (uiout, "current"); 336cf7f2e2dSJohn Marino 337cf7f2e2dSJohn Marino ui_out_field_int (uiout, "id", pspace->num); 338cf7f2e2dSJohn Marino 339*ef5ccd6cSJohn Marino if (pspace->pspace_exec_filename) 340*ef5ccd6cSJohn Marino ui_out_field_string (uiout, "exec", pspace->pspace_exec_filename); 341cf7f2e2dSJohn Marino else 342cf7f2e2dSJohn Marino ui_out_field_skip (uiout, "exec"); 343cf7f2e2dSJohn Marino 344cf7f2e2dSJohn Marino /* Print extra info that doesn't really fit in tabular form. 345cf7f2e2dSJohn Marino Currently, we print the list of inferiors bound to a pspace. 346cf7f2e2dSJohn Marino There can be more than one inferior bound to the same pspace, 347cf7f2e2dSJohn Marino e.g., both parent/child inferiors in a vfork, or, on targets 348cf7f2e2dSJohn Marino that share pspaces between inferiors. */ 349cf7f2e2dSJohn Marino printed_header = 0; 350cf7f2e2dSJohn Marino for (inf = inferior_list; inf; inf = inf->next) 351cf7f2e2dSJohn Marino if (inf->pspace == pspace) 352cf7f2e2dSJohn Marino { 353cf7f2e2dSJohn Marino if (!printed_header) 354cf7f2e2dSJohn Marino { 355cf7f2e2dSJohn Marino printed_header = 1; 356cf7f2e2dSJohn Marino printf_filtered ("\n\tBound inferiors: ID %d (%s)", 357cf7f2e2dSJohn Marino inf->num, 358cf7f2e2dSJohn Marino target_pid_to_str (pid_to_ptid (inf->pid))); 359cf7f2e2dSJohn Marino } 360cf7f2e2dSJohn Marino else 361cf7f2e2dSJohn Marino printf_filtered (", ID %d (%s)", 362cf7f2e2dSJohn Marino inf->num, 363cf7f2e2dSJohn Marino target_pid_to_str (pid_to_ptid (inf->pid))); 364cf7f2e2dSJohn Marino } 365cf7f2e2dSJohn Marino 366cf7f2e2dSJohn Marino ui_out_text (uiout, "\n"); 367cf7f2e2dSJohn Marino do_cleanups (chain2); 368cf7f2e2dSJohn Marino } 369cf7f2e2dSJohn Marino 370cf7f2e2dSJohn Marino do_cleanups (old_chain); 371cf7f2e2dSJohn Marino } 372cf7f2e2dSJohn Marino 373cf7f2e2dSJohn Marino /* Boolean test for an already-known program space id. */ 374cf7f2e2dSJohn Marino 375cf7f2e2dSJohn Marino static int 376cf7f2e2dSJohn Marino valid_program_space_id (int num) 377cf7f2e2dSJohn Marino { 378cf7f2e2dSJohn Marino struct program_space *pspace; 379cf7f2e2dSJohn Marino 380cf7f2e2dSJohn Marino ALL_PSPACES (pspace) 381cf7f2e2dSJohn Marino if (pspace->num == num) 382cf7f2e2dSJohn Marino return 1; 383cf7f2e2dSJohn Marino 384cf7f2e2dSJohn Marino return 0; 385cf7f2e2dSJohn Marino } 386cf7f2e2dSJohn Marino 387cf7f2e2dSJohn Marino /* If ARGS is NULL or empty, print information about all program 388cf7f2e2dSJohn Marino spaces. Otherwise, ARGS is a text representation of a LONG 389cf7f2e2dSJohn Marino indicating which the program space to print information about. */ 390cf7f2e2dSJohn Marino 391cf7f2e2dSJohn Marino static void 392cf7f2e2dSJohn Marino maintenance_info_program_spaces_command (char *args, int from_tty) 393cf7f2e2dSJohn Marino { 394cf7f2e2dSJohn Marino int requested = -1; 395cf7f2e2dSJohn Marino 396cf7f2e2dSJohn Marino if (args && *args) 397cf7f2e2dSJohn Marino { 398cf7f2e2dSJohn Marino requested = parse_and_eval_long (args); 399cf7f2e2dSJohn Marino if (!valid_program_space_id (requested)) 400cf7f2e2dSJohn Marino error (_("program space ID %d not known."), requested); 401cf7f2e2dSJohn Marino } 402cf7f2e2dSJohn Marino 403a45ae5f8SJohn Marino print_program_space (current_uiout, requested); 404cf7f2e2dSJohn Marino } 405cf7f2e2dSJohn Marino 406cf7f2e2dSJohn Marino /* Simply returns the count of program spaces. */ 407cf7f2e2dSJohn Marino 408cf7f2e2dSJohn Marino int 409cf7f2e2dSJohn Marino number_of_program_spaces (void) 410cf7f2e2dSJohn Marino { 411cf7f2e2dSJohn Marino struct program_space *pspace; 412cf7f2e2dSJohn Marino int count = 0; 413cf7f2e2dSJohn Marino 414cf7f2e2dSJohn Marino ALL_PSPACES (pspace) 415cf7f2e2dSJohn Marino count++; 416cf7f2e2dSJohn Marino 417cf7f2e2dSJohn Marino return count; 418cf7f2e2dSJohn Marino } 419cf7f2e2dSJohn Marino 420cf7f2e2dSJohn Marino /* Update all program spaces matching to address spaces. The user may 421cf7f2e2dSJohn Marino have created several program spaces, and loaded executables into 422cf7f2e2dSJohn Marino them before connecting to the target interface that will create the 423cf7f2e2dSJohn Marino inferiors. All that happens before GDB has a chance to know if the 424cf7f2e2dSJohn Marino inferiors will share an address space or not. Call this after 425cf7f2e2dSJohn Marino having connected to the target interface and having fetched the 426cf7f2e2dSJohn Marino target description, to fixup the program/address spaces mappings. 427cf7f2e2dSJohn Marino 428cf7f2e2dSJohn Marino It is assumed that there are no bound inferiors yet, otherwise, 429cf7f2e2dSJohn Marino they'd be left with stale referenced to released aspaces. */ 430cf7f2e2dSJohn Marino 431cf7f2e2dSJohn Marino void 432cf7f2e2dSJohn Marino update_address_spaces (void) 433cf7f2e2dSJohn Marino { 434*ef5ccd6cSJohn Marino int shared_aspace = gdbarch_has_shared_address_space (target_gdbarch ()); 435cf7f2e2dSJohn Marino struct program_space *pspace; 436cf7f2e2dSJohn Marino struct inferior *inf; 437cf7f2e2dSJohn Marino 438cf7f2e2dSJohn Marino init_address_spaces (); 439cf7f2e2dSJohn Marino 440cf7f2e2dSJohn Marino if (shared_aspace) 441cf7f2e2dSJohn Marino { 442cf7f2e2dSJohn Marino struct address_space *aspace = new_address_space (); 443cf7f2e2dSJohn Marino 444cf7f2e2dSJohn Marino free_address_space (current_program_space->aspace); 445cf7f2e2dSJohn Marino ALL_PSPACES (pspace) 446cf7f2e2dSJohn Marino pspace->aspace = aspace; 447cf7f2e2dSJohn Marino } 448cf7f2e2dSJohn Marino else 449cf7f2e2dSJohn Marino ALL_PSPACES (pspace) 450cf7f2e2dSJohn Marino { 451cf7f2e2dSJohn Marino free_address_space (pspace->aspace); 452cf7f2e2dSJohn Marino pspace->aspace = new_address_space (); 453cf7f2e2dSJohn Marino } 454cf7f2e2dSJohn Marino 455cf7f2e2dSJohn Marino for (inf = inferior_list; inf; inf = inf->next) 456*ef5ccd6cSJohn Marino if (gdbarch_has_global_solist (target_gdbarch ())) 457cf7f2e2dSJohn Marino inf->aspace = maybe_new_address_space (); 458cf7f2e2dSJohn Marino else 459cf7f2e2dSJohn Marino inf->aspace = inf->pspace->aspace; 460cf7f2e2dSJohn Marino } 461cf7f2e2dSJohn Marino 462cf7f2e2dSJohn Marino /* Save the current program space so that it may be restored by a later 463cf7f2e2dSJohn Marino call to do_cleanups. Returns the struct cleanup pointer needed for 464cf7f2e2dSJohn Marino later doing the cleanup. */ 465cf7f2e2dSJohn Marino 466cf7f2e2dSJohn Marino struct cleanup * 467cf7f2e2dSJohn Marino save_current_space_and_thread (void) 468cf7f2e2dSJohn Marino { 469cf7f2e2dSJohn Marino struct cleanup *old_chain; 470cf7f2e2dSJohn Marino 471cf7f2e2dSJohn Marino /* If restoring to null thread, we need to restore the pspace as 472cf7f2e2dSJohn Marino well, hence, we need to save the current program space first. */ 473cf7f2e2dSJohn Marino old_chain = save_current_program_space (); 474cf7f2e2dSJohn Marino save_current_inferior (); 475cf7f2e2dSJohn Marino make_cleanup_restore_current_thread (); 476cf7f2e2dSJohn Marino 477cf7f2e2dSJohn Marino return old_chain; 478cf7f2e2dSJohn Marino } 479cf7f2e2dSJohn Marino 480cf7f2e2dSJohn Marino /* Switches full context to program space PSPACE. Switches to the 481cf7f2e2dSJohn Marino first thread found bound to PSPACE. */ 482cf7f2e2dSJohn Marino 483cf7f2e2dSJohn Marino void 484cf7f2e2dSJohn Marino switch_to_program_space_and_thread (struct program_space *pspace) 485cf7f2e2dSJohn Marino { 486cf7f2e2dSJohn Marino struct inferior *inf; 487cf7f2e2dSJohn Marino 488cf7f2e2dSJohn Marino inf = find_inferior_for_program_space (pspace); 489cf7f2e2dSJohn Marino if (inf != NULL) 490cf7f2e2dSJohn Marino { 491cf7f2e2dSJohn Marino struct thread_info *tp; 492cf7f2e2dSJohn Marino 493cf7f2e2dSJohn Marino tp = any_live_thread_of_process (inf->pid); 494cf7f2e2dSJohn Marino if (tp != NULL) 495cf7f2e2dSJohn Marino { 496cf7f2e2dSJohn Marino switch_to_thread (tp->ptid); 497cf7f2e2dSJohn Marino /* Switching thread switches pspace implicitly. We're 498cf7f2e2dSJohn Marino done. */ 499cf7f2e2dSJohn Marino return; 500cf7f2e2dSJohn Marino } 501cf7f2e2dSJohn Marino } 502cf7f2e2dSJohn Marino 503cf7f2e2dSJohn Marino switch_to_thread (null_ptid); 504cf7f2e2dSJohn Marino set_current_program_space (pspace); 505cf7f2e2dSJohn Marino } 506cf7f2e2dSJohn Marino 507cf7f2e2dSJohn Marino 508cf7f2e2dSJohn Marino 509*ef5ccd6cSJohn Marino /* See progspace.h. */ 510cf7f2e2dSJohn Marino 511cf7f2e2dSJohn Marino void 512*ef5ccd6cSJohn Marino clear_program_space_solib_cache (struct program_space *pspace) 513cf7f2e2dSJohn Marino { 514*ef5ccd6cSJohn Marino VEC_free (so_list_ptr, pspace->added_solibs); 515cf7f2e2dSJohn Marino 516*ef5ccd6cSJohn Marino free_char_ptr_vec (pspace->deleted_solibs); 517*ef5ccd6cSJohn Marino pspace->deleted_solibs = NULL; 518cf7f2e2dSJohn Marino } 519cf7f2e2dSJohn Marino 520cf7f2e2dSJohn Marino 521cf7f2e2dSJohn Marino 522cf7f2e2dSJohn Marino void 523cf7f2e2dSJohn Marino initialize_progspace (void) 524cf7f2e2dSJohn Marino { 525cf7f2e2dSJohn Marino add_cmd ("program-spaces", class_maintenance, 526c50c785cSJohn Marino maintenance_info_program_spaces_command, 527c50c785cSJohn Marino _("Info about currently known program spaces."), 528cf7f2e2dSJohn Marino &maintenanceinfolist); 529cf7f2e2dSJohn Marino 530cf7f2e2dSJohn Marino /* There's always one program space. Note that this function isn't 531cf7f2e2dSJohn Marino an automatic _initialize_foo function, since other 532cf7f2e2dSJohn Marino _initialize_foo routines may need to install their per-pspace 533cf7f2e2dSJohn Marino data keys. We can only allocate a progspace when all those 534cf7f2e2dSJohn Marino modules have done that. Do this before 535cf7f2e2dSJohn Marino initialize_current_architecture, because that accesses exec_bfd, 536cf7f2e2dSJohn Marino which in turn dereferences current_program_space. */ 537cf7f2e2dSJohn Marino current_program_space = add_program_space (new_address_space ()); 538cf7f2e2dSJohn Marino } 539