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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
/* BFD back end for SCO5 core files (U-area and raw sections)
2
   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3
   Free Software Foundation, Inc.
4
   Written by Jouke Numan <jnuman@hiscom.nl>
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
#include "libaout.h"            /* BFD a.out internal data structures */
27
 
28
#include <stdio.h>
29
#include <sys/types.h>
30
#include <sys/param.h>
31
#include <sys/dir.h>
32
#include <signal.h>
33
 
34
#include <sys/user.h>           /* After a.out.h  */
35
#ifdef SCO5_CORE
36
#include <sys/paccess.h>
37
#include <sys/region.h>
38
#endif
39
 
40
struct sco5_core_struct
41
{
42
  struct user u;
43
};
44
 
45
/* forward declarations */
46
 
47
static asection *make_bfd_asection
48
  PARAMS ((bfd *, const char *, flagword, bfd_size_type, bfd_vma, file_ptr));
49
static struct user *read_uarea PARAMS ((bfd *, int));
50
const bfd_target *sco5_core_file_p PARAMS ((bfd *abfd));
51
char *sco5_core_file_failing_command PARAMS ((bfd *abfd));
52
int sco5_core_file_failing_signal PARAMS ((bfd *abfd));
53
#define sco5_core_file_matches_executable_p generic_core_file_matches_executable_p
54
static void swap_abort PARAMS ((void));
55
 
56
static asection *
57
make_bfd_asection (abfd, name, flags, size, vma, filepos)
58
     bfd *abfd;
59
     const char *name;
60
     flagword flags;
61
     bfd_size_type size;
62
     bfd_vma vma;
63
     file_ptr filepos;
64
{
65
  asection *asect;
66
 
67
  asect = bfd_make_section_anyway_with_flags (abfd, name, flags);
68
  if (!asect)
69
    return NULL;
70
  asect->size = size;
71
  asect->vma = vma;
72
  asect->filepos = filepos;
73
  asect->alignment_power = 2;
74
 
75
  return asect;
76
}
77
 
78
static struct user *
79
read_uarea(abfd, filepos)
80
     bfd *abfd;
81
     int filepos;
82
 
83
{
84
  struct sco5_core_struct *rawptr;
85
  bfd_size_type amt = sizeof (struct sco5_core_struct);
86
 
87
  rawptr = (struct sco5_core_struct *) bfd_zmalloc (amt);
88
  if (rawptr == NULL)
89
    return NULL;
90
 
91
  abfd->tdata.sco5_core_data = rawptr;
92
 
93
  if (bfd_seek (abfd, (file_ptr) filepos, SEEK_SET) != 0
94
      || bfd_bread ((void *) &rawptr->u, (bfd_size_type) sizeof rawptr->u,
95
                   abfd) != sizeof rawptr->u)
96
    {
97
      bfd_set_error (bfd_error_wrong_format);
98
      return NULL;
99
    }
100
 
101
  /* Sanity check perhaps??? */
102
  if (rawptr->u.u_dsize > 0x1000000)    /* Remember, it's in pages...  */
103
    {
104
      bfd_set_error (bfd_error_wrong_format);
105
      return NULL;
106
    }
107
  if (rawptr->u.u_ssize > 0x1000000)
108
    {
109
      bfd_set_error (bfd_error_wrong_format);
110
      return NULL;
111
    }
112
  return &rawptr->u;
113
}
114
 
115
const bfd_target *
116
sco5_core_file_p (abfd)
117
     bfd *abfd;
118
{
119
  int coffset_siz, val, nsecs, cheadoffs;
120
  int coresize;
121
  struct user *u;
122
  struct coreoffsets coffsets;
123
  struct coresecthead chead;
124
  char *secname;
125
  flagword flags;
126
 
127
  /* Read coreoffsets region at end of core (see core(FP)).  */
128
 
129
  {
130
    struct stat statbuf;
131
 
132
    if (bfd_stat (abfd, &statbuf) < 0)
133
      return NULL;
134
 
135
    coresize = statbuf.st_size;
136
  }
137
  /* Last long in core is sizeof struct coreoffsets, read it */
138
  if ((bfd_seek (abfd, (file_ptr) (coresize - sizeof coffset_siz),
139
                 SEEK_SET) != 0)
140
      || bfd_bread ((void *) &coffset_siz, (bfd_size_type) sizeof coffset_siz,
141
                   abfd) != sizeof coffset_siz)
142
    {
143
      bfd_set_error (bfd_error_wrong_format);
144
      return NULL;
145
    }
146
 
147
  /* Use it to seek start of coreoffsets region, read it and determine
148
     validity */
149
  if ((bfd_seek (abfd, (file_ptr) (coresize - coffset_siz), SEEK_SET) != 0)
150
      || (bfd_bread ((void *) &coffsets, (bfd_size_type) sizeof coffsets, abfd)
151
          != sizeof coffsets)
152
      || ((coffsets.u_info != 1) && (coffsets.u_info != C_VERSION)))
153
    {
154
      bfd_set_error (bfd_error_wrong_format);
155
      return NULL;
156
    }
157
 
158
  if (coffsets.u_info == 1)
159
    {
160
      /* Old version, no section heads, read info from user struct */
161
 
162
      u = read_uarea (abfd, coffsets.u_user);
163
      if (! u)
164
        goto fail;
165
 
166
      if (!make_bfd_asection (abfd, ".reg", SEC_HAS_CONTENTS,
167
                              (bfd_size_type) coffsets.u_usize,
168
 
169
                              (file_ptr) coffsets.u_user))
170
        goto fail;
171
 
172
      if (!make_bfd_asection (abfd, ".data",
173
                              SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
174
                              ((bfd_size_type) u->u_exdata.ux_dsize
175
                               + u->u_exdata.ux_bsize),
176
                              (bfd_vma) u->u_exdata.ux_datorg,
177
                              (file_ptr) coffsets.u_data))
178
        goto fail;
179
 
180
      if (!make_bfd_asection (abfd, ".stack",
181
                              SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
182
                              (bfd_size_type) u->u_ssize * NBPC,
183
                              (bfd_vma) u->u_sub,
184
                              (file_ptr) coffsets.u_stack))
185
        goto fail;
186
 
187
      return abfd->xvec;                /* Done for version 1 */
188
    }
189
 
190
  /* Immediately before coreoffsets region is a long with offset in core
191
     to first coresecthead (CORES_OFFSETS), the long before this is the
192
     number of section heads in the list. Read both longs and read the
193
     coresecthead and check its validity */
194
 
195
  if ((bfd_seek (abfd,
196
                 (file_ptr) (coresize - coffset_siz - 2 * sizeof coffset_siz),
197
                 SEEK_SET) != 0)
198
      || (bfd_bread ((void *) &nsecs, (bfd_size_type) sizeof nsecs, abfd)
199
          != sizeof nsecs)
200
      || (bfd_bread ((void *) &cheadoffs, (bfd_size_type) sizeof cheadoffs,
201
                    abfd) != sizeof cheadoffs)
202
      || (bfd_seek (abfd, (file_ptr) cheadoffs, SEEK_SET) != 0)
203
      || (bfd_bread ((void *) &chead, (bfd_size_type) sizeof chead, abfd)
204
          != sizeof chead)
205
      || (chead.cs_stype != CORES_OFFSETS)
206
      || (chead.cs_x.csx_magic != COREMAGIC_NUMBER))
207
    {
208
      bfd_set_error (bfd_error_wrong_format);
209
      goto fail;
210
    }
211
 
212
  /* OK, we believe you.  You're a core file (sure, sure).  */
213
 
214
  /* Now loop over all regions and map them */
215
  nsecs--;                              /* We've seen CORES_OFFSETS already */
216
  for (; nsecs; nsecs--)
217
    {
218
      if ((bfd_seek (abfd, (file_ptr) chead.cs_hseek, SEEK_SET) != 0)
219
          || (bfd_bread ((void *) &chead, (bfd_size_type) sizeof chead, abfd)
220
              != sizeof chead))
221
        {
222
          bfd_set_error (bfd_error_wrong_format);
223
          goto fail;
224
        }
225
 
226
      switch (chead.cs_stype)
227
        {
228
        case CORES_MAGIC:                       /* Core header, check magic */
229
          if (chead.cs_x.csx_magic != COREMAGIC_NUMBER)
230
            {
231
              bfd_set_error (bfd_error_wrong_format);
232
              goto fail;
233
            }
234
          secname = NULL;
235
          nsecs++;                              /* MAGIC not in section cnt!*/
236
          break;
237
        case CORES_UAREA:                       /* U-area, read in tdata */
238
          u = read_uarea (abfd, chead.cs_sseek);
239
          if (! u)
240
            goto fail;
241
 
242
          /* This is tricky.  As the "register section", we give them
243
             the entire upage and stack.  u.u_ar0 points to where
244
             "register 0" is stored.  There are two tricks with this,
245
             though.  One is that the rest of the registers might be
246
             at positive or negative (or both) displacements from
247
             *u_ar0.  The other is that u_ar0 is sometimes an absolute
248
             address in kernel memory, and on other systems it is an
249
             offset from the beginning of the `struct user'.
250
 
251
             As a practical matter, we don't know where the registers
252
             actually are, so we have to pass the whole area to GDB.
253
             We encode the value of u_ar0 by setting the .regs section
254
             up so that its virtual memory address 0 is at the place
255
             pointed to by u_ar0 (by setting the vma of the start of
256
             the section to -u_ar0).  GDB uses this info to locate the
257
             regs, using minor trickery to get around the
258
             offset-or-absolute-addr problem.  */
259
 
260
          chead.cs_vaddr = 0 - (bfd_vma) u->u_ar0;
261
 
262
          secname = ".reg";
263
          flags = SEC_HAS_CONTENTS;
264
 
265
          break;
266
        case CORES_PREGION:                     /* A program region, map it */
267
          switch (chead.cs_x.csx_preg.csxp_rtyp)
268
            {
269
            case PT_DATA:
270
              secname = ".data";        /* Data region.          */
271
              break;
272
            case PT_STACK:
273
              secname = ".stack";       /* Stack region.         */
274
              break;
275
            case PT_SHMEM:
276
              secname = ".shmem";       /* Shared memory         */
277
              break;
278
            case PT_LIBDAT:
279
              secname = ".libdat";      /* Shared library data   */
280
              break;
281
            case PT_V86:
282
              secname = ".virt86";      /* Virtual 8086 mode     */
283
              break;
284
            case PT_SHFIL:
285
              secname = ".mmfile";      /* Memory mapped file    */
286
              break;
287
            case PT_XDATA0:
288
              secname = ".Xdat0";       /* XENIX data region, virtual 0 */
289
              break;
290
            default:
291
              secname = "";
292
            }
293
          flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
294
          break;
295
        case CORES_PROC:                        /* struct proc */
296
        case CORES_ITIMER:                      /* interval timers */
297
        case CORES_SCOUTSNAME:                  /* struct scoutsname */
298
          secname = NULL;       /* Ignore these */
299
          break;
300
        default:
301
          (*_bfd_error_handler) ("Unhandled SCO core file section type %d\n",
302
                                 chead.cs_stype);
303
          continue;
304
        }
305
 
306
      if (secname
307
          && !make_bfd_asection (abfd, secname, flags,
308
                                 (bfd_size_type) chead.cs_vsize,
309
                                 (bfd_vma) chead.cs_vaddr,
310
                                 (file_ptr) chead.cs_sseek))
311
        goto fail;
312
 
313
    }
314
 
315
  return abfd->xvec;
316
 
317
 fail:
318
  if (abfd->tdata.any)
319
    {
320
      bfd_release (abfd, abfd->tdata.any);
321
      abfd->tdata.any = NULL;
322
    }
323
  bfd_section_list_clear (abfd);
324
  return NULL;
325
}
326
 
327
char *
328
sco5_core_file_failing_command (abfd)
329
     bfd *abfd;
330
{
331
  char *com = abfd->tdata.sco5_core_data->u.u_comm;
332
  if (*com)
333
    return com;
334
  else
335
    return NULL;
336
}
337
 
338
int
339
sco5_core_file_failing_signal (ignore_abfd)
340
     bfd *ignore_abfd;
341
{
342
  return ((ignore_abfd->tdata.sco5_core_data->u.u_sysabort != 0)
343
          ? ignore_abfd->tdata.sco5_core_data->u.u_sysabort
344
          : -1);
345
}
346
 
347
/* If somebody calls any byte-swapping routines, shoot them.  */
348
static void
349
swap_abort ()
350
{
351
  abort (); /* This way doesn't require any declaration for ANSI to fuck up */
352
}
353
 
354
#define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
355
#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
356
#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
357
#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
358
#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
359
#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
360
 
361
const bfd_target sco5_core_vec =
362
  {
363
    "sco5-core",
364
    bfd_target_unknown_flavour,
365
    BFD_ENDIAN_LITTLE,         /* target byte order */
366
    BFD_ENDIAN_LITTLE,         /* target headers byte order */
367
    (HAS_RELOC | EXEC_P |       /* object flags */
368
     HAS_LINENO | HAS_DEBUG |
369
     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
370
    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
371
    0,                                                      /* symbol prefix */
372
    ' ',                                                   /* ar_pad_char */
373
    16,                                                    /* ar_max_namelen */
374
    NO_GET64, NO_GETS64, NO_PUT64,      /* 64 bit data */
375
    NO_GET, NO_GETS, NO_PUT,            /* 32 bit data */
376
    NO_GET, NO_GETS, NO_PUT,            /* 16 bit data */
377
    NO_GET64, NO_GETS64, NO_PUT64,      /* 64 bit hdrs */
378
    NO_GET, NO_GETS, NO_PUT,            /* 32 bit hdrs */
379
    NO_GET, NO_GETS, NO_PUT,            /* 16 bit hdrs */
380
 
381
    {                           /* bfd_check_format */
382
      _bfd_dummy_target,                /* unknown format */
383
      _bfd_dummy_target,                /* object file */
384
      _bfd_dummy_target,                /* archive */
385
      sco5_core_file_p                  /* a core file */
386
    },
387
    {                           /* bfd_set_format */
388
      bfd_false, bfd_false,
389
      bfd_false, bfd_false
390
    },
391
    {                           /* bfd_write_contents */
392
      bfd_false, bfd_false,
393
      bfd_false, bfd_false
394
    },
395
 
396
    BFD_JUMP_TABLE_GENERIC (_bfd_generic),
397
    BFD_JUMP_TABLE_COPY (_bfd_generic),
398
    BFD_JUMP_TABLE_CORE (sco5),
399
    BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
400
    BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
401
    BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
402
    BFD_JUMP_TABLE_WRITE (_bfd_generic),
403
    BFD_JUMP_TABLE_LINK (_bfd_nolink),
404
    BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
405
 
406
    NULL,
407
 
408
    (PTR) 0                      /* backend_data */
409
  };

powered by: WebSVN 2.1.0

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