This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / bfd / rs6000-core.c
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
6    character set it is.
7    Written by Metin G. Ozisik, Mimi Ph\373\364ng-Th\345o V\365, 
8      and John Gilmore.
9    Archive support from Damon A. Permezel.
10    Contributed by IBM Corporation and Cygnus Support.
11
12 This file is part of BFD, the Binary File Descriptor library.
13
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.
18
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.
23
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.  */
27
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.
31
32    FIXMEmgo comments are left from Metin Ozisik's original port.
33
34    This is in a separate file from coff-rs6000.c, because it includes
35    system include files that conflict with coff/rs6000.h.
36   */
37
38 /* Internalcoff.h and coffcode.h modify themselves based on this flag.  */
39 #define RS6000COFF_C 1
40
41 #include "bfd.h"
42 #include "sysdep.h"
43 #include "libbfd.h"
44
45 #ifdef AIX_CORE
46
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.  */
50 #ifdef AOUTHDR
51 #undef AOUTHDR
52 #endif
53 #define AOUTHDR second_AOUTHDR
54
55 #undef  SCNHDR
56
57
58 /* ------------------------------------------------------------------------ */
59 /*      Support for core file stuff..                                       */
60 /* ------------------------------------------------------------------------ */
61
62 #include <sys/user.h>
63 #include <sys/ldr.h>
64 #include <sys/core.h>
65
66
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. */
70
71 #define NUM_OF_SPEC_REGS  7
72
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)
78
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. 
81
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
84    right now.  */
85 #ifdef CORE_VERSION_1
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
90 #else
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
95 #endif
96
97 /* These are stored in the bfd's tdata */
98 typedef struct {
99   struct core_dump hdr;         /* core file header */
100   asection *data_section,
101            *stack_section,
102            *reg_section,        /* section for GPRs and special registers. */
103            *reg2_section;       /* section for FPRs. */
104
105   /* This tells us where everything is mapped (shared libraries and so on).
106      GDB needs it.  */
107   asection *ldinfo_section;
108 #define core_ldinfosec(bfd) (((Rs6kCorData *)(bfd->tdata.any))->ldinfo_section)
109 } Rs6kCorData;
110
111
112 /* Decide if a given bfd represents a `core' file or not. There really is no
113    magic number or anything like, in rs6000coff. */
114
115 const bfd_target *
116 rs6000coff_core_p (abfd)
117      bfd *abfd;
118 {
119   int fd;
120   struct core_dump coredata;
121   struct stat statbuf;
122   char *tmpptr;
123
124   /* Use bfd_xxx routines, rather than O/S primitives to read coredata. FIXMEmgo */
125   fd = open (abfd->filename, O_RDONLY);
126   if (fd < 0)
127     {
128       bfd_set_error (bfd_error_system_call);
129       return NULL;
130     }
131
132   if (fstat (fd, &statbuf) < 0)
133     {
134       bfd_set_error (bfd_error_system_call);
135       close (fd);
136       return NULL;
137     }
138   if (read (fd, &coredata, sizeof (struct core_dump))
139       != sizeof (struct core_dump))
140     {
141       bfd_set_error (bfd_error_wrong_format);
142       close (fd);
143       return NULL;
144     }
145
146   if (close (fd) < 0)
147     {
148       bfd_set_error (bfd_error_system_call);
149       return NULL;
150     }
151
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).
159
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
165      limited anyway.  */
166      
167   if (!(coredata.c_flag & UBLOCK_VALID)
168       || !(coredata.c_flag & LE_VALID))
169     {
170       bfd_set_error (bfd_error_wrong_format);
171       return NULL;
172     }
173
174   if (!(coredata.c_flag & USTACK_VALID))
175     {
176       bfd_set_error (bfd_error_file_truncated);
177       return NULL;
178     }
179
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)
184     {
185       /* If the size is wrong, it means we're misinterpreting something.  */
186       bfd_set_error (bfd_error_wrong_format);
187       return NULL;
188     }
189
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)
194     {
195       bfd_set_error (bfd_error_wrong_format);
196       return NULL;
197     }
198
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));
203
204   /* maybe you should alloc space for the whole core chunk over here!! FIXMEmgo */
205   tmpptr = (char*)bfd_zalloc (abfd, sizeof (Rs6kCorData));
206   if (!tmpptr)
207     return NULL;
208       
209   set_tdata (abfd, tmpptr);
210
211   /* Copy core file header.  */
212   core_hdr (abfd) = coredata;
213
214   /* .stack section. */
215   if ((core_stacksec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
216        == NULL)
217     return NULL;
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;        /*???? */
223
224   /* .reg section for GPRs and special registers. */
225   if ((core_regsec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
226        == NULL)
227     return NULL;
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;
234
235   /* .reg2 section for FPRs (floating point registers). */
236   if ((core_reg2sec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
237        == NULL)
238     return NULL;
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;
245
246   if ((core_ldinfosec (abfd) = (asection*) bfd_zalloc (abfd, sizeof (asection)))
247        == NULL)
248     return NULL;
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;
258
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;
266
267   if (coredata.c_flag & FULL_CORE)
268     {
269       asection *sec = (asection *) bfd_zalloc (abfd, sizeof (asection));
270       if (sec == NULL)
271         return NULL;
272       sec->name = ".data";
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;
277
278       sec->next = abfd->sections;
279       abfd->sections = sec;
280       ++abfd->section_count;
281     }
282
283   return abfd->xvec;                            /* this is garbage for now. */
284 }
285
286
287
288 /* return `true' if given core is from the given executable.. */
289 boolean
290 rs6000coff_core_file_matches_executable_p (core_bfd, exec_bfd)
291      bfd *core_bfd;
292      bfd *exec_bfd;
293 {
294   struct core_dump coredata;
295   struct ld_info ldinfo;
296   int size;
297   char *path, *s;
298   size_t alloc;
299   const char *str1, *str2;
300   boolean ret;
301
302   if (bfd_seek (core_bfd, 0, SEEK_SET) != 0
303       || bfd_read (&coredata, sizeof coredata, 1, core_bfd) != sizeof coredata)
304     return false;
305
306   if (bfd_seek (core_bfd, (long) coredata.c_tab, SEEK_SET) != 0)
307     return false;
308
309   size = (char *) &ldinfo.ldinfo_filename[0] - (char *) &ldinfo.ldinfo_next;
310   if (bfd_read (&ldinfo, size, 1, core_bfd) != size)
311     return false;
312
313   alloc = 100;
314   path = bfd_malloc (alloc);
315   if (path == NULL)
316     return false;
317   s = path;
318
319   while (1)
320     {
321       if (bfd_read (s, 1, 1, core_bfd) != 1)
322         {
323           free (path);
324           return false;
325         }
326       if (*s == '\0')
327         break;
328       ++s;
329       if (s == path + alloc)
330         {
331           char *n;
332
333           alloc *= 2;
334           n = bfd_realloc (path, alloc);
335           if (n == NULL)
336             {
337               free (path);
338               return false;
339             }
340           s = n + (path - s);
341           path = n;
342         }
343     }
344   
345   str1 = strrchr (path, '/');
346   str2 = strrchr (exec_bfd->filename, '/');
347
348   /* step over character '/' */
349   str1 = str1 != NULL ? str1 + 1 : path;
350   str2 = str2 != NULL ? str2 + 1 : exec_bfd->filename;
351
352   if (strcmp (str1, str2) == 0)
353     ret = true;
354   else
355     ret = false;
356
357   free (path);
358
359   return ret;
360 }
361
362 char *
363 rs6000coff_core_file_failing_command (abfd)
364      bfd *abfd;
365 {
366   char *com = core_hdr (abfd).CORE_COMM_FIELD;
367   if (*com)
368     return com;
369   else
370     return 0;
371 }
372
373 int
374 rs6000coff_core_file_failing_signal (abfd)
375      bfd *abfd;
376 {
377   return core_hdr (abfd).c_signo;
378 }
379
380
381 boolean
382 rs6000coff_get_section_contents (abfd, section, location, offset, count)
383      bfd *abfd;
384      sec_ptr section;
385      PTR location;
386      file_ptr offset;
387      int count;
388 {
389     if (count == 0)
390         return true;
391
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. */
395
396     if (abfd->format == bfd_core && strcmp (section->name, ".reg") == 0) {
397
398       struct mstsave mstatus;
399       int    regoffset = (char*)&mstatus.gpr[0] - (char*)&mstatus;
400
401       /* Assert that the only way this code will be executed is reading the
402          whole section. */
403       if (offset || count != (sizeof(mstatus.gpr) + (4 * NUM_OF_SPEC_REGS)))
404         (*_bfd_error_handler)
405           ("ERROR! in rs6000coff_get_section_contents()\n");
406
407       /* for `.reg' section, `filepos' is a pointer to the `mstsave' structure
408          in the core file. */
409
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 */
414
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. */
418
419       location = (PTR) ((char*)location + sizeof (mstatus.gpr));
420       regoffset = (char*)&mstatus.iar - (char*)&mstatus;
421
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 */
426       
427       /* increment location address, and read the special registers.. */
428       /* FIXMEmgo */
429       return (true);
430     }
431
432     /* else, use default bfd section content transfer. */
433     else
434       return _bfd_generic_get_section_contents 
435                         (abfd, section, location, offset, count);
436 }
437
438 #endif /* AIX_CORE */