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