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