]> Git Repo - binutils.git/blob - gdb/core.c
gdb-2.4+.aux.coff
[binutils.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
This page took 0.062961 seconds and 4 git commands to generate.