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