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