Better ld --fatal-warnings support
[deliverable/binutils-gdb.git] / bfd / hpux-core.c
CommitLineData
252b5132 1/* BFD back-end for HP/UX core files.
6f2750fe 2 Copyright (C) 1993-2016 Free Software Foundation, Inc.
252b5132
RH
3 Written by Stu Grossman, Cygnus Support.
4 Converted to back-end form by Ian Lance Taylor, Cygnus SUpport
5
cd123cb7 6 This file is part of BFD, the Binary File Descriptor library.
252b5132 7
cd123cb7
NC
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
252b5132 12
cd123cb7
NC
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
252b5132 22
252b5132
RH
23
24/* This file can only be compiled on systems which use HP/UX style
25 core files. */
26
252b5132 27#include "sysdep.h"
3db64b00 28#include "bfd.h"
252b5132
RH
29#include "libbfd.h"
30
31#if defined (HOST_HPPAHPUX) || defined (HOST_HP300HPUX) || defined (HOST_HPPAMPEIX)
32
33/* FIXME: sys/core.h doesn't exist for HPUX version 7. HPUX version
34 5, 6, and 7 core files seem to be standard trad-core.c type core
35 files; can we just use trad-core.c in addition to this file? */
36
37#include <sys/core.h>
38#include <sys/utsname.h>
39
40#endif /* HOST_HPPAHPUX */
41
42#ifdef HOST_HPPABSD
43
44/* Not a very swift place to put it, but that's where the BSD port
45 puts them. */
46#include "/hpux/usr/include/sys/core.h"
47
48#endif /* HOST_HPPABSD */
49
50#include <sys/param.h>
51#ifdef HAVE_DIRENT_H
52# include <dirent.h>
53#else
54# ifdef HAVE_SYS_NDIR_H
55# include <sys/ndir.h>
56# endif
57# ifdef HAVE_SYS_DIR_H
58# include <sys/dir.h>
59# endif
60# ifdef HAVE_NDIR_H
61# include <ndir.h>
62# endif
63#endif
64#include <signal.h>
9b818146 65#ifdef HPUX_CORE
252b5132 66#include <machine/reg.h>
9b818146 67#endif
252b5132
RH
68#include <sys/file.h>
69
70/* Kludge: There's no explicit mechanism provided by sys/core.h to
71 conditionally know whether a proc_info has thread id fields.
72 However, CORE_ANON_SHMEM shows up first at 10.30, which is
73 happily also when meaningful thread id's show up in proc_info. */
74#if defined(CORE_ANON_SHMEM)
75#define PROC_INFO_HAS_THREAD_ID (1)
76#endif
77
78/* This type appears at HP-UX 10.30. Defining it if not defined
79 by sys/core.h allows us to build for older HP-UX's, and (since
80 it won't be encountered in core-dumps from older HP-UX's) is
81 harmless. */
82#if !defined(CORE_ANON_SHMEM)
83#define CORE_ANON_SHMEM 0x00000200 /* anonymous shared memory */
84#endif
85
86/* These are stored in the bfd's tdata */
87
88/* .lwpid and .user_tid are only valid if PROC_INFO_HAS_THREAD_ID, else they
89 are set to 0. Also, until HP-UX implements MxN threads, .user_tid and
90 .lwpid are synonymous. */
3fde5a36 91struct hpux_core_struct
252b5132
RH
92{
93 int sig;
94 int lwpid; /* Kernel thread ID. */
95 unsigned long user_tid; /* User thread ID. */
96 char cmd[MAXCOMLEN + 1];
97};
98
99#define core_hdr(bfd) ((bfd)->tdata.hpux_core_data)
100#define core_signal(bfd) (core_hdr(bfd)->sig)
101#define core_command(bfd) (core_hdr(bfd)->cmd)
102#define core_kernel_thread_id(bfd) (core_hdr(bfd)->lwpid)
103#define core_user_thread_id(bfd) (core_hdr(bfd)->user_tid)
69d246d9 104#define hpux_core_core_file_matches_executable_p generic_core_file_matches_executable_p
261b8d08 105#define hpux_core_core_file_pid _bfd_nocore_core_file_pid
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 378
6d00b590 379const bfd_target core_hpux_vec =
252b5132
RH
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 */
d3aeb6ee
AM
389 0, /* symbol prefix */
390 ' ', /* ar_pad_char */
391 16, /* ar_max_namelen */
392 0, /* match priority. */
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
2c3fc389 427 NULL /* backend_data */
8ce8c090 428 };
This page took 1.035263 seconds and 4 git commands to generate.