1 /* IBM RS/6000 "XCOFF" back-end for BFD.
2 Copyright (C) 1990, 91, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
3 FIXME: Can someone provide a transliteration of this name into ASCII?
4 Using the following chars caused a compiler warning on HIUX (so I replaced
5 them with octal escapes), and isn't useful without an understanding of what
7 Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365,
9 Archive support from Damon A. Permezel.
10 Contributed by IBM Corporation and Cygnus Support.
12 This file is part of BFD, the Binary File Descriptor library.
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
28 /* This port currently only handles reading object files, except when
29 compiled on an RS/6000 host. -- no archive support, no core files.
30 In all cases, it does not support writing.
32 FIXMEmgo comments are left from Metin Ozisik's original port.
34 This is in a separate file from coff-rs6000.c, because it includes
35 system include files that conflict with coff/rs6000.h.
38 /* Internalcoff.h and coffcode.h modify themselves based on this flag. */
39 #define RS6000COFF_C 1
47 /* AOUTHDR is defined by the above. We need another defn of it, from the
48 system include files. Punt the old one and get us a new name for the
49 typedef in the system include files. */
53 #define AOUTHDR second_AOUTHDR
58 /* ------------------------------------------------------------------------ */
59 /* Support for core file stuff.. */
60 /* ------------------------------------------------------------------------ */
67 /* Number of special purpose registers supported by gdb. This value
68 should match `tm.h' in gdb directory. Clean this mess up and use
69 the macros in sys/reg.h. FIXMEmgo. */
71 #define NUM_OF_SPEC_REGS 7
73 #define core_hdr(bfd) (((Rs6kCorData*)(bfd->tdata.any))->hdr)
74 #define core_datasec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->data_section)
75 #define core_stacksec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->stack_section)
76 #define core_regsec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->reg_section)
77 #define core_reg2sec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->reg2_section)
79 /* AIX 4.1 Changed the names and locations of a few items in the core file,
80 this seems to be the quickest easiet way to deal with it.
82 Note however that encoding magic addresses (STACK_END_ADDR) is going
83 to be _very_ fragile. But I don't see any easy way to get that info
86 #define CORE_DATA_SIZE_FIELD c_u.U_dsize
87 #define CORE_COMM_FIELD c_u.U_comm
88 #define SAVE_FIELD c_mst
89 #define STACK_END_ADDR 0x2ff23000
91 #define CORE_DATA_SIZE_FIELD c_u.u_dsize
92 #define CORE_COMM_FIELD c_u.u_comm
93 #define SAVE_FIELD c_u.u_save
94 #define STACK_END_ADDR 0x2ff80000
97 /* These are stored in the bfd's tdata */
99 struct core_dump hdr; /* core file header */
100 asection *data_section,
102 *reg_section, /* section for GPRs and special registers. */
103 *reg2_section; /* section for FPRs. */
105 /* This tells us where everything is mapped (shared libraries and so on).
107 asection *ldinfo_section;
108 #define core_ldinfosec(bfd) (((Rs6kCorData *)(bfd->tdata.any))->ldinfo_section)
112 /* Decide if a given bfd represents a `core' file or not. There really is no
113 magic number or anything like, in rs6000coff. */
116 rs6000coff_core_p (abfd)
120 struct core_dump coredata;
124 /* Use bfd_xxx routines, rather than O/S primitives to read coredata. FIXMEmgo */
125 fd = open (abfd->filename, O_RDONLY);
128 bfd_set_error (bfd_error_system_call);
132 if (fstat (fd, &statbuf) < 0)
134 bfd_set_error (bfd_error_system_call);
138 if (read (fd, &coredata, sizeof (struct core_dump))
139 != sizeof (struct core_dump))
141 bfd_set_error (bfd_error_wrong_format);
148 bfd_set_error (bfd_error_system_call);
152 /* If the core file ulimit is too small, the system will first
153 omit the data segment, then omit the stack, then decline to
154 dump core altogether (as far as I know UBLOCK_VALID and LE_VALID
155 are always set) (this is based on experimentation on AIX 3.2).
156 Now, the thing is that GDB users will be surprised
157 if segments just silently don't appear (well, maybe they would
158 think to check "info files", I don't know).
160 For the data segment, we have no choice but to keep going if it's
161 not there, since the default behavior is not to dump it (regardless
162 of the ulimit, it's based on SA_FULLDUMP). But for the stack segment,
163 if it's not there, we refuse to have anything to do with this core
164 file. The usefulness of a core dump without a stack segment is pretty
167 if (!(coredata.c_flag & UBLOCK_VALID)
168 || !(coredata.c_flag & LE_VALID))
170 bfd_set_error (bfd_error_wrong_format);
174 if (!(coredata.c_flag & USTACK_VALID))
176 bfd_set_error (bfd_error_file_truncated);
180 /* Don't check the core file size for a full core, AIX 4.1 includes
181 additional shared library sections in a full core. */
182 if (!(coredata.c_flag & (FULL_CORE | CORE_TRUNC))
183 && ((bfd_vma)coredata.c_stack + coredata.c_size) != statbuf.st_size)
185 /* If the size is wrong, it means we're misinterpreting something. */
186 bfd_set_error (bfd_error_wrong_format);
190 /* Sanity check on the c_tab field. */
191 if ((u_long) coredata.c_tab < sizeof coredata ||
192 (u_long) coredata.c_tab >= statbuf.st_size ||
193 (long) coredata.c_tab >= (long)coredata.c_stack)
195 bfd_set_error (bfd_error_wrong_format);
199 /* Issue warning if the core file was truncated during writing. */
200 if (coredata.c_flag & CORE_TRUNC)
201 (*_bfd_error_handler) ("%s: warning core file truncated",
202 bfd_get_filename (abfd));
204 /* maybe you should alloc space for the whole core chunk over here!! FIXMEmgo */
205 tmpptr = (char*)bfd_zalloc (abfd, sizeof (Rs6kCorData));
209 set_tdata (abfd, tmpptr);
211 /* Copy core file header. */
212 core_hdr (abfd) = coredata;
214 /* .stack section. */
215 if ((core_stacksec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
218 core_stacksec (abfd)->name = ".stack";
219 core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
220 core_stacksec (abfd)->_raw_size = coredata.c_size;
221 core_stacksec (abfd)->vma = STACK_END_ADDR - coredata.c_size;
222 core_stacksec (abfd)->filepos = (int)coredata.c_stack; /*???? */
224 /* .reg section for GPRs and special registers. */
225 if ((core_regsec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
228 core_regsec (abfd)->name = ".reg";
229 core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
230 core_regsec (abfd)->_raw_size = (32 + NUM_OF_SPEC_REGS) * 4;
231 core_regsec (abfd)->vma = 0; /* not used?? */
232 core_regsec (abfd)->filepos =
233 (char*)&coredata.SAVE_FIELD - (char*)&coredata;
235 /* .reg2 section for FPRs (floating point registers). */
236 if ((core_reg2sec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
239 core_reg2sec (abfd)->name = ".reg2";
240 core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS;
241 core_reg2sec (abfd)->_raw_size = 8 * 32; /* 32 FPRs. */
242 core_reg2sec (abfd)->vma = 0; /* not used?? */
243 core_reg2sec (abfd)->filepos =
244 (char*)&coredata.SAVE_FIELD.fpr[0] - (char*)&coredata;
246 if ((core_ldinfosec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
249 core_ldinfosec (abfd)->name = ".ldinfo";
250 core_ldinfosec (abfd)->flags = SEC_HAS_CONTENTS;
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 core_ldinfosec (abfd)->_raw_size = 0x7fffffff;
255 /* Not relevant for ldinfo section. */
256 core_ldinfosec (abfd)->vma = 0;
257 core_ldinfosec (abfd)->filepos = (file_ptr) coredata.c_tab;
259 /* set up section chain here. */
260 abfd->section_count = 4;
261 abfd->sections = core_stacksec (abfd);
262 core_stacksec (abfd)->next = core_regsec(abfd);
263 core_regsec (abfd)->next = core_reg2sec (abfd);
264 core_reg2sec (abfd)->next = core_ldinfosec (abfd);
265 core_ldinfosec (abfd)->next = NULL;
267 if (coredata.c_flag & FULL_CORE)
269 asection *sec = (asection *) bfd_zalloc (abfd, sizeof (asection));
273 sec->flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
274 sec->_raw_size = coredata.CORE_DATA_SIZE_FIELD;
275 sec->vma = CDATA_ADDR (coredata.CORE_DATA_SIZE_FIELD);
276 sec->filepos = (int)coredata.c_stack + coredata.c_size;
278 sec->next = abfd->sections;
279 abfd->sections = sec;
280 ++abfd->section_count;
283 return abfd->xvec; /* this is garbage for now. */
288 /* return `true' if given core is from the given executable.. */
290 rs6000coff_core_file_matches_executable_p (core_bfd, exec_bfd)
294 struct core_dump coredata;
295 struct ld_info ldinfo;
299 const char *str1, *str2;
302 if (bfd_seek (core_bfd, 0, SEEK_SET) != 0
303 || bfd_read (&coredata, sizeof coredata, 1, core_bfd) != sizeof coredata)
306 if (bfd_seek (core_bfd, (long) coredata.c_tab, SEEK_SET) != 0)
309 size = (char *) &ldinfo.ldinfo_filename[0] - (char *) &ldinfo.ldinfo_next;
310 if (bfd_read (&ldinfo, size, 1, core_bfd) != size)
314 path = bfd_malloc (alloc);
321 if (bfd_read (s, 1, 1, core_bfd) != 1)
329 if (s == path + alloc)
334 n = bfd_realloc (path, alloc);
345 str1 = strrchr (path, '/');
346 str2 = strrchr (exec_bfd->filename, '/');
348 /* step over character '/' */
349 str1 = str1 != NULL ? str1 + 1 : path;
350 str2 = str2 != NULL ? str2 + 1 : exec_bfd->filename;
352 if (strcmp (str1, str2) == 0)
363 rs6000coff_core_file_failing_command (abfd)
366 char *com = core_hdr (abfd).CORE_COMM_FIELD;
374 rs6000coff_core_file_failing_signal (abfd)
377 return core_hdr (abfd).c_signo;
382 rs6000coff_get_section_contents (abfd, section, location, offset, count)
392 /* Reading a core file's sections will be slightly different. For the
393 rest of them we can use bfd_generic_get_section_contents () I suppose. */
394 /* Make sure this routine works for any bfd and any section. FIXMEmgo. */
396 if (abfd->format == bfd_core && strcmp (section->name, ".reg") == 0) {
398 struct mstsave mstatus;
399 int regoffset = (char*)&mstatus.gpr[0] - (char*)&mstatus;
401 /* Assert that the only way this code will be executed is reading the
403 if (offset || count != (sizeof(mstatus.gpr) + (4 * NUM_OF_SPEC_REGS)))
404 (*_bfd_error_handler)
405 ("ERROR! in rs6000coff_get_section_contents()\n");
407 /* for `.reg' section, `filepos' is a pointer to the `mstsave' structure
410 /* read GPR's into the location. */
411 if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1
412 || bfd_read(location, sizeof (mstatus.gpr), 1, abfd) != sizeof (mstatus.gpr))
413 return (false); /* on error */
415 /* increment location to the beginning of special registers in the section,
416 reset register offset value to the beginning of first special register
417 in mstsave structure, and read special registers. */
419 location = (PTR) ((char*)location + sizeof (mstatus.gpr));
420 regoffset = (char*)&mstatus.iar - (char*)&mstatus;
422 if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1
423 || bfd_read(location, 4 * NUM_OF_SPEC_REGS, 1, abfd) !=
424 4 * NUM_OF_SPEC_REGS)
425 return (false); /* on error */
427 /* increment location address, and read the special registers.. */
432 /* else, use default bfd section content transfer. */
434 return _bfd_generic_get_section_contents
435 (abfd, section, location, offset, count);
438 #endif /* AIX_CORE */