1 /* Work with core dump and executable files, for GDB.
2 Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
4 This file is part of GDB.
6 GDB is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
11 GDB is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GDB; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
22 #include "frame.h" /* required by inferior.h */
26 #include <sys/types.h>
30 #ifdef COFF_ENCAPSULATE
31 #include "a.out.encap.h"
37 #define N_MAGIC(exec) ((exec).magic)
39 #define N_MAGIC(exec) ((exec).a_magic)
44 #include <sys/param.h>
50 #include <sys/ptrace.h>
56 #define N_TXTADDR(hdr) 0
57 #endif /* no N_TXTADDR */
60 #define N_DATADDR(hdr) hdr.a_text
61 #endif /* no N_DATADDR */
65 #define AOUTHDR struct exec
69 extern char *sys_siglist
[];
71 extern core_file_command (), exec_file_command ();
73 /* Hook for `exec_file_command' command to call. */
75 void (*exec_file_display_hook
) ();
77 /* File names of core file and executable file. */
82 /* Descriptors on which core file and executable file are open.
83 Note that the execchan is closed when an inferior is created
84 and reopened if the inferior dies or is killed. */
89 /* Last modification time of executable file.
90 Also used in source.c to compare against mtime of a source file. */
94 /* Virtual addresses of bounds of the two areas of memory in the core file. */
98 CORE_ADDR stack_start
;
101 /* Virtual addresses of bounds of two areas of memory in the exec file.
102 Note that the data area in the exec file is used only when there is no core file. */
104 CORE_ADDR text_start
;
107 CORE_ADDR exec_data_start
;
108 CORE_ADDR exec_data_end
;
110 /* Offset within executable file of start of text area data. */
114 /* Offset within executable file of start of data area data. */
116 int exec_data_offset
;
118 /* Offset within core file of start of data area data. */
122 /* Offset within core file of start of stack area data. */
127 /* various coff data structures */
133 #endif /* not COFF_FORMAT */
135 /* a.out header saved in core file. */
137 AOUTHDR core_aouthdr
;
139 /* a.out header of exec file. */
141 AOUTHDR exec_aouthdr
;
143 void validate_files ();
144 unsigned int register_addr ();
146 /* Call this to specify the hook for exec_file_command to call back.
147 This is called from the x-window display code. */
150 specify_exec_file_hook (hook
)
153 exec_file_display_hook
= hook
;
156 /* The exec file must be closed before running an inferior.
157 If it is needed again after the inferior dies, it must
171 if (execchan
< 0 && execfile
!= 0)
173 char *filename
= concat (execfile
, "", "");
174 exec_file_command (filename
, 0);
179 /* If we have both a core file and an exec file,
180 print a warning if they don't go together.
181 This should really check that the core file came
182 from that exec file, but I don't know how to do it. */
187 if (execfile
!= 0 && corefile
!= 0)
191 fstat (corechan
, &st_core
);
193 if (N_MAGIC (core_aouthdr
) != 0
194 && bcmp (&core_aouthdr
, &exec_aouthdr
, sizeof core_aouthdr
))
195 printf ("Warning: core file does not match specified executable file.\n");
196 else if (exec_mtime
> st_core
.st_mtime
)
197 printf ("Warning: exec file is newer than core file.\n");
201 /* Return the name of the executable file as a string.
202 ERR nonzero means get error if there is none specified;
203 otherwise return 0 in that case. */
209 if (err
&& execfile
== 0)
210 error ("No executable file specified.\n\
211 Use the \"exec-file\" and \"symbol-file\" commands.");
218 return corefile
!= 0;
225 extern char *get_sym_file ();
228 printf ("Executable file \"%s\".\n", execfile
);
230 printf ("No executable file\n");
232 printf ("No core dump file\n");
234 printf ("Core dump file \"%s\".\n", corefile
);
236 if (have_inferior_p ())
237 printf ("Using the running image of the program, rather than these files.\n");
239 symfile
= get_sym_file ();
241 printf ("Symbols from \"%s\".\n", symfile
);
243 #ifdef FILES_INFO_HOOK
244 if (FILES_INFO_HOOK ())
248 if (! have_inferior_p ())
252 printf ("Text segment in executable from 0x%x to 0x%x.\n",
253 text_start
, text_end
);
254 printf ("Data segment in executable from 0x%x to 0x%x.\n",
255 exec_data_start
, exec_data_end
);
257 printf ("(But since we have a core file, we're using...)\n");
261 printf ("Data segment in core file from 0x%x to 0x%x.\n",
262 data_start
, data_end
);
263 printf ("Stack segment in core file from 0x%x to 0x%x.\n",
264 stack_start
, stack_end
);
269 /* Read "memory data" from core file and/or executable file.
270 Returns zero if successful, 1 if xfer_core_file failed, errno value if
274 read_memory (memaddr
, myaddr
, len
)
282 if (have_inferior_p ())
284 if (remote_debugging
)
285 return remote_read_inferior_memory (memaddr
, myaddr
, len
);
287 return read_inferior_memory (memaddr
, myaddr
, len
);
290 return xfer_core_file (memaddr
, myaddr
, len
);
293 /* Write LEN bytes of data starting at address MYADDR
294 into debugged program memory at address MEMADDR.
295 Returns zero if successful, or an errno value if ptrace failed. */
298 write_memory (memaddr
, myaddr
, len
)
303 if (have_inferior_p ())
305 if (remote_debugging
)
306 return remote_write_inferior_memory (memaddr
, myaddr
, len
);
308 return write_inferior_memory (memaddr
, myaddr
, len
);
311 error ("Can write memory only when program being debugged is running.");
314 #ifndef XFER_CORE_FILE
315 /* Read from the program's memory (except for inferior processes).
316 This function is misnamed, since it only reads, never writes; and
317 since it will use the core file and/or executable file as necessary.
319 It should be extended to write as well as read, FIXME, for patching files.
321 Return 0 if address could be read, 1 if not. */
324 xfer_core_file (memaddr
, myaddr
, len
)
341 /* Determine which file the next bunch of addresses reside in,
342 and where in the file. Set the file's read/write pointer
343 to point at the proper place for the desired address
344 and set xferfile and xferchan for the correct file.
346 If desired address is nonexistent, leave them zero.
348 i is set to the number of bytes that can be handled
349 along with the next address.
351 We put the most likely tests first for efficiency. */
353 /* Note that if there is no core file
354 data_start and data_end are equal. */
355 if (memaddr
>= data_start
&& memaddr
< data_end
)
357 i
= min (len
, data_end
- memaddr
);
358 fileptr
= memaddr
- data_start
+ data_offset
;
359 xferfile
= &corefile
;
362 /* Note that if there is no core file
363 stack_start and stack_end are equal. */
364 else if (memaddr
>= stack_start
&& memaddr
< stack_end
)
366 i
= min (len
, stack_end
- memaddr
);
367 fileptr
= memaddr
- stack_start
+ stack_offset
;
368 xferfile
= &corefile
;
371 else if (corechan
< 0
372 && memaddr
>= exec_data_start
&& memaddr
< exec_data_end
)
374 i
= min (len
, exec_data_end
- memaddr
);
375 fileptr
= memaddr
- exec_data_start
+ exec_data_offset
;
376 xferfile
= &execfile
;
379 else if (memaddr
>= text_start
&& memaddr
< text_end
)
381 i
= min (len
, text_end
- memaddr
);
382 fileptr
= memaddr
- text_start
+ text_offset
;
383 xferfile
= &execfile
;
386 else if (memaddr
< text_start
)
388 i
= min (len
, text_start
- memaddr
);
390 else if (memaddr
>= text_end
391 && memaddr
< (corechan
>= 0? data_start
: exec_data_start
))
393 i
= min (len
, data_start
- memaddr
);
395 else if (corechan
>= 0
396 && memaddr
>= data_end
&& memaddr
< stack_start
)
398 i
= min (len
, stack_start
- memaddr
);
400 else if (corechan
< 0 && memaddr
>= exec_data_end
)
402 /* Since there is nothing at higher addresses than data
403 (without a core file or an inferior, there is no
404 stack, set i to do the rest of the operation now. */
407 else if (memaddr
>= stack_end
&& stack_end
!= 0)
409 /* Since there is nothing at higher addresses than
410 the stack, set i to do the rest of the operation now. */
415 /* Address did not classify into one of the known ranges.
416 This shouldn't happen; we catch the endpoints. */
417 fatal ("Internal: Bad case logic in xfer_core_file.");
420 /* Now we know which file to use.
421 Set up its pointer and transfer the data. */
425 if (xferfile
== &execfile
)
426 error ("No program file to examine.");
428 error ("No core dump file or running program to examine.");
429 val
= lseek (xferchan
, fileptr
, 0);
431 perror_with_name (*xferfile
);
432 val
= myread (xferchan
, myaddr
, i
);
434 perror_with_name (*xferfile
);
436 /* If this address is for nonexistent memory,
437 read zeros if reading, or do nothing if writing.
438 Actually, we never right. */
451 #endif /* XFER_CORE_FILE */
453 /* My replacement for the read system call.
454 Used like `read' but keeps going if `read' returns too soon. */
457 myread (desc
, addr
, len
)
467 val
= read (desc
, addr
, len
);
478 #ifdef REGISTER_U_ADDR
480 /* Return the address in the core dump or inferior of register REGNO.
481 BLOCKEND is the address of the end of the user structure. */
484 register_addr (regno
, blockend
)
490 if (regno
< 0 || regno
>= NUM_REGS
)
491 error ("Invalid register number %d.", regno
);
493 REGISTER_U_ADDR (addr
, blockend
, regno
);
498 #endif /* REGISTER_U_ADDR */
507 exec_file_display_hook
= 0;
515 stack_start
= STACK_END_ADDR
;
516 stack_end
= STACK_END_ADDR
;
518 add_com ("core-file", class_files
, core_file_command
,
519 "Use FILE as core dump for examining memory and registers.\n\
520 No arg means have no core file.");
521 add_com ("exec-file", class_files
, exec_file_command
,
522 "Use FILE as program for getting contents of pure memory.\n\
523 If FILE cannot be found as specified, your execution directory path\n\
524 is searched for a command of that name.\n\
525 No arg means have no executable file.");
526 add_info ("files", files_info
, "Names of files being debugged.");