1 /* IBM RS/6000 "XCOFF" back-end for BFD.
2 Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 2000
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
8 Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
10 Archive support from Damon A. Permezel.
11 Contributed by IBM Corporation and Cygnus Support.
13 This file is part of BFD, the Binary File Descriptor library.
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 2 of the License, or
18 (at your option) any later version.
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
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.
33 FIXMEmgo comments are left from Metin Ozisik's original port.
35 This is in a separate file from coff-rs6000.c, because it includes
36 system include files that conflict with coff/rs6000.h.
39 /* Internalcoff.h and coffcode.h modify themselves based on this flag. */
40 #define RS6000COFF_C 1
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)
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. */
61 #define AOUTHDR second_AOUTHDR
66 /* ------------------------------------------------------------------------ */
67 /* Support for core file stuff.. */
68 /* ------------------------------------------------------------------------ */
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. */
79 #define NUM_OF_SPEC_REGS 7
81 #define core_hdr(bfd) (((Rs6kCorData*)(bfd->tdata.any))->hdr)
83 /* AIX 4.1 Changed the names and locations of a few items in the core file,
84 this seems to be the quickest/easiest way to deal with it.
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
90 AIX 4.3 defines an entirely new structure (core_dumpx). Yet the
91 basic logic stays the same and we can still use our macro
92 redefinition mechanism to effect the necessary changes. */
94 #ifdef AIX_CORE_DUMPX_CORE
95 #define CORE_DATA_SIZE_FIELD c_dataorg
96 #define CORE_COMM_FIELD c_u.U_proc.pi_comm
97 #define SAVE_FIELD c_flt.hctx.r32
98 #define STACK_END_ADDR coredata.c_stackorg + coredata.c_size
99 #define LOADER_OFFSET_FIELD c_loader
100 #define LOADER_REGION_SIZE coredata.c_lsize
101 #define CORE_DUMP core_dumpx
103 #ifdef CORE_VERSION_1
104 #define CORE_DATA_SIZE_FIELD c_u.U_dsize
105 #define CORE_COMM_FIELD c_u.U_comm
106 #define SAVE_FIELD c_mst
107 #define STACK_END_ADDR 0x2ff23000
108 #define LOADER_OFFSET_FIELD c_tab
109 #define LOADER_REGION_SIZE 0x7ffffff
110 #define CORE_DUMP core_dump
112 #define CORE_DATA_SIZE_FIELD c_u.u_dsize
113 #define CORE_COMM_FIELD c_u.u_comm
114 #define SAVE_FIELD c_u.u_save
115 #define STACK_END_ADDR 0x2ff80000
116 #define LOADER_OFFSET_FIELD c_tab
117 #define LOADER_REGION_SIZE 0x7ffffff
118 #define CORE_DUMP core_dump
122 /* These are stored in the bfd's tdata */
124 struct CORE_DUMP hdr
; /* core file header */
127 static asection
*make_bfd_asection
PARAMS ((bfd
*, CONST
char *, flagword
,
128 bfd_size_type
, bfd_vma
, file_ptr
));
131 make_bfd_asection (abfd
, name
, flags
, _raw_size
, vma
, filepos
)
135 bfd_size_type _raw_size
;
141 asect
= bfd_make_section_anyway (abfd
, name
);
145 asect
->flags
= flags
;
146 asect
->_raw_size
= _raw_size
;
148 asect
->filepos
= filepos
;
149 asect
->alignment_power
= 8;
154 /* Decide if a given bfd represents a `core' file or not. There really is no
155 magic number or anything like, in rs6000coff. */
158 rs6000coff_core_p (abfd
)
161 struct CORE_DUMP coredata
;
166 if (bfd_seek (abfd
, 0, SEEK_SET
) != 0)
169 nread
= bfd_read (&coredata
, 1, sizeof (struct CORE_DUMP
), abfd
);
170 if (nread
!= sizeof (struct CORE_DUMP
))
172 if (bfd_get_error () != bfd_error_system_call
)
173 bfd_set_error (bfd_error_wrong_format
);
177 if (bfd_stat (abfd
, &statbuf
) < 0)
179 bfd_set_error (bfd_error_system_call
);
183 /* If the core file ulimit is too small, the system will first
184 omit the data segment, then omit the stack, then decline to
185 dump core altogether (as far as I know UBLOCK_VALID and LE_VALID
186 are always set) (this is based on experimentation on AIX 3.2).
187 Now, the thing is that GDB users will be surprised
188 if segments just silently don't appear (well, maybe they would
189 think to check "info files", I don't know).
191 For the data segment, we have no choice but to keep going if it's
192 not there, since the default behavior is not to dump it (regardless
193 of the ulimit, it's based on SA_FULLDUMP). But for the stack segment,
194 if it's not there, we refuse to have anything to do with this core
195 file. The usefulness of a core dump without a stack segment is pretty
198 if (!(coredata
.c_flag
& UBLOCK_VALID
)
199 || !(coredata
.c_flag
& LE_VALID
))
201 bfd_set_error (bfd_error_wrong_format
);
205 if (!(coredata
.c_flag
& USTACK_VALID
))
207 bfd_set_error (bfd_error_file_truncated
);
211 /* Don't check the core file size for a full core, AIX 4.1 includes
212 additional shared library sections in a full core. */
213 if (!(coredata
.c_flag
& (FULL_CORE
| CORE_TRUNC
))
214 && ((bfd_vma
)coredata
.c_stack
+ coredata
.c_size
) != statbuf
.st_size
)
216 /* If the size is wrong, it means we're misinterpreting something. */
217 bfd_set_error (bfd_error_wrong_format
);
221 #ifdef AIX_CORE_DUMPX_CORE
222 /* For the core_dumpx format, make sure c_entries == 0 If it does
223 not, the core file uses the old format */
224 if (coredata
.c_entries
!= 0)
226 bfd_set_error (bfd_error_wrong_format
);
230 /* Sanity check on the c_tab field. */
231 if ((u_long
) coredata
.c_tab
< sizeof coredata
||
232 (u_long
) coredata
.c_tab
>= statbuf
.st_size
||
233 (long) coredata
.c_tab
>= (long)coredata
.c_stack
)
235 bfd_set_error (bfd_error_wrong_format
);
240 /* Issue warning if the core file was truncated during writing. */
241 if (coredata
.c_flag
& CORE_TRUNC
)
242 (*_bfd_error_handler
) (_("%s: warning core file truncated"),
243 bfd_get_filename (abfd
));
245 /* Allocate core file header. */
246 tmpptr
= (char*) bfd_zalloc (abfd
, sizeof (Rs6kCorData
));
250 set_tdata (abfd
, tmpptr
);
252 /* Copy core file header. */
253 core_hdr (abfd
) = coredata
;
255 /* .stack section. */
256 if (!make_bfd_asection (abfd
, ".stack",
257 SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
,
258 (bfd_size_type
) coredata
.c_size
,
259 (bfd_vma
) (STACK_END_ADDR
- coredata
.c_size
),
260 (file_ptr
) coredata
.c_stack
))
263 /* .reg section for GPRs and special registers. */
264 if (!make_bfd_asection (abfd
, ".reg",
266 (bfd_size_type
) ((32 + NUM_OF_SPEC_REGS
) * 4),
268 (file_ptr
) ((char *) &coredata
.SAVE_FIELD
269 - (char *) &coredata
)))
272 /* .reg2 section for FPRs (floating point registers). */
273 if (!make_bfd_asection (abfd
, ".reg2",
275 (bfd_size_type
) 8 * 32, /* 32 FPRs. */
277 (file_ptr
) ((char *) &coredata
.SAVE_FIELD
.fpr
[0]
278 - (char *) &coredata
)))
282 To actually find out how long this section is in this particular
283 core dump would require going down the whole list of struct ld_info's.
284 See if we can just fake it. */
285 if (!make_bfd_asection (abfd
, ".ldinfo",
287 (bfd_size_type
) LOADER_REGION_SIZE
,
289 (file_ptr
) coredata
.LOADER_OFFSET_FIELD
))
292 #ifndef CORE_VERSION_1
293 /* .data section if present.
294 AIX 3 dumps the complete data section and sets FULL_CORE if the
295 ulimit is large enough, otherwise the data section is omitted.
296 AIX 4 sets FULL_CORE even if the core file is truncated, we have
297 to examine coredata.c_datasize below to find out the actual size of
298 the .data section. */
299 if (coredata
.c_flag
& FULL_CORE
)
301 if (!make_bfd_asection (abfd
, ".data",
302 SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
,
303 (bfd_size_type
) coredata
.CORE_DATA_SIZE_FIELD
,
305 CDATA_ADDR (coredata
.CORE_DATA_SIZE_FIELD
),
306 (file_ptr
) coredata
.c_stack
+ coredata
.c_size
))
311 #ifdef CORE_VERSION_1
312 /* AIX 4 adds data sections from loaded objects to the core file,
313 which can be found by examining ldinfo, and anonymously mmapped
316 struct ld_info ldinfo
;
317 bfd_size_type ldinfo_size
;
318 file_ptr ldinfo_offset
= (file_ptr
) coredata
.LOADER_OFFSET_FIELD
;
320 /* .data section from executable. */
321 if (coredata
.c_datasize
)
323 if (!make_bfd_asection (abfd
, ".data",
324 SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
,
325 (bfd_size_type
) coredata
.c_datasize
,
327 CDATA_ADDR (coredata
.CORE_DATA_SIZE_FIELD
),
328 (file_ptr
) coredata
.c_data
))
332 /* .data sections from loaded objects. */
333 ldinfo_size
= (char *) &ldinfo
.ldinfo_filename
[0]
334 - (char *) &ldinfo
.ldinfo_next
;
337 if (bfd_seek (abfd
, ldinfo_offset
, SEEK_SET
) != 0)
339 if (bfd_read (&ldinfo
, ldinfo_size
, 1, abfd
) != ldinfo_size
)
341 if (ldinfo
.ldinfo_core
)
343 if (!make_bfd_asection (abfd
, ".data",
344 SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
,
345 (bfd_size_type
) ldinfo
.ldinfo_datasize
,
346 (bfd_vma
) ldinfo
.ldinfo_dataorg
,
347 (file_ptr
) ldinfo
.ldinfo_core
))
350 if (ldinfo
.ldinfo_next
== 0)
352 ldinfo_offset
+= ldinfo
.ldinfo_next
;
355 /* .vmdata sections from anonymously mmapped regions. */
356 if (coredata
.c_vmregions
)
360 if (bfd_seek (abfd
, (file_ptr
) coredata
.c_vmm
, SEEK_SET
) != 0)
363 for (i
= 0; i
< coredata
.c_vmregions
; i
++)
365 struct vm_info vminfo
;
367 if (bfd_read (&vminfo
, sizeof (vminfo
), 1, abfd
) != sizeof (vminfo
))
369 if (vminfo
.vminfo_offset
)
371 if (!make_bfd_asection (abfd
, ".vmdata",
372 SEC_ALLOC
| SEC_LOAD
| SEC_HAS_CONTENTS
,
373 (bfd_size_type
) vminfo
.vminfo_size
,
374 (bfd_vma
) vminfo
.vminfo_addr
,
375 (file_ptr
) vminfo
.vminfo_offset
))
383 return abfd
->xvec
; /* this is garbage for now. */
388 /* return `true' if given core is from the given executable.. */
390 rs6000coff_core_file_matches_executable_p (core_bfd
, exec_bfd
)
394 struct CORE_DUMP coredata
;
395 struct ld_info ldinfo
;
399 const char *str1
, *str2
;
402 if (bfd_seek (core_bfd
, 0, SEEK_SET
) != 0
403 || bfd_read (&coredata
, sizeof coredata
, 1, core_bfd
) != sizeof coredata
)
406 if (bfd_seek (core_bfd
, (long) coredata
.LOADER_OFFSET_FIELD
, SEEK_SET
) != 0)
409 size
= (char *) &ldinfo
.ldinfo_filename
[0] - (char *) &ldinfo
.ldinfo_next
;
410 if (bfd_read (&ldinfo
, size
, 1, core_bfd
) != size
)
414 path
= bfd_malloc (alloc
);
421 if (bfd_read (s
, 1, 1, core_bfd
) != 1)
429 if (s
== path
+ alloc
)
434 n
= bfd_realloc (path
, alloc
);
445 str1
= strrchr (path
, '/');
446 str2
= strrchr (exec_bfd
->filename
, '/');
448 /* step over character '/' */
449 str1
= str1
!= NULL
? str1
+ 1 : path
;
450 str2
= str2
!= NULL
? str2
+ 1 : exec_bfd
->filename
;
452 if (strcmp (str1
, str2
) == 0)
463 rs6000coff_core_file_failing_command (abfd
)
466 char *com
= core_hdr (abfd
).CORE_COMM_FIELD
;
474 rs6000coff_core_file_failing_signal (abfd
)
477 return core_hdr (abfd
).c_signo
;
482 rs6000coff_get_section_contents (abfd
, section
, location
, offset
, count
)
492 /* Reading a core file's sections will be slightly different. For the
493 rest of them we can use bfd_generic_get_section_contents () I suppose. */
494 /* Make sure this routine works for any bfd and any section. FIXMEmgo. */
496 if (abfd
->format
== bfd_core
&& strcmp (section
->name
, ".reg") == 0) {
498 struct mstsave mstatus
;
499 int regoffset
= (char*)&mstatus
.gpr
[0] - (char*)&mstatus
;
501 /* Assert that the only way this code will be executed is reading the
503 if (offset
|| count
!= (sizeof(mstatus
.gpr
) + (4 * NUM_OF_SPEC_REGS
)))
504 (*_bfd_error_handler
)
505 (_("ERROR! in rs6000coff_get_section_contents()\n"));
507 /* for `.reg' section, `filepos' is a pointer to the `mstsave' structure
510 /* read GPR's into the location. */
511 if ( bfd_seek(abfd
, section
->filepos
+ regoffset
, SEEK_SET
) == -1
512 || bfd_read(location
, sizeof (mstatus
.gpr
), 1, abfd
) != sizeof (mstatus
.gpr
))
513 return (false); /* on error */
515 /* increment location to the beginning of special registers in the section,
516 reset register offset value to the beginning of first special register
517 in mstsave structure, and read special registers. */
519 location
= (PTR
) ((char*)location
+ sizeof (mstatus
.gpr
));
520 regoffset
= (char*)&mstatus
.iar
- (char*)&mstatus
;
522 if ( bfd_seek(abfd
, section
->filepos
+ regoffset
, SEEK_SET
) == -1
523 || bfd_read(location
, 4 * NUM_OF_SPEC_REGS
, 1, abfd
) !=
524 4 * NUM_OF_SPEC_REGS
)
525 return (false); /* on error */
527 /* increment location address, and read the special registers.. */
532 /* else, use default bfd section content transfer. */
534 return _bfd_generic_get_section_contents
535 (abfd
, section
, location
, offset
, count
);
538 #endif /* AIX_CORE */