]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/RCS/core.c,v
gdb-2.4+.aux.coff
[thirdparty/binutils-gdb.git] / gdb / RCS / core.c,v
1 head 1.2;
2 access ;
3 symbols RMS-has:1.2;
4 locks ; strict;
5 comment @ * @;
6
7
8 1.2
9 date 88.01.26.05.04.52; author gnu; state Exp;
10 branches ;
11 next 1.1;
12
13 1.1
14 date 88.01.21.05.04.03; author gnu; state Exp;
15 branches ;
16 next ;
17
18
19 desc
20 @From RMS's development version on wheaties, 20Jan88
21 @
22
23
24 1.2
25 log
26 @Hacks to get it to compile on a/ux. Needs work at finding the registers
27 in a core file.
28 @
29 text
30 @/* Work with core dump and executable files, for GDB.
31 Copyright (C) 1986, 1987 Free Software Foundation, Inc.
32
33 GDB is distributed in the hope that it will be useful, but WITHOUT ANY
34 WARRANTY. No author or distributor accepts responsibility to anyone
35 for the consequences of using it or for whether it serves any
36 particular purpose or works at all, unless he says so in writing.
37 Refer to the GDB General Public License for full details.
38
39 Everyone is granted permission to copy, modify and redistribute GDB,
40 but only under the conditions described in the GDB General Public
41 License. A copy of this license is supposed to have been given to you
42 along with GDB so you can know your rights and responsibilities. It
43 should be in a file named COPYING. Among other things, the copyright
44 notice and this notice must be preserved on all copies.
45
46 In other words, go ahead and share GDB, but don't try to stop
47 anyone else from sharing it farther. Help stamp out software hoarding!
48 */
49
50 #include "initialize.h"
51 #include "defs.h"
52 #include "param.h"
53
54 #include <a.out.h>
55 #include <stdio.h>
56 #include <sys/types.h>
57 #include <sys/param.h>
58 #include <sys/dir.h>
59 #include <sys/file.h>
60 #include <sys/stat.h>
61
62 /* Recognize COFF format systems because a.out.h defines AOUTHDR. */
63 #ifdef AOUTHDR
64 #define COFF_FORMAT
65 #endif
66
67 #ifdef NEW_SUN_CORE
68 #include <sys/core.h>
69 #else /* not NEW_SUN_CORE */
70 #ifdef UMAX_CORE
71 #include <sys/ptrace.h>
72 #else /* not UMAX_CORE */
73 #ifdef mac_aux
74 #include <sys/seg.h>
75 #include <sys/mmu.h>
76 #include <sys/signal.h>
77 #include <sys/time.h>
78 #include <sys/user.h>
79 #else
80 #include <sys/user.h>
81 #endif /* mac_aux */
82 #endif /* UMAX_CORE */
83 #endif /* NEW_SUN_CORE */
84
85 #ifndef N_TXTADDR
86 #define N_TXTADDR(hdr) 0
87 #endif /* no N_TXTADDR */
88
89 #ifndef N_DATADDR
90 #define N_DATADDR(hdr) hdr.a_text
91 #endif /* no N_DATADDR */
92
93 /* Make COFF and non-COFF names for things a little more compatible
94 to reduce conditionals later. */
95
96 #ifdef COFF_FORMAT
97 #define a_magic magic
98 #endif
99
100 #ifndef COFF_FORMAT
101 #define AOUTHDR struct exec
102 #endif
103
104 START_FILE
105
106 /* Hook for `exec_file_command' command to call. */
107
108 void (*exec_file_display_hook) ();
109
110 /* File names of core file and executable file. */
111
112 static char *corefile;
113 static char *execfile;
114
115 /* Descriptors on which core file and executable file are open.
116 Note that the execchan is closed when an inferior is created
117 and reopened if the inferior dies or is killed. */
118
119 static int corechan;
120 static int execchan;
121
122 /* Last modification time of executable file.
123 Also used in source.c to compare against mtime of a source file. */
124
125 int exec_mtime;
126
127 /* Virtual addresses of bounds of the two areas of memory in the core file. */
128
129 static CORE_ADDR data_start;
130 static CORE_ADDR data_end;
131 static CORE_ADDR stack_start;
132 static CORE_ADDR stack_end;
133
134 /* Virtual addresses of bounds of two areas of memory in the exec file.
135 Note that the data area in the exec file is used only when there is no core file. */
136
137 static CORE_ADDR text_start;
138 static CORE_ADDR text_end;
139 static CORE_ADDR exec_data_start;
140 static CORE_ADDR exec_data_end;
141
142 /* Address in executable file of start of text area data. */
143
144 static int text_offset;
145
146 /* Address in executable file of start of data area data. */
147
148 static int exec_data_offset;
149
150 /* Address in core file of start of data area data. */
151
152 static int data_offset;
153
154 /* Address in core file of start of stack area data. */
155
156 static int stack_offset;
157
158 #ifdef COFF_FORMAT
159 /* various coff data structures */
160
161 static FILHDR file_hdr;
162 static SCNHDR text_hdr;
163 static SCNHDR data_hdr;
164
165 #endif /* not COFF_FORMAT */
166
167 /* a.out header saved in core file. */
168
169 static AOUTHDR core_aouthdr;
170
171 /* a.out header of exec file. */
172
173 static AOUTHDR exec_aouthdr;
174
175 static void validate_files ();
176 unsigned int register_addr ();
177 \f
178 core_file_command (filename, from_tty)
179 char *filename;
180 int from_tty;
181 {
182 int val;
183 extern char registers[];
184
185 /* Discard all vestiges of any previous core file
186 and mark data and stack spaces as empty. */
187
188 if (corefile)
189 free (corefile);
190 corefile = 0;
191
192 if (corechan >= 0)
193 close (corechan);
194 corechan = -1;
195
196 data_start = 0;
197 data_end = 0;
198 stack_start = STACK_END_ADDR;
199 stack_end = STACK_END_ADDR;
200
201 /* Now, if a new core file was specified, open it and digest it. */
202
203 if (filename)
204 {
205 if (have_inferior_p ())
206 error ("To look at a core file, you must kill the inferior with \"kill\".");
207 corechan = open (filename, O_RDONLY, 0);
208 if (corechan < 0)
209 perror_with_name (filename);
210 #ifdef NEW_SUN_CORE
211 {
212 struct core corestr;
213
214 val = myread (corechan, &corestr, sizeof corestr);
215 if (val < 0)
216 perror_with_name (filename);
217 if (corestr.c_magic != CORE_MAGIC)
218 error ("\"%s\" does not appear to be a core dump file (magic 0x%x, expected 0x%x)",
219 filename, corestr.c_magic, (int) CORE_MAGIC);
220 else if (sizeof (struct core) != corestr.c_len)
221 error ("\"%s\" has an invalid struct core length (%d, expected %d)",
222 filename, corestr.c_len, (int) sizeof (struct core));
223
224 data_start = exec_data_start;
225 data_end = data_start + corestr.c_dsize;
226 stack_start = stack_end - corestr.c_ssize;
227 data_offset = sizeof corestr;
228 stack_offset = sizeof corestr + corestr.c_dsize;
229
230 bcopy (&corestr.c_regs, registers, 16 * 4);
231 *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = corestr.c_regs.r_ps;
232 *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = corestr.c_regs.r_pc;
233 bcopy (corestr.c_fpstatus.fps_regs,
234 &registers[REGISTER_BYTE (FP0_REGNUM)],
235 sizeof corestr.c_fpstatus.fps_regs);
236 bcopy (&corestr.c_fpstatus.fps_control,
237 &registers[REGISTER_BYTE (FPC_REGNUM)],
238 sizeof corestr.c_fpstatus - sizeof corestr.c_fpstatus.fps_regs);
239
240 bcopy (&corestr.c_aouthdr, &core_aouthdr, sizeof (struct exec));
241
242 printf ("Core file is from \"%s\".\n", corestr.c_cmdname);
243 }
244 #else /* not NEW_SUN_CORE */
245 /* 4.2-style (and perhaps also sysV-style) core dump file. */
246 {
247 #ifdef UMAX_CORE
248 struct ptrace_user u;
249 #else
250 struct user u;
251 #endif
252 int reg_offset;
253
254 val = myread (corechan, &u, sizeof u);
255 if (val < 0)
256 perror_with_name (filename);
257 data_start = exec_data_start;
258
259 #ifdef UMAX_CORE
260 data_end = data_start + u.pt_dsize;
261 stack_start = stack_end - u.pt_ssize;
262 data_offset = sizeof u;
263 stack_offset = data_offset + u.pt_dsize;
264 reg_offset = 0;
265
266 bcopy (&u.pt_aouthdr, &core_aouthdr, sizeof (AOUTHDR));
267
268 #else /* not UMAX_CORE */
269 #ifdef mac_aux
270 /* This may well not work for 0407 (nonshared text) a.out's */
271 data_end = data_start + u.u_dsize << PAGESHIFT;
272 stack_start = stack_end - u.u_ssize << PAGESHIFT;
273 data_offset = USIZE;
274 stack_offset = USIZE + u.u_dsize << PAGESHIFT;
275 reg_offset = (int) &u.u_ar0[0] - (int) &u;
276
277 core_aouthdr.a_magic = u.u_exdata.ux_mag;
278 #else
279 data_end = data_start + NBPG * u.u_dsize;
280 stack_start = stack_end - NBPG * u.u_ssize;
281 data_offset = NBPG * UPAGES;
282 stack_offset = NBPG * (UPAGES + u.u_dsize);
283 reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR;
284
285 /* I don't know where to find this info.
286 So, for now, mark it as not available. */
287 core_aouthdr.a_magic = 0;
288 #endif /* not mac_aux */
289 #endif /* not UMAX_CORE */
290
291 /* Read the register values out of the core file and store
292 them where `read_register' will find them. */
293
294 {
295 register int regno;
296
297 for (regno = 0; regno < NUM_REGS; regno++)
298 {
299 char buf[MAX_REGISTER_RAW_SIZE];
300
301 val = lseek (corechan, register_addr (regno, reg_offset), 0);
302 if (val < 0)
303 perror_with_name (filename);
304
305 val = myread (corechan, buf, sizeof buf);
306 if (val < 0)
307 perror_with_name (filename);
308 supply_register (regno, buf);
309 }
310 }
311 }
312 #endif /* not NEW_SUN_CORE */
313 if (filename[0] == '/')
314 corefile = savestring (filename, strlen (filename));
315 else
316 {
317 char dirname[MAXPATHLEN];
318
319 getwd (dirname);
320 corefile = concat (dirname, "/", filename);
321 }
322
323 set_current_frame (read_register (FP_REGNUM));
324 select_frame (get_current_frame (), 0);
325 validate_files ();
326 }
327 else if (from_tty)
328 printf ("No core file now.\n");
329 }
330 \f
331 exec_file_command (filename, from_tty)
332 char *filename;
333 int from_tty;
334 {
335 int val;
336
337 /* Eliminate all traces of old exec file.
338 Mark text segment as empty. */
339
340 if (execfile)
341 free (execfile);
342 execfile = 0;
343 data_start = 0;
344 data_end -= exec_data_start;
345 text_start = 0;
346 text_end = 0;
347 exec_data_start = 0;
348 exec_data_end = 0;
349 if (execchan >= 0)
350 close (execchan);
351 execchan = -1;
352
353 /* Now open and digest the file the user requested, if any. */
354
355 if (filename)
356 {
357 execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
358 &execfile);
359 if (execchan < 0)
360 perror_with_name (filename);
361
362 #ifdef COFF_FORMAT
363 {
364 int aout_hdrsize;
365 int num_sections;
366
367 if (read_file_hdr (execchan, &file_hdr) < 0)
368 error ("\"%s\": not in executable format.", execfile);
369
370 aout_hdrsize = file_hdr.f_opthdr;
371 num_sections = file_hdr.f_nscns;
372
373 if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0)
374 error ("\"%s\": can't read optional aouthdr", execfile);
375
376 if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections) < 0)
377 error ("\"%s\": can't read text section header", execfile);
378
379 if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
380 error ("\"%s\": can't read data section header", execfile);
381
382 text_start = exec_aouthdr.text_start;
383 text_end = text_start + exec_aouthdr.tsize;
384 text_offset = text_hdr.s_scnptr;
385 exec_data_start = exec_aouthdr.data_start;
386 exec_data_end = exec_data_start + exec_aouthdr.dsize;
387 exec_data_offset = data_hdr.s_scnptr;
388 data_start = exec_data_start;
389 data_end += exec_data_start;
390 exec_mtime = file_hdr.f_timdat;
391 }
392 #else /* not COFF_FORMAT */
393 {
394 struct stat st_exec;
395
396 val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR));
397
398 if (val < 0)
399 perror_with_name (filename);
400
401 text_start = N_TXTADDR (exec_aouthdr);
402 text_end = text_start + exec_aouthdr.a_text;
403 text_offset = N_TXTOFF (exec_aouthdr);
404 exec_data_start = N_DATADDR (exec_aouthdr);
405 exec_data_end = exec_data_start + exec_aouthdr.a_data;
406 exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
407 data_start = exec_data_start;
408 data_end += exec_data_start;
409
410 fstat (execchan, &st_exec);
411 exec_mtime = st_exec.st_mtime;
412 }
413 #endif /* not COFF_FORMAT */
414
415 validate_files ();
416 }
417 else if (from_tty)
418 printf ("No exec file now.\n");
419
420 /* Tell display code (if any) about the changed file name. */
421 if (exec_file_display_hook)
422 (*exec_file_display_hook)
423 (filename ? filename : "No executable specified.\n");
424 }
425
426 /* Call this to specify the hook for exec_file_command to call back.
427 This is called from the x-window display code. */
428
429 specify_exec_file_hook (hook)
430 void (*hook) ();
431 {
432 exec_file_display_hook = hook;
433 }
434
435 /* The exec file must be closed before running an inferior.
436 If it is needed again after the inferior dies, it must
437 be reopened. */
438
439 close_exec_file ()
440 {
441 if (execchan >= 0)
442 close (execchan);
443 execchan = -1;
444 }
445
446 reopen_exec_file ()
447 {
448 if (execchan < 0 && execfile != 0)
449 {
450 char *filename = concat (execfile, "", "");
451 exec_file_command (filename, 0);
452 free (filename);
453 }
454 }
455 \f
456 /* If we have both a core file and an exec file,
457 print a warning if they don't go together.
458 This should really check that the core file came
459 from that exec file, but I don't know how to do it. */
460
461 static void
462 validate_files ()
463 {
464 if (execfile != 0 && corefile != 0)
465 {
466 struct stat st_core;
467
468 fstat (corechan, &st_core);
469
470 if (core_aouthdr.a_magic != 0
471 && bcmp (&core_aouthdr, &exec_aouthdr, sizeof core_aouthdr))
472 printf ("Warning: core file does not match specified executable file.\n");
473 else if (exec_mtime > st_core.st_mtime)
474 printf ("Warning: exec file is newer than core file.\n");
475 }
476 }
477
478 char *
479 get_exec_file ()
480 {
481 if (execfile == 0)
482 error ("No executable file specified.\n\
483 Use the \"exec-file\" and \"symbol-file\" commands.");
484 return execfile;
485 }
486
487 int
488 have_core_file_p ()
489 {
490 return corefile != 0;
491 }
492
493 static void
494 files_info ()
495 {
496 char *symfile;
497 extern char *get_sym_file ();
498
499 if (execfile)
500 printf ("Executable file \"%s\".\n", execfile);
501 else
502 printf ("No executable file\n");
503 if (corefile == 0)
504 printf ("No core dump file\n");
505 else
506 printf ("Core dump file \"%s\".\n", corefile);
507
508 if (have_inferior_p ())
509 printf ("Using the running image of the program, rather than these files.\n");
510
511 symfile = get_sym_file ();
512 if (symfile != 0)
513 printf ("Symbols loaded from \"%s\".\n", symfile);
514
515 if (! have_inferior_p ())
516 {
517 if (execfile)
518 {
519 printf ("Text segment from 0x%x to 0x%x.\n",
520 text_start, text_end);
521 }
522 if (corefile)
523 {
524 printf ("Data segment from 0x%x to 0x%x.\nStack segment from 0x%x to 0x%x.\n",
525 data_start, data_end, stack_start, stack_end);
526 }
527 else
528 {
529 printf ("Data segment in executable from 0x%x to 0x%x.\n",
530 exec_data_start, exec_data_end);
531 }
532 }
533 }
534 \f
535 /* Read "memory data" from core file and/or executable file */
536
537 read_memory (memaddr, myaddr, len)
538 CORE_ADDR memaddr;
539 char *myaddr;
540 int len;
541 {
542 if (have_inferior_p ())
543 read_inferior_memory (memaddr, myaddr, len);
544 else
545 xfer_core_file (memaddr, myaddr, len, 0);
546 }
547
548 /* Write LEN bytes of data starting at address MYADDR
549 into debugged program memory at address MEMADDR.
550 Returns zero if successful, or an errno value if ptrace failed. */
551
552 int
553 write_memory (memaddr, myaddr, len)
554 CORE_ADDR memaddr;
555 char *myaddr;
556 int len;
557 {
558 if (have_inferior_p ())
559 return write_inferior_memory (memaddr, myaddr, len);
560 else
561 error ("Can write memory only when program being debugged is running.");
562 }
563
564 xfer_core_file (memaddr, myaddr, len)
565 CORE_ADDR memaddr;
566 char *myaddr;
567 int len;
568 {
569 register int i;
570 register int val;
571 int xferchan;
572 char **xferfile;
573 int fileptr;
574
575 while (len > 0)
576 {
577 xferfile = 0;
578 xferchan = 0;
579
580 /* Determine which file the next bunch of addresses reside in,
581 and where in the file. Set the file's read/write pointer
582 to point at the proper place for the desired address
583 and set xferfile and xferchan for the correct file.
584 If desired address is nonexistent, leave them zero.
585 i is set to the number of bytes that can be handled
586 along with the next address. */
587
588 if (memaddr < text_start)
589 {
590 i = min (len, text_start - memaddr);
591 }
592 else if (memaddr >= text_end && memaddr < data_start)
593 {
594 i = min (len, data_start - memaddr);
595 }
596 else if (memaddr >= (corechan >= 0 ? data_end : exec_data_end)
597 && memaddr < stack_start)
598 {
599 i = min (len, stack_start - memaddr);
600 }
601 else if (memaddr >= stack_end && stack_end != 0)
602 {
603 i = min (len, - memaddr);
604 }
605 /* Note that if there is no core file
606 data_start and data_end are equal. */
607 else if (memaddr >= data_start && memaddr < data_end)
608 {
609 i = min (len, data_end - memaddr);
610 fileptr = memaddr - data_start + data_offset;
611 xferfile = &corefile;
612 xferchan = corechan;
613 }
614 /* Note that if there is no core file
615 stack_start and stack_end are equal. */
616 else if (memaddr >= stack_start && memaddr < stack_end)
617 {
618 i = min (len, stack_end - memaddr);
619 fileptr = memaddr - stack_start + stack_offset;
620 xferfile = &corefile;
621 xferchan = corechan;
622 }
623 else if (corechan < 0
624 && memaddr >= exec_data_start && memaddr < exec_data_end)
625 {
626 i = min (len, exec_data_end - memaddr);
627 fileptr = memaddr - exec_data_start + exec_data_offset;
628 xferfile = &execfile;
629 xferchan = execchan;
630 }
631 else if (memaddr >= text_start && memaddr < text_end)
632 {
633 i = min (len, text_end - memaddr);
634 fileptr = memaddr - text_start + text_offset;
635 xferfile = &execfile;
636 xferchan = execchan;
637 }
638
639 /* Now we know which file to use.
640 Set up its pointer and transfer the data. */
641 if (xferfile)
642 {
643 if (*xferfile == 0)
644 if (xferfile == &execfile)
645 error ("No program file to examine.");
646 else
647 error ("No core dump file or running program to examine.");
648 val = lseek (xferchan, fileptr, 0);
649 if (val < 0)
650 perror_with_name (*xferfile);
651 val = myread (xferchan, myaddr, i);
652 if (val < 0)
653 perror_with_name (*xferfile);
654 }
655 /* If this address is for nonexistent memory,
656 read zeros if reading, or do nothing if writing. */
657 else
658 bzero (myaddr, i);
659
660 memaddr += i;
661 myaddr += i;
662 len -= i;
663 }
664 }
665 \f
666 /* My replacement for the read system call.
667 Used like `read' but keeps going if `read' returns too soon. */
668
669 myread (desc, addr, len)
670 int desc;
671 char *addr;
672 int len;
673 {
674 register int val;
675 int orglen = len;
676
677 while (len > 0)
678 {
679 val = read (desc, addr, len);
680 if (val < 0)
681 return val;
682 if (val == 0)
683 return orglen - len;
684 len -= val;
685 addr += val;
686 }
687 }
688 \f
689 #ifndef NEW_SUN_CORE
690
691 /* Return the address in the core dump or inferior of register REGNO.
692 BLOCKEND is the address of the end of the user structure. */
693
694 unsigned int
695 register_addr (regno, blockend)
696 int regno;
697 int blockend;
698 {
699 int addr;
700
701 if (regno < 0 || regno >= NUM_REGS)
702 error ("Invalid register number %d.", regno);
703
704 #ifdef mac_aux
705 /* FIXME, we don't know where the regs are. Maybe the test command
706 * that tests what parts of the upage are writeable will find 'em for us.
707 */
708 #define REGISTER_U_ADDR(addr, foo, bar) addr = 0;
709 #endif
710 REGISTER_U_ADDR (addr, blockend, regno);
711
712 return addr;
713 }
714
715 #endif /* not NEW_SUN_CORE */
716 \f
717 static
718 initialize ()
719 {
720 corechan = -1;
721 execchan = -1;
722 corefile = 0;
723 execfile = 0;
724 exec_file_display_hook = 0;
725
726 text_start = 0;
727 text_end = 0;
728 data_start = 0;
729 data_end = 0;
730 exec_data_start = 0;
731 exec_data_end = 0;
732 stack_start = STACK_END_ADDR;
733 stack_end = STACK_END_ADDR;
734
735 add_com ("core-file", class_files, core_file_command,
736 "Use FILE as core dump for examining memory and registers.\n\
737 No arg means have no core file.");
738 add_com ("exec-file", class_files, exec_file_command,
739 "Use FILE as program for getting contents of pure memory.\n\
740 If FILE cannot be found as specified, your execution directory path\n\
741 is searched for a command of that name.\n\
742 No arg means have no executable file.");
743 add_info ("files", files_info, "Names of files being debugged.");
744 }
745
746 END_FILE
747 @
748
749
750 1.1
751 log
752 @Initial revision
753 @
754 text
755 @d27 1
756 d44 5
757 d50 4
758 a53 1
759 #endif
760 d240 10
761 d259 1
762 d675 6
763 @