xref: /openbsd-src/gnu/usr.bin/binutils/bfd/rs6000-core.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
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
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 
13 This file is part of BFD, the Binary File Descriptor library.
14 
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.
19 
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.
24 
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.  */
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/easiest 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 
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.  */
93 
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
102 #else
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
111 #else
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
119 #endif
120 #endif
121 
122 /* These are stored in the bfd's tdata */
123 typedef struct {
124   struct CORE_DUMP hdr;		/* core file header */
125 } Rs6kCorData;
126 
127 static asection *make_bfd_asection PARAMS ((bfd *, CONST char *, flagword,
128 					    bfd_size_type, bfd_vma, file_ptr));
129 
130 static asection *
131 make_bfd_asection (abfd, name, flags, _raw_size, vma, filepos)
132      bfd *abfd;
133      CONST char *name;
134      flagword flags;
135      bfd_size_type _raw_size;
136      bfd_vma vma;
137      file_ptr filepos;
138 {
139   asection *asect;
140 
141   asect = bfd_make_section_anyway (abfd, name);
142   if (!asect)
143     return NULL;
144 
145   asect->flags = flags;
146   asect->_raw_size = _raw_size;
147   asect->vma = vma;
148   asect->filepos = filepos;
149   asect->alignment_power = 8;
150 
151   return asect;
152 }
153 
154 /* Decide if a given bfd represents a `core' file or not. There really is no
155    magic number or anything like, in rs6000coff. */
156 
157 const bfd_target *
158 rs6000coff_core_p (abfd)
159      bfd *abfd;
160 {
161   struct CORE_DUMP coredata;
162   struct stat statbuf;
163   bfd_size_type nread;
164   char *tmpptr;
165 
166   if (bfd_seek (abfd, 0, SEEK_SET) != 0)
167     return NULL;
168 
169   nread = bfd_read (&coredata, 1, sizeof (struct CORE_DUMP), abfd);
170   if (nread != sizeof (struct CORE_DUMP))
171     {
172       if (bfd_get_error () != bfd_error_system_call)
173 	bfd_set_error (bfd_error_wrong_format);
174       return NULL;
175     }
176 
177   if (bfd_stat (abfd, &statbuf) < 0)
178     {
179       bfd_set_error (bfd_error_system_call);
180       return NULL;
181     }
182 
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).
190 
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
196      limited anyway.  */
197 
198   if (!(coredata.c_flag & UBLOCK_VALID)
199       || !(coredata.c_flag & LE_VALID))
200     {
201       bfd_set_error (bfd_error_wrong_format);
202       return NULL;
203     }
204 
205   if (!(coredata.c_flag & USTACK_VALID))
206     {
207       bfd_set_error (bfd_error_file_truncated);
208       return NULL;
209     }
210 
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)
215     {
216       /* If the size is wrong, it means we're misinterpreting something.  */
217       bfd_set_error (bfd_error_wrong_format);
218       return NULL;
219     }
220 
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)
225     {
226       bfd_set_error (bfd_error_wrong_format);
227       return NULL;
228     }
229 #else
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)
234     {
235       bfd_set_error (bfd_error_wrong_format);
236       return NULL;
237     }
238 #endif
239 
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));
244 
245   /* Allocate core file header.  */
246   tmpptr = (char*) bfd_zalloc (abfd, sizeof (Rs6kCorData));
247   if (!tmpptr)
248     return NULL;
249 
250   set_tdata (abfd, tmpptr);
251 
252   /* Copy core file header.  */
253   core_hdr (abfd) = coredata;
254 
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))
261     return NULL;
262 
263   /* .reg section for GPRs and special registers. */
264   if (!make_bfd_asection (abfd, ".reg",
265   			  SEC_HAS_CONTENTS,
266 			  (bfd_size_type) ((32 + NUM_OF_SPEC_REGS) * 4),
267 			  (bfd_vma) 0,
268 			  (file_ptr) ((char *) &coredata.SAVE_FIELD
269 				      - (char *) &coredata)))
270     return NULL;
271 
272   /* .reg2 section for FPRs (floating point registers). */
273   if (!make_bfd_asection (abfd, ".reg2",
274   			  SEC_HAS_CONTENTS,
275 			  (bfd_size_type) 8 * 32,	/* 32 FPRs. */
276 			  (bfd_vma) 0,
277 			  (file_ptr) ((char *) &coredata.SAVE_FIELD.fpr[0]
278 				      - (char *) &coredata)))
279     return NULL;
280 
281   /* .ldinfo section.
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",
286   			  SEC_HAS_CONTENTS,
287 			  (bfd_size_type) LOADER_REGION_SIZE,
288 			  (bfd_vma) 0,
289 			  (file_ptr) coredata.LOADER_OFFSET_FIELD))
290     return NULL;
291 
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)
300     {
301       if (!make_bfd_asection (abfd, ".data",
302 			      SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
303 			      (bfd_size_type) coredata.CORE_DATA_SIZE_FIELD,
304 			      (bfd_vma)
305 				CDATA_ADDR (coredata.CORE_DATA_SIZE_FIELD),
306 			      (file_ptr) coredata.c_stack + coredata.c_size))
307 	return NULL;
308     }
309 #endif
310 
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
314      regions.  */
315   {
316     struct ld_info ldinfo;
317     bfd_size_type ldinfo_size;
318     file_ptr ldinfo_offset = (file_ptr) coredata.LOADER_OFFSET_FIELD;
319 
320     /* .data section from executable.  */
321     if (coredata.c_datasize)
322       {
323 	if (!make_bfd_asection (abfd, ".data",
324 				SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
325 				(bfd_size_type) coredata.c_datasize,
326 				(bfd_vma)
327 				  CDATA_ADDR (coredata.CORE_DATA_SIZE_FIELD),
328 				(file_ptr) coredata.c_data))
329 	  return NULL;
330       }
331 
332     /* .data sections from loaded objects.  */
333     ldinfo_size = (char *) &ldinfo.ldinfo_filename[0]
334 		  - (char *) &ldinfo.ldinfo_next;
335     while (1)
336       {
337 	if (bfd_seek (abfd, ldinfo_offset, SEEK_SET) != 0)
338 	  return NULL;
339 	if (bfd_read (&ldinfo, ldinfo_size, 1, abfd) != ldinfo_size)
340 	  return NULL;
341 	if (ldinfo.ldinfo_core)
342 	  {
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))
348 	      return NULL;
349 	  }
350 	if (ldinfo.ldinfo_next == 0)
351 	  break;
352 	ldinfo_offset += ldinfo.ldinfo_next;
353       }
354 
355     /* .vmdata sections from anonymously mmapped regions.  */
356     if (coredata.c_vmregions)
357       {
358 	int i;
359 
360 	if (bfd_seek (abfd, (file_ptr) coredata.c_vmm, SEEK_SET) != 0)
361 	  return NULL;
362 
363 	for (i = 0; i < coredata.c_vmregions; i++)
364 	  {
365 	    struct vm_info vminfo;
366 
367 	    if (bfd_read (&vminfo, sizeof (vminfo), 1, abfd) != sizeof (vminfo))
368 	      return NULL;
369 	    if (vminfo.vminfo_offset)
370 	      {
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))
376 		  return NULL;
377 	      }
378 	  }
379       }
380   }
381 #endif
382 
383   return abfd->xvec;				/* this is garbage for now. */
384 }
385 
386 
387 
388 /* return `true' if given core is from the given executable.. */
389 boolean
390 rs6000coff_core_file_matches_executable_p (core_bfd, exec_bfd)
391      bfd *core_bfd;
392      bfd *exec_bfd;
393 {
394   struct CORE_DUMP coredata;
395   struct ld_info ldinfo;
396   bfd_size_type size;
397   char *path, *s;
398   size_t alloc;
399   const char *str1, *str2;
400   boolean ret;
401 
402   if (bfd_seek (core_bfd, 0, SEEK_SET) != 0
403       || bfd_read (&coredata, sizeof coredata, 1, core_bfd) != sizeof coredata)
404     return false;
405 
406   if (bfd_seek (core_bfd, (long) coredata.LOADER_OFFSET_FIELD, SEEK_SET) != 0)
407     return false;
408 
409   size = (char *) &ldinfo.ldinfo_filename[0] - (char *) &ldinfo.ldinfo_next;
410   if (bfd_read (&ldinfo, size, 1, core_bfd) != size)
411     return false;
412 
413   alloc = 100;
414   path = bfd_malloc (alloc);
415   if (path == NULL)
416     return false;
417   s = path;
418 
419   while (1)
420     {
421       if (bfd_read (s, 1, 1, core_bfd) != 1)
422 	{
423 	  free (path);
424 	  return false;
425 	}
426       if (*s == '\0')
427 	break;
428       ++s;
429       if (s == path + alloc)
430 	{
431 	  char *n;
432 
433 	  alloc *= 2;
434 	  n = bfd_realloc (path, alloc);
435 	  if (n == NULL)
436 	    {
437 	      free (path);
438 	      return false;
439 	    }
440 	  s = n + (path - s);
441 	  path = n;
442 	}
443     }
444 
445   str1 = strrchr (path, '/');
446   str2 = strrchr (exec_bfd->filename, '/');
447 
448   /* step over character '/' */
449   str1 = str1 != NULL ? str1 + 1 : path;
450   str2 = str2 != NULL ? str2 + 1 : exec_bfd->filename;
451 
452   if (strcmp (str1, str2) == 0)
453     ret = true;
454   else
455     ret = false;
456 
457   free (path);
458 
459   return ret;
460 }
461 
462 char *
463 rs6000coff_core_file_failing_command (abfd)
464      bfd *abfd;
465 {
466   char *com = core_hdr (abfd).CORE_COMM_FIELD;
467   if (*com)
468     return com;
469   else
470     return 0;
471 }
472 
473 int
474 rs6000coff_core_file_failing_signal (abfd)
475      bfd *abfd;
476 {
477   return core_hdr (abfd).c_signo;
478 }
479 
480 
481 boolean
482 rs6000coff_get_section_contents (abfd, section, location, offset, count)
483      bfd *abfd;
484      sec_ptr section;
485      PTR location;
486      file_ptr offset;
487      bfd_size_type count;
488 {
489     if (count == 0)
490 	return true;
491 
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. */
495 
496     if (abfd->format == bfd_core && strcmp (section->name, ".reg") == 0) {
497 
498       struct mstsave mstatus;
499       int    regoffset = (char*)&mstatus.gpr[0] - (char*)&mstatus;
500 
501       /* Assert that the only way this code will be executed is reading the
502          whole section. */
503       if (offset || count != (sizeof(mstatus.gpr) + (4 * NUM_OF_SPEC_REGS)))
504         (*_bfd_error_handler)
505 	  (_("ERROR! in rs6000coff_get_section_contents()\n"));
506 
507       /* for `.reg' section, `filepos' is a pointer to the `mstsave' structure
508          in the core file. */
509 
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 */
514 
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. */
518 
519       location = (PTR) ((char*)location + sizeof (mstatus.gpr));
520       regoffset = (char*)&mstatus.iar - (char*)&mstatus;
521 
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 */
526 
527       /* increment location address, and read the special registers.. */
528       /* FIXMEmgo */
529       return (true);
530     }
531 
532     /* else, use default bfd section content transfer. */
533     else
534       return _bfd_generic_get_section_contents
535       			(abfd, section, location, offset, count);
536 }
537 
538 #endif /* AIX_CORE */
539