1 /* IBM RS/6000 "XCOFF" back-end for BFD.
2 Copyright (C) 1990, 1991 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., 675 Mass Ave, Cambridge, MA 02139, 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
72 #define STACK_END_ADDR 0x2ff80000
74 #define core_hdr(bfd) (((Rs6kCorData*)(bfd->tdata.any))->hdr)
75 #define core_datasec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->data_section)
76 #define core_stacksec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->stack_section)
77 #define core_regsec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->reg_section)
78 #define core_reg2sec(bfd) (((Rs6kCorData*)(bfd->tdata.any))->reg2_section)
80 /* These are stored in the bfd's tdata */
82 struct core *hdr; /* core file header */
83 asection *data_section,
85 *reg_section, /* section for GPRs and special registers. */
86 *reg2_section; /* section for FPRs. */
88 /* This tells us where everything is mapped (shared libraries and so on).
90 asection *ldinfo_section;
91 #define core_ldinfosec(bfd) (((Rs6kCorData *)(bfd->tdata.any))->ldinfo_section)
95 /* Decide if a given bfd represents a `core' file or not. There really is no
96 magic number or anything like, in rs6000coff. */
99 rs6000coff_core_p (abfd)
103 struct core_dump coredata;
107 /* Use bfd_xxx routines, rather than O/S primitives to read coredata. FIXMEmgo */
108 fd = open (abfd->filename, O_RDONLY);
111 bfd_error = system_call_error;
115 if (fstat (fd, &statbuf) < 0)
117 bfd_error = system_call_error;
121 if (read (fd, &coredata, sizeof (struct core_dump))
122 != sizeof (struct core_dump))
124 bfd_error = wrong_format;
131 bfd_error = system_call_error;
135 /* If the core file ulimit is too small, the system will first
136 omit the data segment, then omit the stack, then decline to
137 dump core altogether (as far as I know UBLOCK_VALID and LE_VALID
138 are always set) (this is based on experimentation on AIX 3.2).
139 Now, the thing is that GDB users will be surprised
140 if segments just silently don't appear (well, maybe they would
141 think to check "info files", I don't know), but we have no way of
142 returning warnings (as opposed to errors).
144 For the data segment, we have no choice but to keep going if it's
145 not there, since the default behavior is not to dump it (regardless
146 of the ulimit, it's based on SA_FULLDUMP). But for the stack segment,
147 if it's not there, we refuse to have anything to do with this core
148 file. The usefulness of a core dump without a stack segment is pretty
151 if (!(coredata.c_flag & UBLOCK_VALID)
152 || !(coredata.c_flag & LE_VALID))
154 bfd_error = wrong_format;
158 if ((coredata.c_flag & CORE_TRUNC)
159 || !(coredata.c_flag & USTACK_VALID))
161 bfd_error = file_truncated;
165 if (((bfd_vma)coredata.c_stack + coredata.c_size
166 + ((coredata.c_flag & FULL_CORE) ? coredata.c_u.u_dsize : 0))
169 /* If the size is wrong, it means we're misinterpreting something. */
170 bfd_error = wrong_format;
174 /* Sanity check on the c_tab field. */
175 if ((u_long) coredata.c_tab < sizeof coredata ||
176 (u_long) coredata.c_tab >= statbuf.st_size ||
177 (long) coredata.c_tab >= (long)coredata.c_stack)
179 bfd_error = wrong_format;
183 /* maybe you should alloc space for the whole core chunk over here!! FIXMEmgo */
184 tmpptr = (char*)bfd_zalloc (abfd, sizeof (Rs6kCorData));
187 bfd_error = no_memory;
191 set_tdata (abfd, tmpptr);
193 /* .stack section. */
194 if ((core_stacksec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
196 bfd_error = no_memory;
197 /* bfd_release (abfd, ???? ) */
200 core_stacksec (abfd)->name = ".stack";
201 core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
202 core_stacksec (abfd)->_raw_size = coredata.c_size;
203 core_stacksec (abfd)->vma = STACK_END_ADDR - coredata.c_size;
204 core_stacksec (abfd)->filepos = (int)coredata.c_stack; /*???? */
206 /* .reg section for GPRs and special registers. */
207 if ((core_regsec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
209 bfd_error = no_memory;
210 /* bfd_release (abfd, ???? ) */
213 core_regsec (abfd)->name = ".reg";
214 core_regsec (abfd)->flags = SEC_ALLOC;
215 core_regsec (abfd)->_raw_size = (32 + NUM_OF_SPEC_REGS) * 4;
216 core_regsec (abfd)->vma = 0; /* not used?? */
217 core_regsec (abfd)->filepos =
218 (char*)&coredata.c_u.u_save - (char*)&coredata;
220 /* .reg2 section for FPRs (floating point registers). */
221 if ((core_reg2sec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
223 bfd_error = no_memory;
224 /* bfd_release (abfd, ???? ) */
227 core_reg2sec (abfd)->name = ".reg2";
228 core_reg2sec (abfd)->flags = SEC_ALLOC;
229 core_reg2sec (abfd)->_raw_size = 8 * 32; /* 32 FPRs. */
230 core_reg2sec (abfd)->vma = 0; /* not used?? */
231 core_reg2sec (abfd)->filepos =
232 (char*)&coredata.c_u.u_save.fpr[0] - (char*)&coredata;
234 if ((core_ldinfosec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
236 bfd_error = no_memory;
237 /* bfd_release (abfd, ???? ) */
240 core_ldinfosec (abfd)->name = ".ldinfo";
241 core_ldinfosec (abfd)->flags = SEC_ALLOC + SEC_LOAD;
242 /* To actually find out how long this section is in this particular
243 core dump would require going down the whole list of struct ld_info's.
244 See if we can just fake it. */
245 core_ldinfosec (abfd)->_raw_size = 0x7fffffff;
246 /* Not relevant for ldinfo section. */
247 core_ldinfosec (abfd)->vma = 0;
248 core_ldinfosec (abfd)->filepos = coredata.c_tab;
250 /* set up section chain here. */
251 abfd->section_count = 4;
252 abfd->sections = core_stacksec (abfd);
253 core_stacksec (abfd)->next = core_regsec(abfd);
254 core_regsec (abfd)->next = core_reg2sec (abfd);
255 core_reg2sec (abfd)->next = core_ldinfosec (abfd);
256 core_ldinfosec (abfd)->next = NULL;
258 if (coredata.c_flag & FULL_CORE)
260 asection *sec = (asection *) bfd_zalloc (abfd, sizeof (asection));
263 bfd_error = no_memory;
267 sec->flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
268 sec->_raw_size = coredata.c_u.u_dsize;
269 sec->vma = CDATA_ADDR (coredata.c_u.u_dsize);
270 sec->filepos = (int)coredata.c_stack + coredata.c_size;
272 sec->next = abfd->sections;
273 abfd->sections = sec;
274 ++abfd->section_count;
277 return abfd->xvec; /* this is garbage for now. */
282 /* return `true' if given core is from the given executable.. */
284 rs6000coff_core_file_matches_executable_p (core_bfd, exec_bfd)
289 struct core_dump coredata;
290 struct ld_info ldinfo;
291 char pathname [1024];
294 /* Use bfd_xxx routines, rather than O/S primitives, do error checking!!
296 /* Actually should be able to use bfd_get_section_contents now that
297 we have a .ldinfo section. */
298 fd = fopen (core_bfd->filename, FOPEN_RB);
300 fread (&coredata, sizeof (struct core_dump), 1, fd);
301 fseek (fd, (long)coredata.c_tab, 0);
302 fread (&ldinfo, (char*)&ldinfo.ldinfo_filename[0] - (char*)&ldinfo.ldinfo_next,
304 fscanf (fd, "%s", pathname);
306 str1 = strrchr (pathname, '/');
307 str2 = strrchr (exec_bfd->filename, '/');
309 /* step over character '/' */
310 str1 = str1 ? str1+1 : &pathname[0];
311 str2 = str2 ? str2+1 : exec_bfd->filename;
314 return strcmp (str1, str2) == 0;
319 rs6000coff_get_section_contents (abfd, section, location, offset, count)
329 /* Reading a core file's sections will be slightly different. For the
330 rest of them we can use bfd_generic_get_section_contents () I suppose. */
331 /* Make sure this routine works for any bfd and any section. FIXMEmgo. */
333 if (abfd->format == bfd_core && strcmp (section->name, ".reg") == 0) {
335 struct mstsave mstatus;
336 int regoffset = (char*)&mstatus.gpr[0] - (char*)&mstatus;
338 /* Assert that the only way this code will be executed is reading the
340 if (offset || count != (sizeof(mstatus.gpr) + (4 * NUM_OF_SPEC_REGS)))
341 fprintf (stderr, "ERROR! in rs6000coff_get_section_contents()\n");
343 /* for `.reg' section, `filepos' is a pointer to the `mstsave' structure
346 /* read GPR's into the location. */
347 if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1
348 || bfd_read(location, sizeof (mstatus.gpr), 1, abfd) != sizeof (mstatus.gpr))
349 return (false); /* on error */
351 /* increment location to the beginning of special registers in the section,
352 reset register offset value to the beginning of first special register
353 in mstsave structure, and read special registers. */
355 location = (PTR) ((char*)location + sizeof (mstatus.gpr));
356 regoffset = (char*)&mstatus.iar - (char*)&mstatus;
358 if ( bfd_seek(abfd, section->filepos + regoffset, SEEK_SET) == -1
359 || bfd_read(location, 4 * NUM_OF_SPEC_REGS, 1, abfd) !=
360 4 * NUM_OF_SPEC_REGS)
361 return (false); /* on error */
363 /* increment location address, and read the special registers.. */
368 /* else, use default bfd section content transfer. */
370 return bfd_generic_get_section_contents
371 (abfd, section, location, offset, count);
374 #endif /* HOST_AIX */