* Check in Fred Fish's changes in these modules. Fred
[deliverable/binutils-gdb.git] / gdb / state.c
1 /* Support for dumping and reloading various pieces of GDB's internal state.
2 Copyright 1992 Free Software Foundation, Inc.
3 Contributed by Cygnus Support, using pieces from other GDB modules.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21 /* This file provides support for dumping and then later reloading various
22 portions of gdb's internal state. It was originally implemented to
23 support a need for mapping in an image of gdb's symbol table from an
24 external file, where this image was created by an external program, such
25 as an incremental linker. However, it was generalized to enable future
26 support for dumping and reloading various other useful pieces of gdb's
27 internal state.
28
29 State files have a fairly simple form which is intended to be easily
30 extensible. The basic format is:
31
32 <file-header> <state-data> <form-tree>
33
34 Where:
35
36 file-header A simple file-header containing a magic number
37 so that gdb (and other readers) can quickly
38 determine what kind of file this is, and a file
39 offset to the root of the form-tree.
40
41 state-data The "raw" state-data that is referenced by nodes
42 in the form-tree.
43
44 form-tree A tree of arbitrarily sized nodes containing
45 information about gdb's internal state, and
46 possibly referencing data in the state-data section
47 of the file. Resembles DWARF in some respects.
48
49 When writing a state file, a hole is left for the file-header at the
50 beginning of the file, the state data is written immediately after the
51 file header (while storing the file offsets and sizes back into the
52 internal form-tree along the way), the form-tree itself is written
53 at the end of the file, and then the file header is written by seeking
54 back to the beginning of the file. This order is required because
55 the form tree contains file offsets and sizes in the state data portion
56 of the file, and the file header contains the file offset to the start
57 of the form tree.
58
59 Readers simply open the file, validate the magic number, seek to the
60 root of the form-tree, and walk the tree looking for the information that
61 they are interested in (and ignoring things that they aren't, or don't
62 understand).
63
64 */
65
66
67 #include <stdio.h>
68 #include "defs.h"
69 #include "symtab.h"
70 #include "bfd.h"
71 #include "symfile.h"
72 #include "state.h"
73
74 #ifndef SEEK_SET
75 #define SEEK_SET 0
76 #endif
77
78 #ifndef SEEK_END
79 #define SEEK_END 2
80 #endif
81
82 /* Inside the state file, the form-tree consists of a series of
83 form-tree entries (FTE's). The parent/child/sibling relationships
84 are implied by the ordering and by an explicit sibling reference
85 in FTE's that have siblings.
86
87 Specifically, given two sequential FTE's, say A and B, if B immediately
88 follows A, and A does not have a sibling reference to B, then B is
89 the first child of A. Otherwise B must be a sibling of A and A must
90 have a sibling reference for it.
91
92 Each FTE is simply an array of long integers, with at least three
93 members. This form was chosen over a packed data form for simplicity
94 in access, not having to worry about the relative sizes of the different
95 integers (short, int, long), and not having to worry about alignment
96 constraints. Also in the name of simplicity, every FTE has a sibling
97 reference slot reserved for it, even if there are no siblings.
98
99 The first value in an FTE is the size of the FTE in bytes, including
100 the size value itself. The second entry contains a tag which indicates
101 the type of the FTE. The third entry is a sibling reference, which either
102 refers to a valid sibling node or is zero. Following is zero or more
103 attributes, each of which consists of one or more long values. */
104
105 /* Tag names and codes. */
106
107 #define TAG_padding 0x0000 /* Padding */
108 #define TAG_objfile 0x0001 /* Dumped objfile */
109
110 /* Form names, codes, and macros. */
111
112 #define FORM_ABSREF 0x01 /* Next long is absolute file offset */
113 #define FORM_RELREF 0x02 /* Next long is relative file offset */
114 #define FORM_IVAL 0x03 /* Next long is int value */
115 #define FORM_ADDR 0x04 /* Next long is mem addr */
116
117 #define FORM_MASK 0xFF
118 #define FORM_X(atr) ((atr) & FORM_MASK)
119
120 /* Attribute names and codes. */
121
122 #define AT_sibling (0x0100 | FORM_RELREF) /* Reference to sibling node */
123 #define AT_name (0x0200 | FORM_ABSREF) /* Reference to a string */
124 #define AT_offset (0x0300 | FORM_ABSREF) /* Reference to generic data */
125 #define AT_size (0x0400 | FORM_IVAL)
126 #define AT_addr (0x0500 | FORM_ADDR)
127 #define AT_aux_addr (0x0600 | FORM_ADDR)
128
129 /* */
130
131 static void
132 load_symbols PARAMS ((FILE *));
133
134 static void
135 dump_state_command PARAMS ((char *, int));
136
137 static void
138 load_state_command PARAMS ((char *, int));
139
140 #ifdef HAVE_MMAP
141
142 static void
143 write_header PARAMS ((sfd *));
144
145 static void
146 write_formtree PARAMS ((sfd *));
147
148 static void
149 write_objfile_state PARAMS ((sfd *));
150
151 static void
152 free_subtree PARAMS ((struct formnode *));
153
154 static void
155 size_subtree PARAMS ((struct formnode *));
156
157 #endif
158
159 struct formnode *formtree = NULL;
160
161 /* ARGSUSED */
162 static void
163 load_symbols (statefile)
164 FILE *statefile;
165 {
166
167 #if 0
168 /* Discard old symbols. FIXME: This is essentially symbol_file_command's
169 body when there is no name. Make it a common function that is
170 called from each place. */
171
172 if (symfile_objfile)
173 {
174 free_objfile (symfile_objfile);
175 }
176 symfile_objfile = NULL;
177 #endif
178
179 #if 0 && defined (HAVE_MMAP)
180 if (mtop > mbase)
181 {
182 warning ("internal error: mbase (%08x) != mtop (%08x)",
183 mbase, mtop);
184 munmap (mbase, mtop - mbase);
185 }
186 #endif /* HAVE_MMAP */
187
188 /* Getting new symbols may change our opinion about what is frameless. */
189
190 reinit_frame_cache ();
191
192 }
193
194 #ifdef HAVE_MMAP
195
196 /* Allocate a form node */
197
198 static struct formnode *
199 alloc_formnode ()
200 {
201 struct formnode *fnp;
202
203 fnp = (struct formnode *) xmalloc (sizeof (struct formnode));
204 (void) memset (fnp, 0, sizeof (struct formnode));
205 fnp -> sibling = formtree;
206 formtree = fnp;
207 return (fnp);
208 }
209
210 /* Recursively walk a form-tree from the specified node, freeing
211 nodes from the bottom up. The concept is pretty simple, just free
212 all the child nodes, then all the sibling nodes, then the node
213 itself. */
214
215 static void
216 free_subtree (fnp)
217 struct formnode *fnp;
218 {
219 if (fnp != NULL)
220 {
221 free_subtree (fnp -> child);
222 free_subtree (fnp -> sibling);
223 if (fnp -> nodedata != NULL)
224 {
225 free (fnp -> nodedata);
226 }
227 free (fnp);
228 }
229 }
230
231 /* Recursively walk a form-tree from the specified node, computing the
232 size of each subtree from the bottom up.
233
234 At each node, the file space that will be consumed by the subtree
235 rooted in that node is the sum of all the subtrees rooted in each
236 child node plus the size of the node itself.
237
238 Thus for each node, we size the child subtrees, add to that our
239 size, contribute this size towards the size of any parent node, and
240 then ask any of our siblings to do the same.
241
242 Also, once we know the size of any subtree rooted at this node, we
243 can initialize the offset to the sibling node (if any).
244
245 Since every form-tree node must have valid nodedata at this point,
246 we detect and report a warning for any node that doesn't. */
247
248 static void
249 size_subtree (fnp)
250 struct formnode *fnp;
251 {
252 long *lp;
253
254 if (fnp != NULL)
255 {
256 if (fnp -> nodedata == NULL)
257 {
258 warning ("internal error -- empty form node");
259 }
260 else
261 {
262 size_subtree (fnp -> child);
263 fnp -> treesize += *(long *) fnp -> nodedata;
264 if (fnp -> parent != NULL)
265 {
266 fnp -> parent -> treesize += fnp -> treesize;
267 }
268 if (fnp -> sibling)
269 {
270 size_subtree (fnp -> sibling);
271 lp = (long *) (fnp -> nodedata + 2 * sizeof (long));
272 *lp = fnp -> treesize;
273 }
274 }
275 }
276 }
277
278 /* Recursively walk a form-tree from the specified node, writing
279 nodes from the top down. */
280
281 static void
282 write_subtree (fnp, asfd)
283 struct formnode *fnp;
284 sfd *asfd;
285 {
286 if (fnp != NULL)
287 {
288 if (fnp -> nodedata != NULL)
289 {
290 fwrite (fnp -> nodedata, *(long *) fnp -> nodedata, 1, asfd -> fp);
291 }
292 write_subtree (fnp -> child, asfd);
293 write_subtree (fnp -> sibling, asfd);
294 }
295 }
296
297 /* Free the entire current formtree. Called via do_cleanups, regardless
298 of whether there is an error or not. */
299
300 static void
301 free_formtree ()
302 {
303 free_subtree (formtree);
304 formtree = NULL;
305 }
306
307 /* Write out the file header. Generally this is done last, even though
308 it is located at the start of the file, since we need to have file
309 offset to where the annotated form tree was written, and it's size. */
310
311 static void
312 write_header (asfd)
313 sfd *asfd;
314 {
315 fseek (asfd -> fp, 0L, SEEK_SET);
316 fwrite ((char *) &asfd -> hdr, sizeof (asfd -> hdr), 1, asfd -> fp);
317 }
318
319 /* Write out the annotated form tree. We should already have written out
320 the state data, and noted the file offsets and sizes in each node of
321 the form tree that references part of the state data.
322
323 The form tree can be written anywhere in the file where there is room
324 for it. Since there is always room at the end of the file, we write
325 it there. We also need to record the file offset to the start of the
326 form tree, and it's size, for future use when writing the file header.
327
328 In order to compute the sibling references, we need to know, at
329 each node, how much space will be consumed when all of that node's
330 children nodes have been written. Thus we walk the tree, computing
331 the sizes of the subtrees from the bottom up. At any node, the
332 offset from the start of that node to the start of the sibling node
333 is simply the size of the node plus the size of the subtree rooted
334 in that node. */
335
336 static void
337 write_formtree (asfd)
338 sfd *asfd;
339 {
340 size_subtree (formtree);
341 fseek (asfd -> fp, 0L, SEEK_END);
342 asfd -> hdr.sf_ftoff = ftell (asfd -> fp);
343 write_subtree (formtree, asfd);
344 asfd -> hdr.sf_ftsize = ftell (asfd -> fp) - asfd -> hdr.sf_ftoff;
345 }
346
347 /* Note that we currently only support having one objfile with dumpable
348 state. */
349
350 static void
351 write_objfile_state (asfd)
352 sfd *asfd;
353 {
354 struct objfile *objfile;
355 struct formnode *fnp;
356 PTR base;
357 PTR breakval;
358 long *lp;
359 unsigned int ftesize;
360 long ftebuf[64];
361 long foffset;
362
363 /* First walk through the objfile list looking for the first objfile
364 that is dumpable. */
365
366 for (objfile = object_files; objfile != NULL; objfile = objfile -> next)
367 {
368 if (objfile -> flags & OBJF_DUMPABLE)
369 {
370 break;
371 }
372 }
373
374 if (objfile == NULL)
375 {
376 warning ("no dumpable objfile was found");
377 }
378 else
379 {
380 fnp = alloc_formnode ();
381 lp = ftebuf;
382
383 lp++; /* Skip FTE size slot, filled in at the end. */
384 *lp++ = TAG_objfile; /* This is an objfile FTE */
385 *lp++ = 0; /* Zero the sibling reference slot. */
386
387 /* Build an AT_name attribute for the objfile's name, and write
388 the name into the state data. */
389
390 *lp++ = AT_name;
391 *lp++ = (long) ftell (asfd -> fp);
392 fwrite (objfile -> name, strlen (objfile -> name) + 1, 1, asfd -> fp);
393
394 /* Build an AT_addr attribute for the virtual address to which the
395 objfile data is mapped (and needs to be remapped when read in). */
396
397 base = mmap_base ();
398 *lp++ = AT_addr;
399 *lp++ = (long) base;
400
401 /* Build an AT_aux_addr attribute for the address of the objfile
402 structure itself, within the dumpable data. When we read the objfile
403 back in, we use this address as the pointer the "struct objfile". */
404
405 *lp++ = AT_aux_addr;
406 *lp++ = (long) objfile;
407
408 /* Reposition in state file to next paging boundry so we can mmap the
409 dumpable objfile data when we reload it. */
410
411 foffset = (long) mmap_page_align ((PTR) ftell (asfd -> fp));
412 fseek (asfd -> fp, foffset, SEEK_SET);
413
414 /* Build an AT_offset attribute for the offset in the state file to
415 the start of the dumped objfile data. */
416
417 *lp++ = AT_offset;
418 *lp++ = (long) ftell (asfd -> fp);
419
420 /* Build an AT_size attribute for the size of the dumped objfile data. */
421
422 breakval = mmap_sbrk (0);
423 *lp++ = AT_size;
424 *lp++ = breakval - base;
425
426 /* Write the dumpable data. */
427
428 fwrite ((char *) base, breakval - base, 1, asfd -> fp);
429
430 /* Now finish up the FTE by filling in the size slot based on
431 how much of the ftebuf we have used, allocate some memory for
432 it hung off the form tree node, and copy it there. */
433
434 ftebuf[0] = (lp - ftebuf) * sizeof (ftebuf[0]);
435 fnp -> nodedata = (char *) xmalloc (ftebuf[0]);
436 memcpy (fnp -> nodedata, ftebuf, ftebuf[0]);
437 }
438 }
439
440 static void
441 load_state_command (arg_string, from_tty)
442 char *arg_string;
443 int from_tty;
444 {
445 char *filename;
446 char **argv;
447 FILE *fp;
448 struct cleanup *cleanups;
449
450 dont_repeat ();
451
452 if (arg_string == NULL)
453 {
454 error ("load-state takes a file name and optional state specifiers");
455 }
456 else if ((argv = buildargv (arg_string)) == NULL)
457 {
458 fatal ("virtual memory exhausted.", 0);
459 }
460 cleanups = make_cleanup (freeargv, argv);
461
462 filename = tilde_expand (*argv);
463 make_cleanup (free, filename);
464
465 if ((fp = fopen (filename, "r")) == NULL)
466 {
467 perror_with_name (filename);
468 }
469 make_cleanup (fclose, fp);
470 immediate_quit++;
471
472 while (*++argv != NULL)
473 {
474 if (strcmp (*argv, "symbols") == 0)
475 {
476 if (from_tty
477 && !query ("load symbol table state from file \"%s\"? ",
478 filename))
479 {
480 error ("Not confirmed.");
481 }
482 load_symbols (fp);
483 }
484 else
485 {
486 error ("unknown state specifier '%s'", *argv);
487 }
488 }
489 immediate_quit--;
490 do_cleanups (cleanups);
491 }
492
493 /* ARGSUSED */
494 static void
495 dump_state_command (arg_string, from_tty)
496 char *arg_string;
497 int from_tty;
498 {
499 char *filename;
500 char **argv;
501 sfd *asfd;
502 struct cleanup *cleanups;
503
504 dont_repeat ();
505
506 if (arg_string == NULL)
507 {
508 error ("dump-state takes a file name and state specifiers");
509 }
510 else if ((argv = buildargv (arg_string)) == NULL)
511 {
512 fatal ("virtual memory exhausted.", 0);
513 }
514 cleanups = make_cleanup (freeargv, argv);
515
516 filename = tilde_expand (*argv);
517 make_cleanup (free, filename);
518
519 /* Now attempt to create a fresh state file. */
520
521 if ((asfd = sfd_fopen (filename, "w")) == NULL)
522 {
523 perror_with_name (filename);
524 }
525 make_cleanup (sfd_fclose, asfd);
526 make_cleanup (free_formtree, NULL);
527 immediate_quit++;
528
529 /* Now that we have an open and initialized state file, seek to the
530 proper offset to start writing state data and the process the
531 arguments. For each argument, write the state data and initialize
532 a form-tree node for each piece of state data. */
533
534 fseek (asfd -> fp, sizeof (sf_hdr), SEEK_SET);
535 while (*++argv != NULL)
536 {
537 if (strcmp (*argv, "objfile") == 0)
538 {
539 write_objfile_state (asfd);
540 }
541 else
542 {
543 error ("unknown state specifier '%s'", *argv);
544 }
545
546 }
547
548 /* We have written any state data. All that is left to do now is
549 write the form-tree and the file header. */
550
551 write_formtree (asfd);
552 write_header (asfd);
553
554 immediate_quit--;
555 do_cleanups (cleanups);
556 }
557
558 static char *
559 find_fte_by_walk (thisfte, endfte, tag)
560 char *thisfte;
561 char *endfte;
562 long tag;
563 {
564 char *found = NULL;
565 char *nextfte;
566 long thistag;
567 long thissize;
568 long siboffset;
569
570 while (thisfte < endfte)
571 {
572 if ((thistag = *(long *)(thisfte + sizeof (long))) == tag)
573 {
574 found = thisfte;
575 break;
576 }
577 else
578 {
579 thissize = *(long *)(thisfte);
580 siboffset = *(long *)(thisfte + (2 * sizeof (long)));
581 nextfte = thisfte + (siboffset != 0 ? siboffset : thissize);
582 found = find_fte_by_walk (thisfte + thissize, nextfte, tag);
583 thisfte = nextfte;
584 }
585 }
586 return (found);
587 }
588
589 /* Walk the form-tree looking for a specific FTE type. Returns the first
590 one found that matches the specified tag. */
591
592 static char *
593 find_fte (asfd, tag)
594 sfd *asfd;
595 long tag;
596 {
597 char *ftbase;
598 char *ftend;
599 char *ftep;
600 char *found = NULL;
601
602 if (fseek (asfd -> fp, asfd -> hdr.sf_ftoff, SEEK_SET) == 0)
603 {
604 ftbase = xmalloc (asfd -> hdr.sf_ftsize);
605 ftend = ftbase + asfd -> hdr.sf_ftsize;
606 if (fread (ftbase, asfd -> hdr.sf_ftsize, 1, asfd -> fp) == 1)
607 {
608 ftep = find_fte_by_walk (ftbase, ftend, tag);
609 if (ftep != NULL)
610 {
611 found = xmalloc (*(long *)ftep);
612 memcpy (found, ftep, (int) *(long *)ftep);
613 }
614 }
615 free (ftbase);
616 }
617 return (found);
618 }
619
620 struct objfile *
621 objfile_from_statefile (asfd)
622 sfd *asfd;
623 {
624 struct objfile *objfile = NULL;
625 char *ftep;
626 long *thisattr;
627 long *endattr;
628 PTR base;
629 long foffset;
630 long mapsize;
631
632 ftep = find_fte (asfd, TAG_objfile);
633 thisattr = (long *) (ftep + 3 * sizeof (long));
634 endattr = (long *) (ftep + *(long *)ftep);
635 while (thisattr < endattr)
636 {
637 switch (*thisattr++)
638 {
639 case AT_name:
640 /* Ignore for now */
641 thisattr++;
642 break;
643 case AT_addr:
644 base = (PTR) *thisattr++;
645 break;
646 case AT_aux_addr:
647 objfile = (struct objfile *) *thisattr++;
648 break;
649 case AT_offset:
650 foffset = *thisattr++;
651 break;
652 case AT_size:
653 mapsize = *thisattr++;
654 break;
655 }
656 }
657 if (mmap_remap (base, mapsize, (int) fileno (asfd -> fp), foffset) != base)
658 {
659 print_sys_errmsg (asfd -> filename, errno);
660 error ("mapping failed");
661 }
662
663 return (objfile);
664 }
665
666 #else
667
668 struct objfile *
669 objfile_from_statefile (asfd)
670 sfd *asfd;
671 {
672 error ("this version of gdb doesn't support reloading symtabs from state files");
673 }
674
675 #endif /* HAVE_MMAP */
676
677 /* Close a state file, freeing all memory that was used by the state
678 file descriptor, closing the raw file pointer, etc. */
679
680 void
681 sfd_fclose (asfd)
682 sfd *asfd;
683 {
684 if (asfd != NULL)
685 {
686 if (asfd -> fp != NULL)
687 {
688 fclose (asfd -> fp);
689 }
690 if (asfd -> filename != NULL)
691 {
692 free (asfd -> filename);
693 }
694 free (asfd);
695 }
696 }
697
698 /* Given the name of a possible statefile, and flags to use to open it,
699 try to open the file and prepare it for use.
700
701 If the flags contain 'r', then we want to read an existing state
702 file, so attempt to read in the state file header and determine if this
703 is a valid state file. If not, return NULL.
704
705 Returns a pointer to a properly initialized state file descriptor if
706 successful. */
707
708 sfd *
709 sfd_fopen (name, flags)
710 char *name;
711 char *flags;
712 {
713 int success = 0;
714 sfd *asfd;
715
716 asfd = (sfd *) xmalloc (sizeof (sfd));
717 (void) memset (asfd, 0, sizeof (sfd));
718 asfd -> filename = xmalloc (strlen (name) + 1);
719 (void) strcpy (asfd -> filename, name);
720
721 if ((asfd -> fp = fopen (asfd -> filename, flags)) != NULL)
722 {
723 /* We have the file, now see if we are reading an existing file
724 or writing to a new file. We don't currently support "rw". */
725 if (strchr (flags, 'r') != NULL)
726 {
727 if (fread ((char *) &asfd -> hdr, sizeof (asfd -> hdr), 1,
728 asfd -> fp) == 1)
729 {
730 if (SF_GOOD_MAGIC (asfd))
731 {
732 success = 1;
733 }
734 }
735 }
736 else
737 {
738 /* This is a new state file. Initialize various things. */
739 asfd -> hdr.sf_mag0 = SF_MAG0;
740 asfd -> hdr.sf_mag1 = SF_MAG1;
741 asfd -> hdr.sf_mag2 = SF_MAG2;
742 asfd -> hdr.sf_mag3 = SF_MAG3;
743 success = 1;
744 }
745 }
746
747 if (!success)
748 {
749 sfd_fclose (asfd);
750 asfd = NULL;
751 }
752 return (asfd);
753
754 }
755
756 \f
757 void
758 _initialize_state ()
759 {
760
761 #ifdef HAVE_MMAP
762
763 add_com ("load-state", class_support, load_state_command,
764 "Load some saved gdb state from FILE.\n\
765 Select and load some portion of gdb's saved state from the specified file.\n\
766 The dump-state command may be used to save various portions of gdb's\n\
767 internal state.");
768
769 add_com ("dump-state", class_support, dump_state_command,
770 "Dump some of gdb's state to FILE.\n\
771 Select and dump some portion of gdb's internal state to the specified file.\n\
772 The load-state command may be used to reload various portions of gdb's\n\
773 internal state from the file.");
774
775 #endif /* HAVE_MMAP */
776
777 }
This page took 0.046125 seconds and 5 git commands to generate.