gdb-3.1
[deliverable/binutils-gdb.git] / gdb / RCS / core.c,v
CommitLineData
e91b87a3 1head 1.4;
2access ;
3symbols ;
4locks ; strict;
5comment @ * @;
6
7
81.4
9date 89.03.27.18.39.18; author gnu; state Exp;
10branches ;
11next 1.3;
12
131.3
14date 89.02.10.01.39.45; author gnu; state Exp;
15branches ;
16next 1.2;
17
181.2
19date 89.02.09.23.22.33; author gnu; state Exp;
20branches ;
21next 1.1;
22
231.1
24date 89.02.09.22.49.56; author gnu; state Exp;
25branches ;
26next ;
27
28
29desc
30@@
31
32
331.4
34log
35@Unisoft Assholes changes for user.ps. Avoid sys/fcntl.h.
36@
37text
38@/* Work with core dump and executable files, for GDB.
39 Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
40
41GDB is distributed in the hope that it will be useful, but WITHOUT ANY
42WARRANTY. No author or distributor accepts responsibility to anyone
43for the consequences of using it or for whether it serves any
44particular purpose or works at all, unless he says so in writing.
45Refer to the GDB General Public License for full details.
46
47Everyone is granted permission to copy, modify and redistribute GDB,
48but only under the conditions described in the GDB General Public
49License. A copy of this license is supposed to have been given to you
50along with GDB so you can know your rights and responsibilities. It
51should be in a file named COPYING. Among other things, the copyright
52notice and this notice must be preserved on all copies.
53
54In other words, go ahead and share GDB, but don't try to stop
55anyone else from sharing it farther. Help stamp out software hoarding!
56*/
57
58#include "defs.h"
59#include "param.h"
60#include "gdbcore.h"
61
62#ifdef USG
63#include <sys/types.h>
64#include <fcntl.h>
65#endif
66
67#ifdef COFF_ENCAPSULATE
68#include "a.out.encap.h"
69#else
70#include <a.out.h>
71#endif
72
73#ifndef N_MAGIC
74#ifdef COFF_FORMAT
75#define N_MAGIC(exec) ((exec).magic)
76#else
77#define N_MAGIC(exec) ((exec).a_magic)
78#endif
79#endif
80
81#include <stdio.h>
82#include <signal.h>
83#include <sys/param.h>
84#include <sys/dir.h>
85#include <sys/file.h>
86#include <sys/stat.h>
87
88#ifdef UNISOFT_ASSHOLES
89#define PMMU
90#define NEW_PMMU
91#include <sys/seg.h> /* Required for user.ps */
92#include <sys/time.h> /* '' */
93#include <sys/mmu.h> /* '' */
94#include <sys/reg.h>
95#define mc68881 /* Required to get float in user.ps */
96#endif
97
98#ifdef UMAX_CORE
99#include <sys/ptrace.h>
100#else
101#include <sys/user.h>
102#endif
103
104#ifndef N_TXTADDR
105#define N_TXTADDR(hdr) 0
106#endif /* no N_TXTADDR */
107
108#ifndef N_DATADDR
109#define N_DATADDR(hdr) hdr.a_text
110#endif /* no N_DATADDR */
111
112#ifndef COFF_FORMAT
113#define AOUTHDR struct exec
114#endif
115
116extern char *sys_siglist[];
117
118extern core_file_command (), exec_file_command ();
119
120/* Hook for `exec_file_command' command to call. */
121
122void (*exec_file_display_hook) ();
123
124/* File names of core file and executable file. */
125
126char *corefile;
127char *execfile;
128
129/* Descriptors on which core file and executable file are open.
130 Note that the execchan is closed when an inferior is created
131 and reopened if the inferior dies or is killed. */
132
133int corechan;
134int execchan;
135
136/* Last modification time of executable file.
137 Also used in source.c to compare against mtime of a source file. */
138
139int exec_mtime;
140
141/* Virtual addresses of bounds of the two areas of memory in the core file. */
142
143CORE_ADDR data_start;
144CORE_ADDR data_end;
145CORE_ADDR stack_start;
146CORE_ADDR stack_end;
147
148/* Virtual addresses of bounds of two areas of memory in the exec file.
149 Note that the data area in the exec file is used only when there is no core file. */
150
151CORE_ADDR text_start;
152CORE_ADDR text_end;
153
154CORE_ADDR exec_data_start;
155CORE_ADDR exec_data_end;
156
157/* Address in executable file of start of text area data. */
158
159int text_offset;
160
161/* Address in executable file of start of data area data. */
162
163int exec_data_offset;
164
165/* Address in core file of start of data area data. */
166
167int data_offset;
168
169/* Address in core file of start of stack area data. */
170
171int stack_offset;
172
173#ifdef COFF_FORMAT
174/* various coff data structures */
175
176FILHDR file_hdr;
177SCNHDR text_hdr;
178SCNHDR data_hdr;
179
180#endif /* not COFF_FORMAT */
181
182/* a.out header saved in core file. */
183
184AOUTHDR core_aouthdr;
185
186/* a.out header of exec file. */
187
188AOUTHDR exec_aouthdr;
189
190void validate_files ();
191unsigned int register_addr ();
192\f
193/* Call this to specify the hook for exec_file_command to call back.
194 This is called from the x-window display code. */
195
196void
197specify_exec_file_hook (hook)
198 void (*hook) ();
199{
200 exec_file_display_hook = hook;
201}
202
203/* The exec file must be closed before running an inferior.
204 If it is needed again after the inferior dies, it must
205 be reopened. */
206
207void
208close_exec_file ()
209{
210 if (execchan >= 0)
211 close (execchan);
212 execchan = -1;
213}
214
215void
216reopen_exec_file ()
217{
218 if (execchan < 0 && execfile != 0)
219 {
220 char *filename = concat (execfile, "", "");
221 exec_file_command (filename, 0);
222 free (filename);
223 }
224}
225\f
226/* If we have both a core file and an exec file,
227 print a warning if they don't go together.
228 This should really check that the core file came
229 from that exec file, but I don't know how to do it. */
230
231void
232validate_files ()
233{
234 if (execfile != 0 && corefile != 0)
235 {
236 struct stat st_core;
237
238 fstat (corechan, &st_core);
239
240 if (N_MAGIC (core_aouthdr) != 0
241 && bcmp (&core_aouthdr, &exec_aouthdr, sizeof core_aouthdr))
242 printf ("Warning: core file does not match specified executable file.\n");
243 else if (exec_mtime > st_core.st_mtime)
244 printf ("Warning: exec file is newer than core file.\n");
245 }
246}
247
248/* Return the name of the executable file as a string.
249 ERR nonzero means get error if there is none specified;
250 otherwise return 0 in that case. */
251
252char *
253get_exec_file (err)
254 int err;
255{
256 if (err && execfile == 0)
257 error ("No executable file specified.\n\
258Use the \"exec-file\" and \"symbol-file\" commands.");
259 return execfile;
260}
261
262int
263have_core_file_p ()
264{
265 return corefile != 0;
266}
267
268static void
269files_info ()
270{
271 char *symfile;
272 extern char *get_sym_file ();
273
274 if (execfile)
275 printf ("Executable file \"%s\".\n", execfile);
276 else
277 printf ("No executable file\n");
278
279 if (corefile)
280 printf ("Core dump file \"%s\".\n", corefile);
281 else
282 printf ("No core dump file\n");
283
284 if (have_inferior_p ())
285 printf ("Using the running image of the program, rather than these files.\n");
286
287 symfile = get_sym_file ();
288 if (symfile != 0)
289 printf ("Symbols from \"%s\".\n", symfile);
290
291 if (! have_inferior_p ())
292 {
293 if (execfile)
294 {
295 printf ("Text segment in executable from 0x%x to 0x%x.\n",
296 text_start, text_end);
297 printf ("Data segment in executable from 0x%x to 0x%x.\n",
298 exec_data_start, exec_data_end);
299 if (corefile)
300 printf("(But since we have a core file, we're using...)\n");
301 }
302 if (corefile)
303 {
304 printf ("Data segment in core file from 0x%x to 0x%x.\n",
305 data_start, data_end);
306 printf ("Stack segment in core file from 0x%x to 0x%x.\n",
307 stack_start, stack_end);
308 }
309 }
310}
311\f
312/* Read "memory data" from core file and/or executable file.
313 Returns zero if successful, 1 if xfer_core_file failed, errno value if
314 ptrace failed. */
315
316int
317read_memory (memaddr, myaddr, len)
318 CORE_ADDR memaddr;
319 char *myaddr;
320 int len;
321{
322 if (have_inferior_p ())
323 return read_inferior_memory (memaddr, myaddr, len);
324 else
325 return xfer_core_file (memaddr, myaddr, len);
326}
327
328/* Write LEN bytes of data starting at address MYADDR
329 into debugged program memory at address MEMADDR.
330 Returns zero if successful, or an errno value if ptrace failed. */
331
332int
333write_memory (memaddr, myaddr, len)
334 CORE_ADDR memaddr;
335 char *myaddr;
336 int len;
337{
338 if (have_inferior_p ())
339 return write_inferior_memory (memaddr, myaddr, len);
340 else
341 error ("Can write memory only when program being debugged is running.");
342}
343
344/* Read from the program's memory (except for inferior processes).
345 This function is misnamed, since it only reads, never writes; and
346 since it will use the core file and/or executable file as necessary.
347
348 It should be extended to write as well as read, FIXME, for patching files.
349
350 Return 0 if address could be read, 1 if not. */
351
352int
353xfer_core_file (memaddr, myaddr, len)
354 CORE_ADDR memaddr;
355 char *myaddr;
356 int len;
357{
358 register int i;
359 register int val;
360 int xferchan;
361 char **xferfile;
362 int fileptr;
363 int returnval = 0;
364
365 while (len > 0)
366 {
367 xferfile = 0;
368 xferchan = 0;
369
370 /* Determine which file the next bunch of addresses reside in,
371 and where in the file. Set the file's read/write pointer
372 to point at the proper place for the desired address
373 and set xferfile and xferchan for the correct file.
374
375 If desired address is nonexistent, leave them zero.
376
377 i is set to the number of bytes that can be handled
378 along with the next address.
379
380 We put the most likely tests first for efficiency. */
381
382 /* Note that if there is no core file
383 data_start and data_end are equal. */
384 if (memaddr >= data_start && memaddr < data_end)
385 {
386 i = min (len, data_end - memaddr);
387 fileptr = memaddr - data_start + data_offset;
388 xferfile = &corefile;
389 xferchan = corechan;
390 }
391 /* Note that if there is no core file
392 stack_start and stack_end are equal. */
393 else if (memaddr >= stack_start && memaddr < stack_end)
394 {
395 i = min (len, stack_end - memaddr);
396 fileptr = memaddr - stack_start + stack_offset;
397 xferfile = &corefile;
398 xferchan = corechan;
399 }
400 else if (corechan < 0
401 && memaddr >= exec_data_start && memaddr < exec_data_end)
402 {
403 i = min (len, exec_data_end - memaddr);
404 fileptr = memaddr - exec_data_start + exec_data_offset;
405 xferfile = &execfile;
406 xferchan = execchan;
407 }
408 else if (memaddr >= text_start && memaddr < text_end)
409 {
410 i = min (len, text_end - memaddr);
411 fileptr = memaddr - text_start + text_offset;
412 xferfile = &execfile;
413 xferchan = execchan;
414 }
415 else if (memaddr < text_start)
416 {
417 i = min (len, text_start - memaddr);
418 }
419 else if (memaddr >= text_end
420 && memaddr < (corechan >= 0? data_start : exec_data_start))
421 {
422 i = min (len, data_start - memaddr);
423 }
424 else if (memaddr >= (corechan >= 0 ? data_end : exec_data_end)
425 && memaddr < stack_start)
426 {
427 i = min (len, stack_start - memaddr);
428 }
429 else if (memaddr >= stack_end && stack_end != 0)
430 {
431 i = min (len, - memaddr);
432 }
433 else
434 {
435 /* Address did not classify into one of the known ranges.
436 This could be because data_start != exec_data_start
437 or data_end similarly. */
438 abort();
439 }
440
441 /* Now we know which file to use.
442 Set up its pointer and transfer the data. */
443 if (xferfile)
444 {
445 if (*xferfile == 0)
446 if (xferfile == &execfile)
447 error ("No program file to examine.");
448 else
449 error ("No core dump file or running program to examine.");
450 val = lseek (xferchan, fileptr, 0);
451 if (val < 0)
452 perror_with_name (*xferfile);
453 val = myread (xferchan, myaddr, i);
454 if (val < 0)
455 perror_with_name (*xferfile);
456 }
457 /* If this address is for nonexistent memory,
458 read zeros if reading, or do nothing if writing.
459 (FIXME we never write.) */
460 else
461 {
462 bzero (myaddr, i);
463 returnval = 1;
464 }
465
466 memaddr += i;
467 myaddr += i;
468 len -= i;
469 }
470 return returnval;
471}
472\f
473/* My replacement for the read system call.
474 Used like `read' but keeps going if `read' returns too soon. */
475
476int
477myread (desc, addr, len)
478 int desc;
479 char *addr;
480 int len;
481{
482 register int val;
483 int orglen = len;
484
485 while (len > 0)
486 {
487 val = read (desc, addr, len);
488 if (val < 0)
489 return val;
490 if (val == 0)
491 return orglen - len;
492 len -= val;
493 addr += val;
494 }
495 return orglen;
496}
497\f
498#ifdef REGISTER_U_ADDR
499
500/* Return the address in the core dump or inferior of register REGNO.
501 BLOCKEND is the address of the end of the user structure. */
502
503unsigned int
504register_addr (regno, blockend)
505 int regno;
506 int blockend;
507{
508 int addr;
509
510 if (regno < 0 || regno >= NUM_REGS)
511 error ("Invalid register number %d.", regno);
512
513 REGISTER_U_ADDR (addr, blockend, regno);
514
515 return addr;
516}
517
518#endif /* REGISTER_U_ADDR */
519\f
520void
521_initialize_core()
522{
523 corechan = -1;
524 execchan = -1;
525 corefile = 0;
526 execfile = 0;
527 exec_file_display_hook = 0;
528
529 text_start = 0;
530 text_end = 0;
531 data_start = 0;
532 data_end = 0;
533 exec_data_start = 0;
534 exec_data_end = 0;
535 stack_start = STACK_END_ADDR;
536 stack_end = STACK_END_ADDR;
537
538 add_com ("core-file", class_files, core_file_command,
539 "Use FILE as core dump for examining memory and registers.\n\
540No arg means have no core file.");
541 add_com ("exec-file", class_files, exec_file_command,
542 "Use FILE as program for getting contents of pure memory.\n\
543If FILE cannot be found as specified, your execution directory path\n\
544is searched for a command of that name.\n\
545No arg means have no executable file.");
546 add_info ("files", files_info, "Names of files being debugged.");
547}
548
549@
550
551
5521.3
553log
554@Fix up "info files" some more, to give more information.
555Rearrange the tests in xfer_core_file to avoid dependencies
556between data_start and exec_data_start, and for efficiency
557and add an abort() to test correctness. (If you take out
558never mind...)
559@
560text
561@d27 1
562a27 1
563#include <sys/fcntl.h>
564d50 10
565@
566
567
5681.2
569log
570@Create gdbcore.h for externally visible variables;
571spiff up the "info files" output to make it easier to read and more
572informative.
573@
574text
575@d250 4
576d257 4
577a260 7
578 printf ("Data segment in core file from 0x%x to 0x%x.\nStack segment in core file from 0x%x to 0x%x.\n",
579 data_start, data_end, stack_start, stack_end);
580 }
581 else if (execfile)
582 {
583 printf ("Data segment in executable from 0x%x to 0x%x.\n",
584 exec_data_start, exec_data_end);
585d297 3
586a299 1
587/* Return 0 if address could be read, 1 if not. */
588d301 4
589d327 1
590d329 1
591d331 3
592a333 1
593 along with the next address. */
594a334 17
595 if (memaddr < text_start)
596 {
597 i = min (len, text_start - memaddr);
598 }
599 else if (memaddr >= text_end && memaddr < data_start)
600 {
601 i = min (len, data_start - memaddr);
602 }
603 else if (memaddr >= (corechan >= 0 ? data_end : exec_data_end)
604 && memaddr < stack_start)
605 {
606 i = min (len, stack_start - memaddr);
607 }
608 else if (memaddr >= stack_end && stack_end != 0)
609 {
610 i = min (len, - memaddr);
611 }
612d337 1
613a337 1
614 else if (memaddr >= data_start && memaddr < data_end)
615d368 25
616d411 2
617a412 1
618 read zeros if reading, or do nothing if writing. */
619@
620
621
6221.1
623log
624@Initial revision
625@
626text
627@d2 1
628a2 1
629 Copyright (C) 1986, 1987 Free Software Foundation, Inc.
630d23 1
631d35 1
632d43 1
633d231 4
634a234 1
635 if (corefile == 0)
636a235 2
637 else
638 printf ("Core dump file \"%s\".\n", corefile);
639d242 1
640a242 1
641 printf ("Symbols loaded from \"%s\".\n", symfile);
642d248 1
643a248 1
644 printf ("Text segment from 0x%x to 0x%x.\n",
645d253 1
646a253 1
647 printf ("Data segment from 0x%x to 0x%x.\nStack segment from 0x%x to 0x%x.\n",
648d256 1
649a256 1
650 else
651@
This page took 0.048249 seconds and 4 git commands to generate.