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