OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [cisco-core.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.