aoutf1.h revision 104834
1275970Scy/* A.out "format 1" file handling code for BFD.
2275970Scy   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
3275970Scy   2001, 2002
4275970Scy   Free Software Foundation, Inc.
5275970Scy   Written by Cygnus Support.
6275970Scy
7275970ScyThis file is part of BFD, the Binary File Descriptor library.
8275970Scy
9275970ScyThis program is free software; you can redistribute it and/or modify
10275970Scyit under the terms of the GNU General Public License as published by
11275970Scythe Free Software Foundation; either version 2 of the License, or
12275970Scy(at your option) any later version.
13275970Scy
14275970ScyThis program is distributed in the hope that it will be useful,
15275970Scybut WITHOUT ANY WARRANTY; without even the implied warranty of
16275970ScyMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17275970ScyGNU General Public License for more details.
18275970Scy
19275970ScyYou should have received a copy of the GNU General Public License
20275970Scyalong with this program; if not, write to the Free Software
21275970ScyFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22275970Scy
23275970Scy#include "bfd.h"
24275970Scy#include "sysdep.h"
25275970Scy#include "libbfd.h"
26275970Scy
27275970Scy#include "aout/sun4.h"
28275970Scy#include "libaout.h"		/* BFD a.out internal data structures */
29275970Scy
30275970Scy#include "aout/aout64.h"
31275970Scy#include "aout/stab_gnu.h"
32275970Scy#include "aout/ar.h"
33275970Scy
34275970Scy/* This is needed to reject a NewsOS file, e.g. in
35275970Scy   gdb/testsuite/gdb.t10/crossload.exp. <kingdon@cygnus.com>
36275970Scy   I needed to add M_UNKNOWN to recognize a 68000 object, so this will
37275970Scy   probably no longer reject a NewsOS object.  <ian@cygnus.com>.  */
38275970Scy#ifndef MACHTYPE_OK
39275970Scy#define MACHTYPE_OK(mtype) \
40275970Scy  (((mtype) == M_SPARC && bfd_lookup_arch (bfd_arch_sparc, 0) != NULL) \
41275970Scy   || (((mtype) == M_UNKNOWN || (mtype) == M_68010 || (mtype) == M_68020) \
42275970Scy       && bfd_lookup_arch (bfd_arch_m68k, 0) != NULL))
43275970Scy#endif
44275970Scy
45275970Scy/*
46275970ScyThe file @code{aoutf1.h} contains the code for BFD's
47275970Scya.out back end. Control over the generated back end is given by these
48275970Scytwo preprocessor names:
49275970Scy@table @code
50275970Scy@item ARCH_SIZE
51275970ScyThis value should be either 32 or 64, depending upon the size of an
52275970Scyint in the target format. It changes the sizes of the structs which
53275970Scyperform the memory/disk mapping of structures.
54275970Scy
55275970ScyThe 64 bit backend may only be used if the host compiler supports 64
56275970Scyints (eg long long with gcc), by defining the name @code{BFD_HOST_64_BIT} in @code{bfd.h}.
57275970ScyWith this name defined, @emph{all} bfd operations are performed with 64bit
58275970Scyarithmetic, not just those to a 64bit target.
59275970Scy
60275970Scy@item TARGETNAME
61275970ScyThe name put into the target vector.
62275970Scy@item
63275970Scy@end table
64275970Scy
65275970Scy*/
66275970Scy
67275970Scy/*SUPPRESS558*/
68275970Scy/*SUPPRESS529*/
69275970Scy
70275970Scy#if ARCH_SIZE == 64
71275970Scy#define sunos_set_arch_mach sunos_64_set_arch_mach
72275970Scy#define sunos_write_object_contents aout_64_sunos4_write_object_contents
73275970Scy#else
74275970Scy#define sunos_set_arch_mach sunos_32_set_arch_mach
75275970Scy#define sunos_write_object_contents aout_32_sunos4_write_object_contents
76275970Scy#endif
77275970Scy
78275970Scystatic boolean sunos_merge_private_bfd_data PARAMS ((bfd *, bfd *));
79275970Scystatic void sunos_set_arch_mach PARAMS ((bfd *, enum machine_type));
80275970Scystatic void choose_reloc_size PARAMS ((bfd *));
81275970Scystatic boolean sunos_write_object_contents PARAMS ((bfd *));
82275970Scystatic const bfd_target *sunos4_core_file_p PARAMS ((bfd *));
83275970Scystatic char *sunos4_core_file_failing_command PARAMS ((bfd *));
84275970Scystatic int sunos4_core_file_failing_signal PARAMS ((bfd *));
85275970Scystatic boolean sunos4_core_file_matches_executable_p PARAMS ((bfd *, bfd *));
86275970Scystatic boolean sunos4_set_sizes PARAMS ((bfd *));
87275970Scy
88275970Scy/* Merge backend data into the output file.
89275970Scy   This is necessary on sparclet-aout where we want the resultant machine
90275970Scy   number to be M_SPARCLET if any input file is M_SPARCLET.  */
91275970Scy
92275970Scy#define MY_bfd_merge_private_bfd_data sunos_merge_private_bfd_data
93285612Sdelphij
94285612Sdelphijstatic boolean
95275970Scysunos_merge_private_bfd_data (ibfd, obfd)
96275970Scy     bfd *ibfd, *obfd;
97275970Scy{
98275970Scy  if (bfd_get_flavour (ibfd) != bfd_target_aout_flavour
99275970Scy      || bfd_get_flavour (obfd) != bfd_target_aout_flavour)
100275970Scy    return true;
101275970Scy
102275970Scy  if (bfd_get_arch (obfd) == bfd_arch_sparc)
103275970Scy    {
104275970Scy      if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
105275970Scy	bfd_set_arch_mach (obfd, bfd_arch_sparc, bfd_get_mach (ibfd));
106275970Scy    }
107275970Scy
108275970Scy  return true;
109275970Scy}
110275970Scy
111275970Scy/* This is either sunos_32_set_arch_mach or sunos_64_set_arch_mach,
112275970Scy   depending upon ARCH_SIZE.  */
113275970Scy
114275970Scystatic void
115275970Scysunos_set_arch_mach (abfd, machtype)
116275970Scy     bfd *abfd;
117275970Scy     enum machine_type machtype;
118275970Scy{
119275970Scy  /* Determine the architecture and machine type of the object file.  */
120275970Scy  enum bfd_architecture arch;
121275970Scy  unsigned long machine;
122275970Scy  switch (machtype)
123275970Scy    {
124275970Scy
125275970Scy    case M_UNKNOWN:
126275970Scy      /* Some Sun3s make magic numbers without cpu types in them, so
127275970Scy	 we'll default to the 68000.  */
128275970Scy      arch = bfd_arch_m68k;
129275970Scy      machine = bfd_mach_m68000;
130275970Scy      break;
131275970Scy
132275970Scy    case M_68010:
133275970Scy    case M_HP200:
134275970Scy      arch = bfd_arch_m68k;
135275970Scy      machine = bfd_mach_m68010;
136275970Scy      break;
137275970Scy
138275970Scy    case M_68020:
139275970Scy    case M_HP300:
140275970Scy      arch = bfd_arch_m68k;
141275970Scy      machine = bfd_mach_m68020;
142275970Scy      break;
143275970Scy
144275970Scy    case M_SPARC:
145275970Scy      arch = bfd_arch_sparc;
146275970Scy      machine = 0;
147275970Scy      break;
148275970Scy
149275970Scy    case M_SPARCLET:
150275970Scy      arch = bfd_arch_sparc;
151275970Scy      machine = bfd_mach_sparc_sparclet;
152275970Scy      break;
153275970Scy
154275970Scy    case M_SPARCLITE_LE:
155275970Scy      arch = bfd_arch_sparc;
156275970Scy      machine = bfd_mach_sparc_sparclite_le;
157275970Scy      break;
158275970Scy
159275970Scy    case M_386:
160275970Scy    case M_386_DYNIX:
161275970Scy      arch = bfd_arch_i386;
162275970Scy      machine = 0;
163275970Scy      break;
164275970Scy
165275970Scy    case M_29K:
166275970Scy      arch = bfd_arch_a29k;
167275970Scy      machine = 0;
168275970Scy      break;
169275970Scy
170275970Scy    case M_HPUX:
171275970Scy      arch = bfd_arch_m68k;
172275970Scy      machine = 0;
173275970Scy      break;
174275970Scy
175275970Scy    default:
176275970Scy      arch = bfd_arch_obscure;
177275970Scy      machine = 0;
178275970Scy      break;
179275970Scy    }
180275970Scy  bfd_set_arch_mach (abfd, arch, machine);
181275970Scy}
182275970Scy
183275970Scy#define SET_ARCH_MACH(ABFD, EXEC) \
184275970Scy  NAME(sunos,set_arch_mach) (ABFD, N_MACHTYPE (EXEC)); \
185275970Scy  choose_reloc_size(ABFD);
186275970Scy
187275970Scy/* Determine the size of a relocation entry, based on the architecture */
188275970Scystatic void
189275970Scychoose_reloc_size (abfd)
190275970Scy     bfd *abfd;
191275970Scy{
192275970Scy  switch (bfd_get_arch (abfd))
193275970Scy    {
194275970Scy    case bfd_arch_sparc:
195275970Scy    case bfd_arch_a29k:
196275970Scy      obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
197275970Scy      break;
198275970Scy    default:
199275970Scy      obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
200275970Scy      break;
201275970Scy    }
202275970Scy}
203275970Scy
204275970Scy/* Write an object file in SunOS format.  Section contents have
205275970Scy   already been written.  We write the file header, symbols, and
206275970Scy   relocation.  The real name of this function is either
207275970Scy   aout_64_sunos4_write_object_contents or
208275970Scy   aout_32_sunos4_write_object_contents, depending upon ARCH_SIZE.  */
209275970Scy
210275970Scystatic boolean
211275970Scysunos_write_object_contents (abfd)
212275970Scy     bfd *abfd;
213275970Scy{
214275970Scy  struct external_exec exec_bytes;
215275970Scy  struct internal_exec *execp = exec_hdr (abfd);
216275970Scy
217275970Scy  /* Magic number, maestro, please!  */
218275970Scy  switch (bfd_get_arch (abfd))
219275970Scy    {
220275970Scy    case bfd_arch_m68k:
221275970Scy      switch (bfd_get_mach (abfd))
222275970Scy	{
223275970Scy	case bfd_mach_m68000:
224275970Scy	  N_SET_MACHTYPE (*execp, M_UNKNOWN);
225275970Scy	  break;
226275970Scy	case bfd_mach_m68010:
227275970Scy	  N_SET_MACHTYPE (*execp, M_68010);
228275970Scy	  break;
229275970Scy	default:
230275970Scy	case bfd_mach_m68020:
231275970Scy	  N_SET_MACHTYPE (*execp, M_68020);
232275970Scy	  break;
233275970Scy	}
234275970Scy      break;
235275970Scy    case bfd_arch_sparc:
236275970Scy      switch (bfd_get_mach (abfd))
237275970Scy	{
238275970Scy	case bfd_mach_sparc_sparclet:
239275970Scy	  N_SET_MACHTYPE (*execp, M_SPARCLET);
240275970Scy	  break;
241275970Scy	case bfd_mach_sparc_sparclite_le:
242275970Scy	  N_SET_MACHTYPE (*execp, M_SPARCLITE_LE);
243275970Scy	  break;
244275970Scy	default:
245275970Scy	  N_SET_MACHTYPE (*execp, M_SPARC);
246275970Scy	  break;
247275970Scy	}
248275970Scy      break;
249275970Scy    case bfd_arch_i386:
250275970Scy      N_SET_MACHTYPE (*execp, M_386);
251275970Scy      break;
252275970Scy    case bfd_arch_a29k:
253275970Scy      N_SET_MACHTYPE (*execp, M_29K);
254275970Scy      break;
255275970Scy    default:
256275970Scy      N_SET_MACHTYPE (*execp, M_UNKNOWN);
257275970Scy    }
258275970Scy
259275970Scy  choose_reloc_size (abfd);
260275970Scy
261275970Scy  N_SET_FLAGS (*execp, aout_backend_info (abfd)->exec_hdr_flags);
262275970Scy
263275970Scy  N_SET_DYNAMIC (*execp, (long)(bfd_get_file_flags (abfd) & DYNAMIC));
264275970Scy
265275970Scy  WRITE_HEADERS (abfd, execp);
266275970Scy
267275970Scy  return true;
268275970Scy}
269275970Scy
270275970Scy/* core files */
271275970Scy
272275970Scy#define CORE_MAGIC 0x080456
273275970Scy#define CORE_NAMELEN 16
274275970Scy
275275970Scy/* The core structure is taken from the Sun documentation.
276275970Scy  Unfortunately, they don't document the FPA structure, or at least I
277275970Scy  can't find it easily.  Fortunately the core header contains its own
278275970Scy  length.  So this shouldn't cause problems, except for c_ucode, which
279275970Scy  so far we don't use but is easy to find with a little arithmetic.  */
280275970Scy
281275970Scy/* But the reg structure can be gotten from the SPARC processor handbook.
282275970Scy  This really should be in a GNU include file though so that gdb can use
283275970Scy  the same info.  */
284275970Scystruct regs
285275970Scy{
286275970Scy  int r_psr;
287275970Scy  int r_pc;
288275970Scy  int r_npc;
289275970Scy  int r_y;
290275970Scy  int r_g1;
291275970Scy  int r_g2;
292275970Scy  int r_g3;
293275970Scy  int r_g4;
294275970Scy  int r_g5;
295275970Scy  int r_g6;
296275970Scy  int r_g7;
297275970Scy  int r_o0;
298275970Scy  int r_o1;
299275970Scy  int r_o2;
300275970Scy  int r_o3;
301275970Scy  int r_o4;
302275970Scy  int r_o5;
303275970Scy  int r_o6;
304275970Scy  int r_o7;
305275970Scy};
306275970Scy
307275970Scy/* Taken from Sun documentation: */
308275970Scy
309275970Scy/* FIXME:  It's worse than we expect.  This struct contains TWO substructs
310275970Scy  neither of whose size we know, WITH STUFF IN BETWEEN THEM!  We can't
311275970Scy  even portably access the stuff in between!  */
312275970Scy
313275970Scystruct external_sparc_core
314275970Scy  {
315275970Scy    int c_magic;		/* Corefile magic number */
316275970Scy    int c_len;			/* Sizeof (struct core) */
317275970Scy#define	SPARC_CORE_LEN	432
318275970Scy    int c_regs[19];		/* General purpose registers -- MACHDEP SIZE */
319275970Scy    struct external_exec c_aouthdr;	/* A.out header */
320275970Scy    int c_signo;		/* Killing signal, if any */
321275970Scy    int c_tsize;		/* Text size (bytes) */
322275970Scy    int c_dsize;		/* Data size (bytes) */
323275970Scy    int c_ssize;		/* Stack size (bytes) */
324275970Scy    char c_cmdname[CORE_NAMELEN + 1];	/* Command name */
325275970Scy    double fp_stuff[1];		/* external FPU state (size unknown by us) */
326275970Scy    /* The type "double" is critical here, for alignment.
327275970Scy    SunOS declares a struct here, but the struct's alignment
328275970Scy      is double since it contains doubles.  */
329275970Scy    int c_ucode;		/* Exception no. from u_code */
330275970Scy    /* (this member is not accessible by name since we don't
331275970Scy    portably know the size of fp_stuff.) */
332275970Scy  };
333275970Scy
334275970Scy/* Core files generated by the BCP (the part of Solaris which allows
335275970Scy   it to run SunOS4 a.out files).  */
336275970Scystruct external_solaris_bcp_core
337275970Scy  {
338275970Scy    int c_magic;		/* Corefile magic number */
339275970Scy    int c_len;			/* Sizeof (struct core) */
340275970Scy#define	SOLARIS_BCP_CORE_LEN	456
341275970Scy    int c_regs[19];		/* General purpose registers -- MACHDEP SIZE */
342275970Scy    int c_exdata_vp;		/* exdata structure */
343275970Scy    int c_exdata_tsize;
344275970Scy    int c_exdata_dsize;
345275970Scy    int c_exdata_bsize;
346275970Scy    int c_exdata_lsize;
347275970Scy    int c_exdata_nshlibs;
348275970Scy    short c_exdata_mach;
349275970Scy    short c_exdata_mag;
350275970Scy    int c_exdata_toffset;
351275970Scy    int c_exdata_doffset;
352275970Scy    int c_exdata_loffset;
353275970Scy    int c_exdata_txtorg;
354275970Scy    int c_exdata_datorg;
355275970Scy    int c_exdata_entloc;
356275970Scy    int c_signo;		/* Killing signal, if any */
357275970Scy    int c_tsize;		/* Text size (bytes) */
358275970Scy    int c_dsize;		/* Data size (bytes) */
359275970Scy    int c_ssize;		/* Stack size (bytes) */
360275970Scy    char c_cmdname[CORE_NAMELEN + 1];	/* Command name */
361275970Scy    double fp_stuff[1];		/* external FPU state (size unknown by us) */
362275970Scy    /* The type "double" is critical here, for alignment.
363275970Scy    SunOS declares a struct here, but the struct's alignment
364275970Scy      is double since it contains doubles.  */
365275970Scy    int c_ucode;		/* Exception no. from u_code */
366275970Scy    /* (this member is not accessible by name since we don't
367275970Scy    portably know the size of fp_stuff.) */
368275970Scy  };
369275970Scy
370275970Scystruct external_sun3_core
371275970Scy  {
372275970Scy    int c_magic;		/* Corefile magic number */
373275970Scy    int c_len;			/* Sizeof (struct core) */
374275970Scy#define	SUN3_CORE_LEN	826	/* As of SunOS 4.1.1 */
375275970Scy    int c_regs[18];		/* General purpose registers -- MACHDEP SIZE */
376275970Scy    struct external_exec c_aouthdr;	/* A.out header */
377275970Scy    int c_signo;		/* Killing signal, if any */
378275970Scy    int c_tsize;		/* Text size (bytes) */
379275970Scy    int c_dsize;		/* Data size (bytes) */
380275970Scy    int c_ssize;		/* Stack size (bytes) */
381275970Scy    char c_cmdname[CORE_NAMELEN + 1];	/* Command name */
382275970Scy    double fp_stuff[1];		/* external FPU state (size unknown by us) */
383275970Scy    /* The type "double" is critical here, for alignment.
384275970Scy    SunOS declares a struct here, but the struct's alignment
385275970Scy      is double since it contains doubles.  */
386275970Scy    int c_ucode;		/* Exception no. from u_code */
387275970Scy    /* (this member is not accessible by name since we don't
388275970Scy    portably know the size of fp_stuff.) */
389275970Scy  };
390275970Scy
391275970Scystruct internal_sunos_core
392275970Scy  {
393275970Scy    int c_magic;		/* Corefile magic number */
394275970Scy    int c_len;			/* Sizeof (struct core) */
395275970Scy    long c_regs_pos;		/* file offset of General purpose registers */
396275970Scy    int c_regs_size;		/* size of General purpose registers */
397275970Scy    struct internal_exec c_aouthdr;	/* A.out header */
398275970Scy    int c_signo;		/* Killing signal, if any */
399275970Scy    int c_tsize;		/* Text size (bytes) */
400275970Scy    int c_dsize;		/* Data size (bytes) */
401275970Scy    bfd_vma c_data_addr;	/* Data start (address) */
402275970Scy    int c_ssize;		/* Stack size (bytes) */
403275970Scy    bfd_vma c_stacktop;		/* Stack top (address) */
404275970Scy    char c_cmdname[CORE_NAMELEN + 1];	/* Command name */
405275970Scy    long fp_stuff_pos;		/* file offset of external FPU state (regs) */
406275970Scy    int fp_stuff_size;		/* Size of it */
407275970Scy    int c_ucode;		/* Exception no. from u_code */
408275970Scy  };
409275970Scy
410275970Scystatic void swapcore_sun3
411275970Scy  PARAMS ((bfd *, char *, struct internal_sunos_core *));
412275970Scystatic void swapcore_sparc
413275970Scy  PARAMS ((bfd *, char *, struct internal_sunos_core *));
414275970Scystatic void swapcore_solaris_bcp
415275970Scy  PARAMS ((bfd *, char *, struct internal_sunos_core *));
416275970Scy
417275970Scy/* byte-swap in the Sun-3 core structure */
418275970Scystatic void
419275970Scyswapcore_sun3 (abfd, ext, intcore)
420275970Scy     bfd *abfd;
421275970Scy     char *ext;
422275970Scy     struct internal_sunos_core *intcore;
423275970Scy{
424275970Scy  struct external_sun3_core *extcore = (struct external_sun3_core *) ext;
425275970Scy
426275970Scy  intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic);
427275970Scy  intcore->c_len = H_GET_32 (abfd, &extcore->c_len);
428275970Scy  intcore->c_regs_pos = (long) (((struct external_sun3_core *) 0)->c_regs);
429275970Scy  intcore->c_regs_size = sizeof (extcore->c_regs);
430275970Scy#if ARCH_SIZE == 64
431275970Scy  aout_64_swap_exec_header_in
432275970Scy#else
433275970Scy  aout_32_swap_exec_header_in
434275970Scy#endif
435275970Scy    (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr);
436275970Scy  intcore->c_signo = H_GET_32 (abfd, &extcore->c_signo);
437275970Scy  intcore->c_tsize = H_GET_32 (abfd, &extcore->c_tsize);
438275970Scy  intcore->c_dsize = H_GET_32 (abfd, &extcore->c_dsize);
439275970Scy  intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr);
440275970Scy  intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize);
441275970Scy  memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname));
442275970Scy  intcore->fp_stuff_pos = (long) (((struct external_sun3_core *) 0)->fp_stuff);
443275970Scy  /* FP stuff takes up whole rest of struct, except c_ucode.  */
444275970Scy  intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
445275970Scy    (file_ptr) (((struct external_sun3_core *) 0)->fp_stuff);
446275970Scy  /* Ucode is the last thing in the struct -- just before the end */
447275970Scy  intcore->c_ucode = H_GET_32 (abfd,
448275970Scy			       (intcore->c_len
449275970Scy				- sizeof (extcore->c_ucode)
450275970Scy				+ (unsigned char *) extcore));
451275970Scy  intcore->c_stacktop = 0x0E000000;	/* By experimentation */
452275970Scy}
453275970Scy
454275970Scy/* byte-swap in the Sparc core structure */
455275970Scystatic void
456275970Scyswapcore_sparc (abfd, ext, intcore)
457285612Sdelphij     bfd *abfd;
458285612Sdelphij     char *ext;
459275970Scy     struct internal_sunos_core *intcore;
460275970Scy{
461275970Scy  struct external_sparc_core *extcore = (struct external_sparc_core *) ext;
462275970Scy
463275970Scy  intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic);
464275970Scy  intcore->c_len = H_GET_32 (abfd, &extcore->c_len);
465275970Scy  intcore->c_regs_pos = (long) (((struct external_sparc_core *) 0)->c_regs);
466275970Scy  intcore->c_regs_size = sizeof (extcore->c_regs);
467#if ARCH_SIZE == 64
468  aout_64_swap_exec_header_in
469#else
470  aout_32_swap_exec_header_in
471#endif
472    (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr);
473  intcore->c_signo = H_GET_32 (abfd, &extcore->c_signo);
474  intcore->c_tsize = H_GET_32 (abfd, &extcore->c_tsize);
475  intcore->c_dsize = H_GET_32 (abfd, &extcore->c_dsize);
476  intcore->c_data_addr = N_DATADDR (intcore->c_aouthdr);
477  intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize);
478  memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname));
479  intcore->fp_stuff_pos = (long) (((struct external_sparc_core *) 0)->fp_stuff);
480  /* FP stuff takes up whole rest of struct, except c_ucode.  */
481  intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
482    (file_ptr) (((struct external_sparc_core *) 0)->fp_stuff);
483  /* Ucode is the last thing in the struct -- just before the end */
484  intcore->c_ucode = H_GET_32 (abfd,
485			       (intcore->c_len
486				- sizeof (extcore->c_ucode)
487				+ (unsigned char *) extcore));
488
489  /* Supposedly the user stack grows downward from the bottom of kernel memory.
490     Presuming that this remains true, this definition will work.  */
491  /* Now sun has provided us with another challenge.  The value is different
492     for sparc2 and sparc10 (both running SunOS 4.1.3).  We pick one or
493     the other based on the current value of the stack pointer.  This
494     loses (a) if the stack pointer has been clobbered, or (b) if the stack
495     is larger than 128 megabytes.
496
497     It's times like these you're glad they're switching to ELF.
498
499     Note that using include files or nlist on /vmunix would be wrong,
500     because we want the value for this core file, no matter what kind of
501     machine we were compiled on or are running on.  */
502#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000)
503#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000)
504  {
505    bfd_vma sp = H_GET_32 (abfd, &((struct regs *) &extcore->c_regs[0])->r_o6);
506    if (sp < SPARC_USRSTACK_SPARC10)
507      intcore->c_stacktop = SPARC_USRSTACK_SPARC10;
508    else
509      intcore->c_stacktop = SPARC_USRSTACK_SPARC2;
510  }
511}
512
513/* byte-swap in the Solaris BCP core structure */
514static void
515swapcore_solaris_bcp (abfd, ext, intcore)
516     bfd *abfd;
517     char *ext;
518     struct internal_sunos_core *intcore;
519{
520  struct external_solaris_bcp_core *extcore =
521    (struct external_solaris_bcp_core *) ext;
522
523  intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic);
524  intcore->c_len = H_GET_32 (abfd, &extcore->c_len);
525  intcore->c_regs_pos = (long) (((struct external_solaris_bcp_core *) 0)->c_regs);
526  intcore->c_regs_size = sizeof (extcore->c_regs);
527
528  /* The Solaris BCP exdata structure does not contain an a_syms field,
529     so we are unable to synthesize an internal exec header.
530     Luckily we are able to figure out the start address of the data section,
531     which is the only thing needed from the internal exec header,
532     from the exdata structure.
533
534     As of Solaris 2.3, BCP core files for statically linked executables
535     are buggy. The exdata structure is not properly filled in, and
536     the data section is written from address zero instead of the data
537     start address.  */
538  memset ((PTR) &intcore->c_aouthdr, 0, sizeof (struct internal_exec));
539  intcore->c_data_addr = H_GET_32 (abfd, &extcore->c_exdata_datorg);
540  intcore->c_signo = H_GET_32 (abfd, &extcore->c_signo);
541  intcore->c_tsize = H_GET_32 (abfd, &extcore->c_tsize);
542  intcore->c_dsize = H_GET_32 (abfd, &extcore->c_dsize);
543  intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize);
544  memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname));
545  intcore->fp_stuff_pos =
546    (long) (((struct external_solaris_bcp_core *) 0)->fp_stuff);
547  /* FP stuff takes up whole rest of struct, except c_ucode.  */
548  intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
549    (file_ptr) (((struct external_solaris_bcp_core *) 0)->fp_stuff);
550  /* Ucode is the last thing in the struct -- just before the end */
551  intcore->c_ucode = H_GET_32 (abfd,
552			       (intcore->c_len
553				- sizeof (extcore->c_ucode)
554				+ (unsigned char *) extcore));
555
556  /* Supposedly the user stack grows downward from the bottom of kernel memory.
557     Presuming that this remains true, this definition will work.  */
558  /* Now sun has provided us with another challenge.  The value is different
559     for sparc2 and sparc10 (both running SunOS 4.1.3).  We pick one or
560     the other based on the current value of the stack pointer.  This
561     loses (a) if the stack pointer has been clobbered, or (b) if the stack
562     is larger than 128 megabytes.
563
564     It's times like these you're glad they're switching to ELF.
565
566     Note that using include files or nlist on /vmunix would be wrong,
567     because we want the value for this core file, no matter what kind of
568     machine we were compiled on or are running on.  */
569#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000)
570#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000)
571  {
572    bfd_vma sp = H_GET_32 (abfd, &((struct regs *) &extcore->c_regs[0])->r_o6);
573    if (sp < SPARC_USRSTACK_SPARC10)
574      intcore->c_stacktop = SPARC_USRSTACK_SPARC10;
575    else
576      intcore->c_stacktop = SPARC_USRSTACK_SPARC2;
577  }
578}
579
580/* need this cast because ptr is really void * */
581#define core_hdr(bfd) ((bfd)->tdata.sun_core_data)
582#define core_datasec(bfd) (core_hdr(bfd)->data_section)
583#define core_stacksec(bfd) (core_hdr(bfd)->stack_section)
584#define core_regsec(bfd) (core_hdr(bfd)->reg_section)
585#define core_reg2sec(bfd) (core_hdr(bfd)->reg2_section)
586
587/* These are stored in the bfd's tdata */
588struct sun_core_struct
589{
590  struct internal_sunos_core *hdr;	/* core file header */
591  asection *data_section;
592  asection *stack_section;
593  asection *reg_section;
594  asection *reg2_section;
595};
596
597static const bfd_target *
598sunos4_core_file_p (abfd)
599     bfd *abfd;
600{
601  unsigned char longbuf[4];	/* Raw bytes of various header fields */
602  bfd_size_type core_size, amt;
603  unsigned long core_mag;
604  struct internal_sunos_core *core;
605  char *extcore;
606  struct mergem
607    {
608      struct sun_core_struct suncoredata;
609      struct internal_sunos_core internal_sunos_core;
610      char external_core[1];
611    } *mergem;
612
613  if (bfd_bread ((PTR) longbuf, (bfd_size_type) sizeof (longbuf), abfd)
614      != sizeof (longbuf))
615    return 0;
616  core_mag = H_GET_32 (abfd, longbuf);
617
618  if (core_mag != CORE_MAGIC)
619    return 0;
620
621  /* SunOS core headers can vary in length; second word is size; */
622  if (bfd_bread ((PTR) longbuf, (bfd_size_type) sizeof (longbuf), abfd)
623      != sizeof (longbuf))
624    return 0;
625  core_size = H_GET_32 (abfd, longbuf);
626  /* Sanity check */
627  if (core_size > 20000)
628    return 0;
629
630  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
631    return 0;
632
633  amt = core_size + sizeof (struct mergem);
634  mergem = (struct mergem *) bfd_zalloc (abfd, amt);
635  if (mergem == NULL)
636    return 0;
637
638  extcore = mergem->external_core;
639
640  if ((bfd_bread ((PTR) extcore, core_size, abfd)) != core_size)
641    {
642    loser:
643      bfd_release (abfd, (char *) mergem);
644      abfd->tdata.any = NULL;
645      bfd_section_list_clear (abfd);
646      return 0;
647    }
648
649  /* Validate that it's a core file we know how to handle, due to sun
650     botching the positioning of registers and other fields in a machine
651     dependent way.  */
652  core = &mergem->internal_sunos_core;
653  switch (core_size)
654    {
655    case SPARC_CORE_LEN:
656      swapcore_sparc (abfd, extcore, core);
657      break;
658    case SUN3_CORE_LEN:
659      swapcore_sun3 (abfd, extcore, core);
660      break;
661    case SOLARIS_BCP_CORE_LEN:
662      swapcore_solaris_bcp (abfd, extcore, core);
663      break;
664    default:
665      bfd_set_error (bfd_error_system_call);	/* FIXME */
666      goto loser;
667    }
668
669  abfd->tdata.sun_core_data = &mergem->suncoredata;
670  abfd->tdata.sun_core_data->hdr = core;
671
672  /* Create the sections.  */
673  core_stacksec (abfd) = bfd_make_section_anyway (abfd, ".stack");
674  if (core_stacksec (abfd) == NULL)
675    /* bfd_release frees everything allocated after it's arg.  */
676    goto loser;
677
678  core_datasec (abfd) = bfd_make_section_anyway (abfd, ".data");
679  if (core_datasec (abfd) == NULL)
680    goto loser;
681
682  core_regsec (abfd) = bfd_make_section_anyway (abfd, ".reg");
683  if (core_regsec (abfd) == NULL)
684    goto loser;
685
686  core_reg2sec (abfd) = bfd_make_section_anyway (abfd, ".reg2");
687  if (core_reg2sec (abfd) == NULL)
688    goto loser;
689
690  core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
691  core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
692  core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
693  core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS;
694
695  core_stacksec (abfd)->_raw_size = core->c_ssize;
696  core_datasec (abfd)->_raw_size = core->c_dsize;
697  core_regsec (abfd)->_raw_size = core->c_regs_size;
698  core_reg2sec (abfd)->_raw_size = core->fp_stuff_size;
699
700  core_stacksec (abfd)->vma = (core->c_stacktop - core->c_ssize);
701  core_datasec (abfd)->vma = core->c_data_addr;
702  core_regsec (abfd)->vma = 0;
703  core_reg2sec (abfd)->vma = 0;
704
705  core_stacksec (abfd)->filepos = core->c_len + core->c_dsize;
706  core_datasec (abfd)->filepos = core->c_len;
707  /* We'll access the regs afresh in the core file, like any section: */
708  core_regsec (abfd)->filepos = (file_ptr) core->c_regs_pos;
709  core_reg2sec (abfd)->filepos = (file_ptr) core->fp_stuff_pos;
710
711  /* Align to word at least */
712  core_stacksec (abfd)->alignment_power = 2;
713  core_datasec (abfd)->alignment_power = 2;
714  core_regsec (abfd)->alignment_power = 2;
715  core_reg2sec (abfd)->alignment_power = 2;
716
717  return abfd->xvec;
718}
719
720static char *
721sunos4_core_file_failing_command (abfd)
722     bfd *abfd;
723{
724  return core_hdr (abfd)->hdr->c_cmdname;
725}
726
727static int
728sunos4_core_file_failing_signal (abfd)
729     bfd *abfd;
730{
731  return core_hdr (abfd)->hdr->c_signo;
732}
733
734static boolean
735sunos4_core_file_matches_executable_p (core_bfd, exec_bfd)
736     bfd *core_bfd;
737     bfd *exec_bfd;
738{
739  if (core_bfd->xvec != exec_bfd->xvec)
740    {
741      bfd_set_error (bfd_error_system_call);
742      return false;
743    }
744
745  /* Solaris core files do not include an aouthdr.  */
746  if ((core_hdr (core_bfd)->hdr)->c_len == SOLARIS_BCP_CORE_LEN)
747    return true;
748
749  return (memcmp ((char *) &((core_hdr (core_bfd)->hdr)->c_aouthdr),
750		  (char *) exec_hdr (exec_bfd),
751		  sizeof (struct internal_exec)) == 0);
752}
753
754#define MY_set_sizes sunos4_set_sizes
755static boolean
756sunos4_set_sizes (abfd)
757     bfd *abfd;
758{
759  switch (bfd_get_arch (abfd))
760    {
761    default:
762      return false;
763    case bfd_arch_sparc:
764      adata (abfd).page_size = 0x2000;
765      adata (abfd).segment_size = 0x2000;
766      adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
767      return true;
768    case bfd_arch_m68k:
769      adata (abfd).page_size = 0x2000;
770      adata (abfd).segment_size = 0x20000;
771      adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
772      return true;
773    }
774}
775
776/* We default to setting the toolversion field to 1, as is required by
777   SunOS.  */
778#ifndef MY_exec_hdr_flags
779#define MY_exec_hdr_flags 1
780#endif
781
782#ifndef MY_entry_is_text_address
783#define MY_entry_is_text_address 0
784#endif
785#ifndef MY_add_dynamic_symbols
786#define MY_add_dynamic_symbols 0
787#endif
788#ifndef MY_add_one_symbol
789#define MY_add_one_symbol 0
790#endif
791#ifndef MY_link_dynamic_object
792#define MY_link_dynamic_object 0
793#endif
794#ifndef MY_write_dynamic_symbol
795#define MY_write_dynamic_symbol 0
796#endif
797#ifndef MY_check_dynamic_reloc
798#define MY_check_dynamic_reloc 0
799#endif
800#ifndef MY_finish_dynamic_link
801#define MY_finish_dynamic_link 0
802#endif
803
804static const struct aout_backend_data sunos4_aout_backend =
805{
806  0,				/* zmagic files are not contiguous */
807  1,				/* text includes header */
808  MY_entry_is_text_address,
809  MY_exec_hdr_flags,
810  0,				/* default text vma */
811  sunos4_set_sizes,
812  0,				/* header is counted in zmagic text */
813  MY_add_dynamic_symbols,
814  MY_add_one_symbol,
815  MY_link_dynamic_object,
816  MY_write_dynamic_symbol,
817  MY_check_dynamic_reloc,
818  MY_finish_dynamic_link
819};
820
821#define	MY_core_file_failing_command 	sunos4_core_file_failing_command
822#define	MY_core_file_failing_signal	sunos4_core_file_failing_signal
823#define	MY_core_file_matches_executable_p sunos4_core_file_matches_executable_p
824
825#define MY_bfd_debug_info_start		bfd_void
826#define MY_bfd_debug_info_end		bfd_void
827#define MY_bfd_debug_info_accumulate	\
828			(void (*) PARAMS ((bfd *, struct sec *))) bfd_void
829#define MY_core_file_p			sunos4_core_file_p
830#define MY_write_object_contents	NAME(aout,sunos4_write_object_contents)
831#define MY_backend_data			&sunos4_aout_backend
832
833#ifndef TARGET_IS_LITTLE_ENDIAN_P
834#define TARGET_IS_BIG_ENDIAN_P
835#endif
836
837#include "aout-target.h"
838