* pe-dll.c (build_filler_bfd): Conform error message to standard.
[deliverable/binutils-gdb.git] / bfd / sco5-core.c
CommitLineData
252b5132 1/* BFD back end for SCO5 core files (U-area and raw sections)
b677b8c0 2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
edeb6e24 3 Free Software Foundation, Inc.
252b5132
RH
4 Written by Jouke Numan <jnuman@hiscom.nl>
5
6This file is part of BFD, the Binary File Descriptor library.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
3e110533 20Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
252b5132
RH
21
22#include "bfd.h"
23#include "sysdep.h"
24#include "libbfd.h"
b34976b6 25#include "libaout.h" /* BFD a.out internal data structures */
252b5132
RH
26
27#include <stdio.h>
28#include <sys/types.h>
29#include <sys/param.h>
30#include <sys/dir.h>
31#include <signal.h>
32
b34976b6 33#include <sys/user.h> /* After a.out.h */
9b818146 34#ifdef SCO5_CORE
252b5132
RH
35#include <sys/paccess.h>
36#include <sys/region.h>
9b818146 37#endif
252b5132
RH
38
39struct sco5_core_struct
40{
41 struct user u;
42};
43
44/* forward declarations */
45
b34976b6
AM
46static asection *make_bfd_asection
47 PARAMS ((bfd *, const char *, flagword, bfd_size_type, bfd_vma, file_ptr));
252b5132
RH
48static struct user *read_uarea PARAMS ((bfd *, int));
49const bfd_target *sco5_core_file_p PARAMS ((bfd *abfd));
50char *sco5_core_file_failing_command PARAMS ((bfd *abfd));
51int sco5_core_file_failing_signal PARAMS ((bfd *abfd));
b34976b6
AM
52bfd_boolean sco5_core_file_matches_executable_p
53 PARAMS ((bfd *core_bfd, bfd *exec_bfd));
252b5132
RH
54static void swap_abort PARAMS ((void));
55
56static asection *
eea6121a 57make_bfd_asection (abfd, name, flags, size, vma, filepos)
252b5132
RH
58 bfd *abfd;
59 const char *name;
60 flagword flags;
eea6121a 61 bfd_size_type size;
252b5132
RH
62 bfd_vma vma;
63 file_ptr filepos;
64{
65 asection *asect;
66
67 asect = bfd_make_section_anyway (abfd, name);
68 if (!asect)
69 return NULL;
70 asect->flags = flags;
eea6121a 71 asect->size = size;
252b5132
RH
72 asect->vma = vma;
73 asect->filepos = filepos;
74 asect->alignment_power = 2;
75
76 return asect;
77}
78
252b5132
RH
79static struct user *
80read_uarea(abfd, filepos)
81 bfd *abfd;
82 int filepos;
83
84{
85 struct sco5_core_struct *rawptr;
dc810e39 86 bfd_size_type amt = sizeof (struct sco5_core_struct);
252b5132 87
dc810e39 88 rawptr = (struct sco5_core_struct *) bfd_zmalloc (amt);
252b5132
RH
89 if (rawptr == NULL)
90 return NULL;
91
92 abfd->tdata.sco5_core_data = rawptr;
93
dc810e39
AM
94 if (bfd_seek (abfd, (file_ptr) filepos, SEEK_SET) != 0
95 || bfd_bread ((void *) &rawptr->u, (bfd_size_type) sizeof rawptr->u,
96 abfd) != sizeof rawptr->u)
252b5132
RH
97 {
98 bfd_set_error (bfd_error_wrong_format);
99 return NULL;
100 }
101
102 /* Sanity check perhaps??? */
7b82c249 103 if (rawptr->u.u_dsize > 0x1000000) /* Remember, it's in pages... */
252b5132
RH
104 {
105 bfd_set_error (bfd_error_wrong_format);
106 return NULL;
107 }
108 if (rawptr->u.u_ssize > 0x1000000)
109 {
110 bfd_set_error (bfd_error_wrong_format);
111 return NULL;
112 }
113 return &rawptr->u;
114}
115
252b5132
RH
116const bfd_target *
117sco5_core_file_p (abfd)
118 bfd *abfd;
119{
120 int coffset_siz, val, nsecs, cheadoffs;
121 int coresize;
122 struct user *u;
123 struct coreoffsets coffsets;
124 struct coresecthead chead;
125 char *secname;
126 flagword flags;
127
33216455 128 /* Read coreoffsets region at end of core (see core(FP)). */
252b5132
RH
129
130 {
252b5132 131 struct stat statbuf;
33216455 132
b677b8c0 133 if (bfd_stat (abfd, &statbuf) < 0)
3dff57e8 134 return NULL;
b677b8c0 135
252b5132
RH
136 coresize = statbuf.st_size;
137 }
138 /* Last long in core is sizeof struct coreoffsets, read it */
dc810e39
AM
139 if ((bfd_seek (abfd, (file_ptr) (coresize - sizeof coffset_siz),
140 SEEK_SET) != 0)
141 || bfd_bread ((void *) &coffset_siz, (bfd_size_type) sizeof coffset_siz,
142 abfd) != sizeof coffset_siz)
252b5132 143 {
7b82c249 144 bfd_set_error (bfd_error_wrong_format);
252b5132
RH
145 return NULL;
146 }
147
148 /* Use it to seek start of coreoffsets region, read it and determine
149 validity */
dc810e39
AM
150 if ((bfd_seek (abfd, (file_ptr) (coresize - coffset_siz), SEEK_SET) != 0)
151 || (bfd_bread ((void *) &coffsets, (bfd_size_type) sizeof coffsets, abfd)
252b5132
RH
152 != sizeof coffsets)
153 || ((coffsets.u_info != 1) && (coffsets.u_info != C_VERSION)))
154 {
7b82c249 155 bfd_set_error (bfd_error_wrong_format);
252b5132
RH
156 return NULL;
157 }
158
7b82c249
KH
159 if (coffsets.u_info == 1)
160 {
252b5132
RH
161 /* Old version, no section heads, read info from user struct */
162
9e7b37b3 163 u = read_uarea (abfd, coffsets.u_user);
252b5132 164 if (! u)
9e7b37b3 165 goto fail;
252b5132 166
7b82c249 167 if (!make_bfd_asection (abfd, ".reg", SEC_HAS_CONTENTS,
b34976b6
AM
168 (bfd_size_type) coffsets.u_usize,
169 0 - (bfd_vma) u->u_ar0,
170 (file_ptr) coffsets.u_user))
9e7b37b3 171 goto fail;
7b82c249
KH
172
173 if (!make_bfd_asection (abfd, ".data",
252b5132 174 SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
b34976b6 175 ((bfd_size_type) u->u_exdata.ux_dsize
252b5132 176 + u->u_exdata.ux_bsize),
b34976b6
AM
177 (bfd_vma) u->u_exdata.ux_datorg,
178 (file_ptr) coffsets.u_data))
9e7b37b3 179 goto fail;
7b82c249
KH
180
181 if (!make_bfd_asection (abfd, ".stack",
182 SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
b34976b6
AM
183 (bfd_size_type) u->u_ssize * NBPC,
184 (bfd_vma) u->u_sub,
185 (file_ptr) coffsets.u_stack))
9e7b37b3 186 goto fail;
252b5132
RH
187
188 return abfd->xvec; /* Done for version 1 */
7b82c249 189 }
252b5132
RH
190
191 /* Immediately before coreoffsets region is a long with offset in core
192 to first coresecthead (CORES_OFFSETS), the long before this is the
193 number of section heads in the list. Read both longs and read the
194 coresecthead and check its validity */
7b82c249
KH
195
196 if ((bfd_seek (abfd,
dc810e39 197 (file_ptr) (coresize - coffset_siz - 2 * sizeof coffset_siz),
252b5132 198 SEEK_SET) != 0)
dc810e39
AM
199 || (bfd_bread ((void *) &nsecs, (bfd_size_type) sizeof nsecs, abfd)
200 != sizeof nsecs)
201 || (bfd_bread ((void *) &cheadoffs, (bfd_size_type) sizeof cheadoffs,
202 abfd) != sizeof cheadoffs)
203 || (bfd_seek (abfd, (file_ptr) cheadoffs, SEEK_SET) != 0)
204 || (bfd_bread ((void *) &chead, (bfd_size_type) sizeof chead, abfd)
205 != sizeof chead)
252b5132
RH
206 || (chead.cs_stype != CORES_OFFSETS)
207 || (chead.cs_x.csx_magic != COREMAGIC_NUMBER))
208 {
209 bfd_set_error (bfd_error_wrong_format);
9e7b37b3 210 goto fail;
252b5132
RH
211 }
212
213 /* OK, we believe you. You're a core file (sure, sure). */
214
215 /* Now loop over all regions and map them */
216 nsecs--; /* We've seen CORES_OFFSETS already */
7b82c249 217 for (; nsecs; nsecs--)
252b5132 218 {
dc810e39
AM
219 if ((bfd_seek (abfd, (file_ptr) chead.cs_hseek, SEEK_SET) != 0)
220 || (bfd_bread ((void *) &chead, (bfd_size_type) sizeof chead, abfd)
221 != sizeof chead))
b34976b6
AM
222 {
223 bfd_set_error (bfd_error_wrong_format);
9e7b37b3 224 goto fail;
b34976b6 225 }
252b5132 226
7b82c249 227 switch (chead.cs_stype)
252b5132
RH
228 {
229 case CORES_MAGIC: /* Core header, check magic */
230 if (chead.cs_x.csx_magic != COREMAGIC_NUMBER)
231 {
232 bfd_set_error (bfd_error_wrong_format);
9e7b37b3 233 goto fail;
252b5132
RH
234 }
235 secname = NULL;
236 nsecs++; /* MAGIC not in section cnt!*/
237 break;
238 case CORES_UAREA: /* U-area, read in tdata */
9e7b37b3 239 u = read_uarea (abfd, chead.cs_sseek);
252b5132 240 if (! u)
9e7b37b3 241 goto fail;
252b5132 242
b34976b6 243 /* This is tricky. As the "register section", we give them
252b5132
RH
244 the entire upage and stack. u.u_ar0 points to where
245 "register 0" is stored. There are two tricks with this,
246 though. One is that the rest of the registers might be
247 at positive or negative (or both) displacements from
248 *u_ar0. The other is that u_ar0 is sometimes an absolute
249 address in kernel memory, and on other systems it is an
250 offset from the beginning of the `struct user'.
7b82c249 251
252b5132
RH
252 As a practical matter, we don't know where the registers
253 actually are, so we have to pass the whole area to GDB.
254 We encode the value of u_ar0 by setting the .regs section
255 up so that its virtual memory address 0 is at the place
256 pointed to by u_ar0 (by setting the vma of the start of
257 the section to -u_ar0). GDB uses this info to locate the
258 regs, using minor trickery to get around the
7b82c249 259 offset-or-absolute-addr problem. */
252b5132
RH
260
261 chead.cs_vaddr = 0 - (bfd_vma) u->u_ar0;
262
b34976b6
AM
263 secname = ".reg";
264 flags = SEC_HAS_CONTENTS;
252b5132 265
b34976b6 266 break;
252b5132
RH
267 case CORES_PREGION: /* A program region, map it */
268 switch (chead.cs_x.csx_preg.csxp_rtyp)
269 {
270 case PT_DATA:
b34976b6 271 secname = ".data"; /* Data region. */
252b5132
RH
272 break;
273 case PT_STACK:
b34976b6 274 secname = ".stack"; /* Stack region. */
252b5132
RH
275 break;
276 case PT_SHMEM:
b34976b6 277 secname = ".shmem"; /* Shared memory */
252b5132
RH
278 break;
279 case PT_LIBDAT:
b34976b6 280 secname = ".libdat"; /* Shared library data */
252b5132
RH
281 break;
282 case PT_V86:
b34976b6 283 secname = ".virt86"; /* Virtual 8086 mode */
252b5132
RH
284 break;
285 case PT_SHFIL:
b34976b6 286 secname = ".mmfile"; /* Memory mapped file */
252b5132
RH
287 break;
288 case PT_XDATA0:
b34976b6 289 secname = ".Xdat0"; /* XENIX data region, virtual 0 */
252b5132
RH
290 break;
291 default:
292 secname = "";
293 }
294 flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
295 break;
296 case CORES_PROC: /* struct proc */
297 case CORES_ITIMER: /* interval timers */
298 case CORES_SCOUTSNAME: /* struct scoutsname */
299 secname = NULL; /* Ignore these */
300 break;
b34976b6
AM
301 default:
302 (*_bfd_error_handler) ("Unhandled SCO core file section type %d\n",
303 chead.cs_stype);
304 continue;
305 }
252b5132
RH
306
307 if (secname
308 && !make_bfd_asection (abfd, secname, flags,
309 (bfd_size_type) chead.cs_vsize,
310 (bfd_vma) chead.cs_vaddr,
311 (file_ptr) chead.cs_sseek))
9e7b37b3 312 goto fail;
252b5132
RH
313
314 }
315
316 return abfd->xvec;
317
9e7b37b3
AM
318 fail:
319 if (abfd->tdata.any)
320 {
321 bfd_release (abfd, abfd->tdata.any);
322 abfd->tdata.any = NULL;
323 }
324 bfd_section_list_clear (abfd);
325 return NULL;
252b5132
RH
326}
327
328char *
329sco5_core_file_failing_command (abfd)
330 bfd *abfd;
331{
332 char *com = abfd->tdata.sco5_core_data->u.u_comm;
333 if (*com)
334 return com;
335 else
336 return NULL;
337}
338
252b5132
RH
339int
340sco5_core_file_failing_signal (ignore_abfd)
341 bfd *ignore_abfd;
342{
7b82c249
KH
343 return ((ignore_abfd->tdata.sco5_core_data->u.u_sysabort != 0)
344 ? ignore_abfd->tdata.sco5_core_data->u.u_sysabort
252b5132
RH
345 : -1);
346}
347
b34976b6 348bfd_boolean
252b5132 349sco5_core_file_matches_executable_p (core_bfd, exec_bfd)
dc810e39
AM
350 bfd *core_bfd ATTRIBUTE_UNUSED;
351 bfd *exec_bfd ATTRIBUTE_UNUSED;
252b5132 352{
b34976b6 353 return TRUE; /* FIXME, We have no way of telling at this point */
252b5132
RH
354}
355
252b5132
RH
356/* If somebody calls any byte-swapping routines, shoot them. */
357static void
7b82c249 358swap_abort ()
252b5132 359{
7b82c249 360 abort (); /* This way doesn't require any declaration for ANSI to fuck up */
252b5132 361}
8ce8c090 362
edeb6e24
AM
363#define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
364#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
365#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
8ce8c090
AM
366#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
367#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
368#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
252b5132
RH
369
370const bfd_target sco5_core_vec =
371 {
372 "sco5-core",
373 bfd_target_unknown_flavour,
b34976b6
AM
374 BFD_ENDIAN_LITTLE, /* target byte order */
375 BFD_ENDIAN_LITTLE, /* target headers byte order */
376 (HAS_RELOC | EXEC_P | /* object flags */
252b5132
RH
377 HAS_LINENO | HAS_DEBUG |
378 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
379 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
b34976b6
AM
380 0, /* symbol prefix */
381 ' ', /* ar_pad_char */
382 16, /* ar_max_namelen */
8ce8c090 383 NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit data */
edeb6e24
AM
384 NO_GET, NO_GETS, NO_PUT, /* 32 bit data */
385 NO_GET, NO_GETS, NO_PUT, /* 16 bit data */
8ce8c090 386 NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs */
edeb6e24
AM
387 NO_GET, NO_GETS, NO_PUT, /* 32 bit hdrs */
388 NO_GET, NO_GETS, NO_PUT, /* 16 bit hdrs */
b34976b6
AM
389
390 { /* bfd_check_format */
8ce8c090
AM
391 _bfd_dummy_target, /* unknown format */
392 _bfd_dummy_target, /* object file */
393 _bfd_dummy_target, /* archive */
394 sco5_core_file_p /* a core file */
252b5132 395 },
b34976b6 396 { /* bfd_set_format */
8ce8c090
AM
397 bfd_false, bfd_false,
398 bfd_false, bfd_false
252b5132 399 },
b34976b6 400 { /* bfd_write_contents */
8ce8c090
AM
401 bfd_false, bfd_false,
402 bfd_false, bfd_false
252b5132
RH
403 },
404
3f3c5c34
AM
405 BFD_JUMP_TABLE_GENERIC (_bfd_generic),
406 BFD_JUMP_TABLE_COPY (_bfd_generic),
407 BFD_JUMP_TABLE_CORE (sco5),
408 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
409 BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
410 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
411 BFD_JUMP_TABLE_WRITE (_bfd_generic),
412 BFD_JUMP_TABLE_LINK (_bfd_nolink),
413 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
252b5132 414
c3c89269 415 NULL,
7b82c249 416
b34976b6 417 (PTR) 0 /* backend_data */
8ce8c090 418 };
This page took 0.354709 seconds and 4 git commands to generate.