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