2d5155f59e9b3e8d4ddb88474869f7110c63247f
[platform/upstream/binutils.git] / bfd / trad-core.c
1 /* BFD back end for traditional Unix core files (U-area and sections, raw)
2    Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.  */
3
4 /* This file does not define a particular back-end, but it defines routines
5    that can be used by other back-ends.  */
6 #include <sysdep.h>
7 #include "bfd.h"
8 #include <stdio.h>
9 #include "libbfd.h"
10
11 #include "liba.out.h"           /* BFD a.out internal data structures */
12
13 #include <sys/types.h>
14 #include <sys/param.h>
15 #include <sys/dir.h>
16 #include <signal.h>
17 #include <machine/reg.h>
18
19 #include <sys/user.h>           /* After a.out.h  */
20 #include <sys/file.h>
21 #include <sys/stat.h>
22
23 #include <errno.h>
24
25 /* need this cast b/c ptr is really void * */
26 #define core_hdr(bfd) (((struct core_data *) (bfd->tdata))->hdr)
27 #define core_datasec(bfd) (((struct core_data *) ((bfd)->tdata))->data_section)
28 #define core_stacksec(bfd) (((struct core_data*)((bfd)->tdata))->stack_section)
29 #define core_regsec(bfd) (((struct core_data *) ((bfd)->tdata))->reg_section)
30 #define core_upage(bfd) (((struct core_data *) ((bfd)->tdata))->upage)
31
32 /* These are stored in the bfd's tdata */
33 struct core_data {
34   struct user *upage;             /* core file header */
35   asection *data_section;
36   asection *stack_section;
37   asection *reg_section;
38 };
39
40 /* ARGSUSED */
41 bfd_target *
42 trad_unix_core_file_p (abfd)
43      bfd *abfd;
44 {
45 #if HOST_SYS == SUN_SYS
46   return 0;
47 #else
48   int val;
49   char *rawptr;
50   struct user u;
51   unsigned int reg_offset, fp_reg_offset;
52
53   /* 4.2-style (and perhaps also sysV-style) core dump file.  */
54
55   val = bfd_read ((void *)&u, 1, sizeof u, abfd);
56   if (val != sizeof u)
57     return 0;                   /* Too small to be a core file */
58
59   /* Sanity check perhaps??? */
60   if (u.u_dsize > 0x1000000)    /* Remember, it's in pages... */
61     return 0;
62   if (u.u_ssize > 0x1000000)
63     return 0;
64   /* Check that the size claimed is no greater than the file size. FIXME. */
65
66   /* OK, we believe you.  You're a core file (sure, sure).  */
67
68   /* Allocate both the upage and the struct core_data at once, so
69      a single free() will free them both.  */
70   rawptr = (char *)zalloc (sizeof (u) + sizeof (struct core_data));
71   if (rawptr == NULL) {
72     bfd_error = no_memory;
73     return 0;
74   }
75   
76   set_tdata (abfd, (struct core_data *)rawptr);
77   core_upage (abfd) = (struct user *)(rawptr + sizeof (struct core_data));
78   *core_upage (abfd) = u;               /* Save that upage! */
79
80   /* create the sections.  This is raunchy, but bfd_close wants to reclaim
81      them */
82   core_stacksec (abfd) = (asection *) zalloc (sizeof (asection));
83   if (core_stacksec (abfd) == NULL) {
84 loser:
85     bfd_error = no_memory;
86     free ((void *)rawptr);
87     return 0;
88   }
89   core_datasec (abfd) = (asection *) zalloc (sizeof (asection));
90   if (core_datasec (abfd) == NULL) {
91 loser1:
92     free ((void *)core_stacksec (abfd));
93     goto loser;
94   }
95   core_regsec (abfd) = (asection *) zalloc (sizeof (asection));
96   if (core_regsec (abfd) == NULL) {
97 loser2:
98     free ((void *)core_datasec (abfd));
99     goto loser1;
100   }
101
102   core_stacksec (abfd)->name = ".stack";
103   core_datasec (abfd)->name = ".data";
104   core_regsec (abfd)->name = ".reg";
105
106   core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
107   core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
108   core_regsec (abfd)->flags = SEC_ALLOC;
109
110   core_datasec (abfd)->size =  NBPG * u.u_dsize;
111   core_stacksec (abfd)->size = NBPG * u.u_ssize;
112   core_regsec (abfd)->size = NBPG * UPAGES;  /* Larger than sizeof struct u */
113
114   /* What a hack... we'd like to steal it from the exec file,
115      since the upage does not seem to provide it.  FIXME.  */
116   core_datasec (abfd)->vma = TEXT_START_ADDR + (NBPG * u.u_tsize);
117   core_stacksec (abfd)->vma = STACK_END_ADDR - (NBPG * u.u_ssize);
118   core_regsec (abfd)->vma = -1;
119
120   core_datasec (abfd)->filepos = NBPG * UPAGES;
121   core_stacksec (abfd)->filepos = (NBPG * UPAGES) + NBPG * u.u_dsize;
122   core_regsec (abfd)->filepos = 0;      /* Register segment is the upage */
123
124   /* Align to word at least */
125   core_stacksec (abfd)->alignment_power = 2;
126   core_datasec (abfd)->alignment_power = 2;
127   core_regsec (abfd)->alignment_power = 2;
128
129   abfd->sections = core_stacksec (abfd);
130   core_stacksec (abfd)->next = core_datasec (abfd);
131   core_datasec (abfd)->next = core_regsec (abfd);
132   abfd->section_count = 3;
133
134   return abfd->xvec;
135 #endif
136 }
137
138 char *
139 trad_unix_core_file_failing_command (abfd)
140      bfd *abfd;
141 {
142   if (*core_upage (abfd)->u_comm)
143     return core_upage (abfd)->u_comm;
144   else
145     return 0;
146 }
147
148 /* ARGSUSED */
149 int
150 trad_unix_core_file_failing_signal (ignore_abfd)
151      bfd *ignore_abfd;
152 {
153   return -1;            /* FIXME, where is it? */
154 }
155
156 /* ARGSUSED */
157 boolean
158 trad_unix_core_file_matches_executable_p  (core_bfd, exec_bfd)
159      bfd *core_bfd, *exec_bfd;
160 {
161   return true;          /* FIXME, We have no way of telling at this point */
162 }