aoutf1.h revision 33965
1/* A.out "format 1" file handling code for BFD.
2   Copyright 1990, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
3   Written by Cygnus Support.
4
5This file is part of BFD, the Binary File Descriptor library.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21#include "bfd.h"
22#include "sysdep.h"
23#include "libbfd.h"
24
25#include "aout/sun4.h"
26#include "libaout.h"		/* BFD a.out internal data structures */
27
28#include "aout/aout64.h"
29#include "aout/stab_gnu.h"
30#include "aout/ar.h"
31
32/* This is needed to reject a NewsOS file, e.g. in
33   gdb/testsuite/gdb.t10/crossload.exp. <kingdon@cygnus.com>
34   I needed to add M_UNKNOWN to recognize a 68000 object, so this will
35   probably no longer reject a NewsOS object.  <ian@cygnus.com>. */
36#ifndef MACHTYPE_OK
37#define MACHTYPE_OK(mtype) \
38  (((mtype) == M_SPARC && bfd_lookup_arch (bfd_arch_sparc, 0) != NULL) \
39   || (((mtype) == M_UNKNOWN || (mtype) == M_68010 || (mtype) == M_68020) \
40       && bfd_lookup_arch (bfd_arch_m68k, 0) != NULL))
41#endif
42
43/*
44The file @code{aoutf1.h} contains the code for BFD's
45a.out back end. Control over the generated back end is given by these
46two preprocessor names:
47@table @code
48@item ARCH_SIZE
49This value should be either 32 or 64, depending upon the size of an
50int in the target format. It changes the sizes of the structs which
51perform the memory/disk mapping of structures.
52
53The 64 bit backend may only be used if the host compiler supports 64
54ints (eg long long with gcc), by defining the name @code{BFD_HOST_64_BIT} in @code{bfd.h}.
55With this name defined, @emph{all} bfd operations are performed with 64bit
56arithmetic, not just those to a 64bit target.
57
58@item TARGETNAME
59The name put into the target vector.
60@item
61@end table
62
63*/
64
65/*SUPPRESS558*/
66/*SUPPRESS529*/
67
68#if ARCH_SIZE == 64
69#define sunos_set_arch_mach sunos_64_set_arch_mach
70#define sunos_write_object_contents aout_64_sunos4_write_object_contents
71#else
72#define sunos_set_arch_mach sunos_32_set_arch_mach
73#define sunos_write_object_contents aout_32_sunos4_write_object_contents
74#endif
75
76static boolean sunos_merge_private_bfd_data PARAMS ((bfd *, bfd *));
77static void sunos_set_arch_mach PARAMS ((bfd *, int));
78static void choose_reloc_size PARAMS ((bfd *));
79static boolean sunos_write_object_contents PARAMS ((bfd *));
80static const bfd_target *sunos4_core_file_p PARAMS ((bfd *));
81static char *sunos4_core_file_failing_command PARAMS ((bfd *));
82static int sunos4_core_file_failing_signal PARAMS ((bfd *));
83static boolean sunos4_core_file_matches_executable_p PARAMS ((bfd *, bfd *));
84static boolean sunos4_set_sizes PARAMS ((bfd *));
85
86/* Merge backend data into the output file.
87   This is necessary on sparclet-aout where we want the resultant machine
88   number to be M_SPARCLET if any input file is M_SPARCLET.  */
89
90#define MY_bfd_merge_private_bfd_data sunos_merge_private_bfd_data
91
92static boolean
93sunos_merge_private_bfd_data (ibfd, obfd)
94     bfd *ibfd, *obfd;
95{
96  if (bfd_get_flavour (ibfd) != bfd_target_aout_flavour
97      || bfd_get_flavour (obfd) != bfd_target_aout_flavour)
98    return true;
99
100  if (bfd_get_arch (obfd) == bfd_arch_sparc)
101    {
102      if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
103	bfd_set_arch_mach (obfd, bfd_arch_sparc, bfd_get_mach (ibfd));
104    }
105
106  return true;
107}
108
109/* This is either sunos_32_set_arch_mach or sunos_64_set_arch_mach,
110   depending upon ARCH_SIZE.  */
111
112static void
113sunos_set_arch_mach (abfd, machtype)
114     bfd *abfd;
115     int machtype;
116{
117  /* Determine the architecture and machine type of the object file.  */
118  enum bfd_architecture arch;
119  long machine;
120  switch (machtype)
121    {
122
123    case M_UNKNOWN:
124      /* Some Sun3s make magic numbers without cpu types in them, so
125	 we'll default to the 68000. */
126      arch = bfd_arch_m68k;
127      machine = 68000;
128      break;
129
130    case M_68010:
131    case M_HP200:
132      arch = bfd_arch_m68k;
133      machine = 68010;
134      break;
135
136    case M_68020:
137    case M_HP300:
138      arch = bfd_arch_m68k;
139      machine = 68020;
140      break;
141
142    case M_SPARC:
143      arch = bfd_arch_sparc;
144      machine = 0;
145      break;
146
147    case M_SPARCLET:
148      arch = bfd_arch_sparc;
149      machine = bfd_mach_sparc_sparclet;
150      break;
151
152    case M_386:
153    case M_386_DYNIX:
154      arch = bfd_arch_i386;
155      machine = 0;
156      break;
157
158    case M_29K:
159      arch = bfd_arch_a29k;
160      machine = 0;
161      break;
162
163    case M_HPUX:
164      arch = bfd_arch_m68k;
165      machine = 0;
166      break;
167
168    default:
169      arch = bfd_arch_obscure;
170      machine = 0;
171      break;
172    }
173  bfd_set_arch_mach (abfd, arch, machine);
174}
175
176#define SET_ARCH_MACH(ABFD, EXEC) \
177  NAME(sunos,set_arch_mach)(ABFD, N_MACHTYPE (EXEC)); \
178  choose_reloc_size(ABFD);
179
180/* Determine the size of a relocation entry, based on the architecture */
181static void
182choose_reloc_size (abfd)
183     bfd *abfd;
184{
185  switch (bfd_get_arch (abfd))
186    {
187    case bfd_arch_sparc:
188    case bfd_arch_a29k:
189      obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
190      break;
191    default:
192      obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
193      break;
194    }
195}
196
197/* Write an object file in SunOS format.  Section contents have
198   already been written.  We write the file header, symbols, and
199   relocation.  The real name of this function is either
200   aout_64_sunos4_write_object_contents or
201   aout_32_sunos4_write_object_contents, depending upon ARCH_SIZE.  */
202
203static boolean
204sunos_write_object_contents (abfd)
205     bfd *abfd;
206{
207  struct external_exec exec_bytes;
208  struct internal_exec *execp = exec_hdr (abfd);
209
210  /* Magic number, maestro, please!  */
211  switch (bfd_get_arch (abfd))
212    {
213    case bfd_arch_m68k:
214      switch (bfd_get_mach (abfd))
215	{
216	case 68000:
217	  N_SET_MACHTYPE (*execp, M_UNKNOWN);
218	  break;
219	case 68010:
220	  N_SET_MACHTYPE (*execp, M_68010);
221	  break;
222	default:
223	case 68020:
224	  N_SET_MACHTYPE (*execp, M_68020);
225	  break;
226	}
227      break;
228    case bfd_arch_sparc:
229      switch (bfd_get_mach (abfd))
230	{
231	case bfd_mach_sparc_sparclet:
232	  N_SET_MACHTYPE (*execp, M_SPARCLET);
233	  break;
234	default:
235	  N_SET_MACHTYPE (*execp, M_SPARC);
236	  break;
237	}
238      break;
239    case bfd_arch_i386:
240      N_SET_MACHTYPE (*execp, M_386);
241      break;
242    case bfd_arch_a29k:
243      N_SET_MACHTYPE (*execp, M_29K);
244      break;
245    default:
246      N_SET_MACHTYPE (*execp, M_UNKNOWN);
247    }
248
249  choose_reloc_size (abfd);
250
251  N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags);
252
253  N_SET_DYNAMIC (*execp, bfd_get_file_flags (abfd) & DYNAMIC);
254
255  WRITE_HEADERS (abfd, execp);
256
257  return true;
258}
259
260/* core files */
261
262#define CORE_MAGIC 0x080456
263#define CORE_NAMELEN 16
264
265/* The core structure is taken from the Sun documentation.
266  Unfortunately, they don't document the FPA structure, or at least I
267  can't find it easily.  Fortunately the core header contains its own
268  length.  So this shouldn't cause problems, except for c_ucode, which
269  so far we don't use but is easy to find with a little arithmetic. */
270
271/* But the reg structure can be gotten from the SPARC processor handbook.
272  This really should be in a GNU include file though so that gdb can use
273  the same info. */
274struct regs
275{
276  int r_psr;
277  int r_pc;
278  int r_npc;
279  int r_y;
280  int r_g1;
281  int r_g2;
282  int r_g3;
283  int r_g4;
284  int r_g5;
285  int r_g6;
286  int r_g7;
287  int r_o0;
288  int r_o1;
289  int r_o2;
290  int r_o3;
291  int r_o4;
292  int r_o5;
293  int r_o6;
294  int r_o7;
295};
296
297/* Taken from Sun documentation: */
298
299/* FIXME:  It's worse than we expect.  This struct contains TWO substructs
300  neither of whose size we know, WITH STUFF IN BETWEEN THEM!  We can't
301  even portably access the stuff in between!  */
302
303struct external_sparc_core
304  {
305    int c_magic;		/* Corefile magic number */
306    int c_len;			/* Sizeof (struct core) */
307#define	SPARC_CORE_LEN	432
308    int c_regs[19];		/* General purpose registers -- MACHDEP SIZE */
309    struct external_exec c_aouthdr;	/* A.out header */
310    int c_signo;		/* Killing signal, if any */
311    int c_tsize;		/* Text size (bytes) */
312    int c_dsize;		/* Data size (bytes) */
313    int c_ssize;		/* Stack size (bytes) */
314    char c_cmdname[CORE_NAMELEN + 1];	/* Command name */
315    double fp_stuff[1];		/* external FPU state (size unknown by us) */
316    /* The type "double" is critical here, for alignment.
317    SunOS declares a struct here, but the struct's alignment
318      is double since it contains doubles.  */
319    int c_ucode;		/* Exception no. from u_code */
320    /* (this member is not accessible by name since we don't
321    portably know the size of fp_stuff.) */
322  };
323
324/* Core files generated by the BCP (the part of Solaris which allows
325   it to run SunOS4 a.out files).  */
326struct external_solaris_bcp_core
327  {
328    int c_magic;		/* Corefile magic number */
329    int c_len;			/* Sizeof (struct core) */
330#define	SOLARIS_BCP_CORE_LEN	456
331    int c_regs[19];		/* General purpose registers -- MACHDEP SIZE */
332    int c_exdata_vp;		/* exdata structure */
333    int c_exdata_tsize;
334    int c_exdata_dsize;
335    int c_exdata_bsize;
336    int c_exdata_lsize;
337    int c_exdata_nshlibs;
338    short c_exdata_mach;
339    short c_exdata_mag;
340    int c_exdata_toffset;
341    int c_exdata_doffset;
342    int c_exdata_loffset;
343    int c_exdata_txtorg;
344    int c_exdata_datorg;
345    int c_exdata_entloc;
346    int c_signo;		/* Killing signal, if any */
347    int c_tsize;		/* Text size (bytes) */
348    int c_dsize;		/* Data size (bytes) */
349    int c_ssize;		/* Stack size (bytes) */
350    char c_cmdname[CORE_NAMELEN + 1];	/* Command name */
351    double fp_stuff[1];		/* external FPU state (size unknown by us) */
352    /* The type "double" is critical here, for alignment.
353    SunOS declares a struct here, but the struct's alignment
354      is double since it contains doubles.  */
355    int c_ucode;		/* Exception no. from u_code */
356    /* (this member is not accessible by name since we don't
357    portably know the size of fp_stuff.) */
358  };
359
360struct external_sun3_core
361  {
362    int c_magic;		/* Corefile magic number */
363    int c_len;			/* Sizeof (struct core) */
364#define	SUN3_CORE_LEN	826	/* As of SunOS 4.1.1 */
365    int c_regs[18];		/* General purpose registers -- MACHDEP SIZE */
366    struct external_exec c_aouthdr;	/* A.out header */
367    int c_signo;		/* Killing signal, if any */
368    int c_tsize;		/* Text size (bytes) */
369    int c_dsize;		/* Data size (bytes) */
370    int c_ssize;		/* Stack size (bytes) */
371    char c_cmdname[CORE_NAMELEN + 1];	/* Command name */
372    double fp_stuff[1];		/* external FPU state (size unknown by us) */
373    /* The type "double" is critical here, for alignment.
374    SunOS declares a struct here, but the struct's alignment
375      is double since it contains doubles.  */
376    int c_ucode;		/* Exception no. from u_code */
377    /* (this member is not accessible by name since we don't
378    portably know the size of fp_stuff.) */
379  };
380
381struct internal_sunos_core
382  {
383    int c_magic;		/* Corefile magic number */
384    int c_len;			/* Sizeof (struct core) */
385    long c_regs_pos;		/* file offset of General purpose registers */
386    int c_regs_size;		/* size of General purpose registers */
387    struct internal_exec c_aouthdr;	/* A.out header */
388    int c_signo;		/* Killing signal, if any */
389    int c_tsize;		/* Text size (bytes) */
390    int c_dsize;		/* Data size (bytes) */
391    bfd_vma c_data_addr;	/* Data start (address) */
392    int c_ssize;		/* Stack size (bytes) */
393    bfd_vma c_stacktop;		/* Stack top (address) */
394    char c_cmdname[CORE_NAMELEN + 1];	/* Command name */
395    long fp_stuff_pos;		/* file offset of external FPU state (regs) */
396    int fp_stuff_size;		/* Size of it */
397    int c_ucode;		/* Exception no. from u_code */
398  };
399
400static void swapcore_sun3
401  PARAMS ((bfd *, char *, struct internal_sunos_core *));
402static void swapcore_sparc
403  PARAMS ((bfd *, char *, struct internal_sunos_core *));
404static void swapcore_solaris_bcp
405  PARAMS ((bfd *, char *, struct internal_sunos_core *));
406
407/* byte-swap in the Sun-3 core structure */
408static void
409swapcore_sun3 (abfd, ext, intcore)
410     bfd *abfd;
411     char *ext;
412     struct internal_sunos_core *intcore;
413{
414  struct external_sun3_core *extcore = (struct external_sun3_core *) ext;
415
416  intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic);
417  intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len);
418  intcore->c_regs_pos = (long) (((struct external_sun3_core *) 0)->c_regs);
419  intcore->c_regs_size = sizeof (extcore->c_regs);
420#if ARCH_SIZE == 64
421  aout_64_swap_exec_header_in
422#else
423  aout_32_swap_exec_header_in
424#endif
425    (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr);
426  intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo);
427  intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize);
428  intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize);
429  intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr);
430  intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize);
431  memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname));
432  intcore->fp_stuff_pos = (long) (((struct external_sun3_core *) 0)->fp_stuff);
433  /* FP stuff takes up whole rest of struct, except c_ucode. */
434  intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
435    (file_ptr) (((struct external_sun3_core *) 0)->fp_stuff);
436  /* Ucode is the last thing in the struct -- just before the end */
437  intcore->c_ucode =
438    bfd_h_get_32 (abfd,
439    intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore);
440  intcore->c_stacktop = 0x0E000000;	/* By experimentation */
441}
442
443
444/* byte-swap in the Sparc core structure */
445static void
446swapcore_sparc (abfd, ext, intcore)
447     bfd *abfd;
448     char *ext;
449     struct internal_sunos_core *intcore;
450{
451  struct external_sparc_core *extcore = (struct external_sparc_core *) ext;
452
453  intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic);
454  intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len);
455  intcore->c_regs_pos = (long) (((struct external_sparc_core *) 0)->c_regs);
456  intcore->c_regs_size = sizeof (extcore->c_regs);
457#if ARCH_SIZE == 64
458  aout_64_swap_exec_header_in
459#else
460  aout_32_swap_exec_header_in
461#endif
462    (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr);
463  intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo);
464  intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize);
465  intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize);
466  intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr);
467  intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize);
468  memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname));
469  intcore->fp_stuff_pos = (long) (((struct external_sparc_core *) 0)->fp_stuff);
470  /* FP stuff takes up whole rest of struct, except c_ucode. */
471  intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
472    (file_ptr) (((struct external_sparc_core *) 0)->fp_stuff);
473  /* Ucode is the last thing in the struct -- just before the end */
474  intcore->c_ucode =
475    bfd_h_get_32 (abfd,
476    intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore);
477
478  /* Supposedly the user stack grows downward from the bottom of kernel memory.
479     Presuming that this remains true, this definition will work.  */
480  /* Now sun has provided us with another challenge.  The value is different
481     for sparc2 and sparc10 (both running SunOS 4.1.3).  We pick one or
482     the other based on the current value of the stack pointer.  This
483     loses (a) if the stack pointer has been clobbered, or (b) if the stack
484     is larger than 128 megabytes.
485
486     It's times like these you're glad they're switching to ELF.
487
488     Note that using include files or nlist on /vmunix would be wrong,
489     because we want the value for this core file, no matter what kind of
490     machine we were compiled on or are running on.  */
491#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000)
492#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000)
493  {
494    bfd_vma sp = bfd_h_get_32
495    (abfd, (unsigned char *) &((struct regs *) &extcore->c_regs[0])->r_o6);
496    if (sp < SPARC_USRSTACK_SPARC10)
497      intcore->c_stacktop = SPARC_USRSTACK_SPARC10;
498    else
499      intcore->c_stacktop = SPARC_USRSTACK_SPARC2;
500  }
501}
502
503/* byte-swap in the Solaris BCP core structure */
504static void
505swapcore_solaris_bcp (abfd, ext, intcore)
506     bfd *abfd;
507     char *ext;
508     struct internal_sunos_core *intcore;
509{
510  struct external_solaris_bcp_core *extcore =
511    (struct external_solaris_bcp_core *) ext;
512
513  intcore->c_magic = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_magic);
514  intcore->c_len = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_len);
515  intcore->c_regs_pos = (long) (((struct external_solaris_bcp_core *) 0)->c_regs);
516  intcore->c_regs_size = sizeof (extcore->c_regs);
517
518  /* The Solaris BCP exdata structure does not contain an a_syms field,
519     so we are unable to synthesize an internal exec header.
520     Luckily we are able to figure out the start address of the data section,
521     which is the only thing needed from the internal exec header,
522     from the exdata structure.
523
524     As of Solaris 2.3, BCP core files for statically linked executables
525     are buggy. The exdata structure is not properly filled in, and
526     the data section is written from address zero instead of the data
527     start address.  */
528  memset ((PTR) &intcore->c_aouthdr, 0, sizeof (struct internal_exec));
529  intcore->c_data_addr =
530    bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_exdata_datorg);
531  intcore->c_signo = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_signo);
532  intcore->c_tsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_tsize);
533  intcore->c_dsize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_dsize);
534  intcore->c_ssize = bfd_h_get_32 (abfd, (unsigned char *) &extcore->c_ssize);
535  memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname));
536  intcore->fp_stuff_pos =
537    (long) (((struct external_solaris_bcp_core *) 0)->fp_stuff);
538  /* FP stuff takes up whole rest of struct, except c_ucode. */
539  intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
540    (file_ptr) (((struct external_solaris_bcp_core *) 0)->fp_stuff);
541  /* Ucode is the last thing in the struct -- just before the end */
542  intcore->c_ucode =
543    bfd_h_get_32 (abfd,
544    intcore->c_len - sizeof (extcore->c_ucode) + (unsigned char *) extcore);
545
546  /* Supposedly the user stack grows downward from the bottom of kernel memory.
547     Presuming that this remains true, this definition will work.  */
548  /* Now sun has provided us with another challenge.  The value is different
549     for sparc2 and sparc10 (both running SunOS 4.1.3).  We pick one or
550     the other based on the current value of the stack pointer.  This
551     loses (a) if the stack pointer has been clobbered, or (b) if the stack
552     is larger than 128 megabytes.
553
554     It's times like these you're glad they're switching to ELF.
555
556     Note that using include files or nlist on /vmunix would be wrong,
557     because we want the value for this core file, no matter what kind of
558     machine we were compiled on or are running on.  */
559#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000)
560#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000)
561  {
562    bfd_vma sp = bfd_h_get_32
563    (abfd, (unsigned char *) &((struct regs *) &extcore->c_regs[0])->r_o6);
564    if (sp < SPARC_USRSTACK_SPARC10)
565      intcore->c_stacktop = SPARC_USRSTACK_SPARC10;
566    else
567      intcore->c_stacktop = SPARC_USRSTACK_SPARC2;
568  }
569}
570
571/* need this cast because ptr is really void * */
572#define core_hdr(bfd) ((bfd)->tdata.sun_core_data)
573#define core_datasec(bfd) (core_hdr(bfd)->data_section)
574#define core_stacksec(bfd) (core_hdr(bfd)->stack_section)
575#define core_regsec(bfd) (core_hdr(bfd)->reg_section)
576#define core_reg2sec(bfd) (core_hdr(bfd)->reg2_section)
577
578/* These are stored in the bfd's tdata */
579struct sun_core_struct
580{
581  struct internal_sunos_core *hdr;	/* core file header */
582  asection *data_section;
583  asection *stack_section;
584  asection *reg_section;
585  asection *reg2_section;
586};
587
588static const bfd_target *
589sunos4_core_file_p (abfd)
590     bfd *abfd;
591{
592  unsigned char longbuf[4];	/* Raw bytes of various header fields */
593  bfd_size_type core_size;
594  unsigned long core_mag;
595  struct internal_sunos_core *core;
596  char *extcore;
597  struct mergem
598    {
599      struct sun_core_struct suncoredata;
600      struct internal_sunos_core internal_sunos_core;
601      char external_core[1];
602    }
603   *mergem;
604
605  if (bfd_read ((PTR) longbuf, 1, sizeof (longbuf), abfd) !=
606      sizeof (longbuf))
607    return 0;
608  core_mag = bfd_h_get_32 (abfd, longbuf);
609
610  if (core_mag != CORE_MAGIC)
611    return 0;
612
613  /* SunOS core headers can vary in length; second word is size; */
614  if (bfd_read ((PTR) longbuf, 1, sizeof (longbuf), abfd) !=
615      sizeof (longbuf))
616    return 0;
617  core_size = bfd_h_get_32 (abfd, longbuf);
618  /* Sanity check */
619  if (core_size > 20000)
620    return 0;
621
622  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) < 0)
623    return 0;
624
625  mergem = (struct mergem *) bfd_zalloc (abfd, core_size + sizeof (struct mergem));
626  if (mergem == NULL)
627    return 0;
628
629  extcore = mergem->external_core;
630
631  if ((bfd_read ((PTR) extcore, 1, core_size, abfd)) != core_size)
632    {
633      bfd_release (abfd, (char *) mergem);
634      return 0;
635    }
636
637  /* Validate that it's a core file we know how to handle, due to sun
638     botching the positioning of registers and other fields in a machine
639     dependent way.  */
640  core = &mergem->internal_sunos_core;
641  switch (core_size)
642    {
643    case SPARC_CORE_LEN:
644      swapcore_sparc (abfd, extcore, core);
645      break;
646    case SUN3_CORE_LEN:
647      swapcore_sun3 (abfd, extcore, core);
648      break;
649    case SOLARIS_BCP_CORE_LEN:
650      swapcore_solaris_bcp (abfd, extcore, core);
651      break;
652    default:
653      bfd_set_error (bfd_error_system_call);	/* FIXME */
654      bfd_release (abfd, (char *) mergem);
655      return 0;
656    }
657
658  abfd->tdata.sun_core_data = &mergem->suncoredata;
659  abfd->tdata.sun_core_data->hdr = core;
660
661  /* create the sections.  This is raunchy, but bfd_close wants to reclaim
662     them */
663  core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
664  if (core_stacksec (abfd) == NULL)
665    {
666    loser:
667      bfd_release (abfd, (char *) mergem);
668      return 0;
669    }
670  core_datasec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
671  if (core_datasec (abfd) == NULL)
672    {
673    loser1:
674      bfd_release (abfd, core_stacksec (abfd));
675      goto loser;
676    }
677  core_regsec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
678  if (core_regsec (abfd) == NULL)
679    {
680    loser2:
681      bfd_release (abfd, core_datasec (abfd));
682      goto loser1;
683    }
684  core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, sizeof (asection));
685  if (core_reg2sec (abfd) == NULL)
686    {
687      bfd_release (abfd, core_regsec (abfd));
688      goto loser2;
689    }
690
691  core_stacksec (abfd)->name = ".stack";
692  core_datasec (abfd)->name = ".data";
693  core_regsec (abfd)->name = ".reg";
694  core_reg2sec (abfd)->name = ".reg2";
695
696  core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
697  core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
698  core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
699  core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS;
700
701  core_stacksec (abfd)->_raw_size = core->c_ssize;
702  core_datasec (abfd)->_raw_size = core->c_dsize;
703  core_regsec (abfd)->_raw_size = core->c_regs_size;
704  core_reg2sec (abfd)->_raw_size = core->fp_stuff_size;
705
706  core_stacksec (abfd)->vma = (core->c_stacktop - core->c_ssize);
707  core_datasec (abfd)->vma = core->c_data_addr;
708  core_regsec (abfd)->vma = 0;
709  core_reg2sec (abfd)->vma = 0;
710
711  core_stacksec (abfd)->filepos = core->c_len + core->c_dsize;
712  core_datasec (abfd)->filepos = core->c_len;
713  /* We'll access the regs afresh in the core file, like any section: */
714  core_regsec (abfd)->filepos = (file_ptr) core->c_regs_pos;
715  core_reg2sec (abfd)->filepos = (file_ptr) core->fp_stuff_pos;
716
717  /* Align to word at least */
718  core_stacksec (abfd)->alignment_power = 2;
719  core_datasec (abfd)->alignment_power = 2;
720  core_regsec (abfd)->alignment_power = 2;
721  core_reg2sec (abfd)->alignment_power = 2;
722
723  abfd->sections = core_stacksec (abfd);
724  core_stacksec (abfd)->next = core_datasec (abfd);
725  core_datasec (abfd)->next = core_regsec (abfd);
726  core_regsec (abfd)->next = core_reg2sec (abfd);
727
728  abfd->section_count = 4;
729
730  return abfd->xvec;
731}
732
733static char *
734sunos4_core_file_failing_command (abfd)
735     bfd *abfd;
736{
737  return core_hdr (abfd)->hdr->c_cmdname;
738}
739
740static int
741sunos4_core_file_failing_signal (abfd)
742     bfd *abfd;
743{
744  return core_hdr (abfd)->hdr->c_signo;
745}
746
747static boolean
748sunos4_core_file_matches_executable_p (core_bfd, exec_bfd)
749     bfd *core_bfd;
750     bfd *exec_bfd;
751{
752  if (core_bfd->xvec != exec_bfd->xvec)
753    {
754      bfd_set_error (bfd_error_system_call);
755      return false;
756    }
757
758  /* Solaris core files do not include an aouthdr. */
759  if ((core_hdr (core_bfd)->hdr)->c_len == SOLARIS_BCP_CORE_LEN)
760    return true;
761
762  return (memcmp ((char *) &((core_hdr (core_bfd)->hdr)->c_aouthdr),
763		  (char *) exec_hdr (exec_bfd),
764		  sizeof (struct internal_exec)) == 0) ? true : false;
765}
766
767#define MY_set_sizes sunos4_set_sizes
768static boolean
769sunos4_set_sizes (abfd)
770     bfd *abfd;
771{
772  switch (bfd_get_arch (abfd))
773    {
774    default:
775      return false;
776    case bfd_arch_sparc:
777      adata (abfd).page_size = 0x2000;
778      adata (abfd).segment_size = 0x2000;
779      adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
780      return true;
781    case bfd_arch_m68k:
782      adata (abfd).page_size = 0x2000;
783      adata (abfd).segment_size = 0x20000;
784      adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
785      return true;
786    }
787}
788
789/* We default to setting the toolversion field to 1, as is required by
790   SunOS.  */
791#ifndef MY_exec_hdr_flags
792#define MY_exec_hdr_flags 1
793#endif
794
795#ifndef MY_entry_is_text_address
796#define MY_entry_is_text_address 0
797#endif
798#ifndef MY_add_dynamic_symbols
799#define MY_add_dynamic_symbols 0
800#endif
801#ifndef MY_add_one_symbol
802#define MY_add_one_symbol 0
803#endif
804#ifndef MY_link_dynamic_object
805#define MY_link_dynamic_object 0
806#endif
807#ifndef MY_write_dynamic_symbol
808#define MY_write_dynamic_symbol 0
809#endif
810#ifndef MY_check_dynamic_reloc
811#define MY_check_dynamic_reloc 0
812#endif
813#ifndef MY_finish_dynamic_link
814#define MY_finish_dynamic_link 0
815#endif
816
817static CONST struct aout_backend_data sunos4_aout_backend =
818{
819  0,				/* zmagic files are not contiguous */
820  1,				/* text includes header */
821  MY_entry_is_text_address,
822  MY_exec_hdr_flags,
823  0,				/* default text vma */
824  sunos4_set_sizes,
825  0,				/* header is counted in zmagic text */
826  MY_add_dynamic_symbols,
827  MY_add_one_symbol,
828  MY_link_dynamic_object,
829  MY_write_dynamic_symbol,
830  MY_check_dynamic_reloc,
831  MY_finish_dynamic_link
832};
833
834#define	MY_core_file_failing_command 	sunos4_core_file_failing_command
835#define	MY_core_file_failing_signal	sunos4_core_file_failing_signal
836#define	MY_core_file_matches_executable_p sunos4_core_file_matches_executable_p
837
838#define MY_bfd_debug_info_start		bfd_void
839#define MY_bfd_debug_info_end		bfd_void
840#define MY_bfd_debug_info_accumulate	\
841			(void (*) PARAMS ((bfd *, struct sec *))) bfd_void
842#define MY_core_file_p			sunos4_core_file_p
843#define MY_write_object_contents	NAME(aout,sunos4_write_object_contents)
844#define MY_backend_data			&sunos4_aout_backend
845
846#ifndef TARGET_IS_LITTLE_ENDIAN_P
847#define TARGET_IS_BIG_ENDIAN_P
848#endif
849
850#include "aout-target.h"
851