* i386-tdep.c (i386_reg_struct_return_p): Handle structures with a
[deliverable/binutils-gdb.git] / bfd / aix5ppc-core.c
CommitLineData
eb1e0e80 1/* IBM RS/6000 "XCOFF" back-end for BFD.
9553c638 2 Copyright 2001, 2002, 2003, 2004
eb1e0e80
NC
3 Free Software Foundation, Inc.
4 Written by Tom Rix
5 Contributed by Redhat.
6
7 This file is part of BFD, the Binary File Descriptor library.
8
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 2 of the License, or
12 (at your option) any later version.
13
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
3e110533 21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
53e09e0a 22 MA 02110-1301, USA. */
eb1e0e80
NC
23
24#include "bfd.h"
25
26#ifdef AIX_5_CORE
27
28#include "sysdep.h"
29#include "libbfd.h"
30
b34976b6
AM
31const bfd_target *xcoff64_core_p
32 PARAMS ((bfd *));
33bfd_boolean xcoff64_core_file_matches_executable_p
34 PARAMS ((bfd *, bfd *));
35char *xcoff64_core_file_failing_command
36 PARAMS ((bfd *));
37int xcoff64_core_file_failing_signal
38 PARAMS ((bfd *));
eb1e0e80
NC
39
40/* Aix 5.1 system include file. */
41
42/* Need to define this macro so struct ld_info64 get included. */
43#define __LDINFO_PTRACE64__
44#include <sys/ldr.h>
45#include <core.h>
46
47#define core_hdr(abfd) ((struct core_dumpxx *) abfd->tdata.any)
48
49#define CHECK_FILE_OFFSET(s, v) \
50 ((bfd_signed_vma)(v) < 0 || (bfd_signed_vma)(v) > (bfd_signed_vma)(s).st_size)
51
52const bfd_target *
53xcoff64_core_p (abfd)
54 bfd *abfd;
55{
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;
63 bfd_target *return_value = NULL;
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
111 return return_value;
112 }
113
114 new_core_hdr = (struct core_dumpxx *)
115 bfd_zalloc (abfd, sizeof (struct core_dumpxx));
b34976b6 116 if (NULL == new_core_hdr)
eb1e0e80
NC
117 return return_value;
118
119 memcpy (new_core_hdr, &core, sizeof (struct core_dumpxx));
120 core_hdr(abfd) = (char *)new_core_hdr;
121
122 /* .stack section. */
123 sec = bfd_make_section_anyway (abfd, ".stack");
b34976b6 124 if (NULL == sec)
eb1e0e80
NC
125 return return_value;
126
127 sec->flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
eea6121a 128 sec->size = core.c_size;
eb1e0e80
NC
129 sec->vma = core.c_stackorg;
130 sec->filepos = core.c_stack;
131
132 /* .reg section for all registers. */
133 sec = bfd_make_section_anyway (abfd, ".reg");
b34976b6 134 if (NULL == sec)
eb1e0e80
NC
135 return return_value;
136
137 sec->flags = SEC_HAS_CONTENTS | SEC_IN_MEMORY;
eea6121a 138 sec->size = sizeof (struct __context64);
eb1e0e80
NC
139 sec->vma = 0;
140 sec->filepos = 0;
141 sec->contents = (bfd_byte *)&new_core_hdr->c_flt.r64;
142
143 /* .ldinfo section.
144 To actually find out how long this section is in this particular
b34976b6 145 core dump would require going down the whole list of struct
eb1e0e80
NC
146 ld_info's. See if we can just fake it. */
147 sec = bfd_make_section_anyway (abfd, ".ldinfo");
148 if (NULL == sec)
149 return return_value;
150
151 sec->flags = SEC_HAS_CONTENTS;
eea6121a 152 sec->size = core.c_lsize;
eb1e0e80
NC
153 sec->vma = 0;
154 sec->filepos = core.c_loader;
155
156 /* AIX 4 adds data sections from loaded objects to the core file,
157 which can be found by examining ldinfo, and anonymously mmapped
158 regions. */
b34976b6 159
eb1e0e80
NC
160 /* .data section from executable. */
161 sec = bfd_make_section_anyway (abfd, ".data");
b34976b6 162 if (NULL == sec)
eb1e0e80
NC
163 return return_value;
164
165 sec->flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
eea6121a 166 sec->size = core.c_datasize;
eb1e0e80
NC
167 sec->vma = core.c_dataorg;
168 sec->filepos = core.c_data;
169
170 /* .data sections from loaded objects. */
171 ld_offset = core.c_loader;
b34976b6
AM
172
173 while (1)
eb1e0e80 174 {
b34976b6 175 if (bfd_seek (abfd, ld_offset, SEEK_SET) != 0)
eb1e0e80
NC
176 return return_value;
177
178 if (sizeof (struct __ld_info64) !=
b34976b6 179 bfd_bread (&ldinfo, sizeof (struct __ld_info64), abfd))
eb1e0e80
NC
180 return return_value;
181
b34976b6 182 if (ldinfo.ldinfo_core)
eb1e0e80
NC
183 {
184 sec = bfd_make_section_anyway (abfd, ".data");
b34976b6 185 if (NULL == sec)
eb1e0e80
NC
186 return return_value;
187
188 sec->flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
eea6121a 189 sec->size = ldinfo.ldinfo_datasize;
eb1e0e80
NC
190 sec->vma = ldinfo.ldinfo_dataorg;
191 sec->filepos = ldinfo.ldinfo_core;
192 }
193
194 if (0 == ldinfo.ldinfo_next)
195 break;
196 ld_offset += ldinfo.ldinfo_next;
197 }
198
199 /* .vmdata sections from anonymously mmapped regions. */
b34976b6 200 if (core.c_vmregions)
eb1e0e80 201 {
b34976b6 202 if (bfd_seek (abfd, core.c_vmm, SEEK_SET) != 0)
eb1e0e80
NC
203 return return_value;
204
b34976b6 205 for (i = 0; i < core.c_vmregions; i++)
eb1e0e80 206 if (sizeof (struct vm_infox) !=
b34976b6 207 bfd_bread (&vminfo, sizeof (struct vm_infox), abfd))
eb1e0e80
NC
208 return return_value;
209
b34976b6 210 if (vminfo.vminfo_offset)
eb1e0e80
NC
211 {
212 sec = bfd_make_section_anyway (abfd, ".vmdata");
b34976b6 213 if (NULL == sec)
eb1e0e80
NC
214 return return_value;
215
216 sec->flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
eea6121a 217 sec->size = vminfo.vminfo_size;
eb1e0e80
NC
218 sec->vma = vminfo.vminfo_addr;
219 sec->filepos = vminfo.vminfo_offset;
220 }
221 }
222
7cefacd3 223 return_value = (bfd_target *) abfd->xvec; /* This is garbage for now. */
b34976b6 224
eb1e0e80 225 xcoff64_core_p_error:
b34976b6 226 if (bfd_get_error () != bfd_error_system_call)
eb1e0e80 227 bfd_set_error (bfd_error_wrong_format);
b34976b6 228
eb1e0e80
NC
229 return return_value;
230}
231
b34976b6 232/* Return `TRUE' if given core is from the given executable. */
eb1e0e80 233
b34976b6 234bfd_boolean
eb1e0e80
NC
235xcoff64_core_file_matches_executable_p (core_bfd, exec_bfd)
236 bfd *core_bfd;
237 bfd *exec_bfd;
238{
239 struct core_dumpxx core;
240 char *path, *s;
241 size_t alloc;
242 const char *str1, *str2;
b34976b6 243 bfd_boolean return_value = FALSE;
eb1e0e80
NC
244
245 /* Get the header. */
b34976b6 246 if (bfd_seek (core_bfd, 0, SEEK_SET) != 0)
eb1e0e80 247 return return_value;
b34976b6 248
eb1e0e80 249 if (sizeof (struct core_dumpxx) !=
b34976b6 250 bfd_bread (&core, sizeof (struct core_dumpxx), core_bfd))
eb1e0e80
NC
251 return return_value;
252
b34976b6 253 if (bfd_seek (core_bfd, core.c_loader, SEEK_SET) != 0)
eb1e0e80
NC
254 return return_value;
255
256 alloc = 100;
257 path = bfd_malloc (alloc);
b34976b6 258 if (path == NULL)
eb1e0e80
NC
259 return return_value;
260
261 s = path;
262
263 while (1)
264 {
d1e66cd4 265 if (bfd_bread (s, 1, core_bfd) != 1)
eb1e0e80
NC
266 goto xcoff64_core_file_matches_executable_p_end_1;
267
268 if (*s == '\0')
269 break;
270 ++s;
b34976b6 271 if (s == path + alloc)
eb1e0e80
NC
272 {
273 char *n;
274
275 alloc *= 2;
276 n = bfd_realloc (path, alloc);
b34976b6 277 if (n == NULL)
eb1e0e80
NC
278 goto xcoff64_core_file_matches_executable_p_end_1;
279
280 s = n + (path - s);
281 path = n;
282 }
283 }
284
285 str1 = strrchr (path, '/');
286 str2 = strrchr (exec_bfd->filename, '/');
287
288 /* Step over character '/'. */
289 str1 = str1 != NULL ? str1 + 1 : path;
290 str2 = str2 != NULL ? str2 + 1 : exec_bfd->filename;
291
b34976b6
AM
292 if (strcmp (str1, str2) == 0)
293 return_value = TRUE;
eb1e0e80
NC
294
295 xcoff64_core_file_matches_executable_p_end_1:
296 free (path);
297 return return_value;
298}
299
300char *
301xcoff64_core_file_failing_command (abfd)
302 bfd *abfd;
303{
304 struct core_dumpxx *c = core_hdr (abfd);
305 char *return_value = 0;
306
b34976b6 307 if (NULL != c)
eb1e0e80
NC
308 return_value = c->c_u.U_proc.pi_comm;
309
310 return return_value;
311}
312
313int
314xcoff64_core_file_failing_signal (abfd)
315 bfd *abfd;
316{
317 struct core_dumpxx *c = core_hdr (abfd);
318 int return_value = 0;
319
b34976b6 320 if (NULL != c)
eb1e0e80
NC
321 return_value = c->c_signo;
322
323 return return_value;
324}
325
326#else /* AIX_5_CORE */
327
b34976b6
AM
328const bfd_target *xcoff64_core_p
329 PARAMS ((bfd *));
330bfd_boolean xcoff64_core_file_matches_executable_p
331 PARAMS ((bfd *, bfd *));
332char *xcoff64_core_file_failing_command
333 PARAMS ((bfd *));
334int xcoff64_core_file_failing_signal
335 PARAMS ((bfd *));
eb1e0e80
NC
336
337const bfd_target *
338xcoff64_core_p (abfd)
2d653fc7 339 bfd *abfd ATTRIBUTE_UNUSED;
eb1e0e80
NC
340{
341 bfd_set_error (bfd_error_wrong_format);
342 return 0;
343}
344
b34976b6 345bfd_boolean
eb1e0e80 346xcoff64_core_file_matches_executable_p (core_bfd, exec_bfd)
2d653fc7
AM
347 bfd *core_bfd ATTRIBUTE_UNUSED;
348 bfd *exec_bfd ATTRIBUTE_UNUSED;
eb1e0e80 349{
b34976b6 350 return FALSE;
eb1e0e80
NC
351}
352
353char *
354xcoff64_core_file_failing_command (abfd)
2d653fc7 355 bfd *abfd ATTRIBUTE_UNUSED;
eb1e0e80
NC
356{
357 return 0;
358}
359
360int
361xcoff64_core_file_failing_signal (abfd)
2d653fc7 362 bfd *abfd ATTRIBUTE_UNUSED;
eb1e0e80
NC
363{
364 return 0;
365}
366
367#endif /* AIX_5_CORE */
This page took 0.196078 seconds and 4 git commands to generate.