source: trunk/binutils/bfd/hpux-core.c

Last change on this file was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 12.9 KB
Line 
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
7This file is part of BFD, the Binary File Descriptor library.
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, 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. */
89struct 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
103static asection *make_bfd_asection
104 PARAMS ((bfd *, const char *, flagword, bfd_size_type, bfd_vma,
105 unsigned int));
106static const bfd_target *hpux_core_core_file_p
107 PARAMS ((bfd *));
108static char *hpux_core_core_file_failing_command
109 PARAMS ((bfd *));
110static int hpux_core_core_file_failing_signal
111 PARAMS ((bfd *));
112static bfd_boolean hpux_core_core_file_matches_executable_p
113 PARAMS ((bfd *, bfd *));
114static void swap_abort
115 PARAMS ((void));
116
117static asection *
118make_bfd_asection (abfd, name, flags, _raw_size, vma, alignment_power)
119 bfd *abfd;
120 const char *name;
121 flagword flags;
122 bfd_size_type _raw_size;
123 bfd_vma vma;
124 unsigned int alignment_power;
125{
126 asection *asect;
127 char *newname;
128
129 newname = bfd_alloc (abfd, (bfd_size_type) strlen (name) + 1);
130 if (!newname)
131 return NULL;
132
133 strcpy (newname, name);
134
135 asect = bfd_make_section_anyway (abfd, newname);
136 if (!asect)
137 return NULL;
138
139 asect->flags = flags;
140 asect->_raw_size = _raw_size;
141 asect->vma = vma;
142 asect->filepos = bfd_tell (abfd);
143 asect->alignment_power = alignment_power;
144
145 return asect;
146}
147
148/* this function builds a bfd target if the file is a corefile.
149 It returns null or 0 if it finds out thaat it is not a core file.
150 The way it checks this is by looking for allowed 'type' field values.
151 These are declared in sys/core.h
152 There are some values which are 'reserved for future use'. In particular
153 CORE_NONE is actually defined as 0. This may be a catch-all for cases
154 in which the core file is generated by some non-hpux application.
155 (I am just guessing here!)
156*/
157static const bfd_target *
158hpux_core_core_file_p (abfd)
159 bfd *abfd;
160{
161 int good_sections = 0;
162 int unknown_sections = 0;
163
164 core_hdr (abfd) = (struct hpux_core_struct *)
165 bfd_zalloc (abfd, (bfd_size_type) sizeof (struct hpux_core_struct));
166 if (!core_hdr (abfd))
167 return NULL;
168
169 while (1)
170 {
171 int val;
172 struct corehead core_header;
173
174 val = bfd_bread ((void *) &core_header,
175 (bfd_size_type) sizeof core_header, abfd);
176 if (val <= 0)
177 break;
178 switch (core_header.type)
179 {
180 case CORE_KERNEL:
181 case CORE_FORMAT:
182 /* Just skip this. */
183 bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR);
184 good_sections++;
185 break;
186 case CORE_EXEC:
187 {
188 struct proc_exec proc_exec;
189 if (bfd_bread ((void *) &proc_exec, (bfd_size_type) core_header.len,
190 abfd) != core_header.len)
191 break;
192 strncpy (core_command (abfd), proc_exec.cmd, MAXCOMLEN + 1);
193 good_sections++;
194 }
195 break;
196 case CORE_PROC:
197 {
198 struct proc_info proc_info;
199 char secname[100]; /* Of arbitrary size, but plenty large. */
200
201 /* We need to read this section, 'cause we need to determine
202 whether the core-dumped app was threaded before we create
203 any .reg sections. */
204 if (bfd_bread (&proc_info, (bfd_size_type) core_header.len, abfd)
205 != core_header.len)
206 break;
207
208 /* However, we also want to create those sections with the
209 file positioned at the start of the record, it seems. */
210 if (bfd_seek (abfd, (file_ptr) -core_header.len, SEEK_CUR) != 0)
211 break;
212
213#if defined(PROC_INFO_HAS_THREAD_ID)
214 core_kernel_thread_id (abfd) = proc_info.lwpid;
215 core_user_thread_id (abfd) = proc_info.user_tid;
216#else
217 core_kernel_thread_id (abfd) = 0;
218 core_user_thread_id (abfd) = 0;
219#endif
220 /* If the program was unthreaded, then we'll just create a
221 .reg section.
222
223 If the program was threaded, then we'll create .reg/XXXXX
224 section for each thread, where XXXXX is a printable
225 representation of the kernel thread id. We'll also
226 create a .reg section for the thread that was running
227 and signalled at the time of the core-dump (i.e., this
228 is effectively an alias, needed to keep GDB happy.)
229
230 Note that we use `.reg/XXXXX' as opposed to '.regXXXXX'
231 because GDB expects that .reg2 will be the floating-
232 point registers. */
233 if (core_kernel_thread_id (abfd) == 0)
234 {
235 if (!make_bfd_asection (abfd, ".reg",
236 SEC_HAS_CONTENTS,
237 core_header.len,
238 (int) &proc_info - (int) & proc_info.hw_regs,
239 2))
240 goto fail;
241 }
242 else
243 {
244 /* There are threads. Is this the one that caused the
245 core-dump? We'll claim it was the running thread. */
246 if (proc_info.sig != -1)
247 {
248 if (!make_bfd_asection (abfd, ".reg",
249 SEC_HAS_CONTENTS,
250 core_header.len,
251 (int) &proc_info - (int) & proc_info.hw_regs,
252 2))
253 goto fail;
254 }
255 /* We always make one of these sections, for every thread. */
256 sprintf (secname, ".reg/%d", core_kernel_thread_id (abfd));
257 if (!make_bfd_asection (abfd, secname,
258 SEC_HAS_CONTENTS,
259 core_header.len,
260 (int) &proc_info - (int) & proc_info.hw_regs,
261 2))
262 goto fail;
263 }
264 core_signal (abfd) = proc_info.sig;
265 if (bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR) != 0)
266 break;
267 good_sections++;
268 }
269 break;
270
271 case CORE_DATA:
272 case CORE_STACK:
273 case CORE_TEXT:
274 case CORE_MMF:
275 case CORE_SHM:
276 case CORE_ANON_SHMEM:
277 if (!make_bfd_asection (abfd, ".data",
278 SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
279 core_header.len, core_header.addr, 2))
280 goto fail;
281
282 bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR);
283 good_sections++;
284 break;
285
286 case CORE_NONE:
287 /* Let's not punt if we encounter a section of unknown
288 type. Rather, let's make a note of it. If we later
289 see that there were also "good" sections, then we'll
290 declare that this a core file, but we'll also warn that
291 it may be incompatible with this gdb.
292 */
293 unknown_sections++;
294 break;
295
296 default:
297 goto fail; /*unrecognized core file type */
298 }
299 }
300
301 /* OK, we believe you. You're a core file (sure, sure). */
302
303 /* Were there sections of unknown type? If so, yet there were
304 at least some complete sections of known type, then, issue
305 a warning. Possibly the core file was generated on a version
306 of HP-UX that is incompatible with that for which this gdb was
307 built.
308 */
309 if ((unknown_sections > 0) && (good_sections > 0))
310 (*_bfd_error_handler)
311 ("%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",
312 abfd->filename);
313
314 return abfd->xvec;
315
316 fail:
317 bfd_release (abfd, core_hdr (abfd));
318 core_hdr (abfd) = NULL;
319 bfd_section_list_clear (abfd);
320 return NULL;
321}
322
323static char *
324hpux_core_core_file_failing_command (abfd)
325 bfd *abfd;
326{
327 return core_command (abfd);
328}
329
330/* ARGSUSED */
331static int
332hpux_core_core_file_failing_signal (abfd)
333 bfd *abfd;
334{
335 return core_signal (abfd);
336}
337
338/* ARGSUSED */
339static bfd_boolean
340hpux_core_core_file_matches_executable_p (core_bfd, exec_bfd)
341 bfd *core_bfd ATTRIBUTE_UNUSED;
342 bfd *exec_bfd ATTRIBUTE_UNUSED;
343{
344 return TRUE; /* FIXME, We have no way of telling at this point */
345}
346
347
348/* If somebody calls any byte-swapping routines, shoot them. */
349static void
350swap_abort ()
351{
352 abort(); /* This way doesn't require any declaration for ANSI to fuck up */
353}
354#define NO_GET ((bfd_vma (*) PARAMS (( const bfd_byte *))) swap_abort )
355#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) swap_abort )
356#define NO_SIGNED_GET \
357 ((bfd_signed_vma (*) PARAMS ((const bfd_byte *))) swap_abort )
358
359const bfd_target hpux_core_vec =
360 {
361 "hpux-core",
362 bfd_target_unknown_flavour,
363 BFD_ENDIAN_BIG, /* target byte order */
364 BFD_ENDIAN_BIG, /* target headers byte order */
365 (HAS_RELOC | EXEC_P | /* object flags */
366 HAS_LINENO | HAS_DEBUG |
367 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
368 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
369 0, /* symbol prefix */
370 ' ', /* ar_pad_char */
371 16, /* ar_max_namelen */
372 NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */
373 NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */
374 NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */
375 NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */
376 NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */
377 NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */
378
379 { /* bfd_check_format */
380 _bfd_dummy_target, /* unknown format */
381 _bfd_dummy_target, /* object file */
382 _bfd_dummy_target, /* archive */
383 hpux_core_core_file_p /* a core file */
384 },
385 { /* bfd_set_format */
386 bfd_false, bfd_false,
387 bfd_false, bfd_false
388 },
389 { /* bfd_write_contents */
390 bfd_false, bfd_false,
391 bfd_false, bfd_false
392 },
393
394 BFD_JUMP_TABLE_GENERIC (_bfd_generic),
395 BFD_JUMP_TABLE_COPY (_bfd_generic),
396 BFD_JUMP_TABLE_CORE (hpux_core),
397 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
398 BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
399 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
400 BFD_JUMP_TABLE_WRITE (_bfd_generic),
401 BFD_JUMP_TABLE_LINK (_bfd_nolink),
402 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
403
404 NULL,
405
406 (PTR) 0 /* backend_data */
407};
Note: See TracBrowser for help on using the repository browser.