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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [cisco-core.c] - Blame information for rev 148

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

Line No. Rev Author Line
1 14 khays
/* BFD back-end for CISCO crash dumps.
2 148 khays
   Copyright 1994, 1997, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007,
3
   2010, 2011
4 14 khays
   Free Software Foundation, Inc.
5
 
6
   This file is part of BFD, the Binary File Descriptor library.
7
 
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.
12
 
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.
17
 
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.  */
22
 
23
#include "sysdep.h"
24
#include "bfd.h"
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
 
41
int 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 */
52
 
53
typedef enum {
54
    CRASH_REASON_NOTCRASHED = 0,
55
    CRASH_REASON_EXCEPTION = 1,
56
    CRASH_REASON_CORRUPT = 2,
57
} crashreason;
58
 
59
typedef struct {
60
  char magic[4];                /* Magic number */
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) */
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;
70
 
71
struct cisco_core_struct
72
{
73
  int sig;
74
};
75
 
76
static const bfd_target *cisco_core_file_validate PARAMS ((bfd *, int));
77
static const bfd_target *cisco_core_file_p PARAMS ((bfd *));
78
char *cisco_core_file_failing_command PARAMS ((bfd *));
79
int cisco_core_file_failing_signal PARAMS ((bfd *));
80
#define cisco_core_file_matches_executable_p generic_core_file_matches_executable_p
81
#define cisco_core_file_pid _bfd_nocore_core_file_pid
82
 
83
/* Examine the file for a crash info struct at the offset given by
84
   CRASH_INFO_LOC.  */
85
 
86
static const bfd_target *
87
cisco_core_file_validate (abfd, crash_info_loc)
88
     bfd *abfd;
89
     int crash_info_loc;
90
{
91
  char buf[4];
92
  unsigned int crashinfo_offset;
93
  crashinfo_external crashinfo;
94
  bfd_size_type nread;
95
  unsigned int magic;
96
  unsigned int version;
97
  unsigned int rambase;
98
  sec_ptr asect;
99
  struct stat statbuf;
100
  bfd_size_type amt;
101
  flagword flags;
102
 
103
  if (bfd_seek (abfd, (file_ptr) crash_info_loc, SEEK_SET) != 0)
104
    return NULL;
105
 
106
  nread = bfd_bread (buf, (bfd_size_type) 4, abfd);
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
    }
113
  crashinfo_offset = MASK_ADDR (bfd_get_32 (abfd, buf));
114
 
115
  if (bfd_seek (abfd, (file_ptr) crashinfo_offset, SEEK_SET) != 0)
116
    {
117
      /* Most likely we failed because of a bogus (huge) offset */
118
      bfd_set_error (bfd_error_wrong_format);
119
      return NULL;
120
    }
121
 
122
  nread = bfd_bread (&crashinfo, (bfd_size_type) sizeof (crashinfo), abfd);
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
 
136
  magic = bfd_get_32 (abfd, crashinfo.magic);
137
  if (magic != CRASH_MAGIC)
138
    {
139
      bfd_set_error (bfd_error_wrong_format);
140
      return NULL;
141
    }
142
 
143
  version = bfd_get_32 (abfd, crashinfo.version);
144
  if (version == 0)
145
    {
146
      bfd_set_error (bfd_error_wrong_format);
147
      return NULL;
148
    }
149
  else if (version == 1)
150
    {
151
      /* V1 core dumps don't specify the dump base, assume 0 */
152
      rambase = 0;
153
    }
154
  else
155
    {
156
      rambase = bfd_get_32 (abfd, crashinfo.rambase);
157
    }
158
 
159
  /* OK, we believe you.  You're a core file.  */
160
 
161
  amt = sizeof (struct cisco_core_struct);
162
  abfd->tdata.cisco_core_data = (struct cisco_core_struct *) bfd_zmalloc (amt);
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
 
245
  /* Create a ".data" section that maps the entire file, which is
246
     essentially a dump of the target system's RAM.  */
247
 
248
  flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
249
  asect = bfd_make_section_anyway_with_flags (abfd, ".data", flags);
250
  if (asect == NULL)
251
    goto error_return;
252
  /* The size of memory is the size of the core file itself.  */
253
  asect->size = statbuf.st_size;
254
  asect->vma = rambase;
255
  asect->filepos = 0;
256
 
257
  /* Create a ".crash" section to allow access to the saved
258
     crash information.  */
259
 
260
  flags = SEC_HAS_CONTENTS;
261
  asect = bfd_make_section_anyway_with_flags (abfd, ".crash", flags);
262
  if (asect == NULL)
263
    goto error_return;
264
  asect->vma = 0;
265
  asect->filepos = crashinfo_offset;
266
  asect->size = sizeof (crashinfo);
267
 
268
  /* Create a ".reg" section to allow access to the saved
269
     registers.  */
270
 
271
  asect = bfd_make_section_anyway_with_flags (abfd, ".reg", flags);
272
  if (asect == NULL)
273
    goto error_return;
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;
280
  asect->size = (nread < 1024) ? nread : 1024;
281
 
282
  return abfd->xvec;
283
 
284
  /* Get here if we have already started filling out the BFD
285
     and there is an error of some kind.  */
286
 
287
 error_return:
288
  bfd_release (abfd, abfd->tdata.any);
289
  abfd->tdata.any = NULL;
290
  bfd_section_list_clear (abfd);
291
  return NULL;
292
}
293
 
294
static const bfd_target *
295
cisco_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
 
310
char *
311
cisco_core_file_failing_command (abfd)
312
     bfd *abfd ATTRIBUTE_UNUSED;
313
{
314
  return NULL;
315
}
316
 
317
int
318
cisco_core_file_failing_signal (abfd)
319
     bfd *abfd ATTRIBUTE_UNUSED;
320
{
321
  return abfd->tdata.cisco_core_data->sig;
322
}
323
 
324
extern const bfd_target cisco_core_little_vec;
325
 
326
const bfd_target cisco_core_big_vec =
327
  {
328
    "cisco-ios-core-big",
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 */
336 148 khays
    0,                           /* symbol prefix */
337
    ' ',                        /* ar_pad_char */
338
    16,                         /* ar_max_namelen */
339
    0,                           /* match priority.  */
340 14 khays
    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
    },
361
 
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
 
372
    & cisco_core_little_vec,
373
 
374
    (PTR) 0                      /* backend_data */
375
};
376
 
377
const 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 */
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, /* data */
393
    bfd_getl64, bfd_getl_signed_64, bfd_putl64,
394
    bfd_getl32, bfd_getl_signed_32, bfd_putl32,
395
    bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
396
 
397
    {                           /* bfd_check_format */
398
     _bfd_dummy_target,         /* unknown format */
399
     _bfd_dummy_target,         /* object file */
400
     _bfd_dummy_target,         /* archive */
401
     cisco_core_file_p  /* a core file */
402
    },
403
    {                           /* bfd_set_format */
404
     bfd_false, bfd_false,
405
     bfd_false, bfd_false
406
    },
407
    {                           /* bfd_write_contents */
408
     bfd_false, bfd_false,
409
     bfd_false, bfd_false
410
    },
411
 
412
       BFD_JUMP_TABLE_GENERIC (_bfd_generic),
413
       BFD_JUMP_TABLE_COPY (_bfd_generic),
414
       BFD_JUMP_TABLE_CORE (cisco),
415
       BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
416
       BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
417
       BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
418
       BFD_JUMP_TABLE_WRITE (_bfd_generic),
419
       BFD_JUMP_TABLE_LINK (_bfd_nolink),
420
       BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
421
 
422
    &cisco_core_big_vec,
423
 
424
    (PTR) 0                      /* backend_data */
425
};

powered by: WebSVN 2.1.0

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