xref: /dragonfly/contrib/gdb-7/gdb/progspace.c (revision ef5ccd6c)
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 *
new_address_space(void)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 *
maybe_new_address_space(void)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
free_address_space(struct address_space * aspace)90cf7f2e2dSJohn Marino free_address_space (struct address_space *aspace)
91cf7f2e2dSJohn Marino {
92cf7f2e2dSJohn Marino   xfree (aspace);
93cf7f2e2dSJohn Marino }
94cf7f2e2dSJohn Marino 
95cf7f2e2dSJohn Marino int
address_space_num(struct address_space * aspace)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
init_address_spaces(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 *
add_program_space(struct address_space * aspace)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
release_program_space(struct program_space * pspace)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
remove_program_space(struct program_space * pspace)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 *
clone_program_space(struct program_space * dest,struct program_space * src)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
set_current_program_space(struct program_space * pspace)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
restore_program_space(void * arg)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 *
save_current_program_space(void)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
pspace_empty_p(struct program_space * pspace)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
prune_program_spaces(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
print_program_space(struct ui_out * uiout,int requested)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
valid_program_space_id(int num)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
maintenance_info_program_spaces_command(char * args,int from_tty)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
number_of_program_spaces(void)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
update_address_spaces(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 *
save_current_space_and_thread(void)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
switch_to_program_space_and_thread(struct program_space * pspace)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
clear_program_space_solib_cache(struct program_space * pspace)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
initialize_progspace(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