1 /* Work with core dump and executable files, for GDB.
2 Copyright (C) 1986, 1987 Free Software Foundation, Inc.
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.
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.
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!
21 #include "initialize.h"
28 #include <sys/param.h>
33 /* Recognize COFF format systems because a.out.h defines AOUTHDR. */
40 #else /* not NEW_SUN_CORE */
42 #include <sys/ptrace.h>
43 #else /* not UMAX_CORE */
46 #endif /* NEW_SUN_CORE */
49 #define N_TXTADDR(hdr) 0
50 #endif /* no N_TXTADDR */
53 #define N_DATADDR(hdr) hdr.a_text
54 #endif /* no N_DATADDR */
56 /* Make COFF and non-COFF names for things a little more compatible
57 to reduce conditionals later. */
64 #define AOUTHDR struct exec
67 extern char *sys_siglist
[];
71 /* Hook for `exec_file_command' command to call. */
73 void (*exec_file_display_hook
) ();
75 /* File names of core file and executable file. */
77 static char *corefile
;
78 static char *execfile
;
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. */
87 /* Last modification time of executable file.
88 Also used in source.c to compare against mtime of a source file. */
92 /* Virtual addresses of bounds of the two areas of memory in the core file. */
94 static CORE_ADDR data_start
;
95 static CORE_ADDR data_end
;
96 static CORE_ADDR stack_start
;
97 static CORE_ADDR stack_end
;
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. */
102 CORE_ADDR text_start
;
105 static CORE_ADDR exec_data_start
;
106 static CORE_ADDR exec_data_end
;
108 /* Address in executable file of start of text area data. */
110 static int text_offset
;
112 /* Address in executable file of start of data area data. */
114 static int exec_data_offset
;
116 /* Address in core file of start of data area data. */
118 static int data_offset
;
120 /* Address in core file of start of stack area data. */
122 static int stack_offset
;
125 /* various coff data structures */
127 static FILHDR file_hdr
;
128 static SCNHDR text_hdr
;
129 static SCNHDR data_hdr
;
131 #endif /* not COFF_FORMAT */
133 /* a.out header saved in core file. */
135 static AOUTHDR core_aouthdr
;
137 /* a.out header of exec file. */
139 static AOUTHDR exec_aouthdr
;
141 static void validate_files ();
142 unsigned int register_addr ();
144 core_file_command (filename
, from_tty
)
149 extern char registers
[];
151 /* Discard all vestiges of any previous core file
152 and mark data and stack spaces as empty. */
164 stack_start
= STACK_END_ADDR
;
165 stack_end
= STACK_END_ADDR
;
167 /* Now, if a new core file was specified, open it and digest it. */
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);
175 perror_with_name (filename
);
180 val
= myread (corechan
, &corestr
, sizeof corestr
);
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
));
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
;
196 bcopy (&corestr
.c_regs
, registers
, 16 * 4);
197 *(int *)®isters
[REGISTER_BYTE (PS_REGNUM
)] = corestr
.c_regs
.r_ps
;
198 *(int *)®isters
[REGISTER_BYTE (PC_REGNUM
)] = corestr
.c_regs
.r_pc
;
199 bcopy (corestr
.c_fpstatus
.fps_regs
,
200 ®isters
[REGISTER_BYTE (FP0_REGNUM
)],
201 sizeof corestr
.c_fpstatus
.fps_regs
);
202 bcopy (&corestr
.c_fpstatus
.fps_control
,
203 ®isters
[REGISTER_BYTE (FPC_REGNUM
)],
204 sizeof corestr
.c_fpstatus
- sizeof corestr
.c_fpstatus
.fps_regs
);
206 bcopy (&corestr
.c_aouthdr
, &core_aouthdr
, sizeof (struct exec
));
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",
212 corestr
.c_signo
< NSIG
213 ? sys_siglist
[corestr
.c_signo
]
216 #else /* not NEW_SUN_CORE */
217 /* 4.2-style (and perhaps also sysV-style) core dump file. */
220 struct ptrace_user u
;
226 val
= myread (corechan
, &u
, sizeof u
);
228 perror_with_name (filename
);
229 data_start
= exec_data_start
;
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
;
238 bcopy (&u
.pt_aouthdr
, &core_aouthdr
, sizeof (AOUTHDR
));
239 printf ("Core file is from \"%s\".\n", u
.pt_comm
);
241 printf ("Program terminated with signal %d, %s.\n",
244 ? sys_siglist
[u
.pt_signal
]
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
;
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 */
258 /* Read the register values out of the core file and store
259 them where `read_register' will find them. */
264 for (regno
= 0; regno
< NUM_REGS
; regno
++)
266 char buf
[MAX_REGISTER_RAW_SIZE
];
268 val
= lseek (corechan
, register_addr (regno
, reg_offset
), 0);
270 perror_with_name (filename
);
272 val
= myread (corechan
, buf
, sizeof buf
);
274 perror_with_name (filename
);
275 supply_register (regno
, buf
);
279 #endif /* not NEW_SUN_CORE */
280 if (filename
[0] == '/')
281 corefile
= savestring (filename
, strlen (filename
));
284 corefile
= concat (current_directory
, "/", filename
);
287 set_current_frame (read_register (FP_REGNUM
));
288 select_frame (get_current_frame (), 0);
292 printf ("No core file now.\n");
295 exec_file_command (filename
, from_tty
)
301 /* Eliminate all traces of old exec file.
302 Mark text segment as empty. */
308 data_end
-= exec_data_start
;
317 /* Now open and digest the file the user requested, if any. */
321 execchan
= openp (getenv ("PATH"), 1, filename
, O_RDONLY
, 0,
324 perror_with_name (filename
);
331 if (read_file_hdr (execchan
, &file_hdr
) < 0)
332 error ("\"%s\": not in executable format.", execfile
);
334 aout_hdrsize
= file_hdr
.f_opthdr
;
335 num_sections
= file_hdr
.f_nscns
;
337 if (read_aout_hdr (execchan
, &exec_aouthdr
, aout_hdrsize
) < 0)
338 error ("\"%s\": can't read optional aouthdr", execfile
);
340 if (read_section_hdr (execchan
, _TEXT
, &text_hdr
, num_sections
) < 0)
341 error ("\"%s\": can't read text section header", execfile
);
343 if (read_section_hdr (execchan
, _DATA
, &data_hdr
, num_sections
) < 0)
344 error ("\"%s\": can't read data section header", execfile
);
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
;
356 #else /* not COFF_FORMAT */
360 val
= myread (execchan
, &exec_aouthdr
, sizeof (AOUTHDR
));
363 perror_with_name (filename
);
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
;
374 fstat (execchan
, &st_exec
);
375 exec_mtime
= st_exec
.st_mtime
;
377 #endif /* not COFF_FORMAT */
382 printf ("No exec file now.\n");
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");
390 /* Call this to specify the hook for exec_file_command to call back.
391 This is called from the x-window display code. */
393 specify_exec_file_hook (hook
)
396 exec_file_display_hook
= hook
;
399 /* The exec file must be closed before running an inferior.
400 If it is needed again after the inferior dies, it must
412 if (execchan
< 0 && execfile
!= 0)
414 char *filename
= concat (execfile
, "", "");
415 exec_file_command (filename
, 0);
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. */
428 if (execfile
!= 0 && corefile
!= 0)
432 fstat (corechan
, &st_core
);
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");
446 error ("No executable file specified.\n\
447 Use the \"exec-file\" and \"symbol-file\" commands.");
454 return corefile
!= 0;
461 extern char *get_sym_file ();
464 printf ("Executable file \"%s\".\n", execfile
);
466 printf ("No executable file\n");
468 printf ("No core dump file\n");
470 printf ("Core dump file \"%s\".\n", corefile
);
472 if (have_inferior_p ())
473 printf ("Using the running image of the program, rather than these files.\n");
475 symfile
= get_sym_file ();
477 printf ("Symbols loaded from \"%s\".\n", symfile
);
479 if (! have_inferior_p ())
483 printf ("Text segment from 0x%x to 0x%x.\n",
484 text_start
, text_end
);
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
);
493 printf ("Data segment in executable from 0x%x to 0x%x.\n",
494 exec_data_start
, exec_data_end
);
499 /* Read "memory data" from core file and/or executable file */
501 read_memory (memaddr
, myaddr
, len
)
506 if (have_inferior_p ())
507 read_inferior_memory (memaddr
, myaddr
, len
);
509 xfer_core_file (memaddr
, myaddr
, len
, 0);
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. */
517 write_memory (memaddr
, myaddr
, len
)
522 if (have_inferior_p ())
523 return write_inferior_memory (memaddr
, myaddr
, len
);
525 error ("Can write memory only when program being debugged is running.");
528 xfer_core_file (memaddr
, myaddr
, len
)
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. */
552 if (memaddr
< text_start
)
554 i
= min (len
, text_start
- memaddr
);
556 else if (memaddr
>= text_end
&& memaddr
< data_start
)
558 i
= min (len
, data_start
- memaddr
);
560 else if (memaddr
>= (corechan
>= 0 ? data_end
: exec_data_end
)
561 && memaddr
< stack_start
)
563 i
= min (len
, stack_start
- memaddr
);
565 else if (memaddr
>= stack_end
&& stack_end
!= 0)
567 i
= min (len
, - memaddr
);
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
)
573 i
= min (len
, data_end
- memaddr
);
574 fileptr
= memaddr
- data_start
+ data_offset
;
575 xferfile
= &corefile
;
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
)
582 i
= min (len
, stack_end
- memaddr
);
583 fileptr
= memaddr
- stack_start
+ stack_offset
;
584 xferfile
= &corefile
;
587 else if (corechan
< 0
588 && memaddr
>= exec_data_start
&& memaddr
< exec_data_end
)
590 i
= min (len
, exec_data_end
- memaddr
);
591 fileptr
= memaddr
- exec_data_start
+ exec_data_offset
;
592 xferfile
= &execfile
;
595 else if (memaddr
>= text_start
&& memaddr
< text_end
)
597 i
= min (len
, text_end
- memaddr
);
598 fileptr
= memaddr
- text_start
+ text_offset
;
599 xferfile
= &execfile
;
603 /* Now we know which file to use.
604 Set up its pointer and transfer the data. */
608 if (xferfile
== &execfile
)
609 error ("No program file to examine.");
611 error ("No core dump file or running program to examine.");
612 val
= lseek (xferchan
, fileptr
, 0);
614 perror_with_name (*xferfile
);
615 val
= myread (xferchan
, myaddr
, i
);
617 perror_with_name (*xferfile
);
619 /* If this address is for nonexistent memory,
620 read zeros if reading, or do nothing if writing. */
630 /* My replacement for the read system call.
631 Used like `read' but keeps going if `read' returns too soon. */
633 myread (desc
, addr
, len
)
643 val
= read (desc
, addr
, len
);
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. */
659 register_addr (regno
, blockend
)
665 if (regno
< 0 || regno
>= NUM_REGS
)
666 error ("Invalid register number %d.", regno
);
668 REGISTER_U_ADDR (addr
, blockend
, regno
);
673 #endif /* not NEW_SUN_CORE */
682 exec_file_display_hook
= 0;
690 stack_start
= STACK_END_ADDR
;
691 stack_end
= STACK_END_ADDR
;
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.");