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