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