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