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 146

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

powered by: WebSVN 2.1.0

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