1 /* BFD back-end for CISCO crash dumps.
3 Copyright 1994 Free Software Foundation, Inc.
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 /* core_file_failing_signal returns a host signal (this probably should
39 #define CRASH_INFO (0xffc)
40 #define CRASH_MAGIC 0xdead1234
43 CRASH_REASON_NOTCRASHED
= 0,
44 CRASH_REASON_EXCEPTION
= 1,
45 CRASH_REASON_CORRUPT
= 2,
48 struct crashinfo_external
50 char magic
[4]; /* Magic number */
51 char version
[4]; /* Version number */
52 char reason
[4]; /* Crash reason */
53 char cpu_vector
[4]; /* CPU vector for exceptions */
54 char registers
[4]; /* Pointer to saved registers */
55 char rambase
[4]; /* Base of RAM (not in V1 crash info) */
58 struct cisco_core_struct
63 static const bfd_target
*
64 cisco_core_file_p (abfd
)
68 unsigned int crashinfo_offset
;
69 struct crashinfo_external crashinfo
;
75 if (bfd_seek (abfd
, CRASH_INFO
, SEEK_SET
) != 0)
78 nread
= bfd_read (buf
, 1, 4, abfd
);
81 if (bfd_get_error () != bfd_error_system_call
)
82 bfd_set_error (bfd_error_wrong_format
);
85 crashinfo_offset
= bfd_get_32 (abfd
, buf
);
87 if (bfd_seek (abfd
, crashinfo_offset
, SEEK_SET
) != 0)
90 nread
= bfd_read (&crashinfo
, 1, sizeof (crashinfo
), abfd
);
91 if (nread
!= sizeof (crashinfo
))
93 if (bfd_get_error () != bfd_error_system_call
)
94 bfd_set_error (bfd_error_wrong_format
);
98 if (bfd_stat (abfd
, &statbuf
) < 0)
100 bfd_set_error (bfd_error_system_call
);
104 if (bfd_get_32 (abfd
, crashinfo
.magic
) != CRASH_MAGIC
)
106 bfd_set_error (bfd_error_wrong_format
);
110 switch (bfd_get_32 (abfd
, crashinfo
.version
))
113 bfd_set_error (bfd_error_wrong_format
);
120 rambase
= bfd_get_32 (abfd
, crashinfo
.rambase
);
124 /* OK, we believe you. You're a core file. */
126 abfd
->tdata
.cisco_core_data
=
127 ((struct cisco_core_struct
*)
128 bfd_zmalloc (sizeof (struct cisco_core_struct
)));
129 if (abfd
->tdata
.cisco_core_data
== NULL
)
132 switch ((crashreason
) bfd_get_32 (abfd
, crashinfo
.reason
))
134 case CRASH_REASON_NOTCRASHED
:
135 /* Crash file probably came from write core. */
136 abfd
->tdata
.cisco_core_data
->sig
= 0;
138 case CRASH_REASON_CORRUPT
:
139 /* The crash context area was corrupt -- proceed with caution.
140 We have no way of passing this information back to the caller. */
141 abfd
->tdata
.cisco_core_data
->sig
= 0;
143 case CRASH_REASON_EXCEPTION
:
144 /* Crash occured due to CPU exception. */
146 /* This is 68k-specific; for MIPS we'll need to interpret
147 cpu_vector differently based on the target configuration
148 (since CISCO core files don't seem to have the processor
151 switch (bfd_get_32 (abfd
, crashinfo
.cpu_vector
))
154 case 2 : abfd
->tdata
.cisco_core_data
->sig
= SIGBUS
; break;
156 case 3 : abfd
->tdata
.cisco_core_data
->sig
= SIGBUS
; break;
157 /* illegal instruction */
158 case 4 : abfd
->tdata
.cisco_core_data
->sig
= SIGILL
; break;
160 case 5 : abfd
->tdata
.cisco_core_data
->sig
= SIGFPE
; break;
161 /* chk instruction */
162 case 6 : abfd
->tdata
.cisco_core_data
->sig
= SIGFPE
; break;
163 /* trapv instruction */
164 case 7 : abfd
->tdata
.cisco_core_data
->sig
= SIGFPE
; break;
165 /* privilege violation */
166 case 8 : abfd
->tdata
.cisco_core_data
->sig
= SIGSEGV
; break;
168 case 9 : abfd
->tdata
.cisco_core_data
->sig
= SIGTRAP
; break;
169 /* line 1010 emulator */
170 case 10: abfd
->tdata
.cisco_core_data
->sig
= SIGILL
; break;
171 /* line 1111 emulator */
172 case 11: abfd
->tdata
.cisco_core_data
->sig
= SIGILL
; break;
174 /* Coprocessor protocol violation. Using a standard MMU or FPU
175 this cannot be triggered by software. Call it a SIGBUS. */
176 case 13: abfd
->tdata
.cisco_core_data
->sig
= SIGBUS
; break;
179 case 31: abfd
->tdata
.cisco_core_data
->sig
= SIGINT
; break;
181 case 33: abfd
->tdata
.cisco_core_data
->sig
= SIGTRAP
; break;
183 /* floating point err */
184 case 48: abfd
->tdata
.cisco_core_data
->sig
= SIGFPE
; break;
185 /* floating point err */
186 case 49: abfd
->tdata
.cisco_core_data
->sig
= SIGFPE
; break;
188 case 50: abfd
->tdata
.cisco_core_data
->sig
= SIGFPE
; break;
190 case 51: abfd
->tdata
.cisco_core_data
->sig
= SIGFPE
; break;
192 case 52: abfd
->tdata
.cisco_core_data
->sig
= SIGFPE
; break;
194 case 53: abfd
->tdata
.cisco_core_data
->sig
= SIGFPE
; break;
196 case 54: abfd
->tdata
.cisco_core_data
->sig
= SIGFPE
; break;
199 #define SIGEMT SIGTRAP
201 /* "software generated"*/
202 abfd
->tdata
.cisco_core_data
->sig
= SIGEMT
;
206 /* Unknown crash reason. */
207 abfd
->tdata
.cisco_core_data
->sig
= 0;
211 abfd
->sections
= NULL
;
212 abfd
->section_count
= 0;
214 asect
= (asection
*) bfd_zmalloc (sizeof (asection
));
217 asect
->name
= ".reg";
218 asect
->flags
= SEC_HAS_CONTENTS
;
219 /* This can be bigger than the real size. Set it to the size of the whole
221 asect
->_raw_size
= statbuf
.st_size
;
223 asect
->filepos
= bfd_get_32 (abfd
, crashinfo
.registers
) - rambase
;
224 asect
->next
= abfd
->sections
;
225 abfd
->sections
= asect
;
226 ++abfd
->section_count
;
228 /* There is only one section containing data from the target system's RAM.
230 asect
= (asection
*) bfd_zmalloc (sizeof (asection
));
233 asect
->name
= ".data";
234 asect
->flags
= SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
;
235 /* The size of memory is the size of the core file itself. */
236 asect
->_raw_size
= statbuf
.st_size
;
237 asect
->vma
= rambase
;
239 asect
->next
= abfd
->sections
;
240 abfd
->sections
= asect
;
241 ++abfd
->section_count
;
248 for (asect
= abfd
->sections
; asect
!= NULL
;)
250 nextsect
= asect
->next
;
254 free (abfd
->tdata
.cisco_core_data
);
260 cisco_core_file_failing_command (abfd
)
267 cisco_core_file_failing_signal (abfd
)
270 return abfd
->tdata
.cisco_core_data
->sig
;
274 cisco_core_file_matches_executable_p (core_bfd
, exec_bfd
)
281 const bfd_target cisco_core_vec
=
284 bfd_target_unknown_flavour
,
285 BFD_ENDIAN_BIG
, /* target byte order */
286 BFD_ENDIAN_BIG
, /* target headers byte order */
287 (HAS_RELOC
| EXEC_P
| /* object flags */
288 HAS_LINENO
| HAS_DEBUG
|
289 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
290 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
291 0, /* symbol prefix */
292 ' ', /* ar_pad_char */
293 16, /* ar_max_namelen */
294 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
295 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
296 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* data */
297 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
298 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
299 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* hdrs */
301 { /* bfd_check_format */
302 _bfd_dummy_target
, /* unknown format */
303 _bfd_dummy_target
, /* object file */
304 _bfd_dummy_target
, /* archive */
305 cisco_core_file_p
/* a core file */
307 { /* bfd_set_format */
308 bfd_false
, bfd_false
,
311 { /* bfd_write_contents */
312 bfd_false
, bfd_false
,
316 BFD_JUMP_TABLE_GENERIC (_bfd_generic
),
317 BFD_JUMP_TABLE_COPY (_bfd_generic
),
318 BFD_JUMP_TABLE_CORE (cisco
),
319 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive
),
320 BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols
),
321 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs
),
322 BFD_JUMP_TABLE_WRITE (_bfd_generic
),
323 BFD_JUMP_TABLE_LINK (_bfd_nolink
),
324 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),
326 (PTR
) 0 /* backend_data */