gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / aix5ppc-core.c
CommitLineData
eb1e0e80 1/* IBM RS/6000 "XCOFF" back-end for BFD.
b3adc24a 2 Copyright (C) 2001-2020 Free Software Foundation, Inc.
eb1e0e80 3 Written by Tom Rix
e729279b 4 Contributed by Red Hat Inc.
eb1e0e80
NC
5
6 This file is part of BFD, the Binary File Descriptor library.
7
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
cd123cb7 10 the Free Software Foundation; either version 3 of the License, or
eb1e0e80
NC
11 (at your option) any later version.
12
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
3e110533 20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
53e09e0a 21 MA 02110-1301, USA. */
eb1e0e80 22
3db64b00 23#include "sysdep.h"
eb1e0e80
NC
24#include "bfd.h"
25
601b73d5 26bfd_cleanup xcoff64_core_p (bfd *);
e729279b
NC
27bfd_boolean xcoff64_core_file_matches_executable_p (bfd *, bfd *);
28char *xcoff64_core_file_failing_command (bfd *);
29int xcoff64_core_file_failing_signal (bfd *);
eb1e0e80 30
9bf46c00
AM
31#ifdef AIX_5_CORE
32
9bf46c00
AM
33#include "libbfd.h"
34
eb1e0e80
NC
35/* Aix 5.1 system include file. */
36
37/* Need to define this macro so struct ld_info64 get included. */
38#define __LDINFO_PTRACE64__
39#include <sys/ldr.h>
40#include <core.h>
41
e0c88096
NC
42/* The default architecture and machine for matching core files. */
43#define DEFAULT_ARCHITECTURE bfd_arch_powerpc
44#define DEFAULT_MACHINE bfd_mach_ppc_620
45
eb1e0e80
NC
46#define core_hdr(abfd) ((struct core_dumpxx *) abfd->tdata.any)
47
48#define CHECK_FILE_OFFSET(s, v) \
49 ((bfd_signed_vma)(v) < 0 || (bfd_signed_vma)(v) > (bfd_signed_vma)(s).st_size)
50
601b73d5 51bfd_cleanup
e729279b 52xcoff64_core_p (bfd *abfd)
eb1e0e80 53{
e0c88096
NC
54 enum bfd_architecture arch;
55 unsigned long mach;
eb1e0e80
NC
56 struct core_dumpxx core, *new_core_hdr;
57 struct stat statbuf;
58 asection *sec;
59 struct __ld_info64 ldinfo;
60 bfd_vma ld_offset;
61 bfd_size_type i;
62 struct vm_infox vminfo;
117ed4f8 63 flagword flags;
eb1e0e80
NC
64
65 /* Get the header. */
66 if (bfd_seek (abfd, 0, SEEK_SET) != 0)
67 goto xcoff64_core_p_error;
68
b34976b6 69 if (sizeof (struct core_dumpxx)
d1e66cd4 70 != bfd_bread (&core, sizeof (struct core_dumpxx), abfd))
eb1e0e80
NC
71 goto xcoff64_core_p_error;
72
b34976b6 73 if (bfd_stat (abfd, &statbuf) < 0)
eb1e0e80
NC
74 goto xcoff64_core_p_error;
75
76 /* Sanity checks
77 c_flag has CORE_VERSION_1, Aix 4+
78 c_entries = 0 for Aix 4.3+
79 IS_PROC64 is a macro defined in procinfo.h, test for 64 bit process.
80
81 We will still be confused if a Aix 4.3 64 bit core file is
82 copied over to a Aix 5 machine.
83
84 Check file header offsets
85
86 See rs6000-core.c for comment on size of core
87 If there isn't enough of a real core file, bail. */
88
b34976b6
AM
89 if ((CORE_VERSION_1 != (core.c_flag & CORE_VERSION_1))
90 || (0 != core.c_entries)
91 || (! (IS_PROC64 (&core.c_u.U_proc)))
92 || ((CHECK_FILE_OFFSET (statbuf, core.c_fdsinfox)))
93 || ((CHECK_FILE_OFFSET (statbuf, core.c_loader)))
94 || ((CHECK_FILE_OFFSET (statbuf, core.c_loader + core.c_lsize)))
95 || ((CHECK_FILE_OFFSET (statbuf, core.c_thr)))
96 || ((CHECK_FILE_OFFSET (statbuf, core.c_segregion)))
97 || ((CHECK_FILE_OFFSET (statbuf, core.c_stack)))
98 || ((CHECK_FILE_OFFSET (statbuf, core.c_stack + core.c_size)))
99 || ((CHECK_FILE_OFFSET (statbuf, core.c_data)))
100 || ((CHECK_FILE_OFFSET (statbuf, core.c_data + core.c_datasize)))
101 || (! (core.c_flag & UBLOCK_VALID))
102 || (! (core.c_flag & LE_VALID)))
eb1e0e80
NC
103 goto xcoff64_core_p_error;
104
5c4491d3 105 /* Check for truncated stack or general truncating. */
b34976b6 106 if ((! (core.c_flag & USTACK_VALID))
eb1e0e80
NC
107 || (core.c_flag & CORE_TRUNC))
108 {
109 bfd_set_error (bfd_error_file_truncated);
110
601b73d5 111 return NULL;
eb1e0e80
NC
112 }
113
e729279b 114 new_core_hdr = bfd_zalloc (abfd, sizeof (struct core_dumpxx));
b34976b6 115 if (NULL == new_core_hdr)
601b73d5 116 return NULL;
eb1e0e80
NC
117
118 memcpy (new_core_hdr, &core, sizeof (struct core_dumpxx));
fd6212e6
NC
119 /* The core_hdr() macro is no longer used here because it would
120 expand to code relying on gcc's cast-as-lvalue extension,
121 which was removed in gcc 4.0. */
122 abfd->tdata.any = new_core_hdr;
eb1e0e80
NC
123
124 /* .stack section. */
117ed4f8
AM
125 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
126 sec = bfd_make_section_anyway_with_flags (abfd, ".stack", flags);
b34976b6 127 if (NULL == sec)
601b73d5 128 return NULL;
eb1e0e80 129
eea6121a 130 sec->size = core.c_size;
eb1e0e80
NC
131 sec->vma = core.c_stackorg;
132 sec->filepos = core.c_stack;
133
134 /* .reg section for all registers. */
117ed4f8
AM
135 flags = SEC_HAS_CONTENTS | SEC_IN_MEMORY;
136 sec = bfd_make_section_anyway_with_flags (abfd, ".reg", flags);
b34976b6 137 if (NULL == sec)
601b73d5 138 return NULL;
eb1e0e80 139
eea6121a 140 sec->size = sizeof (struct __context64);
eb1e0e80
NC
141 sec->vma = 0;
142 sec->filepos = 0;
143 sec->contents = (bfd_byte *)&new_core_hdr->c_flt.r64;
144
145 /* .ldinfo section.
146 To actually find out how long this section is in this particular
b34976b6 147 core dump would require going down the whole list of struct
eb1e0e80 148 ld_info's. See if we can just fake it. */
117ed4f8
AM
149 flags = SEC_HAS_CONTENTS;
150 sec = bfd_make_section_anyway_with_flags (abfd, ".ldinfo", flags);
eb1e0e80 151 if (NULL == sec)
601b73d5 152 return NULL;
eb1e0e80 153
eea6121a 154 sec->size = core.c_lsize;
eb1e0e80
NC
155 sec->vma = 0;
156 sec->filepos = core.c_loader;
157
158 /* AIX 4 adds data sections from loaded objects to the core file,
159 which can be found by examining ldinfo, and anonymously mmapped
160 regions. */
b34976b6 161
eb1e0e80 162 /* .data section from executable. */
117ed4f8
AM
163 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
164 sec = bfd_make_section_anyway_with_flags (abfd, ".data", flags);
b34976b6 165 if (NULL == sec)
601b73d5 166 return NULL;
eb1e0e80 167
eea6121a 168 sec->size = core.c_datasize;
eb1e0e80
NC
169 sec->vma = core.c_dataorg;
170 sec->filepos = core.c_data;
171
172 /* .data sections from loaded objects. */
173 ld_offset = core.c_loader;
b34976b6
AM
174
175 while (1)
eb1e0e80 176 {
b34976b6 177 if (bfd_seek (abfd, ld_offset, SEEK_SET) != 0)
601b73d5 178 return NULL;
eb1e0e80
NC
179
180 if (sizeof (struct __ld_info64) !=
b34976b6 181 bfd_bread (&ldinfo, sizeof (struct __ld_info64), abfd))
601b73d5 182 return NULL;
eb1e0e80 183
b34976b6 184 if (ldinfo.ldinfo_core)
eb1e0e80 185 {
117ed4f8
AM
186 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
187 sec = bfd_make_section_anyway_with_flags (abfd, ".data", flags);
b34976b6 188 if (NULL == sec)
601b73d5 189 return NULL;
eb1e0e80 190
eea6121a 191 sec->size = ldinfo.ldinfo_datasize;
eb1e0e80
NC
192 sec->vma = ldinfo.ldinfo_dataorg;
193 sec->filepos = ldinfo.ldinfo_core;
194 }
195
196 if (0 == ldinfo.ldinfo_next)
197 break;
198 ld_offset += ldinfo.ldinfo_next;
199 }
200
201 /* .vmdata sections from anonymously mmapped regions. */
b34976b6 202 if (core.c_vmregions)
eb1e0e80 203 {
b34976b6 204 if (bfd_seek (abfd, core.c_vmm, SEEK_SET) != 0)
601b73d5 205 return NULL;
eb1e0e80 206
b34976b6 207 for (i = 0; i < core.c_vmregions; i++)
eb1e0e80 208 if (sizeof (struct vm_infox) !=
b34976b6 209 bfd_bread (&vminfo, sizeof (struct vm_infox), abfd))
601b73d5 210 return NULL;
eb1e0e80 211
b34976b6 212 if (vminfo.vminfo_offset)
eb1e0e80 213 {
117ed4f8
AM
214 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
215 sec = bfd_make_section_anyway_with_flags (abfd, ".vmdata", flags);
b34976b6 216 if (NULL == sec)
601b73d5 217 return NULL;
eb1e0e80 218
eea6121a 219 sec->size = vminfo.vminfo_size;
eb1e0e80
NC
220 sec->vma = vminfo.vminfo_addr;
221 sec->filepos = vminfo.vminfo_offset;
222 }
223 }
224
e0c88096
NC
225 /* Set the architecture and machine. */
226 arch = DEFAULT_ARCHITECTURE;
227 mach = DEFAULT_MACHINE;
228 bfd_default_set_arch_mach (abfd, arch, mach);
229
601b73d5 230 return _bfd_no_cleanup;
b34976b6 231
eb1e0e80 232 xcoff64_core_p_error:
b34976b6 233 if (bfd_get_error () != bfd_error_system_call)
eb1e0e80 234 bfd_set_error (bfd_error_wrong_format);
b34976b6 235
601b73d5 236 return NULL;
eb1e0e80
NC
237}
238
b34976b6 239/* Return `TRUE' if given core is from the given executable. */
eb1e0e80 240
b34976b6 241bfd_boolean
e729279b 242xcoff64_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
eb1e0e80
NC
243{
244 struct core_dumpxx core;
245 char *path, *s;
246 size_t alloc;
247 const char *str1, *str2;
b34976b6 248 bfd_boolean return_value = FALSE;
eb1e0e80
NC
249
250 /* Get the header. */
b34976b6 251 if (bfd_seek (core_bfd, 0, SEEK_SET) != 0)
eb1e0e80 252 return return_value;
b34976b6 253
eb1e0e80 254 if (sizeof (struct core_dumpxx) !=
b34976b6 255 bfd_bread (&core, sizeof (struct core_dumpxx), core_bfd))
eb1e0e80
NC
256 return return_value;
257
b34976b6 258 if (bfd_seek (core_bfd, core.c_loader, SEEK_SET) != 0)
eb1e0e80
NC
259 return return_value;
260
261 alloc = 100;
262 path = bfd_malloc (alloc);
b34976b6 263 if (path == NULL)
eb1e0e80
NC
264 return return_value;
265
266 s = path;
267
268 while (1)
269 {
d1e66cd4 270 if (bfd_bread (s, 1, core_bfd) != 1)
eb1e0e80
NC
271 goto xcoff64_core_file_matches_executable_p_end_1;
272
273 if (*s == '\0')
274 break;
275 ++s;
b34976b6 276 if (s == path + alloc)
eb1e0e80
NC
277 {
278 char *n;
279
280 alloc *= 2;
281 n = bfd_realloc (path, alloc);
b34976b6 282 if (n == NULL)
eb1e0e80
NC
283 goto xcoff64_core_file_matches_executable_p_end_1;
284
285 s = n + (path - s);
286 path = n;
287 }
288 }
289
290 str1 = strrchr (path, '/');
765cf5f6 291 str2 = strrchr (bfd_get_filename (exec_bfd), '/');
eb1e0e80
NC
292
293 /* Step over character '/'. */
294 str1 = str1 != NULL ? str1 + 1 : path;
765cf5f6 295 str2 = str2 != NULL ? str2 + 1 : bfd_get_filename (exec_bfd);
eb1e0e80 296
b34976b6
AM
297 if (strcmp (str1, str2) == 0)
298 return_value = TRUE;
eb1e0e80
NC
299
300 xcoff64_core_file_matches_executable_p_end_1:
301 free (path);
302 return return_value;
303}
304
305char *
e729279b 306xcoff64_core_file_failing_command (bfd *abfd)
eb1e0e80
NC
307{
308 struct core_dumpxx *c = core_hdr (abfd);
309 char *return_value = 0;
310
b34976b6 311 if (NULL != c)
eb1e0e80
NC
312 return_value = c->c_u.U_proc.pi_comm;
313
314 return return_value;
315}
316
317int
e729279b 318xcoff64_core_file_failing_signal (bfd *abfd)
eb1e0e80
NC
319{
320 struct core_dumpxx *c = core_hdr (abfd);
321 int return_value = 0;
322
b34976b6 323 if (NULL != c)
eb1e0e80
NC
324 return_value = c->c_signo;
325
326 return return_value;
327}
328
329#else /* AIX_5_CORE */
330
601b73d5 331bfd_cleanup
e729279b 332xcoff64_core_p (bfd *abfd ATTRIBUTE_UNUSED)
eb1e0e80
NC
333{
334 bfd_set_error (bfd_error_wrong_format);
335 return 0;
336}
337
9bf46c00
AM
338bfd_boolean
339xcoff64_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
340{
341 return generic_core_file_matches_executable_p (core_bfd, exec_bfd);
342}
343
eb1e0e80 344char *
e729279b 345xcoff64_core_file_failing_command (bfd *abfd ATTRIBUTE_UNUSED)
eb1e0e80
NC
346{
347 return 0;
348}
349
350int
e729279b 351xcoff64_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
eb1e0e80
NC
352{
353 return 0;
354}
355
356#endif /* AIX_5_CORE */
This page took 0.880212 seconds and 4 git commands to generate.