z8kgen: temp file to generate z8k-opc.h from
[external/binutils.git] / bfd / sco-core.c
1 /* BFD back end for SCO System V 3.2 Unix core files
2    This was based on trad-core.c, which was written by John Gilmore of
3         Cygnus Support.
4    Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
5    Written by Scott Michel, IntelliMED Corporation. scottm%intime@uunet
6
7    NB: This does work with SCO System V 3.2 Unix and ODT. However, it
8        may well work with other i386 based *nixen and *nixes.
9
10 This file is part of BFD, the Binary File Descriptor library.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
25
26 /* To use this file on a particular host, configure the host with these
27    parameters in the config/h-HOST file:
28
29         HDEFINES=-DSCO_CORE=1
30         HDEPFILES=sco-core.o
31  */
32
33 #include "bfd.h"
34 #include "sysdep.h"
35 #include "libbfd.h"
36 #include "obstack.h"
37 #include "coff/i386.h"
38 #include "coff/internal.h"
39 #include "libcoff.h"
40
41 #include <stdio.h>
42 #include <sys/types.h>
43 #include <sys/param.h>
44 #include <sys/dir.h>
45 #include <signal.h>
46
47 #include <sys/file.h>
48 #include <sys/user.h>           /* After a.out.h  */
49
50 #include <errno.h>
51
52   struct trad_core_struct 
53     {
54       asection *data_section;
55       asection *stack_section;
56       asection *reg_section;
57
58       struct user               u;
59     } *rawptr;
60
61
62 #define core_upage(bfd) (&((bfd)->tdata.trad_core_data->u))
63 #define core_datasec(bfd) ((bfd)->tdata.trad_core_data->data_section)
64 #define core_stacksec(bfd) ((bfd)->tdata.trad_core_data->stack_section)
65 #define core_regsec(bfd) ((bfd)->tdata.trad_core_data->reg_section)
66
67 /* Handle 4.2-style (and perhaps also sysV-style) core dump file.  */
68
69 /* ARGSUSED */
70 bfd_target *
71 sco_core_file_p (abfd)
72      bfd *abfd;
73
74 {
75   int val;
76   struct user u;
77   /* This struct is just for allocating two things with one zalloc, so
78      they will be freed together, without violating alignment constraints. */
79
80
81   bfd_seek(abfd, 0, SEEK_SET);
82   val = bfd_read ((void *)&u, 1, sizeof u, abfd);
83   if (val != sizeof u)
84     return 0;                   /* Too small to be a core file */
85
86   /* Check that the size claimed is no greater than the file size. FIXME. */
87
88   /* OK, we believe you.  You're a core file (sure, sure).  */
89
90   /* Allocate both the upage and the struct core_data at once, so
91      a single free() will free them both.  */
92   rawptr = (struct trad_core_struct *)bfd_zalloc (abfd, sizeof (struct trad_core_struct));
93   if (rawptr == NULL) {
94     bfd_error = no_memory;
95     return 0;
96   }
97   
98   abfd->tdata.trad_core_data = rawptr;
99
100   rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */
101
102   /* Create the sections.  This is raunchy, but bfd_close wants to free
103      them separately.  */
104
105   core_stacksec(abfd) = (asection *) zalloc (sizeof (asection));
106   if (core_stacksec (abfd) == NULL) {
107   loser:
108     bfd_error = no_memory;
109     free ((void *)rawptr);
110     return 0;
111   }
112   core_datasec (abfd) = (asection *) zalloc (sizeof (asection));
113   if (core_datasec (abfd) == NULL) {
114   loser1:
115     free ((void *)core_stacksec (abfd));
116     goto loser;
117   }
118   core_regsec (abfd) = (asection *) zalloc (sizeof (asection));
119   if (core_regsec (abfd) == NULL) {
120     free ((void *)core_datasec (abfd));
121     goto loser1;
122   }
123
124   core_stacksec (abfd)->name = ".stack";
125   core_datasec (abfd)->name = ".data";
126   core_regsec (abfd)->name = ".reg";
127
128   core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
129   core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
130   core_regsec (abfd)->flags = SEC_ALLOC + SEC_HAS_CONTENTS;
131
132   core_datasec (abfd)->_raw_size =  NBPC * u.u_dsize;
133   core_stacksec (abfd)->_raw_size = NBPC * u.u_ssize;
134   core_regsec (abfd)->_raw_size = NBPC * USIZE; /* Larger than sizeof struct u */
135
136   /* Under SCO, we get at the exact addresses of things: */
137   core_datasec (abfd)->vma = u.u_exdata.ux_datorg;
138   core_stacksec (abfd)->vma = u.u_sub;
139
140   /* This is tricky.  As the "register section", we give them the entire
141      upage and stack.  u.u_ar0 points to where "register 0" is stored.
142      There are two tricks with this, though.  One is that the rest of the
143      registers might be at positive or negative (or both) displacements
144      from *u_ar0.  The other is that u_ar0 is sometimes an absolute address
145      in kernel memory, and on other systems it is an offset from the beginning
146      of the `struct user'.
147      
148      As a practical matter, we don't know where the registers actually are,
149      so we have to pass the whole area to GDB.  We encode the value of u_ar0
150      by setting the .regs section up so that its virtual memory address
151      0 is at the place pointed to by u_ar0 (by setting the vma of the start
152      of the section to -u_ar0).  GDB uses this info to locate the regs,
153      using minor trickery to get around the offset-or-absolute-addr problem. */
154   core_regsec (abfd)->vma = 0 - (int) u.u_ar0;
155
156   core_datasec (abfd)->filepos = NBPC * USIZE;
157   core_stacksec (abfd)->filepos = (NBPC * USIZE) + NBPC * u.u_dsize;
158   core_regsec (abfd)->filepos = 0; /* Register segment is the upage */
159
160   /* Align to word at least */
161   core_stacksec (abfd)->alignment_power = 2;
162   core_datasec (abfd)->alignment_power = 2;
163   core_regsec (abfd)->alignment_power = 2;
164
165   abfd->sections = core_stacksec (abfd);
166   core_stacksec (abfd)->next = core_datasec (abfd);
167   core_datasec (abfd)->next = core_regsec (abfd);
168   abfd->section_count = 3;
169
170   return abfd->xvec;
171 }
172
173 char *
174 sco_core_file_failing_command (abfd)
175      bfd *abfd;
176 {
177   char *com = abfd->tdata.trad_core_data->u.u_comm;
178   if (*com)
179     return com;
180   else
181     return 0;
182 }
183
184 /* ARGSUSED */
185 int
186 sco_core_file_failing_signal (abfd)
187      bfd *abfd;
188 {
189   int retval = -1;
190
191   if (core_upage(abfd)->u_sysabort != 0)
192     retval = core_upage(abfd)->u_sysabort;
193
194   return retval;
195 }
196
197 /* ARGSUSED */
198 boolean
199 sco_core_file_matches_executable_p  (core_bfd, exec_bfd)
200      bfd *core_bfd, *exec_bfd;
201 {
202   return true;
203 }
204 \f
205 /* No archive file support via this BFD */
206 #define sco_openr_next_archived_file    bfd_generic_openr_next_archived_file
207 #define sco_generic_stat_arch_elt       bfd_generic_stat_arch_elt
208 #define sco_slurp_armap                 bfd_false
209 #define sco_slurp_extended_name_table   bfd_true
210 #define sco_write_armap                 (PROTO (boolean, (*),   \
211      (bfd *arch, unsigned int elength, struct orl *map, \
212       unsigned int orl_count, int stridx))) bfd_false
213 #define sco_truncate_arname             bfd_dont_truncate_arname
214 #define aout_32_openr_next_archived_file bfd_generic_openr_next_archived_file
215
216 #define sco_close_and_cleanup           bfd_generic_close_and_cleanup
217 #define sco_set_section_contents                (PROTO(boolean, (*),    \
218          (bfd *abfd, asection *section, PTR data, file_ptr offset,      \
219          bfd_size_type count))) bfd_false
220 #define sco_get_section_contents                bfd_generic_get_section_contents
221 #define sco_new_section_hook            (PROTO (boolean, (*),   \
222         (bfd *, sec_ptr))) bfd_true
223 #define sco_get_symtab_upper_bound      bfd_0u
224 #define sco_get_symtab                  (PROTO (unsigned int, (*), \
225         (bfd *, struct symbol_cache_entry **))) bfd_0u
226 #define sco_get_reloc_upper_bound               (PROTO (unsigned int, (*), \
227         (bfd *, sec_ptr))) bfd_0u
228 #define sco_canonicalize_reloc          (PROTO (unsigned int, (*), \
229         (bfd *, sec_ptr, arelent **, struct symbol_cache_entry**))) bfd_0u
230 #define sco_make_empty_symbol           (PROTO (                \
231         struct symbol_cache_entry *, (*), (bfd *))) bfd_false
232 #define sco_print_symbol                        (PROTO (void, (*),      \
233         (bfd *, PTR, struct symbol_cache_entry  *,                      \
234          bfd_print_symbol_type))) bfd_false
235 #define sco_get_lineno                  (PROTO (alent *, (*),   \
236         (bfd *, struct symbol_cache_entry *))) bfd_nullvoidptr
237 #define sco_set_arch_mach                       (PROTO (boolean, (*),   \
238         (bfd *, enum bfd_architecture, unsigned long))) bfd_false
239 #define sco_find_nearest_line           (PROTO (boolean, (*),   \
240         (bfd *abfd, struct sec  *section,                               \
241          struct symbol_cache_entry  **symbols,bfd_vma offset,           \
242          CONST char **file, CONST char **func, unsigned int *line))) bfd_false
243 #define sco_sizeof_headers              (PROTO (int, (*),       \
244         (bfd *, boolean))) bfd_0
245
246 #define sco_bfd_debug_info_start                bfd_void
247 #define sco_bfd_debug_info_end          bfd_void
248 #define sco_bfd_debug_info_accumulate   (PROTO (void, (*),      \
249         (bfd *, struct sec *))) bfd_void
250 #define sco_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
251 #define sco_bfd_relax_section bfd_generic_relax_section
252 /* If somebody calls any byte-swapping routines, shoot them.  */
253 void
254 swap_abort()
255 {
256   abort(); /* This way doesn't require any declaration for ANSI to fuck up */
257 }
258 #define NO_GET  ((PROTO(bfd_vma, (*), (         bfd_byte *))) swap_abort )
259 #define NO_PUT  ((PROTO(void,    (*), (bfd_vma, bfd_byte *))) swap_abort )
260
261 bfd_target sco_core_vec =
262   {
263     "sco-core",
264     bfd_target_unknown_flavour,
265     true,                       /* target byte order */
266     true,                       /* target headers byte order */
267   (HAS_RELOC | EXEC_P |         /* object flags */
268    HAS_LINENO | HAS_DEBUG |
269    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
270
271   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
272     ' ',                                                   /* ar_pad_char */
273     16,                                                    /* ar_max_namelen */
274     3,                                                     /* minimum alignment power */
275     NO_GET, NO_PUT, NO_GET, NO_PUT, NO_GET, NO_PUT, /* data */
276     NO_GET, NO_PUT, NO_GET, NO_PUT, NO_GET, NO_PUT, /* hdrs */
277
278     {_bfd_dummy_target, _bfd_dummy_target,
279      _bfd_dummy_target, sco_core_file_p},
280     {bfd_false, bfd_false,      /* bfd_create_object */
281      bfd_false, bfd_false},
282     {bfd_false, bfd_false,      /* bfd_write_contents */
283      bfd_false, bfd_false},
284     
285     JUMP_TABLE(sco),
286 };
287
288