~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to binutils/bfd/hpux-core.c

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* BFD back-end for HP/UX core files.
 
2
   Copyright 1993, 1994, 1996, 1998, 1999, 2001, 2002
 
3
   Free Software Foundation, Inc.
 
4
   Written by Stu Grossman, Cygnus Support.
 
5
   Converted to back-end form by Ian Lance Taylor, Cygnus SUpport
 
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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
22
 
 
23
/* This file can only be compiled on systems which use HP/UX style
 
24
   core files.  */
 
25
 
 
26
#include "bfd.h"
 
27
#include "sysdep.h"
 
28
#include "libbfd.h"
 
29
 
 
30
#if defined (HOST_HPPAHPUX) || defined (HOST_HP300HPUX) || defined (HOST_HPPAMPEIX)
 
31
 
 
32
/* FIXME: sys/core.h doesn't exist for HPUX version 7.  HPUX version
 
33
   5, 6, and 7 core files seem to be standard trad-core.c type core
 
34
   files; can we just use trad-core.c in addition to this file?  */
 
35
 
 
36
#include <sys/core.h>
 
37
#include <sys/utsname.h>
 
38
 
 
39
#endif /* HOST_HPPAHPUX */
 
40
 
 
41
#ifdef HOST_HPPABSD
 
42
 
 
43
/* Not a very swift place to put it, but that's where the BSD port
 
44
   puts them.  */
 
45
#include "/hpux/usr/include/sys/core.h"
 
46
 
 
47
#endif /* HOST_HPPABSD */
 
48
 
 
49
#include <sys/param.h>
 
50
#ifdef HAVE_DIRENT_H
 
51
# include <dirent.h>
 
52
#else
 
53
# ifdef HAVE_SYS_NDIR_H
 
54
#  include <sys/ndir.h>
 
55
# endif
 
56
# ifdef HAVE_SYS_DIR_H
 
57
#  include <sys/dir.h>
 
58
# endif
 
59
# ifdef HAVE_NDIR_H
 
60
#  include <ndir.h>
 
61
# endif
 
62
#endif
 
63
#include <signal.h>
 
64
#include <machine/reg.h>
 
65
#include <sys/user.h>           /* After a.out.h  */
 
66
#include <sys/file.h>
 
67
 
 
68
/* Kludge: There's no explicit mechanism provided by sys/core.h to
 
69
   conditionally know whether a proc_info has thread id fields.
 
70
   However, CORE_ANON_SHMEM shows up first at 10.30, which is
 
71
   happily also when meaningful thread id's show up in proc_info. */
 
72
#if defined(CORE_ANON_SHMEM)
 
73
#define PROC_INFO_HAS_THREAD_ID (1)
 
74
#endif
 
75
 
 
76
/* This type appears at HP-UX 10.30.  Defining it if not defined
 
77
   by sys/core.h allows us to build for older HP-UX's, and (since
 
78
   it won't be encountered in core-dumps from older HP-UX's) is
 
79
   harmless. */
 
80
#if !defined(CORE_ANON_SHMEM)
 
81
#define CORE_ANON_SHMEM 0x00000200         /* anonymous shared memory */
 
82
#endif
 
83
 
 
84
/* These are stored in the bfd's tdata */
 
85
 
 
86
/* .lwpid and .user_tid are only valid if PROC_INFO_HAS_THREAD_ID, else they
 
87
   are set to 0.  Also, until HP-UX implements MxN threads, .user_tid and
 
88
   .lwpid are synonymous. */
 
89
struct hpux_core_struct
 
90
{
 
91
  int sig;
 
92
  int lwpid;               /* Kernel thread ID. */
 
93
  unsigned long user_tid;  /* User thread ID. */
 
94
  char cmd[MAXCOMLEN + 1];
 
95
};
 
96
 
 
97
#define core_hdr(bfd) ((bfd)->tdata.hpux_core_data)
 
98
#define core_signal(bfd) (core_hdr(bfd)->sig)
 
99
#define core_command(bfd) (core_hdr(bfd)->cmd)
 
100
#define core_kernel_thread_id(bfd) (core_hdr(bfd)->lwpid)
 
101
#define core_user_thread_id(bfd) (core_hdr(bfd)->user_tid)
 
102
 
 
103
static asection *make_bfd_asection
 
104
  PARAMS ((bfd *, const char *, flagword, bfd_size_type, bfd_vma,
 
105
           unsigned int));
 
106
static const bfd_target *hpux_core_core_file_p PARAMS ((bfd *));
 
107
static char *hpux_core_core_file_failing_command PARAMS ((bfd *));
 
108
static int hpux_core_core_file_failing_signal PARAMS ((bfd *));
 
109
static boolean hpux_core_core_file_matches_executable_p
 
110
  PARAMS ((bfd *, bfd *));
 
111
static void swap_abort PARAMS ((void));
 
112
 
 
113
static asection *
 
114
make_bfd_asection (abfd, name, flags, _raw_size, vma, alignment_power)
 
115
     bfd *abfd;
 
116
     const char *name;
 
117
     flagword flags;
 
118
     bfd_size_type _raw_size;
 
119
     bfd_vma vma;
 
120
     unsigned int alignment_power;
 
121
{
 
122
  asection *asect;
 
123
  char *newname;
 
124
 
 
125
  newname = bfd_alloc (abfd, (bfd_size_type) strlen (name) + 1);
 
126
  if (!newname)
 
127
    return NULL;
 
128
 
 
129
  strcpy (newname, name);
 
130
 
 
131
  asect = bfd_make_section_anyway (abfd, newname);
 
132
  if (!asect)
 
133
    return NULL;
 
134
 
 
135
  asect->flags = flags;
 
136
  asect->_raw_size = _raw_size;
 
137
  asect->vma = vma;
 
138
  asect->filepos = bfd_tell (abfd);
 
139
  asect->alignment_power = alignment_power;
 
140
 
 
141
  return asect;
 
142
}
 
143
 
 
144
/* this function builds a bfd target if the file is a corefile.
 
145
   It returns null or 0 if it finds out thaat it is not a core file.
 
146
   The way it checks this is by looking for allowed 'type' field values.
 
147
   These are declared in sys/core.h
 
148
   There are some values which are 'reserved for future use'. In particular
 
149
   CORE_NONE is actually defined as 0. This may be a catch-all for cases
 
150
   in which the core file is generated by some non-hpux application.
 
151
   (I am just guessing here!)
 
152
*/
 
153
static const bfd_target *
 
154
hpux_core_core_file_p (abfd)
 
155
     bfd *abfd;
 
156
{
 
157
  int  good_sections = 0;
 
158
  int  unknown_sections = 0;
 
159
 
 
160
  core_hdr (abfd) = (struct hpux_core_struct *)
 
161
    bfd_zalloc (abfd, (bfd_size_type) sizeof (struct hpux_core_struct));
 
162
  if (!core_hdr (abfd))
 
163
    return NULL;
 
164
 
 
165
  while (1)
 
166
    {
 
167
      int val;
 
168
      struct corehead core_header;
 
169
 
 
170
      val = bfd_bread ((void *) &core_header,
 
171
                      (bfd_size_type) sizeof core_header, abfd);
 
172
      if (val <= 0)
 
173
        break;
 
174
      switch (core_header.type)
 
175
        {
 
176
        case CORE_KERNEL:
 
177
        case CORE_FORMAT:
 
178
          /* Just skip this.  */
 
179
          bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR);
 
180
          good_sections++;
 
181
          break;
 
182
        case CORE_EXEC:
 
183
          {
 
184
            struct proc_exec proc_exec;
 
185
            if (bfd_bread ((void *) &proc_exec, (bfd_size_type) core_header.len,
 
186
                          abfd) != core_header.len)
 
187
              break;
 
188
            strncpy (core_command (abfd), proc_exec.cmd, MAXCOMLEN + 1);
 
189
            good_sections++;
 
190
          }
 
191
          break;
 
192
        case CORE_PROC:
 
193
          {
 
194
            struct proc_info proc_info;
 
195
            char  secname[100];  /* Of arbitrary size, but plenty large. */
 
196
 
 
197
            /* We need to read this section, 'cause we need to determine
 
198
               whether the core-dumped app was threaded before we create
 
199
               any .reg sections. */
 
200
            if (bfd_bread (&proc_info, (bfd_size_type) core_header.len, abfd)
 
201
                != core_header.len)
 
202
              break;
 
203
 
 
204
              /* However, we also want to create those sections with the
 
205
                 file positioned at the start of the record, it seems. */
 
206
            if (bfd_seek (abfd, (file_ptr) -core_header.len, SEEK_CUR) != 0)
 
207
              break;
 
208
 
 
209
#if defined(PROC_INFO_HAS_THREAD_ID)
 
210
            core_kernel_thread_id (abfd) = proc_info.lwpid;
 
211
            core_user_thread_id (abfd) = proc_info.user_tid;
 
212
#else
 
213
            core_kernel_thread_id (abfd) = 0;
 
214
            core_user_thread_id (abfd) = 0;
 
215
#endif
 
216
            /* If the program was unthreaded, then we'll just create a
 
217
               .reg section.
 
218
 
 
219
               If the program was threaded, then we'll create .reg/XXXXX
 
220
               section for each thread, where XXXXX is a printable
 
221
               representation of the kernel thread id.  We'll also
 
222
               create a .reg section for the thread that was running
 
223
               and signalled at the time of the core-dump (i.e., this
 
224
               is effectively an alias, needed to keep GDB happy.)
 
225
 
 
226
               Note that we use `.reg/XXXXX' as opposed to '.regXXXXX'
 
227
               because GDB expects that .reg2 will be the floating-
 
228
               point registers. */
 
229
            if (core_kernel_thread_id (abfd) == 0)
 
230
              {
 
231
                if (!make_bfd_asection (abfd, ".reg",
 
232
                                        SEC_HAS_CONTENTS,
 
233
                                        core_header.len,
 
234
                                        (int) &proc_info - (int) & proc_info.hw_regs,
 
235
                                        2))
 
236
                  goto fail;
 
237
              }
 
238
            else
 
239
              {
 
240
                /* There are threads.  Is this the one that caused the
 
241
                   core-dump?  We'll claim it was the running thread. */
 
242
                if (proc_info.sig != -1)
 
243
                  {
 
244
                    if (!make_bfd_asection (abfd, ".reg",
 
245
                                            SEC_HAS_CONTENTS,
 
246
                                            core_header.len,
 
247
                                            (int) &proc_info - (int) & proc_info.hw_regs,
 
248
                                            2))
 
249
                      goto fail;
 
250
                  }
 
251
                /* We always make one of these sections, for every thread. */
 
252
                sprintf (secname, ".reg/%d", core_kernel_thread_id (abfd));
 
253
                if (!make_bfd_asection (abfd, secname,
 
254
                                        SEC_HAS_CONTENTS,
 
255
                                        core_header.len,
 
256
                                        (int) &proc_info - (int) & proc_info.hw_regs,
 
257
                                        2))
 
258
                  goto fail;
 
259
              }
 
260
            core_signal (abfd) = proc_info.sig;
 
261
            if (bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR) != 0)
 
262
              break;
 
263
            good_sections++;
 
264
          }
 
265
          break;
 
266
 
 
267
        case CORE_DATA:
 
268
        case CORE_STACK:
 
269
        case CORE_TEXT:
 
270
        case CORE_MMF:
 
271
        case CORE_SHM:
 
272
        case CORE_ANON_SHMEM:
 
273
          if (!make_bfd_asection (abfd, ".data",
 
274
                                  SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
 
275
                                  core_header.len, core_header.addr, 2))
 
276
            goto fail;
 
277
 
 
278
          bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR);
 
279
          good_sections++;
 
280
          break;
 
281
 
 
282
        case CORE_NONE:
 
283
          /* Let's not punt if we encounter a section of unknown
 
284
             type.  Rather, let's make a note of it.  If we later
 
285
             see that there were also "good" sections, then we'll
 
286
             declare that this a core file, but we'll also warn that
 
287
             it may be incompatible with this gdb.
 
288
             */
 
289
          unknown_sections++;
 
290
          break;
 
291
 
 
292
         default:
 
293
           goto fail; /*unrecognized core file type */
 
294
        }
 
295
    }
 
296
 
 
297
  /* OK, we believe you.  You're a core file (sure, sure).  */
 
298
 
 
299
  /* Were there sections of unknown type?  If so, yet there were
 
300
     at least some complete sections of known type, then, issue
 
301
     a warning.  Possibly the core file was generated on a version
 
302
     of HP-UX that is incompatible with that for which this gdb was
 
303
     built.
 
304
     */
 
305
  if ((unknown_sections > 0) && (good_sections > 0))
 
306
    (*_bfd_error_handler)
 
307
      ("%s appears to be a core file,\nbut contains unknown sections.  It may have been created on an incompatible\nversion of HP-UX.  As a result, some information may be unavailable.\n",
 
308
       abfd->filename);
 
309
 
 
310
  return abfd->xvec;
 
311
 
 
312
 fail:
 
313
  bfd_release (abfd, core_hdr (abfd));
 
314
  core_hdr (abfd) = NULL;
 
315
  bfd_section_list_clear (abfd);
 
316
  return NULL;
 
317
}
 
318
 
 
319
static char *
 
320
hpux_core_core_file_failing_command (abfd)
 
321
     bfd *abfd;
 
322
{
 
323
  return core_command (abfd);
 
324
}
 
325
 
 
326
/* ARGSUSED */
 
327
static int
 
328
hpux_core_core_file_failing_signal (abfd)
 
329
     bfd *abfd;
 
330
{
 
331
  return core_signal (abfd);
 
332
}
 
333
 
 
334
/* ARGSUSED */
 
335
static boolean
 
336
hpux_core_core_file_matches_executable_p (core_bfd, exec_bfd)
 
337
     bfd *core_bfd ATTRIBUTE_UNUSED;
 
338
     bfd *exec_bfd ATTRIBUTE_UNUSED;
 
339
{
 
340
  return true;                  /* FIXME, We have no way of telling at this point */
 
341
}
 
342
 
 
343
/* If somebody calls any byte-swapping routines, shoot them.  */
 
344
static void
 
345
swap_abort ()
 
346
{
 
347
  abort(); /* This way doesn't require any declaration for ANSI to fuck up */
 
348
}
 
349
#define NO_GET  ((bfd_vma (*) PARAMS ((   const bfd_byte *))) swap_abort )
 
350
#define NO_PUT  ((void    (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
 
351
#define NO_SIGNED_GET \
 
352
  ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
 
353
 
 
354
const bfd_target hpux_core_vec =
 
355
  {
 
356
    "hpux-core",
 
357
    bfd_target_unknown_flavour,
 
358
    BFD_ENDIAN_BIG,             /* target byte order */
 
359
    BFD_ENDIAN_BIG,             /* target headers byte order */
 
360
    (HAS_RELOC | EXEC_P |       /* object flags */
 
361
     HAS_LINENO | HAS_DEBUG |
 
362
     HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
 
363
    (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
 
364
    0,                                                     /* symbol prefix */
 
365
    ' ',                                                   /* ar_pad_char */
 
366
    16,                                                    /* ar_max_namelen */
 
367
    NO_GET, NO_SIGNED_GET, NO_PUT,      /* 64 bit data */
 
368
    NO_GET, NO_SIGNED_GET, NO_PUT,      /* 32 bit data */
 
369
    NO_GET, NO_SIGNED_GET, NO_PUT,      /* 16 bit data */
 
370
    NO_GET, NO_SIGNED_GET, NO_PUT,      /* 64 bit hdrs */
 
371
    NO_GET, NO_SIGNED_GET, NO_PUT,      /* 32 bit hdrs */
 
372
    NO_GET, NO_SIGNED_GET, NO_PUT,      /* 16 bit hdrs */
 
373
 
 
374
    {                           /* bfd_check_format */
 
375
     _bfd_dummy_target,         /* unknown format */
 
376
     _bfd_dummy_target,         /* object file */
 
377
     _bfd_dummy_target,         /* archive */
 
378
     hpux_core_core_file_p      /* a core file */
 
379
    },
 
380
    {                           /* bfd_set_format */
 
381
     bfd_false, bfd_false,
 
382
     bfd_false, bfd_false
 
383
    },
 
384
    {                           /* bfd_write_contents */
 
385
     bfd_false, bfd_false,
 
386
     bfd_false, bfd_false
 
387
    },
 
388
 
 
389
    BFD_JUMP_TABLE_GENERIC (_bfd_generic),
 
390
    BFD_JUMP_TABLE_COPY (_bfd_generic),
 
391
    BFD_JUMP_TABLE_CORE (hpux_core),
 
392
    BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
 
393
    BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
 
394
    BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
 
395
    BFD_JUMP_TABLE_WRITE (_bfd_generic),
 
396
    BFD_JUMP_TABLE_LINK (_bfd_nolink),
 
397
    BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
 
398
 
 
399
    NULL,
 
400
 
 
401
    (PTR) 0                     /* backend_data */
 
402
};