~ubuntu-branches/ubuntu/utopic/binutils-arm64-cross/utopic

« back to all changes in this revision

Viewing changes to binutils-2.23.52.20130611/bfd/sco5-core.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-06-20 17:38:09 UTC
  • Revision ID: package-import@ubuntu.com-20130620173809-app8lzgvymy5fg6c
Tags: 0.7
Build-depend on binutils-source (>= 2.23.52.20130620-1~).

Show diffs side-by-side

added added

removed removed

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