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

Subversion Repositories open8_urisc

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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