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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [bfd/] [cisco-core.c] - Blame information for rev 843

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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