]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/rs6000-core.c
bfd:
[thirdparty/binutils-gdb.git] / bfd / rs6000-core.c
CommitLineData
252b5132
RH
1/* IBM RS/6000 "XCOFF" back-end for BFD.
2 Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
3 Free Software Foundation, Inc.
4 FIXME: Can someone provide a transliteration of this name into ASCII?
5 Using the following chars caused a compiler warning on HIUX (so I replaced
6 them with octal escapes), and isn't useful without an understanding of what
7 character set it is.
8 Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
9 and John Gilmore.
10 Archive support from Damon A. Permezel.
11 Contributed by IBM Corporation and Cygnus Support.
12
13This file is part of BFD, the Binary File Descriptor library.
14
15This program is free software; you can redistribute it and/or modify
16it under the terms of the GNU General Public License as published by
17the Free Software Foundation; either version 2 of the License, or
18(at your option) any later version.
19
20This program is distributed in the hope that it will be useful,
21but WITHOUT ANY WARRANTY; without even the implied warranty of
22MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23GNU General Public License for more details.
24
25You should have received a copy of the GNU General Public License
26along with this program; if not, write to the Free Software
27Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
28
29/* This port currently only handles reading object files, except when
30 compiled on an RS/6000 host. -- no archive support, no core files.
31 In all cases, it does not support writing.
32
33 FIXMEmgo comments are left from Metin Ozisik's original port.
34
35 This is in a separate file from coff-rs6000.c, because it includes
36 system include files that conflict with coff/rs6000.h.
37 */
38
39/* Internalcoff.h and coffcode.h modify themselves based on this flag. */
40#define RS6000COFF_C 1
41
42/* The AIX 4.1 kernel is obviously compiled with -D_LONG_LONG, so
43 we have to define _LONG_LONG for older versions of gcc to get the
44 proper alignments in the user structure. */
45#if defined(_AIX41) && !defined(_LONG_LONG)
46#define _LONG_LONG
47#endif
48
49#include "bfd.h"
50#include "sysdep.h"
51#include "libbfd.h"
52
53#ifdef AIX_CORE
54
55/* AOUTHDR is defined by the above. We need another defn of it, from the
56 system include files. Punt the old one and get us a new name for the
57 typedef in the system include files. */
58#ifdef AOUTHDR
59#undef AOUTHDR
60#endif
61#define AOUTHDR second_AOUTHDR
62
63#undef SCNHDR
64
65
66/* ------------------------------------------------------------------------ */
67/* Support for core file stuff.. */
68/* ------------------------------------------------------------------------ */
69
70#include <sys/user.h>
71#include <sys/ldr.h>
72#include <sys/core.h>
73
74
75/* Number of special purpose registers supported by gdb. This value
76 should match `tm.h' in gdb directory. Clean this mess up and use
77 the macros in sys/reg.h. FIXMEmgo. */
78
79#define NUM_OF_SPEC_REGS 7
80
81#define core_hdr(bfd) (((Rs6kCorData*)(bfd->tdata.any))->hdr)
82
83/* AIX 4.1 Changed the names and locations of a few items in the core file,
84 this seems to be the quickest easiet way to deal with it.
85
86 Note however that encoding magic addresses (STACK_END_ADDR) is going
87 to be _very_ fragile. But I don't see any easy way to get that info
88 right now. */
89#ifdef CORE_VERSION_1
90#define CORE_DATA_SIZE_FIELD c_u.U_dsize
91#define CORE_COMM_FIELD c_u.U_comm
92#define SAVE_FIELD c_mst
93#define STACK_END_ADDR 0x2ff23000
94#else
95#define CORE_DATA_SIZE_FIELD c_u.u_dsize
96#define CORE_COMM_FIELD c_u.u_comm
97#define SAVE_FIELD c_u.u_save
98#define STACK_END_ADDR 0x2ff80000
99#endif
100
101/* These are stored in the bfd's tdata */
102typedef struct {
103 struct core_dump hdr; /* core file header */
104} Rs6kCorData;
105
106static asection *make_bfd_asection PARAMS ((bfd *, CONST char *, flagword,
107 bfd_size_type, bfd_vma, file_ptr));
108
109static asection *
110make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
111 bfd *abfd;
112 CONST char *name;
113 flagword flags;
114 bfd_size_type _raw_size;
115 bfd_vma vma;
116 file_ptr filepos;
117{
118 asection *asect;
119
120 asect = bfd_make_section_anyway (abfd, name);
121 if (!asect)
122 return NULL;
123
124 asect->flags = flags;
125 asect->_raw_size = _raw_size;
126 asect->vma = vma;
127 asect->filepos = filepos;
128 asect->alignment_power = 8;
129
130 return asect;
131}
132
133/* Decide if a given bfd represents a `core' file or not. There really is no
134 magic number or anything like, in rs6000coff. */
135
136const bfd_target *
137rs6000coff_core_p (abfd)
138 bfd *abfd;
139{
140 struct core_dump coredata;
141 struct stat statbuf;
142 bfd_size_type nread;
143 char *tmpptr;
144
145 if (bfd_seek (abfd, 0, SEEK_SET) != 0)
146 return NULL;
147
148 nread = bfd_read (&coredata, 1, sizeof (struct core_dump), abfd);
149 if (nread != sizeof (struct core_dump))
150 {
151 if (bfd_get_error () != bfd_error_system_call)
152 bfd_set_error (bfd_error_wrong_format);
153 return NULL;
154 }
155
156 if (bfd_stat (abfd, &statbuf) < 0)
157 {
158 bfd_set_error (bfd_error_system_call);
159 return NULL;
160 }
161
162 /* If the core file ulimit is too small, the system will first
163 omit the data segment, then omit the stack, then decline to
164 dump core altogether (as far as I know UBLOCK_VALID and LE_VALID
165 are always set) (this is based on experimentation on AIX 3.2).
166 Now, the thing is that GDB users will be surprised
167 if segments just silently don't appear (well, maybe they would
168 think to check "info files", I don't know).
169
170 For the data segment, we have no choice but to keep going if it's
171 not there, since the default behavior is not to dump it (regardless
172 of the ulimit, it's based on SA_FULLDUMP). But for the stack segment,
173 if it's not there, we refuse to have anything to do with this core
174 file. The usefulness of a core dump without a stack segment is pretty
175 limited anyway. */
176
177 if (!(coredata.c_flag & UBLOCK_VALID)
178 || !(coredata.c_flag & LE_VALID))
179 {
180 bfd_set_error (bfd_error_wrong_format);
181 return NULL;
182 }
183
184 if (!(coredata.c_flag & USTACK_VALID))
185 {
186 bfd_set_error (bfd_error_file_truncated);
187 return NULL;
188 }
189
190 /* Don't check the core file size for a full core, AIX 4.1 includes
191 additional shared library sections in a full core. */
192 if (!(coredata.c_flag & (FULL_CORE | CORE_TRUNC))
193 && ((bfd_vma)coredata.c_stack + coredata.c_size) != statbuf.st_size)
194 {
195 /* If the size is wrong, it means we're misinterpreting something. */
196 bfd_set_error (bfd_error_wrong_format);
197 return NULL;
198 }
199
200 /* Sanity check on the c_tab field. */
201 if ((u_long) coredata.c_tab < sizeof coredata ||
202 (u_long) coredata.c_tab >= statbuf.st_size ||
203 (long) coredata.c_tab >= (long)coredata.c_stack)
204 {
205 bfd_set_error (bfd_error_wrong_format);
206 return NULL;
207 }
208
209 /* Issue warning if the core file was truncated during writing. */
210 if (coredata.c_flag & CORE_TRUNC)
211 (*_bfd_error_handler) (_("%s: warning core file truncated"),
212 bfd_get_filename (abfd));
213
214 /* Allocate core file header. */
215 tmpptr = (char*) bfd_zalloc (abfd, sizeof (Rs6kCorData));
216 if (!tmpptr)
217 return NULL;
218
219 set_tdata (abfd, tmpptr);
220
221 /* Copy core file header. */
222 core_hdr (abfd) = coredata;
223
224 /* .stack section. */
225 if (!make_bfd_asection (abfd, ".stack",
226 SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
227 (bfd_size_type) coredata.c_size,
228 (bfd_vma) (STACK_END_ADDR - coredata.c_size),
229 (file_ptr) coredata.c_stack))
230 return NULL;
231
232 /* .reg section for GPRs and special registers. */
233 if (!make_bfd_asection (abfd, ".reg",
234 SEC_HAS_CONTENTS,
235 (bfd_size_type) ((32 + NUM_OF_SPEC_REGS) * 4),
236 (bfd_vma) 0,
237 (file_ptr) ((char *) &coredata.SAVE_FIELD
238 - (char *) &coredata)))
239 return NULL;
240
241 /* .reg2 section for FPRs (floating point registers). */
242 if (!make_bfd_asection (abfd, ".reg2",
243 SEC_HAS_CONTENTS,
244 (bfd_size_type) 8 * 32, /* 32 FPRs. */
245 (bfd_vma) 0,
246 (file_ptr) ((char *) &coredata.SAVE_FIELD.fpr[0]
247 - (char *) &coredata)))
248 return NULL;
249
250 /* .ldinfo section.
251 To actually find out how long this section is in this particular
252 core dump would require going down the whole list of struct ld_info's.
253 See if we can just fake it. */
254 if (!make_bfd_asection (abfd, ".ldinfo",
255 SEC_HAS_CONTENTS,
256 (bfd_size_type) 0x7fffffff,
257 (bfd_vma) 0,
258 (file_ptr) coredata.c_tab))
259 return NULL;
260
261#ifndef CORE_VERSION_1
262 /* .data section if present.
263 AIX 3 dumps the complete data section and sets FULL_CORE if the
264 ulimit is large enough, otherwise the data section is omitted.
265 AIX 4 sets FULL_CORE even if the core file is truncated, we have
266 to examine coredata.c_datasize below to find out the actual size of
267 the .data section. */
268 if (coredata.c_flag & FULL_CORE)
269 {
270 if (!make_bfd_asection (abfd, ".data",
271 SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
272 (bfd_size_type) coredata.CORE_DATA_SIZE_FIELD,
273 (bfd_vma)
274 CDATA_ADDR (coredata.CORE_DATA_SIZE_FIELD),
275 (file_ptr) coredata.c_stack + coredata.c_size))
276 return NULL;
277 }
278#endif
279
280#ifdef CORE_VERSION_1
281 /* AIX 4 adds data sections from loaded objects to the core file,
282 which can be found by examining ldinfo, and anonymously mmapped
283 regions. */
284 {
285 struct ld_info ldinfo;
286 bfd_size_type ldinfo_size;
287 file_ptr ldinfo_offset = (file_ptr) coredata.c_tab;
288
289 /* .data section from executable. */
290 if (coredata.c_datasize)
291 {
292 if (!make_bfd_asection (abfd, ".data",
293 SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
294 (bfd_size_type) coredata.c_datasize,
295 (bfd_vma)
296 CDATA_ADDR (coredata.CORE_DATA_SIZE_FIELD),
297 (file_ptr) coredata.c_data))
298 return NULL;
299 }
300
301 /* .data sections from loaded objects. */
302 ldinfo_size = (char *) &ldinfo.ldinfo_filename[0]
303 - (char *) &ldinfo.ldinfo_next;
304 while (1)
305 {
306 if (bfd_seek (abfd, ldinfo_offset, SEEK_SET) != 0)
307 return NULL;
308 if (bfd_read (&ldinfo, ldinfo_size, 1, abfd) != ldinfo_size)
309 return NULL;
310 if (ldinfo.ldinfo_core)
311 {
312 if (!make_bfd_asection (abfd, ".data",
313 SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
314 (bfd_size_type) ldinfo.ldinfo_datasize,
315 (bfd_vma) ldinfo.ldinfo_dataorg,
316 (file_ptr) ldinfo.ldinfo_core))
317 return NULL;
318 }
319 if (ldinfo.ldinfo_next == 0)
320 break;
321 ldinfo_offset += ldinfo.ldinfo_next;
322 }
323
324 /* .vmdata sections from anonymously mmapped regions. */
325 if (coredata.c_vmregions)
326 {
327 int i;
328
329 if (bfd_seek (abfd, (file_ptr) coredata.c_vmm, SEEK_SET) != 0)
330 return NULL;
331
332 for (i = 0; i < coredata.c_vmregions; i++)
333 {
334 struct vm_info vminfo;
335
336 if (bfd_read (&vminfo, sizeof (vminfo), 1, abfd) != sizeof (vminfo))
337 return NULL;
338 if (vminfo.vminfo_offset)
339 {
340 if (!make_bfd_asection (abfd, ".vmdata",
341 SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
342 (bfd_size_type) vminfo.vminfo_size,
343 (bfd_vma) vminfo.vminfo_addr,
344 (file_ptr) vminfo.vminfo_offset))
345 return NULL;
346 }
347 }
348 }
349 }
350#endif
351
352 return abfd->xvec; /* this is garbage for now. */
353}
354
355
356
357/* return `true' if given core is from the given executable.. */
358boolean
359rs6000coff_core_file_matches_executable_p (core_bfd, exec_bfd)
360 bfd *core_bfd;
361 bfd *exec_bfd;
362{
363 struct core_dump coredata;
364 struct ld_info ldinfo;
365 bfd_size_type size;
366 char *path, *s;
367 size_t alloc;
368 const char *str1, *str2;
369 boolean ret;
370
371 if (bfd_seek (core_bfd, 0, SEEK_SET) != 0
372 || bfd_read (&coredata, sizeof coredata, 1, core_bfd) != sizeof coredata)
373 return false;
374
375 if (bfd_seek (core_bfd, (long) coredata.c_tab, SEEK_SET) != 0)
376 return false;
377
378 size = (char *) &ldinfo.ldinfo_filename[0] - (char *) &ldinfo.ldinfo_next;
379 if (bfd_read (&ldinfo, size, 1, core_bfd) != size)
380 return false;
381
382 alloc = 100;
383 path = bfd_malloc (alloc);
384 if (path == NULL)
385 return false;
386 s = path;
387
388 while (1)
389 {
390 if (bfd_read (s, 1, 1, core_bfd) != 1)
391 {
392 free (path);
393 return false;
394 }
395 if (*s == '\0')
396 break;
397 ++s;
398 if (s == path + alloc)
399 {
400 char *n;
401
402 alloc *= 2;
403 n = bfd_realloc (path, alloc);
404 if (n == NULL)
405 {
406 free (path);
407 return false;
408 }
409 s = n + (path - s);
410 path = n;
411 }
412 }
413
414 str1 = strrchr (path, '/');
415 str2 = strrchr (exec_bfd->filename, '/');
416
417 /* step over character '/' */
418 str1 = str1 != NULL ? str1 + 1 : path;
419 str2 = str2 != NULL ? str2 + 1 : exec_bfd->filename;
420
421 if (strcmp (str1, str2) == 0)
422 ret = true;
423 else
424 ret = false;
425
426 free (path);
427
428 return ret;
429}
430
431char *
432rs6000coff_core_file_failing_command (abfd)
433 bfd *abfd;
434{
435 char *com = core_hdr (abfd).CORE_COMM_FIELD;
436 if (*com)
437 return com;
438 else
439 return 0;
440}
441
442int
443rs6000coff_core_file_failing_signal (abfd)
444 bfd *abfd;
445{
446 return core_hdr (abfd).c_signo;
447}
448
449
450boolean
451rs6000coff_get_section_contents (abfd, section, location, offset, count)
452 bfd *abfd;
453 sec_ptr section;
454 PTR location;
455 file_ptr offset;
456 bfd_size_type count;
457{
458 if (count == 0)
459 return true;
460
461 /* Reading a core file's sections will be slightly different. For the
462 rest of them we can use bfd_generic_get_section_contents () I suppose. */
463 /* Make sure this routine works for any bfd and any section. FIXMEmgo. */
464
465 if (abfd->format == bfd_core && strcmp (section->name, ".reg") == 0) {
466
467 struct mstsave mstatus;
468 int regoffset = (char*)&mstatus.gpr[0] - (char*)&mstatus;
469
470 /* Assert that the only way this code will be executed is reading the
471 whole section. */
472 if (offset || count != (sizeof(mstatus.gpr) + (4 * NUM_OF_SPEC_REGS)))
473 (*_bfd_error_handler)
474 (_("ERROR! in rs6000coff_get_section_contents()\n"));
475
476 /* for `.reg' section, `filepos' is a pointer to the `mstsave' structure
477 in the core file. */
478
479 /* read GPR's into the location. */
480 if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1
481 || bfd_read(location, sizeof (mstatus.gpr), 1, abfd) != sizeof (mstatus.gpr))
482 return (false); /* on error */
483
484 /* increment location to the beginning of special registers in the section,
485 reset register offset value to the beginning of first special register
486 in mstsave structure, and read special registers. */
487
488 location = (PTR) ((char*)location + sizeof (mstatus.gpr));
489 regoffset = (char*)&mstatus.iar - (char*)&mstatus;
490
491 if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1
492 || bfd_read(location, 4 * NUM_OF_SPEC_REGS, 1, abfd) !=
493 4 * NUM_OF_SPEC_REGS)
494 return (false); /* on error */
495
496 /* increment location address, and read the special registers.. */
497 /* FIXMEmgo */
498 return (true);
499 }
500
501 /* else, use default bfd section content transfer. */
502 else
503 return _bfd_generic_get_section_contents
504 (abfd, section, location, offset, count);
505}
506
507#endif /* AIX_CORE */