include/ChangeLog
[deliverable/binutils-gdb.git] / bfd / cisco-core.c
CommitLineData
252b5132 1/* BFD back-end for CISCO crash dumps.
d3aeb6ee
AM
2 Copyright 1994, 1997, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007,
3 2010, 2011
9e7b37b3 4 Free Software Foundation, Inc.
252b5132 5
cd123cb7 6 This file is part of BFD, the Binary File Descriptor library.
252b5132 7
cd123cb7
NC
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
252b5132 12
cd123cb7
NC
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
252b5132 17
cd123cb7
NC
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
252b5132 22
252b5132 23#include "sysdep.h"
3db64b00 24#include "bfd.h"
252b5132
RH
25#include "libbfd.h"
26/* core_file_failing_signal returns a host signal (this probably should
27 be fixed). */
28#include <signal.h>
29
30/* for MSVC builds */
31#ifndef SIGTRAP
32# define SIGTRAP 5
33#endif
34#ifndef SIGEMT
35# define SIGEMT 6
36#endif
37#ifndef SIGBUS
38# define SIGBUS 10
39#endif
40\f
f4bda984
RH
41int crash_info_locs[] = {
42 0x0250, /* mips, ppc, x86, i960 */
43 0x0400, /* m68k, mips, x86, i960 */
44 0x0FFC, /* m68k, mips, ppc, x86, i960 */
45 0x3000, /* ppc */
46 0x4FFC, /* m68k */
47 -1
48};
49
50#define CRASH_MAGIC 0xdead1234
51#define MASK_ADDR(x) ((x) & 0x0fffffff) /* Mask crash info address */
252b5132
RH
52
53typedef enum {
54 CRASH_REASON_NOTCRASHED = 0,
55 CRASH_REASON_EXCEPTION = 1,
56 CRASH_REASON_CORRUPT = 2,
f4bda984 57} crashreason;
252b5132 58
f4bda984
RH
59typedef struct {
60 char magic[4]; /* Magic number */
252b5132
RH
61 char version[4]; /* Version number */
62 char reason[4]; /* Crash reason */
63 char cpu_vector[4]; /* CPU vector for exceptions */
64 char registers[4]; /* Pointer to saved registers */
65 char rambase[4]; /* Base of RAM (not in V1 crash info) */
f4bda984
RH
66 char textbase[4]; /* Base of .text section (not in V3 crash info) */
67 char database[4]; /* Base of .data section (not in V3 crash info) */
68 char bssbase[4]; /* Base of .bss section (not in V3 crash info) */
69} crashinfo_external;
dc810e39 70
252b5132
RH
71struct cisco_core_struct
72{
73 int sig;
74};
dc810e39
AM
75
76static const bfd_target *cisco_core_file_validate PARAMS ((bfd *, int));
77static const bfd_target *cisco_core_file_p PARAMS ((bfd *));
78char *cisco_core_file_failing_command PARAMS ((bfd *));
79int cisco_core_file_failing_signal PARAMS ((bfd *));
69d246d9 80#define cisco_core_file_matches_executable_p generic_core_file_matches_executable_p
35e7447c 81#define cisco_core_file_pid _bfd_nocore_core_file_pid
252b5132 82\f
f4bda984 83/* Examine the file for a crash info struct at the offset given by
e60b52c6 84 CRASH_INFO_LOC. */
f4bda984 85
252b5132 86static const bfd_target *
f4bda984 87cisco_core_file_validate (abfd, crash_info_loc)
252b5132 88 bfd *abfd;
f4bda984 89 int crash_info_loc;
252b5132
RH
90{
91 char buf[4];
92 unsigned int crashinfo_offset;
f4bda984 93 crashinfo_external crashinfo;
74633dd0 94 bfd_size_type nread;
f4bda984
RH
95 unsigned int magic;
96 unsigned int version;
252b5132
RH
97 unsigned int rambase;
98 sec_ptr asect;
99 struct stat statbuf;
dc810e39 100 bfd_size_type amt;
117ed4f8 101 flagword flags;
252b5132 102
dc810e39 103 if (bfd_seek (abfd, (file_ptr) crash_info_loc, SEEK_SET) != 0)
252b5132
RH
104 return NULL;
105
dc810e39 106 nread = bfd_bread (buf, (bfd_size_type) 4, abfd);
252b5132
RH
107 if (nread != 4)
108 {
109 if (bfd_get_error () != bfd_error_system_call)
110 bfd_set_error (bfd_error_wrong_format);
111 return NULL;
112 }
f4bda984 113 crashinfo_offset = MASK_ADDR (bfd_get_32 (abfd, buf));
252b5132 114
dc810e39 115 if (bfd_seek (abfd, (file_ptr) crashinfo_offset, SEEK_SET) != 0)
f4bda984
RH
116 {
117 /* Most likely we failed because of a bogus (huge) offset */
118 bfd_set_error (bfd_error_wrong_format);
119 return NULL;
120 }
252b5132 121
dc810e39 122 nread = bfd_bread (&crashinfo, (bfd_size_type) sizeof (crashinfo), abfd);
252b5132
RH
123 if (nread != sizeof (crashinfo))
124 {
125 if (bfd_get_error () != bfd_error_system_call)
126 bfd_set_error (bfd_error_wrong_format);
127 return NULL;
128 }
129
130 if (bfd_stat (abfd, &statbuf) < 0)
131 {
132 bfd_set_error (bfd_error_system_call);
133 return NULL;
134 }
135
f4bda984
RH
136 magic = bfd_get_32 (abfd, crashinfo.magic);
137 if (magic != CRASH_MAGIC)
252b5132
RH
138 {
139 bfd_set_error (bfd_error_wrong_format);
140 return NULL;
141 }
142
f4bda984
RH
143 version = bfd_get_32 (abfd, crashinfo.version);
144 if (version == 0)
252b5132 145 {
252b5132
RH
146 bfd_set_error (bfd_error_wrong_format);
147 return NULL;
f4bda984
RH
148 }
149 else if (version == 1)
150 {
151 /* V1 core dumps don't specify the dump base, assume 0 */
252b5132 152 rambase = 0;
f4bda984
RH
153 }
154 else
155 {
252b5132 156 rambase = bfd_get_32 (abfd, crashinfo.rambase);
252b5132
RH
157 }
158
159 /* OK, we believe you. You're a core file. */
160
dc810e39
AM
161 amt = sizeof (struct cisco_core_struct);
162 abfd->tdata.cisco_core_data = (struct cisco_core_struct *) bfd_zmalloc (amt);
252b5132
RH
163 if (abfd->tdata.cisco_core_data == NULL)
164 return NULL;
165
166 switch ((crashreason) bfd_get_32 (abfd, crashinfo.reason))
167 {
168 case CRASH_REASON_NOTCRASHED:
169 /* Crash file probably came from write core. */
170 abfd->tdata.cisco_core_data->sig = 0;
171 break;
172 case CRASH_REASON_CORRUPT:
173 /* The crash context area was corrupt -- proceed with caution.
174 We have no way of passing this information back to the caller. */
175 abfd->tdata.cisco_core_data->sig = 0;
176 break;
177 case CRASH_REASON_EXCEPTION:
178 /* Crash occured due to CPU exception. */
179
180 /* This is 68k-specific; for MIPS we'll need to interpret
181 cpu_vector differently based on the target configuration
182 (since CISCO core files don't seem to have the processor
183 encoded in them). */
184
185 switch (bfd_get_32 (abfd, crashinfo.cpu_vector))
186 {
187 /* bus error */
188 case 2 : abfd->tdata.cisco_core_data->sig = SIGBUS; break;
189 /* address error */
190 case 3 : abfd->tdata.cisco_core_data->sig = SIGBUS; break;
191 /* illegal instruction */
192 case 4 : abfd->tdata.cisco_core_data->sig = SIGILL; break;
193 /* zero divide */
194 case 5 : abfd->tdata.cisco_core_data->sig = SIGFPE; break;
195 /* chk instruction */
196 case 6 : abfd->tdata.cisco_core_data->sig = SIGFPE; break;
197 /* trapv instruction */
198 case 7 : abfd->tdata.cisco_core_data->sig = SIGFPE; break;
199 /* privilege violation */
200 case 8 : abfd->tdata.cisco_core_data->sig = SIGSEGV; break;
201 /* trace trap */
202 case 9 : abfd->tdata.cisco_core_data->sig = SIGTRAP; break;
203 /* line 1010 emulator */
204 case 10: abfd->tdata.cisco_core_data->sig = SIGILL; break;
205 /* line 1111 emulator */
206 case 11: abfd->tdata.cisco_core_data->sig = SIGILL; break;
207
208 /* Coprocessor protocol violation. Using a standard MMU or FPU
209 this cannot be triggered by software. Call it a SIGBUS. */
210 case 13: abfd->tdata.cisco_core_data->sig = SIGBUS; break;
211
212 /* interrupt */
213 case 31: abfd->tdata.cisco_core_data->sig = SIGINT; break;
214 /* breakpoint */
215 case 33: abfd->tdata.cisco_core_data->sig = SIGTRAP; break;
216
217 /* floating point err */
218 case 48: abfd->tdata.cisco_core_data->sig = SIGFPE; break;
219 /* floating point err */
220 case 49: abfd->tdata.cisco_core_data->sig = SIGFPE; break;
221 /* zero divide */
222 case 50: abfd->tdata.cisco_core_data->sig = SIGFPE; break;
223 /* underflow */
224 case 51: abfd->tdata.cisco_core_data->sig = SIGFPE; break;
225 /* operand error */
226 case 52: abfd->tdata.cisco_core_data->sig = SIGFPE; break;
227 /* overflow */
228 case 53: abfd->tdata.cisco_core_data->sig = SIGFPE; break;
229 /* NAN */
230 case 54: abfd->tdata.cisco_core_data->sig = SIGFPE; break;
231 default:
232#ifndef SIGEMT
233#define SIGEMT SIGTRAP
234#endif
235 /* "software generated"*/
236 abfd->tdata.cisco_core_data->sig = SIGEMT;
237 }
238 break;
239 default:
240 /* Unknown crash reason. */
241 abfd->tdata.cisco_core_data->sig = 0;
242 break;
243 }
244
9e7b37b3
AM
245 /* Create a ".data" section that maps the entire file, which is
246 essentially a dump of the target system's RAM. */
f4bda984 247
117ed4f8
AM
248 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
249 asect = bfd_make_section_anyway_with_flags (abfd, ".data", flags);
252b5132
RH
250 if (asect == NULL)
251 goto error_return;
9e7b37b3 252 /* The size of memory is the size of the core file itself. */
eea6121a 253 asect->size = statbuf.st_size;
9e7b37b3
AM
254 asect->vma = rambase;
255 asect->filepos = 0;
252b5132 256
f4bda984 257 /* Create a ".crash" section to allow access to the saved
e60b52c6 258 crash information. */
f4bda984 259
117ed4f8
AM
260 flags = SEC_HAS_CONTENTS;
261 asect = bfd_make_section_anyway_with_flags (abfd, ".crash", flags);
f4bda984
RH
262 if (asect == NULL)
263 goto error_return;
f4bda984
RH
264 asect->vma = 0;
265 asect->filepos = crashinfo_offset;
eea6121a 266 asect->size = sizeof (crashinfo);
f4bda984 267
9e7b37b3
AM
268 /* Create a ".reg" section to allow access to the saved
269 registers. */
f4bda984 270
117ed4f8 271 asect = bfd_make_section_anyway_with_flags (abfd, ".reg", flags);
252b5132
RH
272 if (asect == NULL)
273 goto error_return;
9e7b37b3
AM
274 asect->vma = 0;
275 asect->filepos = bfd_get_32 (abfd, crashinfo.registers) - rambase;
276 /* Since we don't know the exact size of the saved register info,
277 choose a register section size that is either the remaining part
278 of the file, or 1024, whichever is smaller. */
279 nread = statbuf.st_size - asect->filepos;
eea6121a 280 asect->size = (nread < 1024) ? nread : 1024;
252b5132
RH
281
282 return abfd->xvec;
283
f4bda984 284 /* Get here if we have already started filling out the BFD
e60b52c6 285 and there is an error of some kind. */
f4bda984 286
252b5132 287 error_return:
9e7b37b3
AM
288 bfd_release (abfd, abfd->tdata.any);
289 abfd->tdata.any = NULL;
290 bfd_section_list_clear (abfd);
291 return NULL;
252b5132
RH
292}
293
f4bda984
RH
294static const bfd_target *
295cisco_core_file_p (abfd)
296 bfd *abfd;
297{
298 int *crash_info_locp;
299 const bfd_target *target = NULL;
300
301 for (crash_info_locp = crash_info_locs;
302 *crash_info_locp != -1 && target == NULL;
303 crash_info_locp++)
304 {
305 target = cisco_core_file_validate (abfd, *crash_info_locp);
306 }
307 return (target);
308}
309
252b5132
RH
310char *
311cisco_core_file_failing_command (abfd)
dc810e39 312 bfd *abfd ATTRIBUTE_UNUSED;
252b5132
RH
313{
314 return NULL;
315}
316
317int
318cisco_core_file_failing_signal (abfd)
dc810e39 319 bfd *abfd ATTRIBUTE_UNUSED;
252b5132
RH
320{
321 return abfd->tdata.cisco_core_data->sig;
322}
252b5132 323\f
f4bda984
RH
324extern const bfd_target cisco_core_little_vec;
325
326const bfd_target cisco_core_big_vec =
252b5132 327 {
f4bda984 328 "cisco-ios-core-big",
252b5132
RH
329 bfd_target_unknown_flavour,
330 BFD_ENDIAN_BIG, /* target byte order */
331 BFD_ENDIAN_BIG, /* target headers byte order */
332 (HAS_RELOC | EXEC_P | /* object flags */
333 HAS_LINENO | HAS_DEBUG |
334 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
335 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
d3aeb6ee
AM
336 0, /* symbol prefix */
337 ' ', /* ar_pad_char */
338 16, /* ar_max_namelen */
339 0, /* match priority. */
252b5132
RH
340 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
341 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
342 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
343 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
344 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
345 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
346
347 { /* bfd_check_format */
348 _bfd_dummy_target, /* unknown format */
349 _bfd_dummy_target, /* object file */
350 _bfd_dummy_target, /* archive */
351 cisco_core_file_p /* a core file */
352 },
353 { /* bfd_set_format */
354 bfd_false, bfd_false,
355 bfd_false, bfd_false
356 },
357 { /* bfd_write_contents */
358 bfd_false, bfd_false,
359 bfd_false, bfd_false
360 },
e60b52c6 361
252b5132
RH
362 BFD_JUMP_TABLE_GENERIC (_bfd_generic),
363 BFD_JUMP_TABLE_COPY (_bfd_generic),
364 BFD_JUMP_TABLE_CORE (cisco),
365 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
366 BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
367 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
368 BFD_JUMP_TABLE_WRITE (_bfd_generic),
369 BFD_JUMP_TABLE_LINK (_bfd_nolink),
370 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
371
f4bda984 372 & cisco_core_little_vec,
e60b52c6 373
f4bda984
RH
374 (PTR) 0 /* backend_data */
375};
376
377const bfd_target cisco_core_little_vec =
378 {
379 "cisco-ios-core-little",
380 bfd_target_unknown_flavour,
381 BFD_ENDIAN_LITTLE, /* target byte order */
382 BFD_ENDIAN_LITTLE, /* target headers byte order */
383 (HAS_RELOC | EXEC_P | /* object flags */
384 HAS_LINENO | HAS_DEBUG |
385 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
386 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
387 0, /* symbol prefix */
388 ' ', /* ar_pad_char */
389 16, /* ar_max_namelen */
20ee8bc9 390 0, /* match_priority */
f4bda984
RH
391 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
392 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
393 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
394 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
395 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
396 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
397
398 { /* bfd_check_format */
399 _bfd_dummy_target, /* unknown format */
400 _bfd_dummy_target, /* object file */
401 _bfd_dummy_target, /* archive */
402 cisco_core_file_p /* a core file */
403 },
404 { /* bfd_set_format */
405 bfd_false, bfd_false,
406 bfd_false, bfd_false
407 },
408 { /* bfd_write_contents */
409 bfd_false, bfd_false,
410 bfd_false, bfd_false
411 },
e60b52c6 412
f4bda984
RH
413 BFD_JUMP_TABLE_GENERIC (_bfd_generic),
414 BFD_JUMP_TABLE_COPY (_bfd_generic),
415 BFD_JUMP_TABLE_CORE (cisco),
416 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
417 BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
418 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
419 BFD_JUMP_TABLE_WRITE (_bfd_generic),
420 BFD_JUMP_TABLE_LINK (_bfd_nolink),
421 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
422
423 &cisco_core_big_vec,
e60b52c6 424
252b5132
RH
425 (PTR) 0 /* backend_data */
426};
This page took 0.525919 seconds and 4 git commands to generate.