1163953Srrs/* A.out "format 1" file handling code for BFD.
2185694Srrs   Copyright (C) 1990-2017 Free Software Foundation, Inc.
3218319Srrs   Written by Cygnus Support.
4218319Srrs
5163953Srrs   This file is part of BFD, the Binary File Descriptor library.
6163953Srrs
7163953Srrs   This program is free software; you can redistribute it and/or modify
8163953Srrs   it under the terms of the GNU General Public License as published by
9163953Srrs   the Free Software Foundation; either version 3 of the License, or
10231038Stuexen   (at your option) any later version.
11163953Srrs
12163953Srrs   This program is distributed in the hope that it will be useful,
13163953Srrs   but WITHOUT ANY WARRANTY; without even the implied warranty of
14231038Stuexen   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15163953Srrs   GNU General Public License for more details.
16163953Srrs
17163953Srrs   You should have received a copy of the GNU General Public License
18163953Srrs   along with this program; if not, write to the Free Software
19163953Srrs   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20163953Srrs   MA 02110-1301, USA.  */
21163953Srrs
22163953Srrs#include "sysdep.h"
23163953Srrs#include "bfd.h"
24163953Srrs#include "libbfd.h"
25163953Srrs
26163953Srrs#include "aout/sun4.h"
27163953Srrs#include "libaout.h"		/* BFD a.out internal data structures.  */
28163953Srrs
29163953Srrs#include "aout/aout64.h"
30163953Srrs#include "aout/stab_gnu.h"
31163953Srrs#include "aout/ar.h"
32163953Srrs
33163953Srrs/* This is needed to reject a NewsOS file, e.g. in
34163953Srrs   gdb/testsuite/gdb.t10/crossload.exp. <kingdon@cygnus.com>
35163953Srrs   I needed to add M_UNKNOWN to recognize a 68000 object, so this will
36163953Srrs   probably no longer reject a NewsOS object.  <ian@cygnus.com>.  */
37163953Srrs#ifndef MACHTYPE_OK
38163953Srrs#define MACHTYPE_OK(mtype) \
39163953Srrs  (((mtype) == M_SPARC && bfd_lookup_arch (bfd_arch_sparc, 0) != NULL) \
40163953Srrs   || (((mtype) == M_UNKNOWN || (mtype) == M_68010 || (mtype) == M_68020) \
41163953Srrs       && bfd_lookup_arch (bfd_arch_m68k, 0) != NULL))
42179783Srrs#endif
43179783Srrs
44179783Srrs/* The file @code{aoutf1.h} contains the code for BFD's
45163953Srrs   a.out back end.  Control over the generated back end is given by these
46163953Srrs   two preprocessor names:
47163953Srrs   @table @code
48163953Srrs   @item ARCH_SIZE
49163953Srrs   This value should be either 32 or 64, depending upon the size of an
50163953Srrs   int in the target format. It changes the sizes of the structs which
51163953Srrs   perform the memory/disk mapping of structures.
52163953Srrs
53163953Srrs   The 64 bit backend may only be used if the host compiler supports 64
54179783Srrs   ints (eg long long with gcc), by defining the name @code{BFD_HOST_64_BIT} in @code{bfd.h}.
55163953Srrs   With this name defined, @emph{all} bfd operations are performed with 64bit
56163953Srrs   arithmetic, not just those to a 64bit target.
57163953Srrs
58163953Srrs   @item TARGETNAME
59179783Srrs   The name put into the target vector.
60179783Srrs   @item
61179783Srrs   @end table.  */
62179783Srrs
63179783Srrs#if ARCH_SIZE == 64
64179783Srrs#define sunos_set_arch_mach sunos_64_set_arch_mach
65163953Srrs#define sunos_write_object_contents aout_64_sunos4_write_object_contents
66163953Srrs#else
67163953Srrs#define sunos_set_arch_mach sunos_32_set_arch_mach
68163953Srrs#define sunos_write_object_contents aout_32_sunos4_write_object_contents
69179783Srrs#endif
70179783Srrs
71179783Srrs/* Merge backend data into the output file.
72179783Srrs   This is necessary on sparclet-aout where we want the resultant machine
73163953Srrs   number to be M_SPARCLET if any input file is M_SPARCLET.  */
74163953Srrs
75163953Srrs#define MY_bfd_merge_private_bfd_data sunos_merge_private_bfd_data
76163953Srrs
77163953Srrsstatic bfd_boolean
78163953Srrssunos_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
79163953Srrs{
80163953Srrs  bfd *obfd = info->output_bfd;
81163953Srrs  if (bfd_get_flavour (ibfd) != bfd_target_aout_flavour
82163953Srrs      || bfd_get_flavour (obfd) != bfd_target_aout_flavour)
83163953Srrs    return TRUE;
84163953Srrs
85163953Srrs  if (bfd_get_arch (obfd) == bfd_arch_sparc)
86163953Srrs    {
87163953Srrs      if (bfd_get_mach (obfd) < bfd_get_mach (ibfd))
88163953Srrs	bfd_set_arch_mach (obfd, bfd_arch_sparc, bfd_get_mach (ibfd));
89163953Srrs    }
90163953Srrs
91163953Srrs  return TRUE;
92163953Srrs}
93163953Srrs
94223132Stuexen/* This is either sunos_32_set_arch_mach or sunos_64_set_arch_mach,
95163953Srrs   depending upon ARCH_SIZE.  */
96163953Srrs
97163953Srrsstatic void
98170056Srrssunos_set_arch_mach (bfd *abfd, enum machine_type machtype)
99163953Srrs{
100163953Srrs  /* Determine the architecture and machine type of the object file.  */
101163953Srrs  enum bfd_architecture arch;
102163953Srrs  unsigned long machine;
103163953Srrs
104163953Srrs  switch (machtype)
105163953Srrs    {
106163953Srrs    case M_UNKNOWN:
107163953Srrs      /* Some Sun3s make magic numbers without cpu types in them, so
108163953Srrs	 we'll default to the 68000.  */
109163953Srrs      arch = bfd_arch_m68k;
110170056Srrs      machine = bfd_mach_m68000;
111163953Srrs      break;
112163953Srrs
113215034Sbrucec    case M_68010:
114163953Srrs    case M_HP200:
115181054Srrs      arch = bfd_arch_m68k;
116185694Srrs      machine = bfd_mach_m68010;
117223132Stuexen      break;
118223132Stuexen
119223132Stuexen    case M_68020:
120223132Stuexen    case M_HP300:
121223162Stuexen      arch = bfd_arch_m68k;
122224641Stuexen      machine = bfd_mach_m68020;
123163953Srrs      break;
124163953Srrs
125163953Srrs    case M_SPARC:
126163953Srrs      arch = bfd_arch_sparc;
127163953Srrs      machine = 0;
128163953Srrs      break;
129163953Srrs
130163953Srrs    case M_SPARCLET:
131163953Srrs      arch = bfd_arch_sparc;
132169655Srrs      machine = bfd_mach_sparc_sparclet;
133169655Srrs      break;
134215410Stuexen
135163953Srrs    case M_SPARCLITE_LE:
136163953Srrs      arch = bfd_arch_sparc;
137163953Srrs      machine = bfd_mach_sparc_sparclite_le;
138163953Srrs      break;
139163953Srrs
140163953Srrs    case M_386:
141163953Srrs    case M_386_DYNIX:
142163953Srrs      arch = bfd_arch_i386;
143215034Sbrucec      machine = 0;
144163953Srrs      break;
145215034Sbrucec
146163953Srrs    case M_HPUX:
147163953Srrs      arch = bfd_arch_m68k;
148163953Srrs      machine = 0;
149163953Srrs      break;
150163953Srrs
151163953Srrs    default:
152163953Srrs      arch = bfd_arch_obscure;
153215034Sbrucec      machine = 0;
154163953Srrs      break;
155163953Srrs    }
156163953Srrs  bfd_set_arch_mach (abfd, arch, machine);
157163953Srrs}
158163953Srrs
159163953Srrs#define SET_ARCH_MACH(ABFD, EXECP) \
160163953Srrs  NAME(sunos,set_arch_mach) (ABFD, N_MACHTYPE (EXECP)); \
161163953Srrs  choose_reloc_size(ABFD);
162163953Srrs
163163953Srrs/* Determine the size of a relocation entry, based on the architecture.  */
164163953Srrs
165163953Srrsstatic void
166163953Srrschoose_reloc_size (bfd *abfd)
167171440Srrs{
168211944Stuexen  switch (bfd_get_arch (abfd))
169217760Stuexen    {
170219057Srrs    case bfd_arch_sparc:
171219057Srrs      obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
172219057Srrs      break;
173219057Srrs    default:
174163953Srrs      obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
175163953Srrs      break;
176163953Srrs    }
177169655Srrs}
178169655Srrs
179163953Srrs/* Write an object file in SunOS format.  Section contents have
180170091Srrs   already been written.  We write the file header, symbols, and
181167598Srrs   relocation.  The real name of this function is either
182215034Sbrucec   aout_64_sunos4_write_object_contents or
183167598Srrs   aout_32_sunos4_write_object_contents, depending upon ARCH_SIZE.  */
184167598Srrs
185163953Srrsstatic bfd_boolean
186167598Srrssunos_write_object_contents (bfd *abfd)
187167598Srrs{
188167598Srrs  struct external_exec exec_bytes;
189167598Srrs  struct internal_exec *execp = exec_hdr (abfd);
190167598Srrs
191167598Srrs  /* Magic number, maestro, please!  */
192167598Srrs  switch (bfd_get_arch (abfd))
193167598Srrs    {
194167598Srrs    case bfd_arch_m68k:
195167598Srrs      switch (bfd_get_mach (abfd))
196167598Srrs	{
197215034Sbrucec	case bfd_mach_m68000:
198167598Srrs	  N_SET_MACHTYPE (execp, M_UNKNOWN);
199167598Srrs	  break;
200167598Srrs	case bfd_mach_m68010:
201167598Srrs	  N_SET_MACHTYPE (execp, M_68010);
202167598Srrs	  break;
203167598Srrs	default:
204167598Srrs	case bfd_mach_m68020:
205167598Srrs	  N_SET_MACHTYPE (execp, M_68020);
206167598Srrs	  break;
207167598Srrs	}
208167598Srrs      break;
209167598Srrs    case bfd_arch_sparc:
210167598Srrs      switch (bfd_get_mach (abfd))
211167598Srrs	{
212167598Srrs	case bfd_mach_sparc_sparclet:
213167598Srrs	  N_SET_MACHTYPE (execp, M_SPARCLET);
214167598Srrs	  break;
215167598Srrs	case bfd_mach_sparc_sparclite_le:
216167598Srrs	  N_SET_MACHTYPE (execp, M_SPARCLITE_LE);
217167598Srrs	  break;
218167598Srrs	default:
219170091Srrs	  N_SET_MACHTYPE (execp, M_SPARC);
220163953Srrs	  break;
221170091Srrs	}
222170091Srrs      break;
223170091Srrs    case bfd_arch_i386:
224170091Srrs      N_SET_MACHTYPE (execp, M_386);
225170091Srrs      break;
226170094Srrs    default:
227170091Srrs      N_SET_MACHTYPE (execp, M_UNKNOWN);
228170091Srrs    }
229170091Srrs
230170091Srrs  choose_reloc_size (abfd);
231163953Srrs
232163953Srrs  N_SET_FLAGS (execp, aout_backend_info (abfd)->exec_hdr_flags);
233163953Srrs
234163953Srrs  N_SET_DYNAMIC (execp, (long)(bfd_get_file_flags (abfd) & DYNAMIC));
235163953Srrs
236163953Srrs  WRITE_HEADERS (abfd, execp);
237163953Srrs
238163953Srrs  return TRUE;
239163953Srrs}
240163953Srrs
241163953Srrs/* Core files.  */
242163953Srrs
243163953Srrs#define CORE_MAGIC   0x080456
244163953Srrs#define CORE_NAMELEN 16
245163953Srrs
246163953Srrs/* The core structure is taken from the Sun documentation.
247163953Srrs  Unfortunately, they don't document the FPA structure, or at least I
248163953Srrs  can't find it easily.  Fortunately the core header contains its own
249163953Srrs  length.  So this shouldn't cause problems, except for c_ucode, which
250163953Srrs  so far we don't use but is easy to find with a little arithmetic.  */
251163953Srrs
252163953Srrs/* But the reg structure can be gotten from the SPARC processor handbook.
253163953Srrs  This really should be in a GNU include file though so that gdb can use
254163953Srrs  the same info.  */
255163953Srrsstruct regs
256163953Srrs{
257163953Srrs  int r_psr;
258171440Srrs  int r_pc;
259171440Srrs  int r_npc;
260171440Srrs  int r_y;
261171440Srrs  int r_g1;
262171440Srrs  int r_g2;
263171440Srrs  int r_g3;
264171440Srrs  int r_g4;
265171440Srrs  int r_g5;
266171440Srrs  int r_g6;
267219120Srrs  int r_g7;
268219120Srrs  int r_o0;
269168943Srrs  int r_o1;
270219120Srrs  int r_o2;
271219120Srrs  int r_o3;
272219397Srrs  int r_o4;
273219120Srrs  int r_o5;
274221460Stuexen  int r_o6;
275221460Stuexen  int r_o7;
276221460Stuexen};
277221460Stuexen
278221460Stuexen/* Taken from Sun documentation: */
279221460Stuexen
280221460Stuexen/* FIXME:  It's worse than we expect.  This struct contains TWO substructs
281217760Stuexen  neither of whose size we know, WITH STUFF IN BETWEEN THEM!  We can't
282217760Stuexen  even portably access the stuff in between!  */
283217760Stuexen
284217760Stuexenstruct external_sparc_core
285217760Stuexen{
286217760Stuexen  int c_magic;				/* Corefile magic number.  */
287217760Stuexen  int c_len;				/* Sizeof (struct core).  */
288217760Stuexen#define	SPARC_CORE_LEN	432
289217760Stuexen  struct regs c_regs;			/* General purpose registers -- MACHDEP SIZE.  */
290217760Stuexen  struct external_exec c_aouthdr;	/* A.out header.  */
291217760Stuexen  int c_signo;				/* Killing signal, if any.  */
292217760Stuexen  int c_tsize;				/* Text size (bytes).  */
293217760Stuexen  int c_dsize;				/* Data size (bytes).  */
294217760Stuexen  int c_ssize;				/* Stack size (bytes).  */
295217760Stuexen  char c_cmdname[CORE_NAMELEN + 1];	/* Command name.  */
296171440Srrs  double fp_stuff[1];			/* External FPU state (size unknown by us).  */
297217760Stuexen  /* The type "double" is critical here, for alignment.
298168943Srrs     SunOS declares a struct here, but the struct's
299168943Srrs     alignment is double since it contains doubles.  */
300168943Srrs  int c_ucode;				/* Exception no. from u_code.  */
301168943Srrs  /* This member is not accessible by name since
302168943Srrs     we don't portably know the size of fp_stuff.  */
303168943Srrs};
304168943Srrs
305168943Srrs/* Core files generated by the BCP (the part of Solaris which allows
306163953Srrs   it to run SunOS4 a.out files).  */
307163953Srrsstruct external_solaris_bcp_core
308163953Srrs{
309163953Srrs  int c_magic;				/* Corefile magic number.  */
310163953Srrs  int c_len;				/* Sizeof (struct core).  */
311163953Srrs#define	SOLARIS_BCP_CORE_LEN	456
312163953Srrs  struct regs c_regs;			/* General purpose registers -- MACHDEP SIZE.  */
313163953Srrs  int c_exdata_vp;			/* Exdata structure.  */
314163953Srrs  int c_exdata_tsize;
315163953Srrs  int c_exdata_dsize;
316163953Srrs  int c_exdata_bsize;
317163953Srrs  int c_exdata_lsize;
318163953Srrs  int c_exdata_nshlibs;
319163953Srrs  short c_exdata_mach;
320163953Srrs  short c_exdata_mag;
321163953Srrs  int c_exdata_toffset;
322163953Srrs  int c_exdata_doffset;
323163953Srrs  int c_exdata_loffset;
324163953Srrs  int c_exdata_txtorg;
325163953Srrs  int c_exdata_datorg;
326163953Srrs  int c_exdata_entloc;
327163953Srrs  int c_signo;				/* Killing signal, if any.  */
328163953Srrs  int c_tsize;				/* Text size (bytes).  */
329163953Srrs  int c_dsize;				/* Data size (bytes).  */
330163953Srrs  int c_ssize;				/* Stack size (bytes).  */
331163953Srrs  char c_cmdname[CORE_NAMELEN + 1];	/* Command name.  */
332163953Srrs  double fp_stuff[1];			/* External FPU state (size unknown by us).  */
333163953Srrs  /* The type "double" is critical here, for alignment.
334163953Srrs     SunOS declares a struct here, but the struct's
335163953Srrs     alignment is double since it contains doubles.  */
336163953Srrs  int c_ucode;				/* Exception no. from u_code.  */
337163953Srrs  /* This member is not accessible by name since
338172190Srrs     we don't portably know the size of fp_stuff.  */
339185694Srrs};
340185694Srrs
341185694Srrsstruct external_sun3_core
342185694Srrs{
343185694Srrs  int c_magic;				/* Corefile magic number.  */
344163953Srrs  int c_len;				/* Sizeof (struct core).  */
345185694Srrs#define	SUN3_CORE_LEN	826		/* As of SunOS 4.1.1.  */
346185694Srrs  int c_regs[18];			/* General purpose registers -- MACHDEP SIZE.  */
347185694Srrs  struct external_exec c_aouthdr;	/* A.out header.  */
348185694Srrs  int c_signo;				/* Killing signal, if any.  */
349172190Srrs  int c_tsize;				/* Text size (bytes).  */
350163953Srrs  int c_dsize;				/* Data size (bytes).  */
351163953Srrs  int c_ssize;				/* Stack size (bytes).  */
352163953Srrs  char c_cmdname[CORE_NAMELEN + 1];	/* Command name.  */
353215034Sbrucec  double fp_stuff[1];			/* External FPU state (size unknown by us).  */
354163953Srrs  /* The type "double" is critical here, for alignment.
355179783Srrs     SunOS declares a struct here, but the struct's
356179783Srrs     alignment is double since it contains doubles.  */
357179783Srrs  int c_ucode;				/* Exception no. from u_code.  */
358179783Srrs  /* This member is not accessible by name since
359179783Srrs     we don't portably know the size of fp_stuff.  */
360163953Srrs};
361179783Srrs
362179783Srrsstruct internal_sunos_core
363179783Srrs{
364179783Srrs  int c_magic;				/* Corefile magic number.  */
365179783Srrs  int c_len;				/* Sizeof (struct core).  */
366163953Srrs  long c_regs_pos;			/* File offset of General purpose registers.  */
367179783Srrs  int c_regs_size;			/* Size of General purpose registers.  */
368179783Srrs  struct internal_exec c_aouthdr;	/* A.out header.  */
369179783Srrs  int c_signo;				/* Killing signal, if any.  */
370179783Srrs  int c_tsize;				/* Text size (bytes).  */
371179783Srrs  int c_dsize;				/* Data size (bytes).  */
372163953Srrs  bfd_vma c_data_addr;			/* Data start (address).  */
373179783Srrs  int c_ssize;				/* Stack size (bytes).  */
374179783Srrs  bfd_vma c_stacktop;			/* Stack top (address).  */
375179783Srrs  char c_cmdname[CORE_NAMELEN + 1];	/* Command name.  */
376179783Srrs  long fp_stuff_pos;			/* File offset of external FPU state (regs).  */
377163953Srrs  int fp_stuff_size;			/* Size of it.  */
378179783Srrs  int c_ucode;				/* Exception no. from u_code.  */
379179783Srrs};
380179783Srrs
381163953Srrs/* Byte-swap in the Sun-3 core structure.  */
382179783Srrs
383179783Srrsstatic void
384163953Srrsswapcore_sun3 (bfd *abfd, char *ext, struct internal_sunos_core *intcore)
385179783Srrs{
386163953Srrs  struct external_sun3_core *extcore = (struct external_sun3_core *) ext;
387179783Srrs
388179783Srrs  intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic);
389179783Srrs  intcore->c_len = H_GET_32 (abfd, &extcore->c_len);
390179783Srrs  intcore->c_regs_pos = offsetof (struct external_sun3_core, c_regs);
391163953Srrs  intcore->c_regs_size = sizeof (extcore->c_regs);
392163953Srrs#if ARCH_SIZE == 64
393163953Srrs  aout_64_swap_exec_header_in
394163953Srrs#else
395163953Srrs  aout_32_swap_exec_header_in
396163953Srrs#endif
397163953Srrs    (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr);
398163953Srrs  intcore->c_signo = H_GET_32 (abfd, &extcore->c_signo);
399163953Srrs  intcore->c_tsize = H_GET_32 (abfd, &extcore->c_tsize);
400163953Srrs  intcore->c_dsize = H_GET_32 (abfd, &extcore->c_dsize);
401163953Srrs  intcore->c_data_addr = N_DATADDR (&intcore->c_aouthdr);
402163953Srrs  intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize);
403163953Srrs  memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname));
404163953Srrs  intcore->fp_stuff_pos = offsetof (struct external_sun3_core, fp_stuff);
405163953Srrs  /* FP stuff takes up whole rest of struct, except c_ucode.  */
406163953Srrs  intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
407163953Srrs    offsetof (struct external_sun3_core, fp_stuff);
408163953Srrs  /* Ucode is the last thing in the struct -- just before the end.  */
409163953Srrs  intcore->c_ucode = H_GET_32 (abfd,
410163953Srrs			       (intcore->c_len
411163953Srrs				- sizeof (extcore->c_ucode)
412172190Srrs				+ (unsigned char *) extcore));
413163953Srrs  intcore->c_stacktop = 0x0E000000;	/* By experimentation.  */
414185694Srrs}
415185694Srrs
416163953Srrs/* Byte-swap in the Sparc core structure.  */
417163953Srrs
418172190Srrsstatic void
419163953Srrsswapcore_sparc (bfd *abfd, char *ext, struct internal_sunos_core *intcore)
420163953Srrs{
421163953Srrs  struct external_sparc_core *extcore = (struct external_sparc_core *) ext;
422163953Srrs
423163953Srrs  intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic);
424170642Srrs  intcore->c_len = H_GET_32 (abfd, &extcore->c_len);
425170642Srrs  intcore->c_regs_pos = offsetof (struct external_sparc_core, c_regs);
426170642Srrs  intcore->c_regs_size = sizeof (extcore->c_regs);
427163953Srrs#if ARCH_SIZE == 64
428163953Srrs  aout_64_swap_exec_header_in
429163953Srrs#else
430172190Srrs  aout_32_swap_exec_header_in
431163953Srrs#endif
432163953Srrs    (abfd, &extcore->c_aouthdr, &intcore->c_aouthdr);
433163953Srrs  intcore->c_signo = H_GET_32 (abfd, &extcore->c_signo);
434163953Srrs  intcore->c_tsize = H_GET_32 (abfd, &extcore->c_tsize);
435163953Srrs  intcore->c_dsize = H_GET_32 (abfd, &extcore->c_dsize);
436163953Srrs  intcore->c_data_addr = N_DATADDR (&intcore->c_aouthdr);
437163953Srrs  intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize);
438163953Srrs  memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname));
439163953Srrs  intcore->fp_stuff_pos = offsetof (struct external_sparc_core, fp_stuff);
440163953Srrs  /* FP stuff takes up whole rest of struct, except c_ucode.  */
441163953Srrs  intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
442218072Srrs    offsetof (struct external_sparc_core, fp_stuff);
443218072Srrs  /* Ucode is the last thing in the struct -- just before the end.  */
444218072Srrs  intcore->c_ucode = H_GET_32 (abfd,
445218072Srrs			       (intcore->c_len
446163953Srrs				- sizeof (extcore->c_ucode)
447163953Srrs				+ (unsigned char *) extcore));
448163953Srrs
449163953Srrs  /* Supposedly the user stack grows downward from the bottom of kernel memory.
450163953Srrs     Presuming that this remains true, this definition will work.  */
451163953Srrs  /* Now sun has provided us with another challenge.  The value is different
452179783Srrs     for sparc2 and sparc10 (both running SunOS 4.1.3).  We pick one or
453179783Srrs     the other based on the current value of the stack pointer.  This
454179783Srrs     loses (a) if the stack pointer has been clobbered, or (b) if the stack
455179783Srrs     is larger than 128 megabytes.
456179783Srrs
457179783Srrs     It's times like these you're glad they're switching to ELF.
458179783Srrs
459163953Srrs     Note that using include files or nlist on /vmunix would be wrong,
460179783Srrs     because we want the value for this core file, no matter what kind of
461163953Srrs     machine we were compiled on or are running on.  */
462163953Srrs#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000)
463179783Srrs#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000)
464163953Srrs  {
465168945Srrs    bfd_vma sp = H_GET_32 (abfd, &extcore->c_regs.r_o6);
466168945Srrs    if (sp < SPARC_USRSTACK_SPARC10)
467168945Srrs      intcore->c_stacktop = SPARC_USRSTACK_SPARC10;
468168945Srrs    else
469168945Srrs      intcore->c_stacktop = SPARC_USRSTACK_SPARC2;
470168945Srrs  }
471168945Srrs}
472168945Srrs
473168945Srrs/* Byte-swap in the Solaris BCP core structure.  */
474168945Srrs
475168945Srrsstatic void
476168945Srrsswapcore_solaris_bcp (bfd *abfd, char *ext, struct internal_sunos_core *intcore)
477168945Srrs{
478168945Srrs  struct external_solaris_bcp_core *extcore =
479168945Srrs    (struct external_solaris_bcp_core *) ext;
480168945Srrs
481168945Srrs  intcore->c_magic = H_GET_32 (abfd, &extcore->c_magic);
482168945Srrs  intcore->c_len = H_GET_32 (abfd, &extcore->c_len);
483168945Srrs  intcore->c_regs_pos = offsetof (struct external_solaris_bcp_core, c_regs);
484168945Srrs  intcore->c_regs_size = sizeof (extcore->c_regs);
485168945Srrs
486179141Srrs  /* The Solaris BCP exdata structure does not contain an a_syms field,
487179141Srrs     so we are unable to synthesize an internal exec header.
488179141Srrs     Luckily we are able to figure out the start address of the data section,
489209289Stuexen     which is the only thing needed from the internal exec header,
490168945Srrs     from the exdata structure.
491179141Srrs
492179141Srrs     As of Solaris 2.3, BCP core files for statically linked executables
493179141Srrs     are buggy. The exdata structure is not properly filled in, and
494168945Srrs     the data section is written from address zero instead of the data
495168945Srrs     start address.  */
496168945Srrs  memset ((void *) &intcore->c_aouthdr, 0, sizeof (struct internal_exec));
497168945Srrs  intcore->c_data_addr = H_GET_32 (abfd, &extcore->c_exdata_datorg);
498168945Srrs  intcore->c_signo = H_GET_32 (abfd, &extcore->c_signo);
499225635Stuexen  intcore->c_tsize = H_GET_32 (abfd, &extcore->c_tsize);
500223132Stuexen  intcore->c_dsize = H_GET_32 (abfd, &extcore->c_dsize);
501168945Srrs  intcore->c_ssize = H_GET_32 (abfd, &extcore->c_ssize);
502168945Srrs  memcpy (intcore->c_cmdname, extcore->c_cmdname, sizeof (intcore->c_cmdname));
503168945Srrs  intcore->fp_stuff_pos =
504168945Srrs    offsetof (struct external_solaris_bcp_core, fp_stuff);
505168945Srrs  /* FP stuff takes up whole rest of struct, except c_ucode.  */
506169352Srrs  intcore->fp_stuff_size = intcore->c_len - (sizeof extcore->c_ucode) -
507168945Srrs    offsetof (struct external_solaris_bcp_core, fp_stuff);
508168945Srrs  /* Ucode is the last thing in the struct -- just before the end */
509168945Srrs  intcore->c_ucode = H_GET_32 (abfd,
510223132Stuexen			       (intcore->c_len
511168945Srrs				- sizeof (extcore->c_ucode)
512168945Srrs				+ (unsigned char *) extcore));
513168945Srrs
514168945Srrs  /* Supposedly the user stack grows downward from the bottom of kernel memory.
515168945Srrs     Presuming that this remains true, this definition will work.  */
516168945Srrs  /* Now sun has provided us with another challenge.  The value is different
517168945Srrs     for sparc2 and sparc10 (both running SunOS 4.1.3).  We pick one or
518168945Srrs     the other based on the current value of the stack pointer.  This
519168945Srrs     loses (a) if the stack pointer has been clobbered, or (b) if the stack
520168945Srrs     is larger than 128 megabytes.
521168945Srrs
522179141Srrs     It's times like these you're glad they're switching to ELF.
523179157Srrs
524181054Srrs     Note that using include files or nlist on /vmunix would be wrong,
525185694Srrs     because we want the value for this core file, no matter what kind of
526223132Stuexen     machine we were compiled on or are running on.  */
527223132Stuexen#define SPARC_USRSTACK_SPARC2 ((bfd_vma)0xf8000000)
528223132Stuexen#define SPARC_USRSTACK_SPARC10 ((bfd_vma)0xf0000000)
529171990Srrs  {
530171990Srrs    bfd_vma sp = H_GET_32 (abfd, &extcore->c_regs.r_o6);
531171990Srrs    if (sp < SPARC_USRSTACK_SPARC10)
532171990Srrs      intcore->c_stacktop = SPARC_USRSTACK_SPARC10;
533171990Srrs    else
534171990Srrs      intcore->c_stacktop = SPARC_USRSTACK_SPARC2;
535171990Srrs  }
536171990Srrs}
537172091Srrs
538171990Srrs/* Need this cast because ptr is really void *.  */
539171990Srrs#define core_hdr(bfd)      ((bfd)->tdata.sun_core_data)
540170056Srrs#define core_datasec(bfd)  (core_hdr (bfd)->data_section)
541170056Srrs#define core_stacksec(bfd) (core_hdr (bfd)->stack_section)
542170056Srrs#define core_regsec(bfd)   (core_hdr (bfd)->reg_section)
543163953Srrs#define core_reg2sec(bfd)  (core_hdr (bfd)->reg2_section)
544163953Srrs
545170744Srrs/* These are stored in the bfd's tdata.  */
546170744Srrsstruct sun_core_struct
547170744Srrs{
548170744Srrs  struct internal_sunos_core *hdr;	/* Core file header.  */
549170744Srrs  asection *data_section;
550170091Srrs  asection *stack_section;
551170091Srrs  asection *reg_section;
552171477Srrs  asection *reg2_section;
553171477Srrs};
554171477Srrs
555171477Srrsstatic const bfd_target *
556171477Srrssunos4_core_file_p (bfd *abfd)
557171477Srrs{
558171477Srrs  unsigned char longbuf[4];	/* Raw bytes of various header fields.  */
559171477Srrs  bfd_size_type core_size, amt;
560170744Srrs  unsigned long core_mag;
561170744Srrs  struct internal_sunos_core *core;
562170744Srrs  char *extcore;
563170744Srrs  struct mergem
564170744Srrs    {
565170744Srrs      struct sun_core_struct suncoredata;
566170744Srrs      struct internal_sunos_core internal_sunos_core;
567170744Srrs      char external_core[1];
568170744Srrs    } *mergem;
569170744Srrs  flagword flags;
570170744Srrs
571170744Srrs  if (bfd_bread ((void *) longbuf, (bfd_size_type) sizeof (longbuf), abfd)
572170744Srrs      != sizeof (longbuf))
573170744Srrs    return NULL;
574170744Srrs  core_mag = H_GET_32 (abfd, longbuf);
575170744Srrs
576224641Stuexen  if (core_mag != CORE_MAGIC)
577170744Srrs    return NULL;
578170744Srrs
579224641Stuexen  /* SunOS core headers can vary in length; second word is size; */
580170744Srrs  if (bfd_bread ((void *) longbuf, (bfd_size_type) sizeof (longbuf), abfd)
581170744Srrs      != sizeof (longbuf))
582170744Srrs    return NULL;
583170744Srrs  core_size = H_GET_32 (abfd, longbuf);
584170744Srrs  /* Sanity check.  */
585224641Stuexen  if (core_size > 20000)
586224641Stuexen    return NULL;
587224641Stuexen
588224641Stuexen  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
589224641Stuexen    return NULL;
590224641Stuexen
591224641Stuexen  amt = core_size + sizeof (struct mergem);
592224641Stuexen  mergem = bfd_zalloc (abfd, amt);
593170091Srrs  if (mergem == NULL)
594171943Srrs    return NULL;
595179783Srrs
596179783Srrs  extcore = mergem->external_core;
597163953Srrs
598  if ((bfd_bread ((void *) extcore, core_size, abfd)) != core_size)
599    {
600    loser:
601      bfd_release (abfd, (char *) mergem);
602      abfd->tdata.any = NULL;
603      bfd_section_list_clear (abfd);
604      return NULL;
605    }
606
607  /* Validate that it's a core file we know how to handle, due to sun
608     botching the positioning of registers and other fields in a machine
609     dependent way.  */
610  core = &mergem->internal_sunos_core;
611  switch (core_size)
612    {
613    case SPARC_CORE_LEN:
614      swapcore_sparc (abfd, extcore, core);
615      break;
616    case SUN3_CORE_LEN:
617      swapcore_sun3 (abfd, extcore, core);
618      break;
619    case SOLARIS_BCP_CORE_LEN:
620      swapcore_solaris_bcp (abfd, extcore, core);
621      break;
622    default:
623      bfd_set_error (bfd_error_system_call);	/* FIXME.  */
624      goto loser;
625    }
626
627  abfd->tdata.sun_core_data = &mergem->suncoredata;
628  abfd->tdata.sun_core_data->hdr = core;
629
630  /* Create the sections.  */
631  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
632  core_stacksec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".stack",
633							     flags);
634  if (core_stacksec (abfd) == NULL)
635    /* bfd_release frees everything allocated after it's arg.  */
636    goto loser;
637
638  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
639  core_datasec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".data",
640							    flags);
641  if (core_datasec (abfd) == NULL)
642    goto loser;
643
644  flags = SEC_HAS_CONTENTS;
645  core_regsec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg",
646							   flags);
647  if (core_regsec (abfd) == NULL)
648    goto loser;
649
650  flags = SEC_HAS_CONTENTS;
651  core_reg2sec (abfd) = bfd_make_section_anyway_with_flags (abfd, ".reg2",
652							    flags);
653  if (core_reg2sec (abfd) == NULL)
654    goto loser;
655
656  core_stacksec (abfd)->size = core->c_ssize;
657  core_datasec (abfd)->size = core->c_dsize;
658  core_regsec (abfd)->size = core->c_regs_size;
659  core_reg2sec (abfd)->size = core->fp_stuff_size;
660
661  core_stacksec (abfd)->vma = (core->c_stacktop - core->c_ssize);
662  core_datasec (abfd)->vma = core->c_data_addr;
663  core_regsec (abfd)->vma = 0;
664  core_reg2sec (abfd)->vma = 0;
665
666  core_stacksec (abfd)->filepos = core->c_len + core->c_dsize;
667  core_datasec (abfd)->filepos = core->c_len;
668  /* We'll access the regs afresh in the core file, like any section:  */
669  core_regsec (abfd)->filepos = (file_ptr) core->c_regs_pos;
670  core_reg2sec (abfd)->filepos = (file_ptr) core->fp_stuff_pos;
671
672  /* Align to word at least.  */
673  core_stacksec (abfd)->alignment_power = 2;
674  core_datasec (abfd)->alignment_power = 2;
675  core_regsec (abfd)->alignment_power = 2;
676  core_reg2sec (abfd)->alignment_power = 2;
677
678  return abfd->xvec;
679}
680
681static char *
682sunos4_core_file_failing_command (bfd *abfd)
683{
684  return core_hdr (abfd)->hdr->c_cmdname;
685}
686
687static int
688sunos4_core_file_failing_signal (bfd *abfd)
689{
690  return core_hdr (abfd)->hdr->c_signo;
691}
692
693static bfd_boolean
694sunos4_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
695{
696  if (core_bfd->xvec != exec_bfd->xvec)
697    {
698      bfd_set_error (bfd_error_system_call);
699      return FALSE;
700    }
701
702  /* Solaris core files do not include an aouthdr.  */
703  if ((core_hdr (core_bfd)->hdr)->c_len == SOLARIS_BCP_CORE_LEN)
704    return TRUE;
705
706  return memcmp ((char *) &((core_hdr (core_bfd)->hdr)->c_aouthdr),
707		 (char *) exec_hdr (exec_bfd),
708		 sizeof (struct internal_exec)) == 0;
709}
710
711#define MY_set_sizes sunos4_set_sizes
712
713static bfd_boolean
714sunos4_set_sizes (bfd *abfd)
715{
716  switch (bfd_get_arch (abfd))
717    {
718    default:
719      return FALSE;
720    case bfd_arch_sparc:
721      adata (abfd).page_size = 0x2000;
722      adata (abfd).segment_size = 0x2000;
723      adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
724      return TRUE;
725    case bfd_arch_m68k:
726      adata (abfd).page_size = 0x2000;
727      adata (abfd).segment_size = 0x20000;
728      adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE;
729      return TRUE;
730    }
731}
732
733/* We default to setting the toolversion field to 1, as is required by
734   SunOS.  */
735#ifndef MY_exec_hdr_flags
736#define MY_exec_hdr_flags 1
737#endif
738
739#ifndef MY_entry_is_text_address
740#define MY_entry_is_text_address 0
741#endif
742#ifndef MY_add_dynamic_symbols
743#define MY_add_dynamic_symbols 0
744#endif
745#ifndef MY_add_one_symbol
746#define MY_add_one_symbol 0
747#endif
748#ifndef MY_link_dynamic_object
749#define MY_link_dynamic_object 0
750#endif
751#ifndef MY_write_dynamic_symbol
752#define MY_write_dynamic_symbol 0
753#endif
754#ifndef MY_check_dynamic_reloc
755#define MY_check_dynamic_reloc 0
756#endif
757#ifndef MY_finish_dynamic_link
758#define MY_finish_dynamic_link 0
759#endif
760
761static const struct aout_backend_data sunos4_aout_backend =
762{
763  0,				/* Zmagic files are not contiguous.  */
764  1,				/* Text includes header.  */
765  MY_entry_is_text_address,
766  MY_exec_hdr_flags,
767  0,				/* Default text vma.  */
768  sunos4_set_sizes,
769  0,				/* Header is counted in zmagic text.  */
770  MY_add_dynamic_symbols,
771  MY_add_one_symbol,
772  MY_link_dynamic_object,
773  MY_write_dynamic_symbol,
774  MY_check_dynamic_reloc,
775  MY_finish_dynamic_link
776};
777
778#define	MY_core_file_failing_command 	sunos4_core_file_failing_command
779#define	MY_core_file_failing_signal	sunos4_core_file_failing_signal
780#define	MY_core_file_matches_executable_p sunos4_core_file_matches_executable_p
781
782#define MY_bfd_debug_info_start		bfd_void
783#define MY_bfd_debug_info_end		bfd_void
784#define MY_bfd_debug_info_accumulate	(void (*) (bfd *, struct bfd_section *)) bfd_void
785#define MY_core_file_p			sunos4_core_file_p
786#define MY_write_object_contents	NAME(aout, sunos4_write_object_contents)
787#define MY_backend_data			& sunos4_aout_backend
788
789#ifndef TARGET_IS_LITTLE_ENDIAN_P
790#define TARGET_IS_BIG_ENDIAN_P
791#endif
792
793#include "aout-target.h"
794