gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / hpux-core.c
CommitLineData
252b5132 1/* BFD back-end for HP/UX core files.
b3adc24a 2 Copyright (C) 1993-2020 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
dc12032b 31#if defined (HOST_HPPAHPUX) || defined (HOST_HPPAMPEIX)
252b5132
RH
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)
07d6d2b8 83#define CORE_ANON_SHMEM 0x00000200 /* anonymous shared memory */
252b5132
RH
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;
07d6d2b8 94 int lwpid; /* Kernel thread ID. */
252b5132
RH
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 107static asection *make_bfd_asection (bfd *, const char *, flagword,
07d6d2b8 108 bfd_size_type, bfd_vma, unsigned int);
40b35c78 109static bfd_cleanup hpux_core_core_file_p (bfd *);
69d246d9
JB
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 115make_bfd_asection (bfd *abfd, const char *name, flagword flags,
07d6d2b8
AM
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,
07d6d2b8
AM
145 asection *sect,
146 void *obj ATTRIBUTE_UNUSED)
94ea025a 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*/
601b73d5 160static bfd_cleanup
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);
07d6d2b8 186 good_sections++;
252b5132
RH
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);
07d6d2b8 195 good_sections++;
252b5132
RH
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
07d6d2b8
AM
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
07d6d2b8
AM
210 /* However, we also want to create those sections with the
211 file positioned at the start of the record, it seems. */
212 if (bfd_seek (abfd, -((file_ptr) core_header.len), SEEK_CUR) != 0)
213 break;
252b5132
RH
214
215#if defined(PROC_INFO_HAS_THREAD_ID)
07d6d2b8
AM
216 core_kernel_thread_id (abfd) = proc_info.lwpid;
217 core_user_thread_id (abfd) = proc_info.user_tid;
252b5132 218#else
07d6d2b8
AM
219 core_kernel_thread_id (abfd) = 0;
220 core_user_thread_id (abfd) = 0;
252b5132 221#endif
07d6d2b8
AM
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;
07d6d2b8
AM
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 {
252b5132
RH
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;
07d6d2b8
AM
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;
07d6d2b8 268 }
252b5132 269 core_signal (abfd) = proc_info.sig;
07d6d2b8
AM
270 if (bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR) != 0)
271 break;
272 good_sections++;
252b5132
RH
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);
07d6d2b8 289 good_sections++;
252b5132
RH
290 break;
291
292 case CORE_NONE:
07d6d2b8
AM
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 */
252b5132 299 unknown_sections++;
07d6d2b8 300 break;
3fde5a36 301
07d6d2b8 302 default:
9e7b37b3 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)
07d6d2b8
AM
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 }
94ea025a
JB
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))
4eca0228 339 _bfd_error_handler
871b3ab2 340 ("%pB appears to be a core file,\nbut contains unknown sections."
dae82561
AM
341 " It may have been created on an incompatible\nversion of HP-UX."
342 " As a result, some information may be unavailable.\n",
343 abfd);
252b5132 344
601b73d5 345 return _bfd_no_cleanup;
9e7b37b3
AM
346
347 fail:
348 bfd_release (abfd, core_hdr (abfd));
349 core_hdr (abfd) = NULL;
350 bfd_section_list_clear (abfd);
351 return NULL;
252b5132
RH
352}
353
354static char *
69d246d9 355hpux_core_core_file_failing_command (bfd *abfd)
252b5132
RH
356{
357 return core_command (abfd);
358}
359
252b5132 360static int
69d246d9 361hpux_core_core_file_failing_signal (bfd *abfd)
252b5132
RH
362{
363 return core_signal (abfd);
364}
365
252b5132 366\f
252b5132
RH
367/* If somebody calls any byte-swapping routines, shoot them. */
368static void
69d246d9 369swap_abort (void)
252b5132
RH
370{
371 abort(); /* This way doesn't require any declaration for ANSI to fuck up */
372}
8ce8c090 373
edeb6e24
AM
374#define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
375#define NO_PUT ((void (*) (bfd_vma, void *)) swap_abort)
376#define NO_GETS ((bfd_signed_vma (*) (const void *)) swap_abort)
8ce8c090
AM
377#define NO_GET64 ((bfd_uint64_t (*) (const void *)) swap_abort)
378#define NO_PUT64 ((void (*) (bfd_uint64_t, void *)) swap_abort)
379#define NO_GETS64 ((bfd_int64_t (*) (const void *)) swap_abort)
252b5132 380
6d00b590 381const bfd_target core_hpux_vec =
252b5132
RH
382 {
383 "hpux-core",
384 bfd_target_unknown_flavour,
385 BFD_ENDIAN_BIG, /* target byte order */
386 BFD_ENDIAN_BIG, /* target headers byte order */
387 (HAS_RELOC | EXEC_P | /* object flags */
388 HAS_LINENO | HAS_DEBUG |
389 HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
390 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
d3aeb6ee
AM
391 0, /* symbol prefix */
392 ' ', /* ar_pad_char */
393 16, /* ar_max_namelen */
394 0, /* match priority. */
8ce8c090 395 NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit data */
edeb6e24
AM
396 NO_GET, NO_GETS, NO_PUT, /* 32 bit data */
397 NO_GET, NO_GETS, NO_PUT, /* 16 bit data */
8ce8c090 398 NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit hdrs */
edeb6e24
AM
399 NO_GET, NO_GETS, NO_PUT, /* 32 bit hdrs */
400 NO_GET, NO_GETS, NO_PUT, /* 16 bit hdrs */
252b5132
RH
401
402 { /* bfd_check_format */
8ce8c090
AM
403 _bfd_dummy_target, /* unknown format */
404 _bfd_dummy_target, /* object file */
405 _bfd_dummy_target, /* archive */
406 hpux_core_core_file_p /* a core file */
252b5132
RH
407 },
408 { /* bfd_set_format */
d00dd7dc
AM
409 _bfd_bool_bfd_false_error,
410 _bfd_bool_bfd_false_error,
411 _bfd_bool_bfd_false_error,
412 _bfd_bool_bfd_false_error
252b5132
RH
413 },
414 { /* bfd_write_contents */
d00dd7dc
AM
415 _bfd_bool_bfd_false_error,
416 _bfd_bool_bfd_false_error,
417 _bfd_bool_bfd_false_error,
418 _bfd_bool_bfd_false_error
252b5132 419 },
3fde5a36 420
3f3c5c34
AM
421 BFD_JUMP_TABLE_GENERIC (_bfd_generic),
422 BFD_JUMP_TABLE_COPY (_bfd_generic),
423 BFD_JUMP_TABLE_CORE (hpux_core),
424 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
425 BFD_JUMP_TABLE_SYMBOLS (_bfd_nosymbols),
426 BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
427 BFD_JUMP_TABLE_WRITE (_bfd_generic),
428 BFD_JUMP_TABLE_LINK (_bfd_nolink),
429 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
252b5132 430
c3c89269 431 NULL,
3fde5a36 432
2c3fc389 433 NULL /* backend_data */
8ce8c090 434 };
This page took 1.135757 seconds and 4 git commands to generate.