* macro.c (sub_actual): Add back ampersand suffix when no
[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
252b5132 106
69d246d9
JB
107static asection *make_bfd_asection (bfd *, const char *, flagword,
108 bfd_size_type, bfd_vma, unsigned int);
109static const bfd_target *hpux_core_core_file_p (bfd *);
110static char *hpux_core_core_file_failing_command (bfd *);
111static int hpux_core_core_file_failing_signal (bfd *);
112static void swap_abort (void);
252b5132
RH
113
114static asection *
69d246d9
JB
115make_bfd_asection (bfd *abfd, const char *name, flagword flags,
116 bfd_size_type size, bfd_vma vma,
117 unsigned int alignment_power)
252b5132
RH
118{
119 asection *asect;
120 char *newname;
121
dc810e39 122 newname = bfd_alloc (abfd, (bfd_size_type) strlen (name) + 1);
252b5132
RH
123 if (!newname)
124 return NULL;
125
126 strcpy (newname, name);
127
117ed4f8 128 asect = bfd_make_section_anyway_with_flags (abfd, newname, flags);
252b5132
RH
129 if (!asect)
130 return NULL;
131
eea6121a 132 asect->size = size;
252b5132
RH
133 asect->vma = vma;
134 asect->filepos = bfd_tell (abfd);
135 asect->alignment_power = alignment_power;
136
137 return asect;
138}
139
94ea025a
JB
140/* Return true if the given core file section corresponds to a thread,
141 based on its name. */
142
143static int
144thread_section_p (bfd *abfd ATTRIBUTE_UNUSED,
145 asection *sect,
146 void *obj ATTRIBUTE_UNUSED)
147{
0112cd26 148 return CONST_STRNEQ (sect->name, ".reg/");
94ea025a
JB
149}
150
252b5132
RH
151/* this function builds a bfd target if the file is a corefile.
152 It returns null or 0 if it finds out thaat it is not a core file.
153 The way it checks this is by looking for allowed 'type' field values.
154 These are declared in sys/core.h
155 There are some values which are 'reserved for future use'. In particular
156 CORE_NONE is actually defined as 0. This may be a catch-all for cases
157 in which the core file is generated by some non-hpux application.
158 (I am just guessing here!)
159*/
160static const bfd_target *
69d246d9 161hpux_core_core_file_p (bfd *abfd)
252b5132
RH
162{
163 int good_sections = 0;
164 int unknown_sections = 0;
165
166 core_hdr (abfd) = (struct hpux_core_struct *)
dc810e39 167 bfd_zalloc (abfd, (bfd_size_type) sizeof (struct hpux_core_struct));
252b5132
RH
168 if (!core_hdr (abfd))
169 return NULL;
170
171 while (1)
172 {
173 int val;
174 struct corehead core_header;
175
dc810e39
AM
176 val = bfd_bread ((void *) &core_header,
177 (bfd_size_type) sizeof core_header, abfd);
252b5132
RH
178 if (val <= 0)
179 break;
180 switch (core_header.type)
181 {
182 case CORE_KERNEL:
183 case CORE_FORMAT:
dc810e39
AM
184 /* Just skip this. */
185 bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR);
252b5132
RH
186 good_sections++;
187 break;
188 case CORE_EXEC:
189 {
190 struct proc_exec proc_exec;
dc810e39
AM
191 if (bfd_bread ((void *) &proc_exec, (bfd_size_type) core_header.len,
192 abfd) != core_header.len)
252b5132
RH
193 break;
194 strncpy (core_command (abfd), proc_exec.cmd, MAXCOMLEN + 1);
195 good_sections++;
196 }
197 break;
198 case CORE_PROC:
199 {
200 struct proc_info proc_info;
201 char secname[100]; /* Of arbitrary size, but plenty large. */
202
203 /* We need to read this section, 'cause we need to determine
204 whether the core-dumped app was threaded before we create
205 any .reg sections. */
dc810e39 206 if (bfd_bread (&proc_info, (bfd_size_type) core_header.len, abfd)
252b5132
RH
207 != core_header.len)
208 break;
209
210 /* However, we also want to create those sections with the
211 file positioned at the start of the record, it seems. */
94ea025a 212 if (bfd_seek (abfd, -((file_ptr) core_header.len), SEEK_CUR) != 0)
252b5132
RH
213 break;
214
215#if defined(PROC_INFO_HAS_THREAD_ID)
216 core_kernel_thread_id (abfd) = proc_info.lwpid;
217 core_user_thread_id (abfd) = proc_info.user_tid;
218#else
219 core_kernel_thread_id (abfd) = 0;
220 core_user_thread_id (abfd) = 0;
221#endif
222 /* If the program was unthreaded, then we'll just create a
223 .reg section.
224
225 If the program was threaded, then we'll create .reg/XXXXX
226 section for each thread, where XXXXX is a printable
227 representation of the kernel thread id. We'll also
228 create a .reg section for the thread that was running
229 and signalled at the time of the core-dump (i.e., this
230 is effectively an alias, needed to keep GDB happy.)
231
232 Note that we use `.reg/XXXXX' as opposed to '.regXXXXX'
233 because GDB expects that .reg2 will be the floating-
234 point registers. */
235 if (core_kernel_thread_id (abfd) == 0)
236 {
237 if (!make_bfd_asection (abfd, ".reg",
3dd2fcf0
DA
238 SEC_HAS_CONTENTS,
239 core_header.len,
240 (bfd_vma) offsetof (struct proc_info,
241 hw_regs),
242 2))
9e7b37b3 243 goto fail;
252b5132
RH
244 }
245 else
246 {
247 /* There are threads. Is this the one that caused the
248 core-dump? We'll claim it was the running thread. */
249 if (proc_info.sig != -1)
250 {
251 if (!make_bfd_asection (abfd, ".reg",
252 SEC_HAS_CONTENTS,
253 core_header.len,
3dd2fcf0
DA
254 (bfd_vma)offsetof (struct proc_info,
255 hw_regs),
252b5132 256 2))
9e7b37b3 257 goto fail;
252b5132
RH
258 }
259 /* We always make one of these sections, for every thread. */
260 sprintf (secname, ".reg/%d", core_kernel_thread_id (abfd));
261 if (!make_bfd_asection (abfd, secname,
3dd2fcf0
DA
262 SEC_HAS_CONTENTS,
263 core_header.len,
264 (bfd_vma) offsetof (struct proc_info,
265 hw_regs),
266 2))
9e7b37b3 267 goto fail;
252b5132
RH
268 }
269 core_signal (abfd) = proc_info.sig;
dc810e39 270 if (bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR) != 0)
252b5132
RH
271 break;
272 good_sections++;
273 }
274 break;
275
276 case CORE_DATA:
277 case CORE_STACK:
278 case CORE_TEXT:
279 case CORE_MMF:
280 case CORE_SHM:
281 case CORE_ANON_SHMEM:
282 if (!make_bfd_asection (abfd, ".data",
283 SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
5198ba8b
DA
284 core_header.len,
285 (bfd_vma) core_header.addr, 2))
9e7b37b3 286 goto fail;
252b5132 287
dc810e39 288 bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR);
252b5132
RH
289 good_sections++;
290 break;
291
292 case CORE_NONE:
293 /* Let's not punt if we encounter a section of unknown
294 type. Rather, let's make a note of it. If we later
295 see that there were also "good" sections, then we'll
296 declare that this a core file, but we'll also warn that
297 it may be incompatible with this gdb.
298 */
299 unknown_sections++;
300 break;
3fde5a36 301
9e7b37b3
AM
302 default:
303 goto fail; /*unrecognized core file type */
252b5132
RH
304 }
305 }
306
307 /* OK, we believe you. You're a core file (sure, sure). */
308
94ea025a
JB
309 /* On HP/UX, we sometimes encounter core files where none of the threads
310 was found to be the running thread (ie the signal was set to -1 for
311 all threads). This happens when the program was aborted externally
312 via a TT_CORE ttrace system call. In that case, we just pick one
313 thread at random to be the active thread. */
314 if (core_kernel_thread_id (abfd) != 0
315 && bfd_get_section_by_name (abfd, ".reg") == NULL)
316 {
317 asection *asect = bfd_sections_find_if (abfd, thread_section_p, NULL);
318 asection *reg_sect;
319
320 if (asect != NULL)
321 {
322 reg_sect = make_bfd_asection (abfd, ".reg", asect->flags,
323 asect->size, asect->vma,
324 asect->alignment_power);
325 if (reg_sect == NULL)
326 goto fail;
327
328 reg_sect->filepos = asect->filepos;
329 }
330 }
331
252b5132
RH
332 /* Were there sections of unknown type? If so, yet there were
333 at least some complete sections of known type, then, issue
334 a warning. Possibly the core file was generated on a version
335 of HP-UX that is incompatible with that for which this gdb was
336 built.
337 */
338 if ((unknown_sections > 0) && (good_sections > 0))
339 (*_bfd_error_handler)
340 ("%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",
341 abfd->filename);
342
343 return abfd->xvec;
9e7b37b3
AM
344
345 fail:
346 bfd_release (abfd, core_hdr (abfd));
347 core_hdr (abfd) = NULL;
348 bfd_section_list_clear (abfd);
349 return NULL;
252b5132
RH
350}
351
352static char *
69d246d9 353hpux_core_core_file_failing_command (bfd *abfd)
252b5132
RH
354{
355 return core_command (abfd);
356}
357
252b5132 358static int
69d246d9 359hpux_core_core_file_failing_signal (bfd *abfd)
252b5132
RH
360{
361 return core_signal (abfd);
362}
363
252b5132 364\f
252b5132
RH
365/* If somebody calls any byte-swapping routines, shoot them. */
366static void
69d246d9 367swap_abort (void)
252b5132
RH
368{
369 abort(); /* This way doesn't require any declaration for ANSI to fuck up */
370}
8ce8c090 371
edeb6e24
AM
372#define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
373#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
374#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
8ce8c090
AM
375#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
376#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
377#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
252b5132
RH
378
379const bfd_target hpux_core_vec =
380 {
381 "hpux-core",
382 bfd_target_unknown_flavour,
383 BFD_ENDIAN_BIG, /* target byte order */
384 BFD_ENDIAN_BIG, /* target headers byte order */
385 (HAS_RELOC | EXEC_P | /* object flags */
386 HAS_LINENO | HAS_DEBUG |
387 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
388 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
389 0, /* symbol prefix */
390 ' ', /* ar_pad_char */
391 16, /* ar_max_namelen */
8ce8c090 392 NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit data */
edeb6e24
AM
393 NO_GET, NO_GETS, NO_PUT, /* 32 bit data */
394 NO_GET, NO_GETS, NO_PUT, /* 16 bit data */
8ce8c090 395 NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs */
edeb6e24
AM
396 NO_GET, NO_GETS, NO_PUT, /* 32 bit hdrs */
397 NO_GET, NO_GETS, NO_PUT, /* 16 bit hdrs */
252b5132
RH
398
399 { /* bfd_check_format */
8ce8c090
AM
400 _bfd_dummy_target, /* unknown format */
401 _bfd_dummy_target, /* object file */
402 _bfd_dummy_target, /* archive */
403 hpux_core_core_file_p /* a core file */
252b5132
RH
404 },
405 { /* bfd_set_format */
8ce8c090
AM
406 bfd_false, bfd_false,
407 bfd_false, bfd_false
252b5132
RH
408 },
409 { /* bfd_write_contents */
8ce8c090
AM
410 bfd_false, bfd_false,
411 bfd_false, bfd_false
252b5132 412 },
3fde5a36 413
3f3c5c34
AM
414 BFD_JUMP_TABLE_GENERIC (_bfd_generic),
415 BFD_JUMP_TABLE_COPY (_bfd_generic),
416 BFD_JUMP_TABLE_CORE (hpux_core),
417 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
418 BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
419 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
420 BFD_JUMP_TABLE_WRITE (_bfd_generic),
421 BFD_JUMP_TABLE_LINK (_bfd_nolink),
422 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
252b5132 423
c3c89269 424 NULL,
3fde5a36 425
252b5132 426 (PTR) 0 /* backend_data */
8ce8c090 427 };
This page took 0.851532 seconds and 4 git commands to generate.