1 /* BFD back end for SCO5 core files (U-area and raw sections)
2 Copyright 1998 Free Software Foundation, Inc.
3 Written by Jouke Numan <jnuman@hiscom.nl>
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 #include "libaout.h" /* BFD a.out internal data structures */
27 #include <sys/types.h>
28 #include <sys/param.h>
32 #include <sys/user.h> /* After a.out.h */
33 #include <sys/paccess.h>
34 #include <sys/region.h>
36 struct sco5_core_struct
41 /* forward declarations */
44 make_bfd_asection
PARAMS ((bfd
*, const char *, flagword
, bfd_size_type
,
46 static asymbol
*sco5_core_make_empty_symbol
PARAMS ((bfd
*));
47 static struct user
*read_uarea
PARAMS ((bfd
*, int));
48 const bfd_target
*sco5_core_file_p
PARAMS ((bfd
*abfd
));
49 char *sco5_core_file_failing_command
PARAMS ((bfd
*abfd
));
50 int sco5_core_file_failing_signal
PARAMS ((bfd
*abfd
));
51 boolean sco5_core_file_matches_executable_p
PARAMS ((bfd
*core_bfd
,
53 static void swap_abort
PARAMS ((void));
56 make_bfd_asection (abfd
, name
, flags
, _raw_size
, vma
, filepos
)
60 bfd_size_type _raw_size
;
66 asect
= bfd_make_section_anyway (abfd
, name
);
70 asect
->_raw_size
= _raw_size
;
72 asect
->filepos
= filepos
;
73 asect
->alignment_power
= 2;
79 sco5_core_make_empty_symbol (abfd
)
82 asymbol
*new = (asymbol
*) bfd_zalloc (abfd
, sizeof (asymbol
));
89 read_uarea(abfd
, filepos
)
94 struct sco5_core_struct
*rawptr
;
96 rawptr
= ((struct sco5_core_struct
*)
97 bfd_zmalloc (sizeof (struct sco5_core_struct
)));
101 abfd
->tdata
.sco5_core_data
= rawptr
;
103 if ((bfd_seek (abfd
, filepos
, SEEK_SET
) != 0)
104 || (bfd_read ((void *)&rawptr
->u
, 1, sizeof rawptr
->u
, abfd
)
105 != sizeof rawptr
->u
))
107 bfd_set_error (bfd_error_wrong_format
);
111 /* Sanity check perhaps??? */
112 if (rawptr
->u
.u_dsize
> 0x1000000) /* Remember, it's in pages... */
114 bfd_set_error (bfd_error_wrong_format
);
117 if (rawptr
->u
.u_ssize
> 0x1000000)
119 bfd_set_error (bfd_error_wrong_format
);
127 sco5_core_file_p (abfd
)
130 int coffset_siz
, val
, nsecs
, cheadoffs
;
133 struct coreoffsets coffsets
;
134 struct coresecthead chead
;
138 /* Read coreoffsets region at end of core (see core(FP)) */
141 FILE *stream
= bfd_cache_lookup (abfd
);
145 if (fstat (fileno (stream
), &statbuf
) < 0)
147 bfd_set_error (bfd_error_system_call
);
150 coresize
= statbuf
.st_size
;
152 /* Last long in core is sizeof struct coreoffsets, read it */
153 if ((bfd_seek (abfd
, coresize
-sizeof coffset_siz
, SEEK_SET
) != 0)
154 || (bfd_read ((void *)&coffset_siz
, 1, sizeof coffset_siz
, abfd
)
155 != sizeof coffset_siz
) )
157 bfd_set_error (bfd_error_wrong_format
);
161 /* Use it to seek start of coreoffsets region, read it and determine
163 if ((bfd_seek (abfd
, coresize
-coffset_siz
, SEEK_SET
) != 0)
164 || (bfd_read ((void *)&coffsets
, 1, sizeof coffsets
, abfd
)
166 || ((coffsets
.u_info
!= 1) && (coffsets
.u_info
!= C_VERSION
)))
168 bfd_set_error (bfd_error_wrong_format
);
173 if (coffsets
.u_info
== 1)
175 /* Old version, no section heads, read info from user struct */
177 u
= read_uarea(abfd
, coffsets
.u_user
);
181 if (!make_bfd_asection (abfd
, ".reg", SEC_HAS_CONTENTS
,
182 (bfd_size_type
) coffsets
.u_usize
,
183 0 - (bfd_vma
) u
->u_ar0
,
184 (file_ptr
) coffsets
.u_user
))
187 if (!make_bfd_asection (abfd
, ".data",
188 SEC_ALLOC
+ SEC_LOAD
+ SEC_HAS_CONTENTS
,
189 ((bfd_size_type
) u
->u_exdata
.ux_dsize
190 + u
->u_exdata
.ux_bsize
),
191 (bfd_vma
) u
->u_exdata
.ux_datorg
,
192 (file_ptr
) coffsets
.u_data
))
195 if (!make_bfd_asection (abfd
, ".stack",
196 SEC_ALLOC
+ SEC_LOAD
+ SEC_HAS_CONTENTS
,
197 (bfd_size_type
) u
->u_ssize
* NBPC
,
199 (file_ptr
) coffsets
.u_stack
))
202 return abfd
->xvec
; /* Done for version 1 */
205 /* Immediately before coreoffsets region is a long with offset in core
206 to first coresecthead (CORES_OFFSETS), the long before this is the
207 number of section heads in the list. Read both longs and read the
208 coresecthead and check its validity */
211 coresize
- coffset_siz
- 2 * sizeof coffset_siz
,
213 || (bfd_read ((void *)&nsecs
, 1, sizeof nsecs
, abfd
) != sizeof nsecs
)
214 || (bfd_read ((void *)&cheadoffs
, 1, sizeof cheadoffs
, abfd
)
216 || (bfd_seek (abfd
, cheadoffs
, SEEK_SET
) != 0)
217 || (bfd_read ((void *)&chead
, 1, sizeof chead
, abfd
) != sizeof chead
)
218 || (chead
.cs_stype
!= CORES_OFFSETS
)
219 || (chead
.cs_x
.csx_magic
!= COREMAGIC_NUMBER
))
221 bfd_set_error (bfd_error_wrong_format
);
225 /* OK, we believe you. You're a core file (sure, sure). */
227 /* Now loop over all regions and map them */
228 nsecs
--; /* We've seen CORES_OFFSETS already */
229 for (; nsecs
; nsecs
--)
231 if ((bfd_seek (abfd
, chead
.cs_hseek
, SEEK_SET
) != 0)
232 || bfd_read ((void *)&chead
, 1, sizeof chead
, abfd
) != sizeof chead
)
234 bfd_set_error (bfd_error_wrong_format
);
238 switch (chead
.cs_stype
)
240 case CORES_MAGIC
: /* Core header, check magic */
241 if (chead
.cs_x
.csx_magic
!= COREMAGIC_NUMBER
)
243 bfd_set_error (bfd_error_wrong_format
);
247 nsecs
++; /* MAGIC not in section cnt!*/
249 case CORES_UAREA
: /* U-area, read in tdata */
250 u
= read_uarea(abfd
, chead
.cs_sseek
);
254 /* This is tricky. As the "register section", we give them
255 the entire upage and stack. u.u_ar0 points to where
256 "register 0" is stored. There are two tricks with this,
257 though. One is that the rest of the registers might be
258 at positive or negative (or both) displacements from
259 *u_ar0. The other is that u_ar0 is sometimes an absolute
260 address in kernel memory, and on other systems it is an
261 offset from the beginning of the `struct user'.
263 As a practical matter, we don't know where the registers
264 actually are, so we have to pass the whole area to GDB.
265 We encode the value of u_ar0 by setting the .regs section
266 up so that its virtual memory address 0 is at the place
267 pointed to by u_ar0 (by setting the vma of the start of
268 the section to -u_ar0). GDB uses this info to locate the
269 regs, using minor trickery to get around the
270 offset-or-absolute-addr problem. */
272 chead
.cs_vaddr
= 0 - (bfd_vma
) u
->u_ar0
;
276 flags
= SEC_HAS_CONTENTS
;
279 case CORES_PREGION
: /* A program region, map it */
280 switch (chead
.cs_x
.csx_preg
.csxp_rtyp
)
283 secname
= ".data"; /* Data region. */
286 secname
= ".stack"; /* Stack region. */
289 secname
= ".shmem"; /* Shared memory */
292 secname
= ".libdat"; /* Shared library data */
295 secname
= ".virt86"; /* Virtual 8086 mode */
298 secname
= ".mmfile"; /* Memory mapped file */
301 secname
= ".Xdat0"; /* XENIX data region, virtual 0 */
306 flags
= SEC_ALLOC
+ SEC_LOAD
+ SEC_HAS_CONTENTS
;
308 case CORES_PROC
: /* struct proc */
309 case CORES_ITIMER
: /* interval timers */
310 case CORES_SCOUTSNAME
: /* struct scoutsname */
311 secname
= NULL
; /* Ignore these */
314 (*_bfd_error_handler
) ("Unhandled SCO core file section type %d\n",
320 && !make_bfd_asection (abfd
, secname
, flags
,
321 (bfd_size_type
) chead
.cs_vsize
,
322 (bfd_vma
) chead
.cs_vaddr
,
323 (file_ptr
) chead
.cs_sseek
))
333 sco5_core_file_failing_command (abfd
)
336 char *com
= abfd
->tdata
.sco5_core_data
->u
.u_comm
;
345 sco5_core_file_failing_signal (ignore_abfd
)
348 return ((ignore_abfd
->tdata
.sco5_core_data
->u
.u_sysabort
!= 0)
349 ? ignore_abfd
->tdata
.sco5_core_data
->u
.u_sysabort
355 sco5_core_file_matches_executable_p (core_bfd
, exec_bfd
)
356 bfd
*core_bfd
, *exec_bfd
;
358 return true; /* FIXME, We have no way of telling at this point */
361 #define sco5_core_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound
362 #define sco5_core_get_symtab _bfd_nosymbols_get_symtab
363 #define sco5_core_print_symbol _bfd_nosymbols_print_symbol
364 #define sco5_core_get_symbol_info _bfd_nosymbols_get_symbol_info
365 #define sco5_core_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
366 #define sco5_core_get_lineno _bfd_nosymbols_get_lineno
367 #define sco5_core_find_nearest_line _bfd_nosymbols_find_nearest_line
368 #define sco5_core_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
369 #define sco5_core_read_minisymbols _bfd_nosymbols_read_minisymbols
370 #define sco5_core_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol
372 /* If somebody calls any byte-swapping routines, shoot them. */
376 abort(); /* This way doesn't require any declaration for ANSI to fuck up */
378 #define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort )
379 #define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
380 #define NO_SIGNED_GET \
381 ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
383 const bfd_target sco5_core_vec
=
386 bfd_target_unknown_flavour
,
387 BFD_ENDIAN_LITTLE
, /* target byte order */
388 BFD_ENDIAN_LITTLE
, /* target headers byte order */
389 (HAS_RELOC
| EXEC_P
| /* object flags */
390 HAS_LINENO
| HAS_DEBUG
|
391 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
392 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
393 0, /* symbol prefix */
394 ' ', /* ar_pad_char */
395 16, /* ar_max_namelen */
396 NO_GET
, NO_SIGNED_GET
, NO_PUT
, /* 64 bit data */
397 NO_GET
, NO_SIGNED_GET
, NO_PUT
, /* 32 bit data */
398 NO_GET
, NO_SIGNED_GET
, NO_PUT
, /* 16 bit data */
399 NO_GET
, NO_SIGNED_GET
, NO_PUT
, /* 64 bit hdrs */
400 NO_GET
, NO_SIGNED_GET
, NO_PUT
, /* 32 bit hdrs */
401 NO_GET
, NO_SIGNED_GET
, NO_PUT
, /* 16 bit hdrs */
403 { /* bfd_check_format */
404 _bfd_dummy_target
, /* unknown format */
405 _bfd_dummy_target
, /* object file */
406 _bfd_dummy_target
, /* archive */
407 sco5_core_file_p
/* a core file */
409 { /* bfd_set_format */
410 bfd_false
, bfd_false
,
413 { /* bfd_write_contents */
414 bfd_false
, bfd_false
,
418 BFD_JUMP_TABLE_GENERIC (_bfd_generic
),
419 BFD_JUMP_TABLE_COPY (_bfd_generic
),
420 BFD_JUMP_TABLE_CORE (sco5
),
421 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive
),
422 BFD_JUMP_TABLE_SYMBOLS (sco5_core
),
423 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs
),
424 BFD_JUMP_TABLE_WRITE (_bfd_generic
),
425 BFD_JUMP_TABLE_LINK (_bfd_nolink
),
426 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),
430 (PTR
) 0 /* backend_data */