1/* BFD semi-generic back-end for a.out binaries.
2   Copyright (C) 1990-2022 Free Software Foundation, Inc.
3   Written by Cygnus Support.
4
5   This file is part of BFD, the Binary File Descriptor library.
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20   MA 02110-1301, USA.  */
21
22/*
23SECTION
24	a.out backends
25
26DESCRIPTION
27
28	BFD supports a number of different flavours of a.out format,
29	though the major differences are only the sizes of the
30	structures on disk, and the shape of the relocation
31	information.
32
33	The support is split into a basic support file @file{aoutx.h}
34	and other files which derive functions from the base. One
35	derivation file is @file{aoutf1.h} (for a.out flavour 1), and
36	adds to the basic a.out functions support for sun3, sun4, and
37	386 a.out files, to create a target jump vector for a specific
38	target.
39
40	This information is further split out into more specific files
41	for each machine, including @file{sunos.c} for sun3 and sun4,
42	and @file{demo64.c} for a demonstration of a 64 bit a.out format.
43
44	The base file @file{aoutx.h} defines general mechanisms for
45	reading and writing records to and from disk and various
46	other methods which BFD requires. It is included by
47	@file{aout32.c} and @file{aout64.c} to form the names
48	<<aout_32_swap_exec_header_in>>, <<aout_64_swap_exec_header_in>>, etc.
49
50	As an example, this is what goes on to make the back end for a
51	sun4, from @file{aout32.c}:
52
53|	#define ARCH_SIZE 32
54|	#include "aoutx.h"
55
56	Which exports names:
57
58|	...
59|	aout_32_canonicalize_reloc
60|	aout_32_find_nearest_line
61|	aout_32_get_lineno
62|	aout_32_get_reloc_upper_bound
63|	...
64
65	from @file{sunos.c}:
66
67|	#define TARGET_NAME "a.out-sunos-big"
68|	#define VECNAME    sparc_aout_sunos_be_vec
69|	#include "aoutf1.h"
70
71	requires all the names from @file{aout32.c}, and produces the jump vector
72
73|	sparc_aout_sunos_be_vec
74
75	The file @file{host-aout.c} is a special case.  It is for a large set
76	of hosts that use ``more or less standard'' a.out files, and
77	for which cross-debugging is not interesting.  It uses the
78	standard 32-bit a.out support routines, but determines the
79	file offsets and addresses of the text, data, and BSS
80	sections, the machine architecture and machine type, and the
81	entry point address, in a host-dependent manner.  Once these
82	values have been determined, generic code is used to handle
83	the  object file.
84
85	When porting it to run on a new system, you must supply:
86
87|        HOST_PAGE_SIZE
88|        HOST_SEGMENT_SIZE
89|        HOST_MACHINE_ARCH       (optional)
90|        HOST_MACHINE_MACHINE    (optional)
91|        HOST_TEXT_START_ADDR
92|        HOST_STACK_END_ADDR
93
94	in the file @file{../include/sys/h-@var{XXX}.h} (for your host).  These
95	values, plus the structures and macros defined in @file{a.out.h} on
96	your host system, will produce a BFD target that will access
97	ordinary a.out files on your host. To configure a new machine
98	to use @file{host-aout.c}, specify:
99
100|	TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
101|	TDEPFILES= host-aout.o trad-core.o
102
103	in the @file{config/@var{XXX}.mt} file, and modify @file{configure.ac}
104	to use the
105	@file{@var{XXX}.mt} file (by setting "<<bfd_target=XXX>>") when your
106	configuration is selected.  */
107
108/* Some assumptions:
109   * Any BFD with D_PAGED set is ZMAGIC, and vice versa.
110     Doesn't matter what the setting of WP_TEXT is on output, but it'll
111     get set on input.
112   * Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC.
113   * Any BFD with both flags clear is OMAGIC.
114   (Just want to make these explicit, so the conditions tested in this
115   file make sense if you're more familiar with a.out than with BFD.)  */
116
117#define KEEPIT udata.i
118
119#include "sysdep.h"
120#include <limits.h>
121#include "bfd.h"
122#include "safe-ctype.h"
123#include "bfdlink.h"
124
125#include "libaout.h"
126#include "libbfd.h"
127#include "aout/aout64.h"
128#include "aout/stab_gnu.h"
129#include "aout/ar.h"
130
131#ifdef BMAGIC
132#define N_IS_BMAGIC(x) (N_MAGIC (x) == BMAGIC)
133#else
134#define N_IS_BMAGIC(x) (0)
135#endif
136
137#ifdef QMAGIC
138#define N_SET_QMAGIC(x) N_SET_MAGIC (x, QMAGIC)
139#else
140#define N_SET_QMAGIC(x) do { /**/ } while (0)
141#endif
142
143/*
144SUBSECTION
145	Relocations
146
147DESCRIPTION
148	The file @file{aoutx.h} provides for both the @emph{standard}
149	and @emph{extended} forms of a.out relocation records.
150
151	The standard records contain only an address, a symbol index,
152	and a type field.  The extended records also have a full
153	integer for an addend.  */
154
155#ifndef CTOR_TABLE_RELOC_HOWTO
156#define CTOR_TABLE_RELOC_IDX 2
157#define CTOR_TABLE_RELOC_HOWTO(BFD)					\
158  ((obj_reloc_entry_size (BFD) == RELOC_EXT_SIZE			\
159    ? howto_table_ext : howto_table_std)				\
160   + CTOR_TABLE_RELOC_IDX)
161#endif
162
163#ifndef MY_swap_std_reloc_in
164#define MY_swap_std_reloc_in NAME (aout, swap_std_reloc_in)
165#endif
166
167#ifndef MY_swap_ext_reloc_in
168#define MY_swap_ext_reloc_in NAME (aout, swap_ext_reloc_in)
169#endif
170
171#ifndef MY_swap_std_reloc_out
172#define MY_swap_std_reloc_out NAME (aout, swap_std_reloc_out)
173#endif
174
175#ifndef MY_swap_ext_reloc_out
176#define MY_swap_ext_reloc_out NAME (aout, swap_ext_reloc_out)
177#endif
178
179#ifndef MY_final_link_relocate
180#define MY_final_link_relocate _bfd_final_link_relocate
181#endif
182
183#ifndef MY_relocate_contents
184#define MY_relocate_contents _bfd_relocate_contents
185#endif
186
187#define howto_table_ext NAME (aout, ext_howto_table)
188#define howto_table_std NAME (aout, std_howto_table)
189
190reloc_howto_type howto_table_ext[] =
191{
192  /*	 Type	      rs   size bsz  pcrel bitpos ovrf			sf name		 part_inpl readmask setmask pcdone.  */
193  HOWTO (RELOC_8,	0,  1,	8,  false, 0, complain_overflow_bitfield, 0, "8",	    false, 0, 0x000000ff, false),
194  HOWTO (RELOC_16,	0,  2,	16, false, 0, complain_overflow_bitfield, 0, "16",	    false, 0, 0x0000ffff, false),
195  HOWTO (RELOC_32,	0,  4,	32, false, 0, complain_overflow_bitfield, 0, "32",	    false, 0, 0xffffffff, false),
196  HOWTO (RELOC_DISP8,	0,  1,	8,  true,  0, complain_overflow_signed,	  0, "DISP8",	    false, 0, 0x000000ff, false),
197  HOWTO (RELOC_DISP16,	0,  2,	16, true,  0, complain_overflow_signed,	  0, "DISP16",	    false, 0, 0x0000ffff, false),
198  HOWTO (RELOC_DISP32,	0,  4,	32, true,  0, complain_overflow_signed,	  0, "DISP32",	    false, 0, 0xffffffff, false),
199  HOWTO (RELOC_WDISP30, 2,  4,	30, true,  0, complain_overflow_signed,	  0, "WDISP30",	    false, 0, 0x3fffffff, false),
200  HOWTO (RELOC_WDISP22, 2,  4,	22, true,  0, complain_overflow_signed,	  0, "WDISP22",	    false, 0, 0x003fffff, false),
201  HOWTO (RELOC_HI22,   10,  4,	22, false, 0, complain_overflow_bitfield, 0, "HI22",	    false, 0, 0x003fffff, false),
202  HOWTO (RELOC_22,	0,  4,	22, false, 0, complain_overflow_bitfield, 0, "22",	    false, 0, 0x003fffff, false),
203  HOWTO (RELOC_13,	0,  4,	13, false, 0, complain_overflow_bitfield, 0, "13",	    false, 0, 0x00001fff, false),
204  HOWTO (RELOC_LO10,	0,  4,	10, false, 0, complain_overflow_dont,	  0, "LO10",	    false, 0, 0x000003ff, false),
205  HOWTO (RELOC_SFA_BASE,0,  4,	32, false, 0, complain_overflow_bitfield, 0, "SFA_BASE",    false, 0, 0xffffffff, false),
206  HOWTO (RELOC_SFA_OFF13,0, 4,	32, false, 0, complain_overflow_bitfield, 0, "SFA_OFF13",   false, 0, 0xffffffff, false),
207  HOWTO (RELOC_BASE10,	0,  4,	10, false, 0, complain_overflow_dont,	  0, "BASE10",	    false, 0, 0x000003ff, false),
208  HOWTO (RELOC_BASE13,	0,  4,	13, false, 0, complain_overflow_signed,	  0, "BASE13",	    false, 0, 0x00001fff, false),
209  HOWTO (RELOC_BASE22, 10,  4,	22, false, 0, complain_overflow_bitfield, 0, "BASE22",	    false, 0, 0x003fffff, false),
210  HOWTO (RELOC_PC10,	0,  4,	10, true,  0, complain_overflow_dont,	  0, "PC10",	    false, 0, 0x000003ff, true),
211  HOWTO (RELOC_PC22,   10,  4,	22, true,  0, complain_overflow_signed,	  0, "PC22",	    false, 0, 0x003fffff, true),
212  HOWTO (RELOC_JMP_TBL, 2,  4,	30, true,  0, complain_overflow_signed,	  0, "JMP_TBL",	    false, 0, 0x3fffffff, false),
213  HOWTO (RELOC_SEGOFF16,0,  4,	0,  false, 0, complain_overflow_bitfield, 0, "SEGOFF16",    false, 0, 0x00000000, false),
214  HOWTO (RELOC_GLOB_DAT,0,  4,	0,  false, 0, complain_overflow_bitfield, 0, "GLOB_DAT",    false, 0, 0x00000000, false),
215  HOWTO (RELOC_JMP_SLOT,0,  4,	0,  false, 0, complain_overflow_bitfield, 0, "JMP_SLOT",    false, 0, 0x00000000, false),
216  HOWTO (RELOC_RELATIVE,0,  4,	0,  false, 0, complain_overflow_bitfield, 0, "RELATIVE",    false, 0, 0x00000000, false),
217  HOWTO (0,		0,  0,	0,  false, 0, complain_overflow_dont,	  0, "R_SPARC_NONE",false, 0, 0x00000000, true),
218  HOWTO (0,		0,  0,	0,  false, 0, complain_overflow_dont,	  0, "R_SPARC_NONE",false, 0, 0x00000000, true),
219#define RELOC_SPARC_REV32 RELOC_WDISP19
220  HOWTO (RELOC_SPARC_REV32, 0, 4, 32, false, 0, complain_overflow_dont,	  0,"R_SPARC_REV32",false, 0, 0xffffffff, false),
221};
222
223/* Convert standard reloc records to "arelent" format (incl byte swap).  */
224
225reloc_howto_type howto_table_std[] =
226{
227  /* type	       rs size bsz  pcrel bitpos ovrf			  sf name     part_inpl readmask  setmask    pcdone.  */
228HOWTO ( 0,	       0,  1,	8,  false, 0, complain_overflow_bitfield,0,"8",		true, 0x000000ff,0x000000ff, false),
229HOWTO ( 1,	       0,  2,	16, false, 0, complain_overflow_bitfield,0,"16",	true, 0x0000ffff,0x0000ffff, false),
230HOWTO ( 2,	       0,  4,	32, false, 0, complain_overflow_bitfield,0,"32",	true, 0xffffffff,0xffffffff, false),
231HOWTO ( 3,	       0,  8,	64, false, 0, complain_overflow_bitfield,0,"64",	true, 0xdeaddead,0xdeaddead, false),
232HOWTO ( 4,	       0,  1,	8,  true,  0, complain_overflow_signed,	 0,"DISP8",	true, 0x000000ff,0x000000ff, false),
233HOWTO ( 5,	       0,  2,	16, true,  0, complain_overflow_signed,	 0,"DISP16",	true, 0x0000ffff,0x0000ffff, false),
234HOWTO ( 6,	       0,  4,	32, true,  0, complain_overflow_signed,	 0,"DISP32",	true, 0xffffffff,0xffffffff, false),
235HOWTO ( 7,	       0,  8,	64, true,  0, complain_overflow_signed,	 0,"DISP64",	true, 0xfeedface,0xfeedface, false),
236HOWTO ( 8,	       0,  4,	 0, false, 0, complain_overflow_bitfield,0,"GOT_REL",	false,	       0,0x00000000, false),
237HOWTO ( 9,	       0,  2,	16, false, 0, complain_overflow_bitfield,0,"BASE16",	false,0xffffffff,0xffffffff, false),
238HOWTO (10,	       0,  4,	32, false, 0, complain_overflow_bitfield,0,"BASE32",	false,0xffffffff,0xffffffff, false),
239EMPTY_HOWTO (-1),
240EMPTY_HOWTO (-1),
241EMPTY_HOWTO (-1),
242EMPTY_HOWTO (-1),
243EMPTY_HOWTO (-1),
244  HOWTO (16,	       0,  4,	 0, false, 0, complain_overflow_bitfield,0,"JMP_TABLE", false,	       0,0x00000000, false),
245EMPTY_HOWTO (-1),
246EMPTY_HOWTO (-1),
247EMPTY_HOWTO (-1),
248EMPTY_HOWTO (-1),
249EMPTY_HOWTO (-1),
250EMPTY_HOWTO (-1),
251EMPTY_HOWTO (-1),
252EMPTY_HOWTO (-1),
253EMPTY_HOWTO (-1),
254EMPTY_HOWTO (-1),
255EMPTY_HOWTO (-1),
256EMPTY_HOWTO (-1),
257EMPTY_HOWTO (-1),
258EMPTY_HOWTO (-1),
259EMPTY_HOWTO (-1),
260  HOWTO (32,	       0,  4,	 0, false, 0, complain_overflow_bitfield,0,"RELATIVE",	false,	       0,0x00000000, false),
261EMPTY_HOWTO (-1),
262EMPTY_HOWTO (-1),
263EMPTY_HOWTO (-1),
264EMPTY_HOWTO (-1),
265EMPTY_HOWTO (-1),
266EMPTY_HOWTO (-1),
267EMPTY_HOWTO (-1),
268  HOWTO (40,	       0,  4,	 0, false, 0, complain_overflow_bitfield,0,"BASEREL",	false,	       0,0x00000000, false),
269};
270
271#define TABLE_SIZE(TABLE)	(sizeof (TABLE) / sizeof (TABLE[0]))
272
273reloc_howto_type *
274NAME (aout, reloc_type_lookup) (bfd *abfd, bfd_reloc_code_real_type code)
275{
276#define EXT(i, j)	case i: return & howto_table_ext [j]
277#define STD(i, j)	case i: return & howto_table_std [j]
278  int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
279
280  if (code == BFD_RELOC_CTOR)
281    switch (bfd_arch_bits_per_address (abfd))
282      {
283      case 32:
284	code = BFD_RELOC_32;
285	break;
286      case 64:
287	code = BFD_RELOC_64;
288	break;
289      }
290
291  if (ext)
292    switch (code)
293      {
294	EXT (BFD_RELOC_8, 0);
295	EXT (BFD_RELOC_16, 1);
296	EXT (BFD_RELOC_32, 2);
297	EXT (BFD_RELOC_HI22, 8);
298	EXT (BFD_RELOC_LO10, 11);
299	EXT (BFD_RELOC_32_PCREL_S2, 6);
300	EXT (BFD_RELOC_SPARC_WDISP22, 7);
301	EXT (BFD_RELOC_SPARC13, 10);
302	EXT (BFD_RELOC_SPARC_GOT10, 14);
303	EXT (BFD_RELOC_SPARC_BASE13, 15);
304	EXT (BFD_RELOC_SPARC_GOT13, 15);
305	EXT (BFD_RELOC_SPARC_GOT22, 16);
306	EXT (BFD_RELOC_SPARC_PC10, 17);
307	EXT (BFD_RELOC_SPARC_PC22, 18);
308	EXT (BFD_RELOC_SPARC_WPLT30, 19);
309	EXT (BFD_RELOC_SPARC_REV32, 26);
310      default:
311	return NULL;
312      }
313  else
314    /* std relocs.  */
315    switch (code)
316      {
317	STD (BFD_RELOC_8, 0);
318	STD (BFD_RELOC_16, 1);
319	STD (BFD_RELOC_32, 2);
320	STD (BFD_RELOC_8_PCREL, 4);
321	STD (BFD_RELOC_16_PCREL, 5);
322	STD (BFD_RELOC_32_PCREL, 6);
323	STD (BFD_RELOC_16_BASEREL, 9);
324	STD (BFD_RELOC_32_BASEREL, 10);
325      default:
326	return NULL;
327      }
328}
329
330reloc_howto_type *
331NAME (aout, reloc_name_lookup) (bfd *abfd, const char *r_name)
332{
333  unsigned int i, size;
334  reloc_howto_type *howto_table;
335
336  if (obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE)
337    {
338      howto_table = howto_table_ext;
339      size = sizeof (howto_table_ext) / sizeof (howto_table_ext[0]);
340    }
341  else
342    {
343      howto_table = howto_table_std;
344      size = sizeof (howto_table_std) / sizeof (howto_table_std[0]);
345    }
346
347  for (i = 0; i < size; i++)
348    if (howto_table[i].name != NULL
349	&& strcasecmp (howto_table[i].name, r_name) == 0)
350      return &howto_table[i];
351
352  return NULL;
353}
354
355/*
356SUBSECTION
357	Internal entry points
358
359DESCRIPTION
360	@file{aoutx.h} exports several routines for accessing the
361	contents of an a.out file, which are gathered and exported in
362	turn by various format specific files (eg sunos.c).
363*/
364
365/*
366FUNCTION
367	 aout_@var{size}_swap_exec_header_in
368
369SYNOPSIS
370	void aout_@var{size}_swap_exec_header_in,
371	   (bfd *abfd,
372	    struct external_exec *bytes,
373	    struct internal_exec *execp);
374
375DESCRIPTION
376	Swap the information in an executable header @var{raw_bytes} taken
377	from a raw byte stream memory image into the internal exec header
378	structure @var{execp}.
379*/
380
381#ifndef NAME_swap_exec_header_in
382void
383NAME (aout, swap_exec_header_in) (bfd *abfd,
384				  struct external_exec *bytes,
385				  struct internal_exec *execp)
386{
387  /* The internal_exec structure has some fields that are unused in this
388     configuration (IE for i960), so ensure that all such uninitialized
389     fields are zero'd out.  There are places where two of these structs
390     are memcmp'd, and thus the contents do matter.  */
391  memset ((void *) execp, 0, sizeof (struct internal_exec));
392  /* Now fill in fields in the execp, from the bytes in the raw data.  */
393  execp->a_info   = H_GET_32 (abfd, bytes->e_info);
394  execp->a_text   = GET_WORD (abfd, bytes->e_text);
395  execp->a_data   = GET_WORD (abfd, bytes->e_data);
396  execp->a_bss    = GET_WORD (abfd, bytes->e_bss);
397  execp->a_syms   = GET_WORD (abfd, bytes->e_syms);
398  execp->a_entry  = GET_WORD (abfd, bytes->e_entry);
399  execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
400  execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
401}
402#define NAME_swap_exec_header_in NAME (aout, swap_exec_header_in)
403#endif
404
405/*
406FUNCTION
407	aout_@var{size}_swap_exec_header_out
408
409SYNOPSIS
410	void aout_@var{size}_swap_exec_header_out
411	  (bfd *abfd,
412	   struct internal_exec *execp,
413	   struct external_exec *raw_bytes);
414
415DESCRIPTION
416	Swap the information in an internal exec header structure
417	@var{execp} into the buffer @var{raw_bytes} ready for writing to disk.
418*/
419void
420NAME (aout, swap_exec_header_out) (bfd *abfd,
421				   struct internal_exec *execp,
422				   struct external_exec *bytes)
423{
424  /* Now fill in fields in the raw data, from the fields in the exec struct.  */
425  H_PUT_32 (abfd, execp->a_info  , bytes->e_info);
426  PUT_WORD (abfd, execp->a_text  , bytes->e_text);
427  PUT_WORD (abfd, execp->a_data  , bytes->e_data);
428  PUT_WORD (abfd, execp->a_bss   , bytes->e_bss);
429  PUT_WORD (abfd, execp->a_syms  , bytes->e_syms);
430  PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
431  PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
432  PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
433}
434
435/* Make all the section for an a.out file.  */
436
437bool
438NAME (aout, make_sections) (bfd *abfd)
439{
440  if (obj_textsec (abfd) == NULL && bfd_make_section (abfd, ".text") == NULL)
441    return false;
442  if (obj_datasec (abfd) == NULL && bfd_make_section (abfd, ".data") == NULL)
443    return false;
444  if (obj_bsssec (abfd) == NULL && bfd_make_section (abfd, ".bss") == NULL)
445    return false;
446  return true;
447}
448
449/*
450FUNCTION
451	aout_@var{size}_some_aout_object_p
452
453SYNOPSIS
454	const bfd_target *aout_@var{size}_some_aout_object_p
455	 (bfd *abfd,
456	  struct internal_exec *execp,
457	  const bfd_target *(*callback_to_real_object_p) (bfd *));
458
459DESCRIPTION
460	Some a.out variant thinks that the file open in @var{abfd}
461	checking is an a.out file.  Do some more checking, and set up
462	for access if it really is.  Call back to the calling
463	environment's "finish up" function just before returning, to
464	handle any last-minute setup.
465*/
466
467bfd_cleanup
468NAME (aout, some_aout_object_p) (bfd *abfd,
469				 struct internal_exec *execp,
470				 bfd_cleanup (*callback_to_real_object_p) (bfd *))
471{
472  struct aout_data_struct *rawptr, *oldrawptr;
473  bfd_cleanup result;
474  size_t amt = sizeof (* rawptr);
475
476  rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
477  if (rawptr == NULL)
478    return NULL;
479
480  oldrawptr = abfd->tdata.aout_data;
481  abfd->tdata.aout_data = rawptr;
482
483  /* Copy the contents of the old tdata struct.  */
484  if (oldrawptr != NULL)
485    *abfd->tdata.aout_data = *oldrawptr;
486
487  abfd->tdata.aout_data->a.hdr = &rawptr->e;
488  /* Copy in the internal_exec struct.  */
489  *(abfd->tdata.aout_data->a.hdr) = *execp;
490  execp = abfd->tdata.aout_data->a.hdr;
491
492  /* Set the file flags.  */
493  abfd->flags = BFD_NO_FLAGS;
494  if (execp->a_drsize || execp->a_trsize)
495    abfd->flags |= HAS_RELOC;
496  /* Setting of EXEC_P has been deferred to the bottom of this function.  */
497  if (execp->a_syms)
498    abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
499  if (N_DYNAMIC (execp))
500    abfd->flags |= DYNAMIC;
501
502  if (N_MAGIC (execp) == ZMAGIC)
503    {
504      abfd->flags |= D_PAGED | WP_TEXT;
505      adata (abfd).magic = z_magic;
506    }
507  else if (N_IS_QMAGIC (execp))
508    {
509      abfd->flags |= D_PAGED | WP_TEXT;
510      adata (abfd).magic = z_magic;
511      adata (abfd).subformat = q_magic_format;
512    }
513  else if (N_MAGIC (execp) == NMAGIC)
514    {
515      abfd->flags |= WP_TEXT;
516      adata (abfd).magic = n_magic;
517    }
518  else if (N_MAGIC (execp) == OMAGIC || N_IS_BMAGIC (execp))
519    adata (abfd).magic = o_magic;
520  else
521    /* Should have been checked with N_BADMAG before this routine
522       was called.  */
523    abort ();
524
525  abfd->start_address = execp->a_entry;
526
527  obj_aout_symbols (abfd) = NULL;
528  abfd->symcount = execp->a_syms / sizeof (struct external_nlist);
529
530  /* The default relocation entry size is that of traditional V7 Unix.  */
531  obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
532
533  /* The default symbol entry size is that of traditional Unix.  */
534  obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
535
536#ifdef USE_MMAP
537  bfd_init_window (&obj_aout_sym_window (abfd));
538  bfd_init_window (&obj_aout_string_window (abfd));
539#endif
540  obj_aout_external_syms (abfd) = NULL;
541  obj_aout_external_strings (abfd) = NULL;
542  obj_aout_sym_hashes (abfd) = NULL;
543
544  if (! NAME (aout, make_sections) (abfd))
545    goto error_ret;
546
547  obj_datasec (abfd)->size = execp->a_data;
548  obj_bsssec (abfd)->size = execp->a_bss;
549
550  obj_textsec (abfd)->flags =
551    (execp->a_trsize != 0
552     ? (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC)
553     : (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
554  obj_datasec (abfd)->flags =
555    (execp->a_drsize != 0
556     ? (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC)
557     : (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
558  obj_bsssec (abfd)->flags = SEC_ALLOC;
559
560#ifdef THIS_IS_ONLY_DOCUMENTATION
561  /* The common code can't fill in these things because they depend
562     on either the start address of the text segment, the rounding
563     up of virtual addresses between segments, or the starting file
564     position of the text segment -- all of which varies among different
565     versions of a.out.  */
566
567  /* Call back to the format-dependent code to fill in the rest of the
568     fields and do any further cleanup.  Things that should be filled
569     in by the callback:  */
570
571  struct exec *execp = exec_hdr (abfd);
572
573  obj_textsec (abfd)->size = N_TXTSIZE (execp);
574  /* Data and bss are already filled in since they're so standard.  */
575
576  /* The virtual memory addresses of the sections.  */
577  obj_textsec (abfd)->vma = N_TXTADDR (execp);
578  obj_datasec (abfd)->vma = N_DATADDR (execp);
579  obj_bsssec  (abfd)->vma = N_BSSADDR (execp);
580
581  /* The file offsets of the sections.  */
582  obj_textsec (abfd)->filepos = N_TXTOFF (execp);
583  obj_datasec (abfd)->filepos = N_DATOFF (execp);
584
585  /* The file offsets of the relocation info.  */
586  obj_textsec (abfd)->rel_filepos = N_TRELOFF (execp);
587  obj_datasec (abfd)->rel_filepos = N_DRELOFF (execp);
588
589  /* The file offsets of the string table and symbol table.  */
590  obj_str_filepos (abfd) = N_STROFF (execp);
591  obj_sym_filepos (abfd) = N_SYMOFF (execp);
592
593  /* Determine the architecture and machine type of the object file.  */
594  switch (N_MACHTYPE (exec_hdr (abfd)))
595    {
596    default:
597      abfd->obj_arch = bfd_arch_obscure;
598      break;
599    }
600
601  adata (abfd)->page_size = TARGET_PAGE_SIZE;
602  adata (abfd)->segment_size = SEGMENT_SIZE;
603  adata (abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
604
605  return _bfd_no_cleanup
606
607  /* The architecture is encoded in various ways in various a.out variants,
608     or is not encoded at all in some of them.  The relocation size depends
609     on the architecture and the a.out variant.  Finally, the return value
610     is the bfd_target vector in use.  If an error occurs, return zero and
611     set bfd_error to the appropriate error code.
612
613     Formats such as b.out, which have additional fields in the a.out
614     header, should cope with them in this callback as well.  */
615#endif				/* DOCUMENTATION */
616
617  result = (*callback_to_real_object_p) (abfd);
618
619  /* Now that the segment addresses have been worked out, take a better
620     guess at whether the file is executable.  If the entry point
621     is within the text segment, assume it is.  (This makes files
622     executable even if their entry point address is 0, as long as
623     their text starts at zero.).
624
625     This test had to be changed to deal with systems where the text segment
626     runs at a different location than the default.  The problem is that the
627     entry address can appear to be outside the text segment, thus causing an
628     erroneous conclusion that the file isn't executable.
629
630     To fix this, we now accept any non-zero entry point as an indication of
631     executability.  This will work most of the time, since only the linker
632     sets the entry point, and that is likely to be non-zero for most systems.  */
633
634  if (execp->a_entry != 0
635      || (execp->a_entry >= obj_textsec (abfd)->vma
636	  && execp->a_entry < (obj_textsec (abfd)->vma
637			       + obj_textsec (abfd)->size)
638	  && execp->a_trsize == 0
639	  && execp->a_drsize == 0))
640    abfd->flags |= EXEC_P;
641#ifdef STAT_FOR_EXEC
642  else
643    {
644      struct stat stat_buf;
645
646      /* The original heuristic doesn't work in some important cases.
647	The a.out file has no information about the text start
648	address.  For files (like kernels) linked to non-standard
649	addresses (ld -Ttext nnn) the entry point may not be between
650	the default text start (obj_textsec(abfd)->vma) and
651	(obj_textsec(abfd)->vma) + text size.  This is not just a mach
652	issue.  Many kernels are loaded at non standard addresses.  */
653      if (abfd->iostream != NULL
654	  && (abfd->flags & BFD_IN_MEMORY) == 0
655	  && (fstat (fileno ((FILE *) (abfd->iostream)), &stat_buf) == 0)
656	  && ((stat_buf.st_mode & 0111) != 0))
657	abfd->flags |= EXEC_P;
658    }
659#endif /* STAT_FOR_EXEC */
660
661  if (result)
662    return result;
663
664 error_ret:
665  bfd_release (abfd, rawptr);
666  abfd->tdata.aout_data = oldrawptr;
667  return NULL;
668}
669
670/*
671FUNCTION
672	aout_@var{size}_mkobject
673
674SYNOPSIS
675	bool aout_@var{size}_mkobject, (bfd *abfd);
676
677DESCRIPTION
678	Initialize BFD @var{abfd} for use with a.out files.
679*/
680
681bool
682NAME (aout, mkobject) (bfd *abfd)
683{
684  struct aout_data_struct *rawptr;
685  size_t amt = sizeof (* rawptr);
686
687  bfd_set_error (bfd_error_system_call);
688
689  rawptr = (struct aout_data_struct *) bfd_zalloc (abfd, amt);
690  if (rawptr == NULL)
691    return false;
692
693  abfd->tdata.aout_data = rawptr;
694  exec_hdr (abfd) = &(rawptr->e);
695
696  obj_textsec (abfd) = NULL;
697  obj_datasec (abfd) = NULL;
698  obj_bsssec (abfd) = NULL;
699
700  return true;
701}
702
703/*
704FUNCTION
705	aout_@var{size}_machine_type
706
707SYNOPSIS
708	enum machine_type  aout_@var{size}_machine_type
709	 (enum bfd_architecture arch,
710	  unsigned long machine,
711	  bool *unknown);
712
713DESCRIPTION
714	Keep track of machine architecture and machine type for
715	a.out's. Return the <<machine_type>> for a particular
716	architecture and machine, or <<M_UNKNOWN>> if that exact architecture
717	and machine can't be represented in a.out format.
718
719	If the architecture is understood, machine type 0 (default)
720	is always understood.
721*/
722
723enum machine_type
724NAME (aout, machine_type) (enum bfd_architecture arch,
725			   unsigned long machine,
726			   bool *unknown)
727{
728  enum machine_type arch_flags;
729
730  arch_flags = M_UNKNOWN;
731  *unknown = true;
732
733  switch (arch)
734    {
735    case bfd_arch_sparc:
736      if (machine == 0
737	  || machine == bfd_mach_sparc
738	  || machine == bfd_mach_sparc_sparclite
739	  || machine == bfd_mach_sparc_sparclite_le
740	  || machine == bfd_mach_sparc_v8plus
741	  || machine == bfd_mach_sparc_v8plusa
742	  || machine == bfd_mach_sparc_v8plusb
743	  || machine == bfd_mach_sparc_v8plusc
744	  || machine == bfd_mach_sparc_v8plusd
745	  || machine == bfd_mach_sparc_v8pluse
746	  || machine == bfd_mach_sparc_v8plusv
747	  || machine == bfd_mach_sparc_v8plusm
748	  || machine == bfd_mach_sparc_v8plusm8
749	  || machine == bfd_mach_sparc_v9
750	  || machine == bfd_mach_sparc_v9a
751	  || machine == bfd_mach_sparc_v9b
752	  || machine == bfd_mach_sparc_v9c
753	  || machine == bfd_mach_sparc_v9d
754	  || machine == bfd_mach_sparc_v9e
755	  || machine == bfd_mach_sparc_v9v
756	  || machine == bfd_mach_sparc_v9m
757	  || machine == bfd_mach_sparc_v9m8)
758	arch_flags = M_SPARC;
759      else if (machine == bfd_mach_sparc_sparclet)
760	arch_flags = M_SPARCLET;
761      break;
762
763    case bfd_arch_i386:
764      if (machine == 0
765	  || machine == bfd_mach_i386_i386
766	  || machine == bfd_mach_i386_i386_intel_syntax)
767	arch_flags = M_386;
768      break;
769
770    case bfd_arch_arm:
771      if (machine == 0 || machine == 5)
772	arch_flags = M_ARM;
773      break;
774
775    case bfd_arch_mips:
776      switch (machine)
777	{
778	case 0:
779	case bfd_mach_mips3000:
780	case bfd_mach_mips3900:
781	  arch_flags = M_MIPS1;
782	  break;
783	case bfd_mach_mips6000:
784	  arch_flags = M_MIPS2;
785	  break;
786	case bfd_mach_mips4000:
787	case bfd_mach_mips4010:
788	case bfd_mach_mips4100:
789	case bfd_mach_mips4300:
790	case bfd_mach_mips4400:
791	case bfd_mach_mips4600:
792	case bfd_mach_mips4650:
793	case bfd_mach_mips8000:
794	case bfd_mach_mips9000:
795	case bfd_mach_mips10000:
796	case bfd_mach_mips12000:
797	case bfd_mach_mips14000:
798	case bfd_mach_mips16000:
799	case bfd_mach_mips16:
800	case bfd_mach_mipsisa32:
801	case bfd_mach_mipsisa32r2:
802	case bfd_mach_mipsisa32r3:
803	case bfd_mach_mipsisa32r5:
804	case bfd_mach_mipsisa32r6:
805	case bfd_mach_mips5:
806	case bfd_mach_mipsisa64:
807	case bfd_mach_mipsisa64r2:
808	case bfd_mach_mipsisa64r3:
809	case bfd_mach_mipsisa64r5:
810	case bfd_mach_mipsisa64r6:
811	case bfd_mach_mips_sb1:
812	case bfd_mach_mips_xlr:
813	  /* FIXME: These should be MIPS3, MIPS4, MIPS16, MIPS32, etc.  */
814	  arch_flags = M_MIPS2;
815	  break;
816	default:
817	  arch_flags = M_UNKNOWN;
818	  break;
819	}
820      break;
821
822    case bfd_arch_ns32k:
823      switch (machine)
824	{
825	case 0:		arch_flags = M_NS32532; break;
826	case 32032:	arch_flags = M_NS32032; break;
827	case 32532:	arch_flags = M_NS32532; break;
828	default:	arch_flags = M_UNKNOWN; break;
829	}
830      break;
831
832    case bfd_arch_vax:
833      *unknown = false;
834      break;
835
836    case bfd_arch_cris:
837      if (machine == 0 || machine == 255)
838	arch_flags = M_CRIS;
839      break;
840
841    default:
842      arch_flags = M_UNKNOWN;
843    }
844
845  if (arch_flags != M_UNKNOWN)
846    *unknown = false;
847
848  return arch_flags;
849}
850
851/*
852FUNCTION
853	aout_@var{size}_set_arch_mach
854
855SYNOPSIS
856	bool aout_@var{size}_set_arch_mach,
857	 (bfd *,
858	  enum bfd_architecture arch,
859	  unsigned long machine);
860
861DESCRIPTION
862	Set the architecture and the machine of the BFD @var{abfd} to the
863	values @var{arch} and @var{machine}.  Verify that @var{abfd}'s format
864	can support the architecture required.
865*/
866
867bool
868NAME (aout, set_arch_mach) (bfd *abfd,
869			    enum bfd_architecture arch,
870			    unsigned long machine)
871{
872  if (! bfd_default_set_arch_mach (abfd, arch, machine))
873    return false;
874
875  if (arch != bfd_arch_unknown)
876    {
877      bool unknown;
878
879      NAME (aout, machine_type) (arch, machine, &unknown);
880      if (unknown)
881	return false;
882    }
883
884  /* Determine the size of a relocation entry.  */
885  switch (arch)
886    {
887    case bfd_arch_sparc:
888    case bfd_arch_mips:
889      obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
890      break;
891    default:
892      obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
893      break;
894    }
895
896  return (*aout_backend_info (abfd)->set_sizes) (abfd);
897}
898
899static void
900adjust_o_magic (bfd *abfd, struct internal_exec *execp)
901{
902  file_ptr pos = adata (abfd).exec_bytes_size;
903  bfd_vma vma = 0;
904  int pad = 0;
905  asection *text = obj_textsec (abfd);
906  asection *data = obj_datasec (abfd);
907  asection *bss = obj_bsssec (abfd);
908
909  /* Text.  */
910  text->filepos = pos;
911  if (!text->user_set_vma)
912    text->vma = vma;
913  else
914    vma = text->vma;
915
916  pos += execp->a_text;
917  vma += execp->a_text;
918
919  /* Data.  */
920  if (!data->user_set_vma)
921    {
922      pos += pad;
923      vma += pad;
924      data->vma = vma;
925    }
926  else
927    vma = data->vma;
928  execp->a_text += pad;
929
930  data->filepos = pos;
931  pos += data->size;
932  vma += data->size;
933
934  /* BSS.  */
935  if (!bss->user_set_vma)
936    {
937      pos += pad;
938      vma += pad;
939      bss->vma = vma;
940    }
941  else
942    {
943      /* The VMA of the .bss section is set by the VMA of the
944	 .data section plus the size of the .data section.  We may
945	 need to add padding bytes to make this true.  */
946      pad = bss->vma - vma;
947      if (pad < 0)
948	pad = 0;
949      pos += pad;
950    }
951  execp->a_data = data->size + pad;
952  bss->filepos = pos;
953  execp->a_bss = bss->size;
954
955  N_SET_MAGIC (execp, OMAGIC);
956}
957
958static void
959adjust_z_magic (bfd *abfd, struct internal_exec *execp)
960{
961  bfd_size_type data_pad, text_pad;
962  file_ptr text_end;
963  const struct aout_backend_data *abdp;
964  /* TRUE if text includes exec header.  */
965  bool ztih;
966  asection *text = obj_textsec (abfd);
967  asection *data = obj_datasec (abfd);
968  asection *bss = obj_bsssec (abfd);
969
970  abdp = aout_backend_info (abfd);
971
972  /* Text.  */
973  ztih = (abdp != NULL
974	  && (abdp->text_includes_header
975	      || obj_aout_subformat (abfd) == q_magic_format));
976  text->filepos = (ztih
977		   ? adata (abfd).exec_bytes_size
978		   : adata (abfd).zmagic_disk_block_size);
979  if (!text->user_set_vma)
980    {
981      /* ?? Do we really need to check for relocs here?  */
982      text->vma = ((abfd->flags & HAS_RELOC)
983		   ? 0
984		   : (ztih
985		      ? abdp->default_text_vma + adata (abfd).exec_bytes_size
986		      : abdp->default_text_vma));
987      text_pad = 0;
988    }
989  else
990    {
991      /* The .text section is being loaded at an unusual address.  We
992	 may need to pad it such that the .data section starts at a page
993	 boundary.  */
994      if (ztih)
995	text_pad = ((text->filepos - text->vma)
996		    & (adata (abfd).page_size - 1));
997      else
998	text_pad = (-text->vma
999		    & (adata (abfd).page_size - 1));
1000    }
1001
1002  /* Find start of data.  */
1003  if (ztih)
1004    {
1005      text_end = text->filepos + execp->a_text;
1006      text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
1007    }
1008  else
1009    {
1010      /* Note that if page_size == zmagic_disk_block_size, then
1011	 filepos == page_size, and this case is the same as the ztih
1012	 case.  */
1013      text_end = execp->a_text;
1014      text_pad += BFD_ALIGN (text_end, adata (abfd).page_size) - text_end;
1015      text_end += text->filepos;
1016    }
1017  execp->a_text += text_pad;
1018
1019  /* Data.  */
1020  if (!data->user_set_vma)
1021    {
1022      bfd_vma vma;
1023      vma = text->vma + execp->a_text;
1024      data->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
1025    }
1026  if (abdp && abdp->zmagic_mapped_contiguous)
1027    {
1028      text_pad = data->vma - (text->vma + execp->a_text);
1029      /* Only pad the text section if the data
1030	 section is going to be placed after it.  */
1031      if (text_pad > 0)
1032	execp->a_text += text_pad;
1033    }
1034  data->filepos = text->filepos + execp->a_text;
1035
1036  /* Fix up exec header while we're at it.  */
1037  if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
1038    execp->a_text += adata (abfd).exec_bytes_size;
1039  if (obj_aout_subformat (abfd) == q_magic_format)
1040    N_SET_QMAGIC (execp);
1041  else
1042    N_SET_MAGIC (execp, ZMAGIC);
1043
1044  /* Spec says data section should be rounded up to page boundary.  */
1045  execp->a_data = align_power (data->size, bss->alignment_power);
1046  execp->a_data = BFD_ALIGN (execp->a_data, adata (abfd).page_size);
1047  data_pad = execp->a_data - data->size;
1048
1049  /* BSS.  */
1050  if (!bss->user_set_vma)
1051    bss->vma = data->vma + execp->a_data;
1052  /* If the BSS immediately follows the data section and extra space
1053     in the page is left after the data section, fudge data
1054     in the header so that the bss section looks smaller by that
1055     amount.  We'll start the bss section there, and lie to the OS.
1056     (Note that a linker script, as well as the above assignment,
1057     could have explicitly set the BSS vma to immediately follow
1058     the data section.)  */
1059  if (align_power (bss->vma, bss->alignment_power) == data->vma + execp->a_data)
1060    execp->a_bss = data_pad > bss->size ? 0 : bss->size - data_pad;
1061  else
1062    execp->a_bss = bss->size;
1063}
1064
1065static void
1066adjust_n_magic (bfd *abfd, struct internal_exec *execp)
1067{
1068  file_ptr pos = adata (abfd).exec_bytes_size;
1069  bfd_vma vma = 0;
1070  int pad;
1071  asection *text = obj_textsec (abfd);
1072  asection *data = obj_datasec (abfd);
1073  asection *bss = obj_bsssec (abfd);
1074
1075  /* Text.  */
1076  text->filepos = pos;
1077  if (!text->user_set_vma)
1078    text->vma = vma;
1079  else
1080    vma = text->vma;
1081  pos += execp->a_text;
1082  vma += execp->a_text;
1083
1084  /* Data.  */
1085  data->filepos = pos;
1086  if (!data->user_set_vma)
1087    data->vma = BFD_ALIGN (vma, adata (abfd).segment_size);
1088  vma = data->vma;
1089
1090  /* Since BSS follows data immediately, see if it needs alignment.  */
1091  vma += data->size;
1092  pad = align_power (vma, bss->alignment_power) - vma;
1093  execp->a_data = data->size + pad;
1094  pos += execp->a_data;
1095
1096  /* BSS.  */
1097  if (!bss->user_set_vma)
1098    bss->vma = vma;
1099  else
1100    vma = bss->vma;
1101
1102  /* Fix up exec header.  */
1103  execp->a_bss = bss->size;
1104  N_SET_MAGIC (execp, NMAGIC);
1105}
1106
1107bool
1108NAME (aout, adjust_sizes_and_vmas) (bfd *abfd)
1109{
1110  struct internal_exec *execp = exec_hdr (abfd);
1111
1112  if (! NAME (aout, make_sections) (abfd))
1113    return false;
1114
1115  if (adata (abfd).magic != undecided_magic)
1116    return true;
1117
1118  execp->a_text = align_power (obj_textsec (abfd)->size,
1119			       obj_textsec (abfd)->alignment_power);
1120
1121  /* Rule (heuristic) for when to pad to a new page.  Note that there
1122     are (at least) two ways demand-paged (ZMAGIC) files have been
1123     handled.  Most Berkeley-based systems start the text segment at
1124     (TARGET_PAGE_SIZE).  However, newer versions of SUNOS start the text
1125     segment right after the exec header; the latter is counted in the
1126     text segment size, and is paged in by the kernel with the rest of
1127     the text.  */
1128
1129  /* This perhaps isn't the right way to do this, but made it simpler for me
1130     to understand enough to implement it.  Better would probably be to go
1131     right from BFD flags to alignment/positioning characteristics.  But the
1132     old code was sloppy enough about handling the flags, and had enough
1133     other magic, that it was a little hard for me to understand.  I think
1134     I understand it better now, but I haven't time to do the cleanup this
1135     minute.  */
1136
1137  if (abfd->flags & D_PAGED)
1138    /* Whether or not WP_TEXT is set -- let D_PAGED override.  */
1139    adata (abfd).magic = z_magic;
1140  else if (abfd->flags & WP_TEXT)
1141    adata (abfd).magic = n_magic;
1142  else
1143    adata (abfd).magic = o_magic;
1144
1145#ifdef BFD_AOUT_DEBUG /* requires gcc2 */
1146#if __GNUC__ >= 2
1147  fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
1148	   ({ char *str;
1149	      switch (adata (abfd).magic)
1150		{
1151		case n_magic: str = "NMAGIC"; break;
1152		case o_magic: str = "OMAGIC"; break;
1153		case z_magic: str = "ZMAGIC"; break;
1154		default: abort ();
1155		}
1156	      str;
1157	    }),
1158	   obj_textsec (abfd)->vma, obj_textsec (abfd)->size,
1159		obj_textsec (abfd)->alignment_power,
1160	   obj_datasec (abfd)->vma, obj_datasec (abfd)->size,
1161		obj_datasec (abfd)->alignment_power,
1162	   obj_bsssec (abfd)->vma, obj_bsssec (abfd)->size,
1163		obj_bsssec (abfd)->alignment_power);
1164#endif
1165#endif
1166
1167  switch (adata (abfd).magic)
1168    {
1169    case o_magic:
1170      adjust_o_magic (abfd, execp);
1171      break;
1172    case z_magic:
1173      adjust_z_magic (abfd, execp);
1174      break;
1175    case n_magic:
1176      adjust_n_magic (abfd, execp);
1177      break;
1178    default:
1179      abort ();
1180    }
1181
1182#ifdef BFD_AOUT_DEBUG
1183  fprintf (stderr, "       text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
1184	   obj_textsec (abfd)->vma, execp->a_text,
1185		obj_textsec (abfd)->filepos,
1186	   obj_datasec (abfd)->vma, execp->a_data,
1187		obj_datasec (abfd)->filepos,
1188	   obj_bsssec (abfd)->vma, execp->a_bss);
1189#endif
1190
1191  return true;
1192}
1193
1194/*
1195FUNCTION
1196	aout_@var{size}_new_section_hook
1197
1198SYNOPSIS
1199	bool aout_@var{size}_new_section_hook,
1200	   (bfd *abfd,
1201	    asection *newsect);
1202
1203DESCRIPTION
1204	Called by the BFD in response to a @code{bfd_make_section}
1205	request.
1206*/
1207bool
1208NAME (aout, new_section_hook) (bfd *abfd, asection *newsect)
1209{
1210  /* Align to double at least.  */
1211  newsect->alignment_power = bfd_get_arch_info (abfd)->section_align_power;
1212
1213  if (bfd_get_format (abfd) == bfd_object)
1214    {
1215      if (obj_textsec (abfd) == NULL && !strcmp (newsect->name, ".text"))
1216	{
1217	  obj_textsec (abfd)= newsect;
1218	  newsect->target_index = N_TEXT;
1219	}
1220      else if (obj_datasec (abfd) == NULL && !strcmp (newsect->name, ".data"))
1221	{
1222	  obj_datasec (abfd) = newsect;
1223	  newsect->target_index = N_DATA;
1224	}
1225      else if (obj_bsssec (abfd) == NULL && !strcmp (newsect->name, ".bss"))
1226	{
1227	  obj_bsssec (abfd) = newsect;
1228	  newsect->target_index = N_BSS;
1229	}
1230    }
1231
1232  /* We allow more than three sections internally.  */
1233  return _bfd_generic_new_section_hook (abfd, newsect);
1234}
1235
1236bool
1237NAME (aout, set_section_contents) (bfd *abfd,
1238				   sec_ptr section,
1239				   const void * location,
1240				   file_ptr offset,
1241				   bfd_size_type count)
1242{
1243  if (! abfd->output_has_begun)
1244    {
1245      if (! NAME (aout, adjust_sizes_and_vmas) (abfd))
1246	return false;
1247    }
1248
1249  if (section == obj_bsssec (abfd))
1250    {
1251      bfd_set_error (bfd_error_no_contents);
1252      return false;
1253    }
1254
1255  if (section != obj_textsec (abfd)
1256      && section != obj_datasec (abfd))
1257    {
1258      if (aout_section_merge_with_text_p (abfd, section))
1259	section->filepos = obj_textsec (abfd)->filepos +
1260			   (section->vma - obj_textsec (abfd)->vma);
1261      else
1262	{
1263	  _bfd_error_handler
1264	    /* xgettext:c-format */
1265	   (_("%pB: can not represent section `%pA' in a.out object file format"),
1266	     abfd, section);
1267	  bfd_set_error (bfd_error_nonrepresentable_section);
1268	  return false;
1269	}
1270    }
1271
1272  if (count != 0)
1273    {
1274      if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
1275	  || bfd_bwrite (location, count, abfd) != count)
1276	return false;
1277    }
1278
1279  return true;
1280}
1281
1282/* Read the external symbols from an a.out file.  */
1283
1284static bool
1285aout_get_external_symbols (bfd *abfd)
1286{
1287  if (obj_aout_external_syms (abfd) == NULL)
1288    {
1289      bfd_size_type count;
1290      struct external_nlist *syms;
1291      bfd_size_type amt = exec_hdr (abfd)->a_syms;
1292
1293      count = amt / EXTERNAL_NLIST_SIZE;
1294      if (count == 0)
1295	return true;		/* Nothing to do.  */
1296
1297#ifdef USE_MMAP
1298      if (! bfd_get_file_window (abfd, obj_sym_filepos (abfd), amt,
1299				 &obj_aout_sym_window (abfd), true))
1300	return false;
1301      syms = (struct external_nlist *) obj_aout_sym_window (abfd).data;
1302#else
1303      /* We allocate using malloc to make the values easy to free
1304	 later on.  If we put them on the objalloc it might not be
1305	 possible to free them.  */
1306      if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0)
1307	return false;
1308      syms = (struct external_nlist *) _bfd_malloc_and_read (abfd, amt, amt);
1309      if (syms == NULL)
1310	return false;
1311#endif
1312
1313      obj_aout_external_syms (abfd) = syms;
1314      obj_aout_external_sym_count (abfd) = count;
1315    }
1316
1317  if (obj_aout_external_strings (abfd) == NULL
1318      && exec_hdr (abfd)->a_syms != 0)
1319    {
1320      unsigned char string_chars[BYTES_IN_WORD];
1321      bfd_size_type stringsize;
1322      char *strings;
1323      bfd_size_type amt = BYTES_IN_WORD;
1324
1325      /* Get the size of the strings.  */
1326      if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
1327	  || bfd_bread ((void *) string_chars, amt, abfd) != amt)
1328	return false;
1329      stringsize = GET_WORD (abfd, string_chars);
1330      if (stringsize == 0)
1331	stringsize = 1;
1332      else if (stringsize < BYTES_IN_WORD
1333	       || (size_t) stringsize != stringsize)
1334	{
1335	  bfd_set_error (bfd_error_bad_value);
1336	  return false;
1337	}
1338
1339#ifdef USE_MMAP
1340      if (stringsize >= BYTES_IN_WORD)
1341	{
1342	  if (! bfd_get_file_window (abfd, obj_str_filepos (abfd), stringsize + 1,
1343				     &obj_aout_string_window (abfd), true))
1344	    return false;
1345	  strings = (char *) obj_aout_string_window (abfd).data;
1346	}
1347      else
1348#endif
1349	{
1350	  strings = (char *) bfd_malloc (stringsize + 1);
1351	  if (strings == NULL)
1352	    return false;
1353
1354	  if (stringsize >= BYTES_IN_WORD)
1355	    {
1356	      amt = stringsize - BYTES_IN_WORD;
1357	      if (bfd_bread (strings + BYTES_IN_WORD, amt, abfd) != amt)
1358		{
1359		  free (strings);
1360		  return false;
1361		}
1362	    }
1363	}
1364      /* Ensure that a zero index yields an empty string.  */
1365      if (stringsize >= BYTES_IN_WORD)
1366	memset (strings, 0, BYTES_IN_WORD);
1367
1368      /* Ensure that the string buffer is NUL terminated.  */
1369      strings[stringsize] = 0;
1370
1371      obj_aout_external_strings (abfd) = strings;
1372      obj_aout_external_string_size (abfd) = stringsize;
1373    }
1374
1375  return true;
1376}
1377
1378/* Translate an a.out symbol into a BFD symbol.  The desc, other, type
1379   and symbol->value fields of CACHE_PTR will be set from the a.out
1380   nlist structure.  This function is responsible for setting
1381   symbol->flags and symbol->section, and adjusting symbol->value.  */
1382
1383static bool
1384translate_from_native_sym_flags (bfd *abfd, aout_symbol_type *cache_ptr)
1385{
1386  flagword visible;
1387
1388  if ((cache_ptr->type & N_STAB) != 0
1389      || cache_ptr->type == N_FN)
1390    {
1391      asection *sec;
1392
1393      /* This is a debugging symbol.  */
1394      cache_ptr->symbol.flags = BSF_DEBUGGING;
1395
1396      /* Work out the symbol section.  */
1397      switch (cache_ptr->type & N_TYPE)
1398	{
1399	case N_TEXT:
1400	case N_FN:
1401	  sec = obj_textsec (abfd);
1402	  break;
1403	case N_DATA:
1404	  sec = obj_datasec (abfd);
1405	  break;
1406	case N_BSS:
1407	  sec = obj_bsssec (abfd);
1408	  break;
1409	default:
1410	case N_ABS:
1411	  sec = bfd_abs_section_ptr;
1412	  break;
1413	}
1414
1415      cache_ptr->symbol.section = sec;
1416      cache_ptr->symbol.value -= sec->vma;
1417
1418      return true;
1419    }
1420
1421  /* Get the default visibility.  This does not apply to all types, so
1422     we just hold it in a local variable to use if wanted.  */
1423  if ((cache_ptr->type & N_EXT) == 0)
1424    visible = BSF_LOCAL;
1425  else
1426    visible = BSF_GLOBAL;
1427
1428  switch (cache_ptr->type)
1429    {
1430    default:
1431    case N_ABS: case N_ABS | N_EXT:
1432      cache_ptr->symbol.section = bfd_abs_section_ptr;
1433      cache_ptr->symbol.flags = visible;
1434      break;
1435
1436    case N_UNDF | N_EXT:
1437      if (cache_ptr->symbol.value != 0)
1438	{
1439	  /* This is a common symbol.  */
1440	  cache_ptr->symbol.flags = BSF_GLOBAL;
1441	  cache_ptr->symbol.section = bfd_com_section_ptr;
1442	}
1443      else
1444	{
1445	  cache_ptr->symbol.flags = 0;
1446	  cache_ptr->symbol.section = bfd_und_section_ptr;
1447	}
1448      break;
1449
1450    case N_TEXT: case N_TEXT | N_EXT:
1451      cache_ptr->symbol.section = obj_textsec (abfd);
1452      cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1453      cache_ptr->symbol.flags = visible;
1454      break;
1455
1456      /* N_SETV symbols used to represent set vectors placed in the
1457	 data section.  They are no longer generated.  Theoretically,
1458	 it was possible to extract the entries and combine them with
1459	 new ones, although I don't know if that was ever actually
1460	 done.  Unless that feature is restored, treat them as data
1461	 symbols.  */
1462    case N_SETV: case N_SETV | N_EXT:
1463    case N_DATA: case N_DATA | N_EXT:
1464      cache_ptr->symbol.section = obj_datasec (abfd);
1465      cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1466      cache_ptr->symbol.flags = visible;
1467      break;
1468
1469    case N_BSS: case N_BSS | N_EXT:
1470      cache_ptr->symbol.section = obj_bsssec (abfd);
1471      cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1472      cache_ptr->symbol.flags = visible;
1473      break;
1474
1475    case N_SETA: case N_SETA | N_EXT:
1476    case N_SETT: case N_SETT | N_EXT:
1477    case N_SETD: case N_SETD | N_EXT:
1478    case N_SETB: case N_SETB | N_EXT:
1479      {
1480	/* This code is no longer needed.  It used to be used to make
1481	   the linker handle set symbols, but they are now handled in
1482	   the add_symbols routine instead.  */
1483	switch (cache_ptr->type & N_TYPE)
1484	  {
1485	  case N_SETA:
1486	    cache_ptr->symbol.section = bfd_abs_section_ptr;
1487	    break;
1488	  case N_SETT:
1489	    cache_ptr->symbol.section = obj_textsec (abfd);
1490	    break;
1491	  case N_SETD:
1492	    cache_ptr->symbol.section = obj_datasec (abfd);
1493	    break;
1494	  case N_SETB:
1495	    cache_ptr->symbol.section = obj_bsssec (abfd);
1496	    break;
1497	  }
1498
1499	cache_ptr->symbol.flags |= BSF_CONSTRUCTOR;
1500      }
1501      break;
1502
1503    case N_WARNING:
1504      /* This symbol is the text of a warning message.  The next
1505	 symbol is the symbol to associate the warning with.  If a
1506	 reference is made to that symbol, a warning is issued.  */
1507      cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
1508      cache_ptr->symbol.section = bfd_abs_section_ptr;
1509      break;
1510
1511    case N_INDR: case N_INDR | N_EXT:
1512      /* An indirect symbol.  This consists of two symbols in a row.
1513	 The first symbol is the name of the indirection.  The second
1514	 symbol is the name of the target.  A reference to the first
1515	 symbol becomes a reference to the second.  */
1516      cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT | visible;
1517      cache_ptr->symbol.section = bfd_ind_section_ptr;
1518      break;
1519
1520    case N_WEAKU:
1521      cache_ptr->symbol.section = bfd_und_section_ptr;
1522      cache_ptr->symbol.flags = BSF_WEAK;
1523      break;
1524
1525    case N_WEAKA:
1526      cache_ptr->symbol.section = bfd_abs_section_ptr;
1527      cache_ptr->symbol.flags = BSF_WEAK;
1528      break;
1529
1530    case N_WEAKT:
1531      cache_ptr->symbol.section = obj_textsec (abfd);
1532      cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1533      cache_ptr->symbol.flags = BSF_WEAK;
1534      break;
1535
1536    case N_WEAKD:
1537      cache_ptr->symbol.section = obj_datasec (abfd);
1538      cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1539      cache_ptr->symbol.flags = BSF_WEAK;
1540      break;
1541
1542    case N_WEAKB:
1543      cache_ptr->symbol.section = obj_bsssec (abfd);
1544      cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1545      cache_ptr->symbol.flags = BSF_WEAK;
1546      break;
1547    }
1548
1549  return true;
1550}
1551
1552/* Set the fields of SYM_POINTER according to CACHE_PTR.  */
1553
1554static bool
1555translate_to_native_sym_flags (bfd *abfd,
1556			       asymbol *cache_ptr,
1557			       struct external_nlist *sym_pointer)
1558{
1559  bfd_vma value = cache_ptr->value;
1560  asection *sec;
1561  bfd_vma off;
1562
1563  /* Mask out any existing type bits in case copying from one section
1564     to another.  */
1565  sym_pointer->e_type[0] &= ~N_TYPE;
1566
1567  sec = bfd_asymbol_section (cache_ptr);
1568  off = 0;
1569
1570  if (sec == NULL)
1571    {
1572      /* This case occurs, e.g., for the *DEBUG* section of a COFF
1573	 file.  */
1574      _bfd_error_handler
1575	/* xgettext:c-format */
1576	(_("%pB: can not represent section for symbol `%s' in a.out "
1577	   "object file format"),
1578	 abfd,
1579	 cache_ptr->name != NULL ? cache_ptr->name : _("*unknown*"));
1580      bfd_set_error (bfd_error_nonrepresentable_section);
1581      return false;
1582    }
1583
1584  if (sec->output_section != NULL)
1585    {
1586      off = sec->output_offset;
1587      sec = sec->output_section;
1588    }
1589
1590  if (bfd_is_abs_section (sec))
1591    sym_pointer->e_type[0] |= N_ABS;
1592  else if (sec == obj_textsec (abfd))
1593    sym_pointer->e_type[0] |= N_TEXT;
1594  else if (sec == obj_datasec (abfd))
1595    sym_pointer->e_type[0] |= N_DATA;
1596  else if (sec == obj_bsssec (abfd))
1597    sym_pointer->e_type[0] |= N_BSS;
1598  else if (bfd_is_und_section (sec))
1599    sym_pointer->e_type[0] = N_UNDF | N_EXT;
1600  else if (bfd_is_ind_section (sec))
1601    sym_pointer->e_type[0] = N_INDR;
1602  else if (bfd_is_com_section (sec))
1603    sym_pointer->e_type[0] = N_UNDF | N_EXT;
1604  else
1605    {
1606      if (aout_section_merge_with_text_p (abfd, sec))
1607	sym_pointer->e_type[0] |= N_TEXT;
1608      else
1609	{
1610	  _bfd_error_handler
1611	    /* xgettext:c-format */
1612	   (_("%pB: can not represent section `%pA' in a.out object file format"),
1613	     abfd, sec);
1614	  bfd_set_error (bfd_error_nonrepresentable_section);
1615	  return false;
1616	}
1617    }
1618
1619  /* Turn the symbol from section relative to absolute again.  */
1620  value += sec->vma + off;
1621
1622  if ((cache_ptr->flags & BSF_WARNING) != 0)
1623    sym_pointer->e_type[0] = N_WARNING;
1624
1625  if ((cache_ptr->flags & BSF_DEBUGGING) != 0)
1626    sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type;
1627  else if ((cache_ptr->flags & BSF_GLOBAL) != 0)
1628    sym_pointer->e_type[0] |= N_EXT;
1629  else if ((cache_ptr->flags & BSF_LOCAL) != 0)
1630    sym_pointer->e_type[0] &= ~N_EXT;
1631
1632  if ((cache_ptr->flags & BSF_CONSTRUCTOR) != 0)
1633    {
1634      int type = ((aout_symbol_type *) cache_ptr)->type;
1635
1636      switch (type)
1637	{
1638	case N_ABS:	type = N_SETA; break;
1639	case N_TEXT:	type = N_SETT; break;
1640	case N_DATA:	type = N_SETD; break;
1641	case N_BSS:	type = N_SETB; break;
1642	}
1643      sym_pointer->e_type[0] = type;
1644    }
1645
1646  if ((cache_ptr->flags & BSF_WEAK) != 0)
1647    {
1648      int type;
1649
1650      switch (sym_pointer->e_type[0] & N_TYPE)
1651	{
1652	default:
1653	case N_ABS:	type = N_WEAKA; break;
1654	case N_TEXT:	type = N_WEAKT; break;
1655	case N_DATA:	type = N_WEAKD; break;
1656	case N_BSS:	type = N_WEAKB; break;
1657	case N_UNDF:	type = N_WEAKU; break;
1658	}
1659      sym_pointer->e_type[0] = type;
1660    }
1661
1662  PUT_WORD (abfd, value, sym_pointer->e_value);
1663
1664  return true;
1665}
1666
1667/* Native-level interface to symbols.  */
1668
1669asymbol *
1670NAME (aout, make_empty_symbol) (bfd *abfd)
1671{
1672  size_t amt = sizeof (aout_symbol_type);
1673
1674  aout_symbol_type *new_symbol = (aout_symbol_type *) bfd_zalloc (abfd, amt);
1675  if (!new_symbol)
1676    return NULL;
1677  new_symbol->symbol.the_bfd = abfd;
1678
1679  return &new_symbol->symbol;
1680}
1681
1682/* Translate a set of external symbols into internal symbols.  */
1683
1684bool
1685NAME (aout, translate_symbol_table) (bfd *abfd,
1686				     aout_symbol_type *in,
1687				     struct external_nlist *ext,
1688				     bfd_size_type count,
1689				     char *str,
1690				     bfd_size_type strsize,
1691				     bool dynamic)
1692{
1693  struct external_nlist *ext_end;
1694
1695  ext_end = ext + count;
1696  for (; ext < ext_end; ext++, in++)
1697    {
1698      bfd_vma x;
1699
1700      x = GET_WORD (abfd, ext->e_strx);
1701      in->symbol.the_bfd = abfd;
1702
1703      /* For the normal symbols, the zero index points at the number
1704	 of bytes in the string table but is to be interpreted as the
1705	 null string.  For the dynamic symbols, the number of bytes in
1706	 the string table is stored in the __DYNAMIC structure and the
1707	 zero index points at an actual string.  */
1708      if (x == 0 && ! dynamic)
1709	in->symbol.name = "";
1710      else if (x < strsize)
1711	in->symbol.name = str + x;
1712      else
1713	{
1714	  _bfd_error_handler
1715	    (_("%pB: invalid string offset %" PRIu64 " >= %" PRIu64),
1716	     abfd, (uint64_t) x, (uint64_t) strsize);
1717	  bfd_set_error (bfd_error_bad_value);
1718	  return false;
1719	}
1720
1721      in->symbol.value = GET_SWORD (abfd,  ext->e_value);
1722      in->desc = H_GET_16 (abfd, ext->e_desc);
1723      in->other = H_GET_8 (abfd, ext->e_other);
1724      in->type = H_GET_8 (abfd,  ext->e_type);
1725      in->symbol.udata.p = NULL;
1726
1727      if (! translate_from_native_sym_flags (abfd, in))
1728	return false;
1729
1730      if (dynamic)
1731	in->symbol.flags |= BSF_DYNAMIC;
1732    }
1733
1734  return true;
1735}
1736
1737/* We read the symbols into a buffer, which is discarded when this
1738   function exits.  We read the strings into a buffer large enough to
1739   hold them all plus all the cached symbol entries.  */
1740
1741bool
1742NAME (aout, slurp_symbol_table) (bfd *abfd)
1743{
1744  struct external_nlist *old_external_syms;
1745  aout_symbol_type *cached;
1746  bfd_size_type cached_size;
1747
1748  /* If there's no work to be done, don't do any.  */
1749  if (obj_aout_symbols (abfd) != NULL)
1750    return true;
1751
1752  old_external_syms = obj_aout_external_syms (abfd);
1753
1754  if (! aout_get_external_symbols (abfd))
1755    return false;
1756
1757  cached_size = obj_aout_external_sym_count (abfd);
1758  if (cached_size == 0)
1759    return true;		/* Nothing to do.  */
1760
1761  cached_size *= sizeof (aout_symbol_type);
1762  cached = (aout_symbol_type *) bfd_zmalloc (cached_size);
1763  if (cached == NULL)
1764    return false;
1765
1766  /* Convert from external symbol information to internal.  */
1767  if (! (NAME (aout, translate_symbol_table)
1768	 (abfd, cached,
1769	  obj_aout_external_syms (abfd),
1770	  obj_aout_external_sym_count (abfd),
1771	  obj_aout_external_strings (abfd),
1772	  obj_aout_external_string_size (abfd),
1773	  false)))
1774    {
1775      free (cached);
1776      return false;
1777    }
1778
1779  abfd->symcount = obj_aout_external_sym_count (abfd);
1780
1781  obj_aout_symbols (abfd) = cached;
1782
1783  /* It is very likely that anybody who calls this function will not
1784     want the external symbol information, so if it was allocated
1785     because of our call to aout_get_external_symbols, we free it up
1786     right away to save space.  */
1787  if (old_external_syms == NULL
1788      && obj_aout_external_syms (abfd) != NULL)
1789    {
1790#ifdef USE_MMAP
1791      bfd_free_window (&obj_aout_sym_window (abfd));
1792#else
1793      free (obj_aout_external_syms (abfd));
1794#endif
1795      obj_aout_external_syms (abfd) = NULL;
1796    }
1797
1798  return true;
1799}
1800
1801/* We use a hash table when writing out symbols so that we only write
1802   out a particular string once.  This helps particularly when the
1803   linker writes out stabs debugging entries, because each different
1804   contributing object file tends to have many duplicate stabs
1805   strings.
1806
1807   This hash table code breaks dbx on SunOS 4.1.3, so we don't do it
1808   if BFD_TRADITIONAL_FORMAT is set.  */
1809
1810/* Get the index of a string in a strtab, adding it if it is not
1811   already present.  */
1812
1813static inline bfd_size_type
1814add_to_stringtab (bfd *abfd,
1815		  struct bfd_strtab_hash *tab,
1816		  const char *str,
1817		  bool copy)
1818{
1819  bool hash;
1820  bfd_size_type str_index;
1821
1822  /* An index of 0 always means the empty string.  */
1823  if (str == 0 || *str == '\0')
1824    return 0;
1825
1826  /* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx
1827     doesn't understand a hashed string table.  */
1828  hash = true;
1829  if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
1830    hash = false;
1831
1832  str_index = _bfd_stringtab_add (tab, str, hash, copy);
1833
1834  if (str_index != (bfd_size_type) -1)
1835    /* Add BYTES_IN_WORD to the return value to account for the
1836       space taken up by the string table size.  */
1837    str_index += BYTES_IN_WORD;
1838
1839  return str_index;
1840}
1841
1842/* Write out a strtab.  ABFD is already at the right location in the
1843   file.  */
1844
1845static bool
1846emit_stringtab (bfd *abfd, struct bfd_strtab_hash *tab)
1847{
1848  bfd_byte buffer[BYTES_IN_WORD];
1849  size_t amt = BYTES_IN_WORD;
1850
1851  /* The string table starts with the size.  */
1852  PUT_WORD (abfd, _bfd_stringtab_size (tab) + BYTES_IN_WORD, buffer);
1853  if (bfd_bwrite ((void *) buffer, amt, abfd) != amt)
1854    return false;
1855
1856  return _bfd_stringtab_emit (abfd, tab);
1857}
1858
1859bool
1860NAME (aout, write_syms) (bfd *abfd)
1861{
1862  unsigned int count ;
1863  asymbol **generic = bfd_get_outsymbols (abfd);
1864  struct bfd_strtab_hash *strtab;
1865
1866  strtab = _bfd_stringtab_init ();
1867  if (strtab == NULL)
1868    return false;
1869
1870  for (count = 0; count < bfd_get_symcount (abfd); count++)
1871    {
1872      asymbol *g = generic[count];
1873      bfd_size_type indx;
1874      struct external_nlist nsp;
1875      size_t amt;
1876
1877      indx = add_to_stringtab (abfd, strtab, g->name, false);
1878      if (indx == (bfd_size_type) -1)
1879	goto error_return;
1880      PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx);
1881
1882      if (bfd_asymbol_flavour (g) == abfd->xvec->flavour)
1883	{
1884	  H_PUT_16 (abfd, aout_symbol (g)->desc,  nsp.e_desc);
1885	  H_PUT_8  (abfd, aout_symbol (g)->other, nsp.e_other);
1886	  H_PUT_8  (abfd, aout_symbol (g)->type,  nsp.e_type);
1887	}
1888      else
1889	{
1890	  H_PUT_16 (abfd, 0, nsp.e_desc);
1891	  H_PUT_8  (abfd, 0, nsp.e_other);
1892	  H_PUT_8  (abfd, 0, nsp.e_type);
1893	}
1894
1895      if (! translate_to_native_sym_flags (abfd, g, &nsp))
1896	goto error_return;
1897
1898      amt = EXTERNAL_NLIST_SIZE;
1899      if (bfd_bwrite ((void *) &nsp, amt, abfd) != amt)
1900	goto error_return;
1901
1902      /* NB: `KEEPIT' currently overlays `udata.p', so set this only
1903	 here, at the end.  */
1904      g->KEEPIT = count;
1905    }
1906
1907  if (! emit_stringtab (abfd, strtab))
1908    goto error_return;
1909
1910  _bfd_stringtab_free (strtab);
1911
1912  return true;
1913
1914 error_return:
1915  _bfd_stringtab_free (strtab);
1916  return false;
1917}
1918
1919long
1920NAME (aout, canonicalize_symtab) (bfd *abfd, asymbol **location)
1921{
1922  unsigned int counter = 0;
1923  aout_symbol_type *symbase;
1924
1925  if (!NAME (aout, slurp_symbol_table) (abfd))
1926    return -1;
1927
1928  for (symbase = obj_aout_symbols (abfd);
1929       counter++ < bfd_get_symcount (abfd);
1930       )
1931    *(location++) = (asymbol *) (symbase++);
1932  *location++ =0;
1933  return bfd_get_symcount (abfd);
1934}
1935
1936/* Standard reloc stuff.  */
1937/* Output standard relocation information to a file in target byte order.  */
1938
1939extern void  NAME (aout, swap_std_reloc_out)
1940  (bfd *, arelent *, struct reloc_std_external *);
1941
1942void
1943NAME (aout, swap_std_reloc_out) (bfd *abfd,
1944				 arelent *g,
1945				 struct reloc_std_external *natptr)
1946{
1947  int r_index;
1948  asymbol *sym = *(g->sym_ptr_ptr);
1949  int r_extern;
1950  unsigned int r_length, r_size;
1951  int r_pcrel;
1952  int r_baserel, r_jmptable, r_relative;
1953  asection *output_section = sym->section->output_section;
1954
1955  PUT_WORD (abfd, g->address, natptr->r_address);
1956
1957  BFD_ASSERT (g->howto != NULL);
1958
1959  r_size = bfd_get_reloc_size (g->howto);
1960  r_length = bfd_log2 (r_size);
1961  if (1u << r_length != r_size)
1962    {
1963      _bfd_error_handler (_("%pB: unsupported AOUT relocation size: %d"),
1964			  abfd, r_size);
1965      bfd_set_error (bfd_error_bad_value);
1966      return;
1967    }
1968
1969  r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC?  */
1970  /* XXX This relies on relocs coming from a.out files.  */
1971  r_baserel = (g->howto->type & 8) != 0;
1972  r_jmptable = (g->howto->type & 16) != 0;
1973  r_relative = (g->howto->type & 32) != 0;
1974
1975  /* Name was clobbered by aout_write_syms to be symbol index.  */
1976
1977  /* If this relocation is relative to a symbol then set the
1978     r_index to the symbols index, and the r_extern bit.
1979
1980     Absolute symbols can come in in two ways, either as an offset
1981     from the abs section, or as a symbol which has an abs value.
1982     check for that here.  */
1983
1984  if (bfd_is_com_section (output_section)
1985      || bfd_is_abs_section (output_section)
1986      || bfd_is_und_section (output_section)
1987      /* PR gas/3041  a.out relocs against weak symbols
1988	 must be treated as if they were against externs.  */
1989      || (sym->flags & BSF_WEAK))
1990    {
1991      if (bfd_abs_section_ptr->symbol == sym)
1992	{
1993	  /* Whoops, looked like an abs symbol, but is
1994	     really an offset from the abs section.  */
1995	  r_index = N_ABS;
1996	  r_extern = 0;
1997	}
1998      else
1999	{
2000	  /* Fill in symbol.  */
2001	  r_extern = 1;
2002	  r_index = (*(g->sym_ptr_ptr))->KEEPIT;
2003	}
2004    }
2005  else
2006    {
2007      /* Just an ordinary section.  */
2008      r_extern = 0;
2009      r_index  = output_section->target_index;
2010    }
2011
2012  /* Now the fun stuff.  */
2013  if (bfd_header_big_endian (abfd))
2014    {
2015      natptr->r_index[0] = r_index >> 16;
2016      natptr->r_index[1] = r_index >> 8;
2017      natptr->r_index[2] = r_index;
2018      natptr->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_BIG : 0)
2019			   | (r_pcrel ? RELOC_STD_BITS_PCREL_BIG : 0)
2020			   | (r_baserel ? RELOC_STD_BITS_BASEREL_BIG : 0)
2021			   | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
2022			   | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
2023			   | (r_length << RELOC_STD_BITS_LENGTH_SH_BIG));
2024    }
2025  else
2026    {
2027      natptr->r_index[2] = r_index >> 16;
2028      natptr->r_index[1] = r_index >> 8;
2029      natptr->r_index[0] = r_index;
2030      natptr->r_type[0] = ((r_extern ? RELOC_STD_BITS_EXTERN_LITTLE : 0)
2031			   | (r_pcrel ? RELOC_STD_BITS_PCREL_LITTLE : 0)
2032			   | (r_baserel ? RELOC_STD_BITS_BASEREL_LITTLE : 0)
2033			   | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
2034			   | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
2035			   | (r_length << RELOC_STD_BITS_LENGTH_SH_LITTLE));
2036    }
2037}
2038
2039/* Extended stuff.  */
2040/* Output extended relocation information to a file in target byte order.  */
2041
2042extern void NAME (aout, swap_ext_reloc_out)
2043  (bfd *, arelent *, struct reloc_ext_external *);
2044
2045void
2046NAME (aout, swap_ext_reloc_out) (bfd *abfd,
2047				 arelent *g,
2048				 struct reloc_ext_external *natptr)
2049{
2050  int r_index;
2051  int r_extern;
2052  unsigned int r_type;
2053  bfd_vma r_addend;
2054  asymbol *sym = *(g->sym_ptr_ptr);
2055  asection *output_section = sym->section->output_section;
2056
2057  PUT_WORD (abfd, g->address, natptr->r_address);
2058
2059  r_type = (unsigned int) g->howto->type;
2060
2061  r_addend = g->addend;
2062  if ((sym->flags & BSF_SECTION_SYM) != 0)
2063    r_addend += (*(g->sym_ptr_ptr))->section->output_section->vma;
2064
2065  /* If this relocation is relative to a symbol then set the
2066     r_index to the symbols index, and the r_extern bit.
2067
2068     Absolute symbols can come in in two ways, either as an offset
2069     from the abs section, or as a symbol which has an abs value.
2070     check for that here.  */
2071  if (bfd_is_abs_section (bfd_asymbol_section (sym)))
2072    {
2073      r_extern = 0;
2074      r_index = N_ABS;
2075    }
2076  else if ((sym->flags & BSF_SECTION_SYM) == 0)
2077    {
2078      if (bfd_is_und_section (bfd_asymbol_section (sym))
2079	  || (sym->flags & BSF_GLOBAL) != 0)
2080	r_extern = 1;
2081      else
2082	r_extern = 0;
2083      r_index = (*(g->sym_ptr_ptr))->KEEPIT;
2084    }
2085  else
2086    {
2087      /* Just an ordinary section.  */
2088      r_extern = 0;
2089      r_index = output_section->target_index;
2090    }
2091
2092  /* Now the fun stuff.  */
2093  if (bfd_header_big_endian (abfd))
2094    {
2095      natptr->r_index[0] = r_index >> 16;
2096      natptr->r_index[1] = r_index >> 8;
2097      natptr->r_index[2] = r_index;
2098      natptr->r_type[0] = ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
2099			   | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
2100    }
2101  else
2102    {
2103      natptr->r_index[2] = r_index >> 16;
2104      natptr->r_index[1] = r_index >> 8;
2105      natptr->r_index[0] = r_index;
2106      natptr->r_type[0] = ((r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
2107			   | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE));
2108    }
2109
2110  PUT_WORD (abfd, r_addend, natptr->r_addend);
2111}
2112
2113/* BFD deals internally with all things based from the section they're
2114   in. so, something in 10 bytes into a text section  with a base of
2115   50 would have a symbol (.text+10) and know .text vma was 50.
2116
2117   Aout keeps all it's symbols based from zero, so the symbol would
2118   contain 60. This macro subs the base of each section from the value
2119   to give the true offset from the section.  */
2120
2121#define MOVE_ADDRESS(ad)						\
2122  if (r_extern)								\
2123    {									\
2124      /* Undefined symbol.  */						\
2125      if (r_index < bfd_get_symcount (abfd))				\
2126	cache_ptr->sym_ptr_ptr = symbols + r_index;			\
2127      cache_ptr->addend = ad;						\
2128    }									\
2129   else									\
2130    {									\
2131      /* Defined, section relative.  Replace symbol with pointer to	\
2132	 symbol which points to section.  */				\
2133      switch (r_index)							\
2134	{								\
2135	case N_TEXT:							\
2136	case N_TEXT | N_EXT:						\
2137	  cache_ptr->sym_ptr_ptr = obj_textsec (abfd)->symbol_ptr_ptr;	\
2138	  cache_ptr->addend = ad - su->textsec->vma;			\
2139	  break;							\
2140	case N_DATA:							\
2141	case N_DATA | N_EXT:						\
2142	  cache_ptr->sym_ptr_ptr = obj_datasec (abfd)->symbol_ptr_ptr;	\
2143	  cache_ptr->addend = ad - su->datasec->vma;			\
2144	  break;							\
2145	case N_BSS:							\
2146	case N_BSS | N_EXT:						\
2147	  cache_ptr->sym_ptr_ptr = obj_bsssec (abfd)->symbol_ptr_ptr;	\
2148	  cache_ptr->addend = ad - su->bsssec->vma;			\
2149	  break;							\
2150	default:							\
2151	case N_ABS:							\
2152	case N_ABS | N_EXT:						\
2153	  cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;	\
2154	  cache_ptr->addend = ad;					\
2155	  break;							\
2156	}								\
2157    }
2158
2159void
2160NAME (aout, swap_ext_reloc_in) (bfd *abfd,
2161				struct reloc_ext_external *bytes,
2162				arelent *cache_ptr,
2163				asymbol **symbols,
2164				bfd_size_type symcount)
2165{
2166  unsigned int r_index;
2167  int r_extern;
2168  unsigned int r_type;
2169  struct aoutdata *su = &(abfd->tdata.aout_data->a);
2170
2171  cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
2172
2173  /* Now the fun stuff.  */
2174  if (bfd_header_big_endian (abfd))
2175    {
2176      r_index = (((unsigned int) bytes->r_index[0] << 16)
2177		 | ((unsigned int) bytes->r_index[1] << 8)
2178		 | bytes->r_index[2]);
2179      r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
2180      r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
2181		>> RELOC_EXT_BITS_TYPE_SH_BIG);
2182    }
2183  else
2184    {
2185      r_index =  (((unsigned int) bytes->r_index[2] << 16)
2186		  | ((unsigned int) bytes->r_index[1] << 8)
2187		  | bytes->r_index[0]);
2188      r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
2189      r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
2190		>> RELOC_EXT_BITS_TYPE_SH_LITTLE);
2191    }
2192
2193  if (r_type < TABLE_SIZE (howto_table_ext))
2194    cache_ptr->howto = howto_table_ext + r_type;
2195  else
2196    cache_ptr->howto = NULL;
2197
2198  /* Base relative relocs are always against the symbol table,
2199     regardless of the setting of r_extern.  r_extern just reflects
2200     whether the symbol the reloc is against is local or global.  */
2201  if (r_type == (unsigned int) RELOC_BASE10
2202      || r_type == (unsigned int) RELOC_BASE13
2203      || r_type == (unsigned int) RELOC_BASE22)
2204    r_extern = 1;
2205
2206  if (r_extern && r_index > symcount)
2207    {
2208      /* We could arrange to return an error, but it might be useful
2209	 to see the file even if it is bad.  */
2210      r_extern = 0;
2211      r_index = N_ABS;
2212    }
2213
2214  MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
2215}
2216
2217void
2218NAME (aout, swap_std_reloc_in) (bfd *abfd,
2219				struct reloc_std_external *bytes,
2220				arelent *cache_ptr,
2221				asymbol **symbols,
2222				bfd_size_type symcount)
2223{
2224  unsigned int r_index;
2225  int r_extern;
2226  unsigned int r_length;
2227  int r_pcrel;
2228  int r_baserel, r_jmptable, r_relative;
2229  struct aoutdata  *su = &(abfd->tdata.aout_data->a);
2230  unsigned int howto_idx;
2231
2232  cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
2233
2234  /* Now the fun stuff.  */
2235  if (bfd_header_big_endian (abfd))
2236    {
2237      r_index = (((unsigned int) bytes->r_index[0] << 16)
2238		 | ((unsigned int) bytes->r_index[1] << 8)
2239		 | bytes->r_index[2]);
2240      r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
2241      r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
2242      r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
2243      r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
2244      r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
2245      r_length  = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
2246		   >> RELOC_STD_BITS_LENGTH_SH_BIG);
2247    }
2248  else
2249    {
2250      r_index = (((unsigned int) bytes->r_index[2] << 16)
2251		 | ((unsigned int) bytes->r_index[1] << 8)
2252		 | bytes->r_index[0]);
2253      r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
2254      r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
2255      r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
2256      r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
2257      r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
2258      r_length  = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
2259		   >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
2260    }
2261
2262  howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
2263	       + 16 * r_jmptable + 32 * r_relative);
2264  if (howto_idx < TABLE_SIZE (howto_table_std))
2265    {
2266      cache_ptr->howto = howto_table_std + howto_idx;
2267      if (cache_ptr->howto->type == (unsigned int) -1)
2268	cache_ptr->howto = NULL;
2269    }
2270  else
2271    cache_ptr->howto = NULL;
2272
2273  /* Base relative relocs are always against the symbol table,
2274     regardless of the setting of r_extern.  r_extern just reflects
2275     whether the symbol the reloc is against is local or global.  */
2276  if (r_baserel)
2277    r_extern = 1;
2278
2279  if (r_extern && r_index >= symcount)
2280    {
2281      /* We could arrange to return an error, but it might be useful
2282	 to see the file even if it is bad.  FIXME: Of course this
2283	 means that objdump -r *doesn't* see the actual reloc, and
2284	 objcopy silently writes a different reloc.  */
2285      r_extern = 0;
2286      r_index = N_ABS;
2287    }
2288
2289  MOVE_ADDRESS (0);
2290}
2291
2292/* Read and swap the relocs for a section.  */
2293
2294bool
2295NAME (aout, slurp_reloc_table) (bfd *abfd, sec_ptr asect, asymbol **symbols)
2296{
2297  bfd_size_type count;
2298  bfd_size_type reloc_size;
2299  void * relocs;
2300  arelent *reloc_cache;
2301  size_t each_size;
2302  unsigned int counter = 0;
2303  arelent *cache_ptr;
2304  bfd_size_type amt;
2305
2306  if (asect->relocation)
2307    return true;
2308
2309  if (asect->flags & SEC_CONSTRUCTOR)
2310    return true;
2311
2312  if (asect == obj_datasec (abfd))
2313    reloc_size = exec_hdr (abfd)->a_drsize;
2314  else if (asect == obj_textsec (abfd))
2315    reloc_size = exec_hdr (abfd)->a_trsize;
2316  else if (asect == obj_bsssec (abfd))
2317    reloc_size = 0;
2318  else
2319    {
2320      bfd_set_error (bfd_error_invalid_operation);
2321      return false;
2322    }
2323
2324  each_size = obj_reloc_entry_size (abfd);
2325  count = reloc_size / each_size;
2326  if (count == 0)
2327    return true;		/* Nothing to be done.  */
2328
2329  if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
2330    return false;
2331  relocs = _bfd_malloc_and_read (abfd, reloc_size, reloc_size);
2332  if (relocs == NULL)
2333    return false;
2334
2335  amt = count * sizeof (arelent);
2336  reloc_cache = (arelent *) bfd_zmalloc (amt);
2337  if (reloc_cache == NULL)
2338    {
2339      free (relocs);
2340      return false;
2341    }
2342
2343  cache_ptr = reloc_cache;
2344  if (each_size == RELOC_EXT_SIZE)
2345    {
2346      struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
2347
2348      for (; counter < count; counter++, rptr++, cache_ptr++)
2349	MY_swap_ext_reloc_in (abfd, rptr, cache_ptr, symbols,
2350			      (bfd_size_type) bfd_get_symcount (abfd));
2351    }
2352  else
2353    {
2354      struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
2355
2356      for (; counter < count; counter++, rptr++, cache_ptr++)
2357	MY_swap_std_reloc_in (abfd, rptr, cache_ptr, symbols,
2358			      (bfd_size_type) bfd_get_symcount (abfd));
2359    }
2360
2361  free (relocs);
2362
2363  asect->relocation = reloc_cache;
2364  asect->reloc_count = cache_ptr - reloc_cache;
2365
2366  return true;
2367}
2368
2369/* Write out a relocation section into an object file.  */
2370
2371bool
2372NAME (aout, squirt_out_relocs) (bfd *abfd, asection *section)
2373{
2374  arelent **generic;
2375  unsigned char *native, *natptr;
2376  size_t each_size;
2377
2378  unsigned int count = section->reloc_count;
2379  bfd_size_type natsize;
2380
2381  if (count == 0 || section->orelocation == NULL)
2382    return true;
2383
2384  each_size = obj_reloc_entry_size (abfd);
2385  natsize = (bfd_size_type) each_size * count;
2386  native = (unsigned char *) bfd_zalloc (abfd, natsize);
2387  if (!native)
2388    return false;
2389
2390  generic = section->orelocation;
2391
2392  if (each_size == RELOC_EXT_SIZE)
2393    {
2394      for (natptr = native;
2395	   count != 0;
2396	   --count, natptr += each_size, ++generic)
2397	{
2398	  /* PR 20921: If the howto field has not been initialised then skip
2399	     this reloc.
2400	     PR 20929: Similarly for the symbol field.  */
2401	  if ((*generic)->howto == NULL
2402	      || (*generic)->sym_ptr_ptr == NULL)
2403	    {
2404	      bfd_set_error (bfd_error_invalid_operation);
2405	      _bfd_error_handler (_("%pB: attempt to write out "
2406				    "unknown reloc type"), abfd);
2407	      return false;
2408	    }
2409	  MY_swap_ext_reloc_out (abfd, *generic,
2410				 (struct reloc_ext_external *) natptr);
2411	}
2412    }
2413  else
2414    {
2415      for (natptr = native;
2416	   count != 0;
2417	   --count, natptr += each_size, ++generic)
2418	{
2419	  if ((*generic)->howto == NULL
2420	      || (*generic)->sym_ptr_ptr == NULL)
2421	    {
2422	      bfd_set_error (bfd_error_invalid_operation);
2423	      _bfd_error_handler (_("%pB: attempt to write out "
2424				    "unknown reloc type"), abfd);
2425	      return false;
2426	    }
2427	  MY_swap_std_reloc_out (abfd, *generic,
2428				 (struct reloc_std_external *) natptr);
2429	}
2430    }
2431
2432  if (bfd_bwrite ((void *) native, natsize, abfd) != natsize)
2433    {
2434      bfd_release (abfd, native);
2435      return false;
2436    }
2437  bfd_release (abfd, native);
2438
2439  return true;
2440}
2441
2442/* This is stupid.  This function should be a boolean predicate.  */
2443
2444long
2445NAME (aout, canonicalize_reloc) (bfd *abfd,
2446				 sec_ptr section,
2447				 arelent **relptr,
2448				 asymbol **symbols)
2449{
2450  arelent *tblptr = section->relocation;
2451  unsigned int count;
2452
2453  if (section == obj_bsssec (abfd))
2454    {
2455      *relptr = NULL;
2456      return 0;
2457    }
2458
2459  if (!(tblptr || NAME (aout, slurp_reloc_table) (abfd, section, symbols)))
2460    return -1;
2461
2462  if (section->flags & SEC_CONSTRUCTOR)
2463    {
2464      arelent_chain *chain = section->constructor_chain;
2465      for (count = 0; count < section->reloc_count; count ++)
2466	{
2467	  *relptr ++ = &chain->relent;
2468	  chain = chain->next;
2469	}
2470    }
2471  else
2472    {
2473      tblptr = section->relocation;
2474
2475      for (count = 0; count++ < section->reloc_count; )
2476	{
2477	  *relptr++ = tblptr++;
2478	}
2479    }
2480  *relptr = 0;
2481
2482  return section->reloc_count;
2483}
2484
2485long
2486NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect)
2487{
2488  bfd_size_type count;
2489
2490  if (bfd_get_format (abfd) != bfd_object)
2491    {
2492      bfd_set_error (bfd_error_invalid_operation);
2493      return -1;
2494    }
2495
2496  if (asect->flags & SEC_CONSTRUCTOR)
2497    count = asect->reloc_count;
2498  else if (asect == obj_datasec (abfd))
2499    count = exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
2500  else if (asect == obj_textsec (abfd))
2501    count = exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
2502  else if (asect == obj_bsssec (abfd))
2503    count = 0;
2504  else
2505    {
2506      bfd_set_error (bfd_error_invalid_operation);
2507      return -1;
2508    }
2509
2510  if (count >= LONG_MAX / sizeof (arelent *))
2511    {
2512      bfd_set_error (bfd_error_file_too_big);
2513      return -1;
2514    }
2515  return (count + 1) * sizeof (arelent *);
2516}
2517
2518long
2519NAME (aout, get_symtab_upper_bound) (bfd *abfd)
2520{
2521  if (!NAME (aout, slurp_symbol_table) (abfd))
2522    return -1;
2523
2524  return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
2525}
2526
2527alent *
2528NAME (aout, get_lineno) (bfd *ignore_abfd ATTRIBUTE_UNUSED,
2529			 asymbol *ignore_symbol ATTRIBUTE_UNUSED)
2530{
2531  return NULL;
2532}
2533
2534void
2535NAME (aout, get_symbol_info) (bfd *ignore_abfd ATTRIBUTE_UNUSED,
2536			      asymbol *symbol,
2537			      symbol_info *ret)
2538{
2539  bfd_symbol_info (symbol, ret);
2540
2541  if (ret->type == '?')
2542    {
2543      int type_code = aout_symbol (symbol)->type & 0xff;
2544      const char *stab_name = bfd_get_stab_name (type_code);
2545      static char buf[10];
2546
2547      if (stab_name == NULL)
2548	{
2549	  sprintf (buf, "(%d)", type_code);
2550	  stab_name = buf;
2551	}
2552      ret->type = '-';
2553      ret->stab_type = type_code;
2554      ret->stab_other = (unsigned) (aout_symbol (symbol)->other & 0xff);
2555      ret->stab_desc = (unsigned) (aout_symbol (symbol)->desc & 0xffff);
2556      ret->stab_name = stab_name;
2557    }
2558}
2559
2560void
2561NAME (aout, print_symbol) (bfd *abfd,
2562			   void * afile,
2563			   asymbol *symbol,
2564			   bfd_print_symbol_type how)
2565{
2566  FILE *file = (FILE *)afile;
2567
2568  switch (how)
2569    {
2570    case bfd_print_symbol_name:
2571      if (symbol->name)
2572	fprintf (file,"%s", symbol->name);
2573      break;
2574    case bfd_print_symbol_more:
2575      fprintf (file,"%4x %2x %2x",
2576	       (unsigned) (aout_symbol (symbol)->desc & 0xffff),
2577	       (unsigned) (aout_symbol (symbol)->other & 0xff),
2578	       (unsigned) (aout_symbol (symbol)->type));
2579      break;
2580    case bfd_print_symbol_all:
2581      {
2582	const char *section_name = symbol->section->name;
2583
2584	bfd_print_symbol_vandf (abfd, (void *)file, symbol);
2585
2586	fprintf (file," %-5s %04x %02x %02x",
2587		 section_name,
2588		 (unsigned) (aout_symbol (symbol)->desc & 0xffff),
2589		 (unsigned) (aout_symbol (symbol)->other & 0xff),
2590		 (unsigned) (aout_symbol (symbol)->type & 0xff));
2591	if (symbol->name)
2592	  fprintf (file," %s", symbol->name);
2593      }
2594      break;
2595    }
2596}
2597
2598/* If we don't have to allocate more than 1MB to hold the generic
2599   symbols, we use the generic minisymbol methord: it's faster, since
2600   it only translates the symbols once, not multiple times.  */
2601#define MINISYM_THRESHOLD (1000000 / sizeof (asymbol))
2602
2603/* Read minisymbols.  For minisymbols, we use the unmodified a.out
2604   symbols.  The minisymbol_to_symbol function translates these into
2605   BFD asymbol structures.  */
2606
2607long
2608NAME (aout, read_minisymbols) (bfd *abfd,
2609			       bool dynamic,
2610			       void * *minisymsp,
2611			       unsigned int *sizep)
2612{
2613  if (dynamic)
2614    /* We could handle the dynamic symbols here as well, but it's
2615       easier to hand them off.  */
2616    return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2617
2618  if (! aout_get_external_symbols (abfd))
2619    return -1;
2620
2621  if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2622    return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2623
2624  *minisymsp = (void *) obj_aout_external_syms (abfd);
2625
2626  /* By passing the external symbols back from this routine, we are
2627     giving up control over the memory block.  Clear
2628     obj_aout_external_syms, so that we do not try to free it
2629     ourselves.  */
2630  obj_aout_external_syms (abfd) = NULL;
2631
2632  *sizep = EXTERNAL_NLIST_SIZE;
2633  return obj_aout_external_sym_count (abfd);
2634}
2635
2636/* Convert a minisymbol to a BFD asymbol.  A minisymbol is just an
2637   unmodified a.out symbol.  The SYM argument is a structure returned
2638   by bfd_make_empty_symbol, which we fill in here.  */
2639
2640asymbol *
2641NAME (aout, minisymbol_to_symbol) (bfd *abfd,
2642				   bool dynamic,
2643				   const void * minisym,
2644				   asymbol *sym)
2645{
2646  if (dynamic
2647      || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2648    return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
2649
2650  memset (sym, 0, sizeof (aout_symbol_type));
2651
2652  /* We call translate_symbol_table to translate a single symbol.  */
2653  if (! (NAME (aout, translate_symbol_table)
2654	 (abfd,
2655	  (aout_symbol_type *) sym,
2656	  (struct external_nlist *) minisym,
2657	  (bfd_size_type) 1,
2658	  obj_aout_external_strings (abfd),
2659	  obj_aout_external_string_size (abfd),
2660	  false)))
2661    return NULL;
2662
2663  return sym;
2664}
2665
2666/* Provided a BFD, a section and an offset into the section, calculate
2667   and return the name of the source file and the line nearest to the
2668   wanted location.  */
2669
2670bool
2671NAME (aout, find_nearest_line) (bfd *abfd,
2672				asymbol **symbols,
2673				asection *section,
2674				bfd_vma offset,
2675				const char **filename_ptr,
2676				const char **functionname_ptr,
2677				unsigned int *line_ptr,
2678				unsigned int *disriminator_ptr)
2679{
2680  /* Run down the file looking for the filename, function and linenumber.  */
2681  asymbol **p;
2682  const char *directory_name = NULL;
2683  const char *main_file_name = NULL;
2684  const char *current_file_name = NULL;
2685  const char *line_file_name = NULL;      /* Value of current_file_name at line number.  */
2686  const char *line_directory_name = NULL; /* Value of directory_name at line number.  */
2687  bfd_vma low_line_vma = 0;
2688  bfd_vma low_func_vma = 0;
2689  asymbol *func = 0;
2690  bfd_size_type filelen, funclen;
2691  char *buf;
2692
2693  *filename_ptr = bfd_get_filename (abfd);
2694  *functionname_ptr = NULL;
2695  *line_ptr = 0;
2696  if (disriminator_ptr)
2697    *disriminator_ptr = 0;
2698
2699  if (symbols != NULL)
2700    {
2701      for (p = symbols; *p; p++)
2702	{
2703	  aout_symbol_type  *q = (aout_symbol_type *) (*p);
2704	next:
2705	  switch (q->type)
2706	    {
2707	    case N_TEXT:
2708	      /* If this looks like a file name symbol, and it comes after
2709		 the line number we have found so far, but before the
2710		 offset, then we have probably not found the right line
2711		 number.  */
2712	      if (q->symbol.value <= offset
2713		  && ((q->symbol.value > low_line_vma
2714		       && (line_file_name != NULL
2715			   || *line_ptr != 0))
2716		      || (q->symbol.value > low_func_vma
2717			  && func != NULL)))
2718		{
2719		  const char *symname;
2720
2721		  symname = q->symbol.name;
2722
2723		  if (symname != NULL
2724		      && strlen (symname) > 2
2725		      && strcmp (symname + strlen (symname) - 2, ".o") == 0)
2726		    {
2727		      if (q->symbol.value > low_line_vma)
2728			{
2729			  *line_ptr = 0;
2730			  line_file_name = NULL;
2731			}
2732		      if (q->symbol.value > low_func_vma)
2733			func = NULL;
2734		    }
2735		}
2736	      break;
2737
2738	    case N_SO:
2739	      /* If this symbol is less than the offset, but greater than
2740		 the line number we have found so far, then we have not
2741		 found the right line number.  */
2742	      if (q->symbol.value <= offset)
2743		{
2744		  if (q->symbol.value > low_line_vma)
2745		    {
2746		      *line_ptr = 0;
2747		      line_file_name = NULL;
2748		    }
2749		  if (q->symbol.value > low_func_vma)
2750		    func = NULL;
2751		}
2752
2753	      main_file_name = current_file_name = q->symbol.name;
2754	      /* Look ahead to next symbol to check if that too is an N_SO.  */
2755	      p++;
2756	      if (*p == NULL)
2757		goto done;
2758	      q = (aout_symbol_type *) (*p);
2759	      if (q->type != (int)N_SO)
2760		goto next;
2761
2762	      /* Found a second N_SO  First is directory; second is filename.  */
2763	      directory_name = current_file_name;
2764	      main_file_name = current_file_name = q->symbol.name;
2765	      if (obj_textsec (abfd) != section)
2766		goto done;
2767	      break;
2768	    case N_SOL:
2769	      current_file_name = q->symbol.name;
2770	      break;
2771
2772	    case N_SLINE:
2773
2774	    case N_DSLINE:
2775	    case N_BSLINE:
2776	      /* We'll keep this if it resolves nearer than the one we have
2777		 already.  */
2778	      if (q->symbol.value >= low_line_vma
2779		  && q->symbol.value <= offset)
2780		{
2781		  *line_ptr = q->desc;
2782		  low_line_vma = q->symbol.value;
2783		  line_file_name = current_file_name;
2784		  line_directory_name = directory_name;
2785		}
2786	      break;
2787	    case N_FUN:
2788	      {
2789		/* We'll keep this if it is nearer than the one we have already.  */
2790		if (q->symbol.value >= low_func_vma
2791		    && q->symbol.value <= offset)
2792		  {
2793		    low_func_vma = q->symbol.value;
2794		    func = (asymbol *)q;
2795		  }
2796		else if (q->symbol.value > offset)
2797		  goto done;
2798	      }
2799	      break;
2800	    }
2801	}
2802    }
2803
2804 done:
2805  if (*line_ptr != 0)
2806    {
2807      main_file_name = line_file_name;
2808      directory_name = line_directory_name;
2809    }
2810
2811  if (main_file_name == NULL
2812      || IS_ABSOLUTE_PATH (main_file_name)
2813      || directory_name == NULL)
2814    filelen = 0;
2815  else
2816    filelen = strlen (directory_name) + strlen (main_file_name);
2817
2818  if (func == NULL)
2819    funclen = 0;
2820  else
2821    funclen = strlen (bfd_asymbol_name (func));
2822
2823  free (adata (abfd).line_buf);
2824
2825  if (filelen + funclen == 0)
2826    adata (abfd).line_buf = buf = NULL;
2827  else
2828    {
2829      buf = (char *) bfd_malloc (filelen + funclen + 3);
2830      adata (abfd).line_buf = buf;
2831      if (buf == NULL)
2832	return false;
2833    }
2834
2835  if (main_file_name != NULL)
2836    {
2837      if (IS_ABSOLUTE_PATH (main_file_name) || directory_name == NULL)
2838	*filename_ptr = main_file_name;
2839      else
2840	{
2841	  if (buf == NULL)
2842	    /* PR binutils/20891: In a corrupt input file both
2843	       main_file_name and directory_name can be empty...  */
2844	    * filename_ptr = NULL;
2845	  else
2846	    {
2847	      snprintf (buf, filelen + 1, "%s%s", directory_name,
2848			main_file_name);
2849	      *filename_ptr = buf;
2850	      buf += filelen + 1;
2851	    }
2852	}
2853    }
2854
2855  if (func)
2856    {
2857      const char *function = func->name;
2858      char *colon;
2859
2860      if (buf == NULL)
2861	{
2862	  /* PR binutils/20892: In a corrupt input file func can be empty.  */
2863	  * functionname_ptr = NULL;
2864	  return true;
2865	}
2866      /* The caller expects a symbol name.  We actually have a
2867	 function name, without the leading underscore.  Put the
2868	 underscore back in, so that the caller gets a symbol name.  */
2869      if (bfd_get_symbol_leading_char (abfd) == '\0')
2870	strcpy (buf, function);
2871      else
2872	{
2873	  buf[0] = bfd_get_symbol_leading_char (abfd);
2874	  strcpy (buf + 1, function);
2875	}
2876      /* Have to remove : stuff.  */
2877      colon = strchr (buf, ':');
2878      if (colon != NULL)
2879	*colon = '\0';
2880      *functionname_ptr = buf;
2881    }
2882
2883  return true;
2884}
2885
2886int
2887NAME (aout, sizeof_headers) (bfd *abfd,
2888			     struct bfd_link_info *info ATTRIBUTE_UNUSED)
2889{
2890  return adata (abfd).exec_bytes_size;
2891}
2892
2893/* Free all information we have cached for this BFD.  We can always
2894   read it again later if we need it.  */
2895
2896bool
2897NAME (aout, bfd_free_cached_info) (bfd *abfd)
2898{
2899  asection *o;
2900
2901  if (bfd_get_format (abfd) != bfd_object
2902      || abfd->tdata.aout_data == NULL)
2903    return true;
2904
2905#define BFCI_FREE(x) do { free (x); x = NULL; } while (0)
2906  BFCI_FREE (obj_aout_symbols (abfd));
2907#ifdef USE_MMAP
2908  obj_aout_external_syms (abfd) = 0;
2909  bfd_free_window (&obj_aout_sym_window (abfd));
2910  bfd_free_window (&obj_aout_string_window (abfd));
2911  obj_aout_external_strings (abfd) = 0;
2912#else
2913  BFCI_FREE (obj_aout_external_syms (abfd));
2914  BFCI_FREE (obj_aout_external_strings (abfd));
2915#endif
2916  for (o = abfd->sections; o != NULL; o = o->next)
2917    BFCI_FREE (o->relocation);
2918#undef BFCI_FREE
2919
2920  return true;
2921}
2922
2923/* a.out link code.  */
2924
2925/* Routine to create an entry in an a.out link hash table.  */
2926
2927struct bfd_hash_entry *
2928NAME (aout, link_hash_newfunc) (struct bfd_hash_entry *entry,
2929				struct bfd_hash_table *table,
2930				const char *string)
2931{
2932  struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
2933
2934  /* Allocate the structure if it has not already been allocated by a
2935     subclass.  */
2936  if (ret == NULL)
2937    ret = (struct aout_link_hash_entry *) bfd_hash_allocate (table,
2938							     sizeof (* ret));
2939  if (ret == NULL)
2940    return NULL;
2941
2942  /* Call the allocation method of the superclass.  */
2943  ret = ((struct aout_link_hash_entry *)
2944	 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
2945				 table, string));
2946  if (ret)
2947    {
2948      /* Set local fields.  */
2949      ret->written = false;
2950      ret->indx = -1;
2951    }
2952
2953  return (struct bfd_hash_entry *) ret;
2954}
2955
2956/* Initialize an a.out link hash table.  */
2957
2958bool
2959NAME (aout, link_hash_table_init) (struct aout_link_hash_table *table,
2960				   bfd *abfd,
2961				   struct bfd_hash_entry *(*newfunc)
2962				   (struct bfd_hash_entry *, struct bfd_hash_table *,
2963				    const char *),
2964				   unsigned int entsize)
2965{
2966  return _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
2967}
2968
2969/* Create an a.out link hash table.  */
2970
2971struct bfd_link_hash_table *
2972NAME (aout, link_hash_table_create) (bfd *abfd)
2973{
2974  struct aout_link_hash_table *ret;
2975  size_t amt = sizeof (* ret);
2976
2977  ret = (struct aout_link_hash_table *) bfd_malloc (amt);
2978  if (ret == NULL)
2979    return NULL;
2980
2981  if (!NAME (aout, link_hash_table_init) (ret, abfd,
2982					  NAME (aout, link_hash_newfunc),
2983					  sizeof (struct aout_link_hash_entry)))
2984    {
2985      free (ret);
2986      return NULL;
2987    }
2988  return &ret->root;
2989}
2990
2991/* Add all symbols from an object file to the hash table.  */
2992
2993static bool
2994aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
2995{
2996  bool (*add_one_symbol)
2997    (struct bfd_link_info *, bfd *, const char *, flagword, asection *,
2998     bfd_vma, const char *, bool, bool, struct bfd_link_hash_entry **);
2999  struct external_nlist *syms;
3000  bfd_size_type sym_count;
3001  char *strings;
3002  bool copy;
3003  struct aout_link_hash_entry **sym_hash;
3004  struct external_nlist *p;
3005  struct external_nlist *pend;
3006  bfd_size_type amt;
3007
3008  syms = obj_aout_external_syms (abfd);
3009  sym_count = obj_aout_external_sym_count (abfd);
3010  strings = obj_aout_external_strings (abfd);
3011  if (info->keep_memory)
3012    copy = false;
3013  else
3014    copy = true;
3015
3016  if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
3017    {
3018      if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
3019	     (abfd, info, &syms, &sym_count, &strings)))
3020	return false;
3021    }
3022
3023  if (sym_count == 0)
3024    return true;		/* Nothing to do.  */
3025
3026  /* We keep a list of the linker hash table entries that correspond
3027     to particular symbols.  We could just look them up in the hash
3028     table, but keeping the list is more efficient.  Perhaps this
3029     should be conditional on info->keep_memory.  */
3030  amt = sym_count * sizeof (struct aout_link_hash_entry *);
3031  sym_hash = (struct aout_link_hash_entry **) bfd_alloc (abfd, amt);
3032  if (sym_hash == NULL)
3033    return false;
3034  obj_aout_sym_hashes (abfd) = sym_hash;
3035
3036  add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
3037  if (add_one_symbol == NULL)
3038    add_one_symbol = _bfd_generic_link_add_one_symbol;
3039
3040  p = syms;
3041  pend = p + sym_count;
3042  for (; p < pend; p++, sym_hash++)
3043    {
3044      int type;
3045      const char *name;
3046      bfd_vma value;
3047      asection *section;
3048      flagword flags;
3049      const char *string;
3050
3051      *sym_hash = NULL;
3052
3053      type = H_GET_8 (abfd, p->e_type);
3054
3055      /* Ignore debugging symbols.  */
3056      if ((type & N_STAB) != 0)
3057	continue;
3058
3059      /* PR 19629: Corrupt binaries can contain illegal string offsets.  */
3060      if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd))
3061	return false;
3062      name = strings + GET_WORD (abfd, p->e_strx);
3063      value = GET_WORD (abfd, p->e_value);
3064      flags = BSF_GLOBAL;
3065      string = NULL;
3066      switch (type)
3067	{
3068	default:
3069	  abort ();
3070
3071	case N_UNDF:
3072	case N_ABS:
3073	case N_TEXT:
3074	case N_DATA:
3075	case N_BSS:
3076	case N_FN_SEQ:
3077	case N_COMM:
3078	case N_SETV:
3079	case N_FN:
3080	  /* Ignore symbols that are not externally visible.  */
3081	  continue;
3082	case N_INDR:
3083	  /* Ignore local indirect symbol.  */
3084	  ++p;
3085	  ++sym_hash;
3086	  continue;
3087
3088	case N_UNDF | N_EXT:
3089	  if (value == 0)
3090	    {
3091	      section = bfd_und_section_ptr;
3092	      flags = 0;
3093	    }
3094	  else
3095	    section = bfd_com_section_ptr;
3096	  break;
3097	case N_ABS | N_EXT:
3098	  section = bfd_abs_section_ptr;
3099	  break;
3100	case N_TEXT | N_EXT:
3101	  section = obj_textsec (abfd);
3102	  value -= bfd_section_vma (section);
3103	  break;
3104	case N_DATA | N_EXT:
3105	case N_SETV | N_EXT:
3106	  /* Treat N_SETV symbols as N_DATA symbol; see comment in
3107	     translate_from_native_sym_flags.  */
3108	  section = obj_datasec (abfd);
3109	  value -= bfd_section_vma (section);
3110	  break;
3111	case N_BSS | N_EXT:
3112	  section = obj_bsssec (abfd);
3113	  value -= bfd_section_vma (section);
3114	  break;
3115	case N_INDR | N_EXT:
3116	  /* An indirect symbol.  The next symbol is the symbol
3117	     which this one really is.  */
3118	  /* See PR 20925 for a reproducer.  */
3119	  if (p + 1 >= pend)
3120	    return false;
3121	  ++p;
3122	  /* PR 19629: Corrupt binaries can contain illegal string offsets.  */
3123	  if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd))
3124	    return false;
3125	  string = strings + GET_WORD (abfd, p->e_strx);
3126	  section = bfd_ind_section_ptr;
3127	  flags |= BSF_INDIRECT;
3128	  break;
3129	case N_COMM | N_EXT:
3130	  section = bfd_com_section_ptr;
3131	  break;
3132	case N_SETA: case N_SETA | N_EXT:
3133	  section = bfd_abs_section_ptr;
3134	  flags |= BSF_CONSTRUCTOR;
3135	  break;
3136	case N_SETT: case N_SETT | N_EXT:
3137	  section = obj_textsec (abfd);
3138	  flags |= BSF_CONSTRUCTOR;
3139	  value -= bfd_section_vma (section);
3140	  break;
3141	case N_SETD: case N_SETD | N_EXT:
3142	  section = obj_datasec (abfd);
3143	  flags |= BSF_CONSTRUCTOR;
3144	  value -= bfd_section_vma (section);
3145	  break;
3146	case N_SETB: case N_SETB | N_EXT:
3147	  section = obj_bsssec (abfd);
3148	  flags |= BSF_CONSTRUCTOR;
3149	  value -= bfd_section_vma (section);
3150	  break;
3151	case N_WARNING:
3152	  /* A warning symbol.  The next symbol is the one to warn
3153	     about.  If there is no next symbol, just look away.  */
3154	  if (p + 1 >= pend)
3155	    return true;
3156	  ++p;
3157	  string = name;
3158	  /* PR 19629: Corrupt binaries can contain illegal string offsets.  */
3159	  if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd))
3160	    return false;
3161	  name = strings + GET_WORD (abfd, p->e_strx);
3162	  section = bfd_und_section_ptr;
3163	  flags |= BSF_WARNING;
3164	  break;
3165	case N_WEAKU:
3166	  section = bfd_und_section_ptr;
3167	  flags = BSF_WEAK;
3168	  break;
3169	case N_WEAKA:
3170	  section = bfd_abs_section_ptr;
3171	  flags = BSF_WEAK;
3172	  break;
3173	case N_WEAKT:
3174	  section = obj_textsec (abfd);
3175	  value -= bfd_section_vma (section);
3176	  flags = BSF_WEAK;
3177	  break;
3178	case N_WEAKD:
3179	  section = obj_datasec (abfd);
3180	  value -= bfd_section_vma (section);
3181	  flags = BSF_WEAK;
3182	  break;
3183	case N_WEAKB:
3184	  section = obj_bsssec (abfd);
3185	  value -= bfd_section_vma (section);
3186	  flags = BSF_WEAK;
3187	  break;
3188	}
3189
3190      if (! ((*add_one_symbol)
3191	     (info, abfd, name, flags, section, value, string, copy, false,
3192	      (struct bfd_link_hash_entry **) sym_hash)))
3193	return false;
3194
3195      /* Restrict the maximum alignment of a common symbol based on
3196	 the architecture, since a.out has no way to represent
3197	 alignment requirements of a section in a .o file.  FIXME:
3198	 This isn't quite right: it should use the architecture of the
3199	 output file, not the input files.  */
3200      if ((*sym_hash)->root.type == bfd_link_hash_common
3201	  && ((*sym_hash)->root.u.c.p->alignment_power >
3202	      bfd_get_arch_info (abfd)->section_align_power))
3203	(*sym_hash)->root.u.c.p->alignment_power =
3204	  bfd_get_arch_info (abfd)->section_align_power;
3205
3206      /* If this is a set symbol, and we are not building sets, then
3207	 it is possible for the hash entry to not have been set.  In
3208	 such a case, treat the symbol as not globally defined.  */
3209      if ((*sym_hash)->root.type == bfd_link_hash_new)
3210	{
3211	  BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
3212	  *sym_hash = NULL;
3213	}
3214
3215      if (type == (N_INDR | N_EXT) || type == N_WARNING)
3216	++sym_hash;
3217    }
3218
3219  return true;
3220}
3221
3222/* Free up the internal symbols read from an a.out file.  */
3223
3224static bool
3225aout_link_free_symbols (bfd *abfd)
3226{
3227  if (obj_aout_external_syms (abfd) != NULL)
3228    {
3229#ifdef USE_MMAP
3230      bfd_free_window (&obj_aout_sym_window (abfd));
3231#else
3232      free ((void *) obj_aout_external_syms (abfd));
3233#endif
3234      obj_aout_external_syms (abfd) = NULL;
3235    }
3236  if (obj_aout_external_strings (abfd) != NULL)
3237    {
3238#ifdef USE_MMAP
3239      bfd_free_window (&obj_aout_string_window (abfd));
3240#else
3241      free ((void *) obj_aout_external_strings (abfd));
3242#endif
3243      obj_aout_external_strings (abfd) = NULL;
3244    }
3245  return true;
3246}
3247
3248/* Add symbols from an a.out object file.  */
3249
3250static bool
3251aout_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
3252{
3253  if (! aout_get_external_symbols (abfd))
3254    return false;
3255  if (! aout_link_add_symbols (abfd, info))
3256    return false;
3257  if (! info->keep_memory)
3258    {
3259      if (! aout_link_free_symbols (abfd))
3260	return false;
3261    }
3262  return true;
3263}
3264
3265/* Look through the internal symbols to see if this object file should
3266   be included in the link.  We should include this object file if it
3267   defines any symbols which are currently undefined.  If this object
3268   file defines a common symbol, then we may adjust the size of the
3269   known symbol but we do not include the object file in the link
3270   (unless there is some other reason to include it).  */
3271
3272static bool
3273aout_link_check_ar_symbols (bfd *abfd,
3274			    struct bfd_link_info *info,
3275			    bool *pneeded,
3276			    bfd **subsbfd)
3277{
3278  struct external_nlist *p;
3279  struct external_nlist *pend;
3280  char *strings;
3281
3282  *pneeded = false;
3283
3284  /* Look through all the symbols.  */
3285  p = obj_aout_external_syms (abfd);
3286  pend = p + obj_aout_external_sym_count (abfd);
3287  strings = obj_aout_external_strings (abfd);
3288  for (; p < pend; p++)
3289    {
3290      int type = H_GET_8 (abfd, p->e_type);
3291      const char *name;
3292      struct bfd_link_hash_entry *h;
3293
3294      /* Ignore symbols that are not externally visible.  This is an
3295	 optimization only, as we check the type more thoroughly
3296	 below.  */
3297      if (((type & N_EXT) == 0
3298	   || (type & N_STAB) != 0
3299	   || type == N_FN)
3300	  && type != N_WEAKA
3301	  && type != N_WEAKT
3302	  && type != N_WEAKD
3303	  && type != N_WEAKB)
3304	{
3305	  if (type == N_WARNING
3306	      || type == N_INDR)
3307	    ++p;
3308	  continue;
3309	}
3310
3311      name = strings + GET_WORD (abfd, p->e_strx);
3312      h = bfd_link_hash_lookup (info->hash, name, false, false, true);
3313
3314      /* We are only interested in symbols that are currently
3315	 undefined or common.  */
3316      if (h == NULL
3317	  || (h->type != bfd_link_hash_undefined
3318	      && h->type != bfd_link_hash_common))
3319	{
3320	  if (type == (N_INDR | N_EXT))
3321	    ++p;
3322	  continue;
3323	}
3324
3325      if (type == (N_TEXT | N_EXT)
3326	  || type == (N_DATA | N_EXT)
3327	  || type == (N_BSS | N_EXT)
3328	  || type == (N_ABS | N_EXT)
3329	  || type == (N_INDR | N_EXT))
3330	{
3331	  /* This object file defines this symbol.  We must link it
3332	     in.  This is true regardless of whether the current
3333	     definition of the symbol is undefined or common.
3334
3335	     If the current definition is common, we have a case in
3336	     which we have already seen an object file including:
3337		 int a;
3338	     and this object file from the archive includes:
3339		 int a = 5;
3340	     In such a case, whether to include this object is target
3341	     dependant for backward compatibility.
3342
3343	     FIXME: The SunOS 4.1.3 linker will pull in the archive
3344	     element if the symbol is defined in the .data section,
3345	     but not if it is defined in the .text section.  That
3346	     seems a bit crazy to me, and it has not been implemented
3347	     yet.  However, it might be correct.  */
3348	  if (h->type == bfd_link_hash_common)
3349	    {
3350	      int skip = 0;
3351
3352	      switch (info->common_skip_ar_symbols)
3353		{
3354		case bfd_link_common_skip_none:
3355		  break;
3356		case bfd_link_common_skip_text:
3357		  skip = (type == (N_TEXT | N_EXT));
3358		  break;
3359		case bfd_link_common_skip_data:
3360		  skip = (type == (N_DATA | N_EXT));
3361		  break;
3362		case bfd_link_common_skip_all:
3363		  skip = 1;
3364		  break;
3365		}
3366
3367	      if (skip)
3368		continue;
3369	    }
3370
3371	  if (!(*info->callbacks
3372		->add_archive_element) (info, abfd, name, subsbfd))
3373	    return false;
3374	  *pneeded = true;
3375	  return true;
3376	}
3377
3378      if (type == (N_UNDF | N_EXT))
3379	{
3380	  bfd_vma value;
3381
3382	  value = GET_WORD (abfd, p->e_value);
3383	  if (value != 0)
3384	    {
3385	      /* This symbol is common in the object from the archive
3386		 file.  */
3387	      if (h->type == bfd_link_hash_undefined)
3388		{
3389		  bfd *symbfd;
3390		  unsigned int power;
3391
3392		  symbfd = h->u.undef.abfd;
3393		  if (symbfd == NULL)
3394		    {
3395		      /* This symbol was created as undefined from
3396			 outside BFD.  We assume that we should link
3397			 in the object file.  This is done for the -u
3398			 option in the linker.  */
3399		      if (!(*info->callbacks
3400			    ->add_archive_element) (info, abfd, name, subsbfd))
3401			return false;
3402		      *pneeded = true;
3403		      return true;
3404		    }
3405		  /* Turn the current link symbol into a common
3406		     symbol.  It is already on the undefs list.  */
3407		  h->type = bfd_link_hash_common;
3408		  h->u.c.p = (struct bfd_link_hash_common_entry *)
3409		    bfd_hash_allocate (&info->hash->table,
3410				       sizeof (struct bfd_link_hash_common_entry));
3411		  if (h->u.c.p == NULL)
3412		    return false;
3413
3414		  h->u.c.size = value;
3415
3416		  /* FIXME: This isn't quite right.  The maximum
3417		     alignment of a common symbol should be set by the
3418		     architecture of the output file, not of the input
3419		     file.  */
3420		  power = bfd_log2 (value);
3421		  if (power > bfd_get_arch_info (abfd)->section_align_power)
3422		    power = bfd_get_arch_info (abfd)->section_align_power;
3423		  h->u.c.p->alignment_power = power;
3424
3425		  h->u.c.p->section = bfd_make_section_old_way (symbfd,
3426								"COMMON");
3427		}
3428	      else
3429		{
3430		  /* Adjust the size of the common symbol if
3431		     necessary.  */
3432		  if (value > h->u.c.size)
3433		    h->u.c.size = value;
3434		}
3435	    }
3436	}
3437
3438      if (type == N_WEAKA
3439	  || type == N_WEAKT
3440	  || type == N_WEAKD
3441	  || type == N_WEAKB)
3442	{
3443	  /* This symbol is weak but defined.  We must pull it in if
3444	     the current link symbol is undefined, but we don't want
3445	     it if the current link symbol is common.  */
3446	  if (h->type == bfd_link_hash_undefined)
3447	    {
3448	      if (!(*info->callbacks
3449		    ->add_archive_element) (info, abfd, name, subsbfd))
3450		return false;
3451	      *pneeded = true;
3452	      return true;
3453	    }
3454	}
3455    }
3456
3457  /* We do not need this object file.  */
3458  return true;
3459}
3460/* Check a single archive element to see if we need to include it in
3461   the link.  *PNEEDED is set according to whether this element is
3462   needed in the link or not.  This is called from
3463   _bfd_generic_link_add_archive_symbols.  */
3464
3465static bool
3466aout_link_check_archive_element (bfd *abfd,
3467				 struct bfd_link_info *info,
3468				 struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
3469				 const char *name ATTRIBUTE_UNUSED,
3470				 bool *pneeded)
3471{
3472  bfd *oldbfd;
3473  bool needed;
3474
3475  if (!aout_get_external_symbols (abfd))
3476    return false;
3477
3478  oldbfd = abfd;
3479  if (!aout_link_check_ar_symbols (abfd, info, pneeded, &abfd))
3480    return false;
3481
3482  needed = *pneeded;
3483  if (needed)
3484    {
3485      /* Potentially, the add_archive_element hook may have set a
3486	 substitute BFD for us.  */
3487      if (abfd != oldbfd)
3488	{
3489	  if (!info->keep_memory
3490	      && !aout_link_free_symbols (oldbfd))
3491	    return false;
3492	  if (!aout_get_external_symbols (abfd))
3493	    return false;
3494	}
3495      if (!aout_link_add_symbols (abfd, info))
3496	return false;
3497    }
3498
3499  if (!info->keep_memory || !needed)
3500    {
3501      if (!aout_link_free_symbols (abfd))
3502	return false;
3503    }
3504
3505  return true;
3506}
3507
3508/* Given an a.out BFD, add symbols to the global hash table as
3509   appropriate.  */
3510
3511bool
3512NAME (aout, link_add_symbols) (bfd *abfd, struct bfd_link_info *info)
3513{
3514  switch (bfd_get_format (abfd))
3515    {
3516    case bfd_object:
3517      return aout_link_add_object_symbols (abfd, info);
3518    case bfd_archive:
3519      return _bfd_generic_link_add_archive_symbols
3520	(abfd, info, aout_link_check_archive_element);
3521    default:
3522      bfd_set_error (bfd_error_wrong_format);
3523      return false;
3524    }
3525}
3526
3527/* A hash table used for header files with N_BINCL entries.  */
3528
3529struct aout_link_includes_table
3530{
3531  struct bfd_hash_table root;
3532};
3533
3534/* A linked list of totals that we have found for a particular header
3535   file.  */
3536
3537struct aout_link_includes_totals
3538{
3539  struct aout_link_includes_totals *next;
3540  bfd_vma total;
3541};
3542
3543/* An entry in the header file hash table.  */
3544
3545struct aout_link_includes_entry
3546{
3547  struct bfd_hash_entry root;
3548  /* List of totals we have found for this file.  */
3549  struct aout_link_includes_totals *totals;
3550};
3551
3552/* Look up an entry in an the header file hash table.  */
3553
3554#define aout_link_includes_lookup(table, string, create, copy)		\
3555  ((struct aout_link_includes_entry *)					\
3556   bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
3557
3558/* During the final link step we need to pass around a bunch of
3559   information, so we do it in an instance of this structure.  */
3560
3561struct aout_final_link_info
3562{
3563  /* General link information.  */
3564  struct bfd_link_info *info;
3565  /* Output bfd.  */
3566  bfd *output_bfd;
3567  /* Reloc file positions.  */
3568  file_ptr treloff, dreloff;
3569  /* File position of symbols.  */
3570  file_ptr symoff;
3571  /* String table.  */
3572  struct bfd_strtab_hash *strtab;
3573  /* Header file hash table.  */
3574  struct aout_link_includes_table includes;
3575  /* A buffer large enough to hold the contents of any section.  */
3576  bfd_byte *contents;
3577  /* A buffer large enough to hold the relocs of any section.  */
3578  void * relocs;
3579  /* A buffer large enough to hold the symbol map of any input BFD.  */
3580  int *symbol_map;
3581  /* A buffer large enough to hold output symbols of any input BFD.  */
3582  struct external_nlist *output_syms;
3583};
3584
3585/* The function to create a new entry in the header file hash table.  */
3586
3587static struct bfd_hash_entry *
3588aout_link_includes_newfunc (struct bfd_hash_entry *entry,
3589			    struct bfd_hash_table *table,
3590			    const char *string)
3591{
3592  struct aout_link_includes_entry *ret =
3593    (struct aout_link_includes_entry *) entry;
3594
3595  /* Allocate the structure if it has not already been allocated by a
3596     subclass.  */
3597  if (ret == NULL)
3598    ret = (struct aout_link_includes_entry *)
3599	bfd_hash_allocate (table, sizeof (* ret));
3600  if (ret == NULL)
3601    return NULL;
3602
3603  /* Call the allocation method of the superclass.  */
3604  ret = ((struct aout_link_includes_entry *)
3605	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
3606  if (ret)
3607    {
3608      /* Set local fields.  */
3609      ret->totals = NULL;
3610    }
3611
3612  return (struct bfd_hash_entry *) ret;
3613}
3614
3615/* Write out a symbol that was not associated with an a.out input
3616   object.  */
3617
3618static bool
3619aout_link_write_other_symbol (struct bfd_hash_entry *bh, void *data)
3620{
3621  struct aout_link_hash_entry *h = (struct aout_link_hash_entry *) bh;
3622  struct aout_final_link_info *flaginfo = (struct aout_final_link_info *) data;
3623  bfd *output_bfd;
3624  int type;
3625  bfd_vma val;
3626  struct external_nlist outsym;
3627  bfd_size_type indx;
3628  size_t amt;
3629
3630  if (h->root.type == bfd_link_hash_warning)
3631    {
3632      h = (struct aout_link_hash_entry *) h->root.u.i.link;
3633      if (h->root.type == bfd_link_hash_new)
3634	return true;
3635    }
3636
3637  output_bfd = flaginfo->output_bfd;
3638
3639  if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
3640    {
3641      if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
3642	     (output_bfd, flaginfo->info, h)))
3643	{
3644	  /* FIXME: No way to handle errors.  */
3645	  abort ();
3646	}
3647    }
3648
3649  if (h->written)
3650    return true;
3651
3652  h->written = true;
3653
3654  /* An indx of -2 means the symbol must be written.  */
3655  if (h->indx != -2
3656      && (flaginfo->info->strip == strip_all
3657	  || (flaginfo->info->strip == strip_some
3658	      && bfd_hash_lookup (flaginfo->info->keep_hash, h->root.root.string,
3659				  false, false) == NULL)))
3660    return true;
3661
3662  switch (h->root.type)
3663    {
3664    default:
3665    case bfd_link_hash_warning:
3666      abort ();
3667      /* Avoid variable not initialized warnings.  */
3668      return true;
3669    case bfd_link_hash_new:
3670      /* This can happen for set symbols when sets are not being
3671	 built.  */
3672      return true;
3673    case bfd_link_hash_undefined:
3674      type = N_UNDF | N_EXT;
3675      val = 0;
3676      break;
3677    case bfd_link_hash_defined:
3678    case bfd_link_hash_defweak:
3679      {
3680	asection *sec;
3681
3682	sec = h->root.u.def.section->output_section;
3683	BFD_ASSERT (bfd_is_abs_section (sec)
3684		    || sec->owner == output_bfd);
3685	if (sec == obj_textsec (output_bfd))
3686	  type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
3687	else if (sec == obj_datasec (output_bfd))
3688	  type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
3689	else if (sec == obj_bsssec (output_bfd))
3690	  type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
3691	else
3692	  type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
3693	type |= N_EXT;
3694	val = (h->root.u.def.value
3695	       + sec->vma
3696	       + h->root.u.def.section->output_offset);
3697      }
3698      break;
3699    case bfd_link_hash_common:
3700      type = N_UNDF | N_EXT;
3701      val = h->root.u.c.size;
3702      break;
3703    case bfd_link_hash_undefweak:
3704      type = N_WEAKU;
3705      val = 0;
3706      break;
3707    case bfd_link_hash_indirect:
3708      /* We ignore these symbols, since the indirected symbol is
3709	 already in the hash table.  */
3710      return true;
3711    }
3712
3713  H_PUT_8 (output_bfd, type, outsym.e_type);
3714  H_PUT_8 (output_bfd, 0, outsym.e_other);
3715  H_PUT_16 (output_bfd, 0, outsym.e_desc);
3716  indx = add_to_stringtab (output_bfd, flaginfo->strtab, h->root.root.string,
3717			   false);
3718  if (indx == - (bfd_size_type) 1)
3719    /* FIXME: No way to handle errors.  */
3720    abort ();
3721
3722  PUT_WORD (output_bfd, indx, outsym.e_strx);
3723  PUT_WORD (output_bfd, val, outsym.e_value);
3724
3725  amt = EXTERNAL_NLIST_SIZE;
3726  if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0
3727      || bfd_bwrite ((void *) &outsym, amt, output_bfd) != amt)
3728    /* FIXME: No way to handle errors.  */
3729    abort ();
3730
3731  flaginfo->symoff += EXTERNAL_NLIST_SIZE;
3732  h->indx = obj_aout_external_sym_count (output_bfd);
3733  ++obj_aout_external_sym_count (output_bfd);
3734
3735  return true;
3736}
3737
3738/* Handle a link order which is supposed to generate a reloc.  */
3739
3740static bool
3741aout_link_reloc_link_order (struct aout_final_link_info *flaginfo,
3742			    asection *o,
3743			    struct bfd_link_order *p)
3744{
3745  struct bfd_link_order_reloc *pr;
3746  int r_index;
3747  int r_extern;
3748  reloc_howto_type *howto;
3749  file_ptr *reloff_ptr = NULL;
3750  struct reloc_std_external srel;
3751  struct reloc_ext_external erel;
3752  void * rel_ptr;
3753  size_t amt;
3754
3755  pr = p->u.reloc.p;
3756
3757  if (p->type == bfd_section_reloc_link_order)
3758    {
3759      r_extern = 0;
3760      if (bfd_is_abs_section (pr->u.section))
3761	r_index = N_ABS | N_EXT;
3762      else
3763	{
3764	  BFD_ASSERT (pr->u.section->owner == flaginfo->output_bfd);
3765	  r_index = pr->u.section->target_index;
3766	}
3767    }
3768  else
3769    {
3770      struct aout_link_hash_entry *h;
3771
3772      BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
3773      r_extern = 1;
3774      h = ((struct aout_link_hash_entry *)
3775	   bfd_wrapped_link_hash_lookup (flaginfo->output_bfd, flaginfo->info,
3776					 pr->u.name, false, false, true));
3777      if (h != NULL
3778	  && h->indx >= 0)
3779	r_index = h->indx;
3780      else if (h != NULL)
3781	{
3782	  /* We decided to strip this symbol, but it turns out that we
3783	     can't.  Note that we lose the other and desc information
3784	     here.  I don't think that will ever matter for a global
3785	     symbol.  */
3786	  h->indx = -2;
3787	  h->written = false;
3788	  if (!aout_link_write_other_symbol (&h->root.root, flaginfo))
3789	    return false;
3790	  r_index = h->indx;
3791	}
3792      else
3793	{
3794	  (*flaginfo->info->callbacks->unattached_reloc)
3795	    (flaginfo->info, pr->u.name, NULL, NULL, (bfd_vma) 0);
3796	  r_index = 0;
3797	}
3798    }
3799
3800  howto = bfd_reloc_type_lookup (flaginfo->output_bfd, pr->reloc);
3801  if (howto == 0)
3802    {
3803      bfd_set_error (bfd_error_bad_value);
3804      return false;
3805    }
3806
3807  if (o == obj_textsec (flaginfo->output_bfd))
3808    reloff_ptr = &flaginfo->treloff;
3809  else if (o == obj_datasec (flaginfo->output_bfd))
3810    reloff_ptr = &flaginfo->dreloff;
3811  else
3812    abort ();
3813
3814  if (obj_reloc_entry_size (flaginfo->output_bfd) == RELOC_STD_SIZE)
3815    {
3816#ifdef MY_put_reloc
3817      MY_put_reloc (flaginfo->output_bfd, r_extern, r_index, p->offset, howto,
3818		    &srel);
3819#else
3820      {
3821	int r_pcrel;
3822	int r_baserel;
3823	int r_jmptable;
3824	int r_relative;
3825	unsigned int r_length;
3826
3827	r_pcrel = (int) howto->pc_relative;
3828	r_baserel = (howto->type & 8) != 0;
3829	r_jmptable = (howto->type & 16) != 0;
3830	r_relative = (howto->type & 32) != 0;
3831	r_length = bfd_log2 (bfd_get_reloc_size (howto));
3832
3833	PUT_WORD (flaginfo->output_bfd, p->offset, srel.r_address);
3834	if (bfd_header_big_endian (flaginfo->output_bfd))
3835	  {
3836	    srel.r_index[0] = r_index >> 16;
3837	    srel.r_index[1] = r_index >> 8;
3838	    srel.r_index[2] = r_index;
3839	    srel.r_type[0] =
3840	      ((r_extern ?     RELOC_STD_BITS_EXTERN_BIG : 0)
3841	       | (r_pcrel ?    RELOC_STD_BITS_PCREL_BIG : 0)
3842	       | (r_baserel ?  RELOC_STD_BITS_BASEREL_BIG : 0)
3843	       | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
3844	       | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
3845	       | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG));
3846	  }
3847	else
3848	  {
3849	    srel.r_index[2] = r_index >> 16;
3850	    srel.r_index[1] = r_index >> 8;
3851	    srel.r_index[0] = r_index;
3852	    srel.r_type[0] =
3853	      ((r_extern ?     RELOC_STD_BITS_EXTERN_LITTLE : 0)
3854	       | (r_pcrel ?    RELOC_STD_BITS_PCREL_LITTLE : 0)
3855	       | (r_baserel ?  RELOC_STD_BITS_BASEREL_LITTLE : 0)
3856	       | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
3857	       | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
3858	       | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE));
3859	  }
3860      }
3861#endif
3862      rel_ptr = (void *) &srel;
3863
3864      /* We have to write the addend into the object file, since
3865	 standard a.out relocs are in place.  It would be more
3866	 reliable if we had the current contents of the file here,
3867	 rather than assuming zeroes, but we can't read the file since
3868	 it was opened using bfd_openw.  */
3869      if (pr->addend != 0)
3870	{
3871	  bfd_size_type size;
3872	  bfd_reloc_status_type r;
3873	  bfd_byte *buf;
3874	  bool ok;
3875
3876	  size = bfd_get_reloc_size (howto);
3877	  buf = (bfd_byte *) bfd_zmalloc (size);
3878	  if (buf == NULL && size != 0)
3879	    return false;
3880	  r = MY_relocate_contents (howto, flaginfo->output_bfd,
3881				    (bfd_vma) pr->addend, buf);
3882	  switch (r)
3883	    {
3884	    case bfd_reloc_ok:
3885	      break;
3886	    default:
3887	    case bfd_reloc_outofrange:
3888	      abort ();
3889	    case bfd_reloc_overflow:
3890	      (*flaginfo->info->callbacks->reloc_overflow)
3891		(flaginfo->info, NULL,
3892		 (p->type == bfd_section_reloc_link_order
3893		  ? bfd_section_name (pr->u.section)
3894		  : pr->u.name),
3895		 howto->name, pr->addend, NULL, NULL, (bfd_vma) 0);
3896	      break;
3897	    }
3898	  ok = bfd_set_section_contents (flaginfo->output_bfd, o, (void *) buf,
3899					 (file_ptr) p->offset, size);
3900	  free (buf);
3901	  if (! ok)
3902	    return false;
3903	}
3904    }
3905  else
3906    {
3907#ifdef MY_put_ext_reloc
3908      MY_put_ext_reloc (flaginfo->output_bfd, r_extern, r_index, p->offset,
3909			howto, &erel, pr->addend);
3910#else
3911      PUT_WORD (flaginfo->output_bfd, p->offset, erel.r_address);
3912
3913      if (bfd_header_big_endian (flaginfo->output_bfd))
3914	{
3915	  erel.r_index[0] = r_index >> 16;
3916	  erel.r_index[1] = r_index >> 8;
3917	  erel.r_index[2] = r_index;
3918	  erel.r_type[0] =
3919	    ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
3920	     | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG));
3921	}
3922      else
3923	{
3924	  erel.r_index[2] = r_index >> 16;
3925	  erel.r_index[1] = r_index >> 8;
3926	  erel.r_index[0] = r_index;
3927	  erel.r_type[0] =
3928	    (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
3929	      | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
3930	}
3931
3932      PUT_WORD (flaginfo->output_bfd, (bfd_vma) pr->addend, erel.r_addend);
3933#endif /* MY_put_ext_reloc */
3934
3935      rel_ptr = (void *) &erel;
3936    }
3937
3938  amt = obj_reloc_entry_size (flaginfo->output_bfd);
3939  if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
3940      || bfd_bwrite (rel_ptr, amt, flaginfo->output_bfd) != amt)
3941    return false;
3942
3943  *reloff_ptr += obj_reloc_entry_size (flaginfo->output_bfd);
3944
3945  /* Assert that the relocs have not run into the symbols, and that n
3946     the text relocs have not run into the data relocs.  */
3947  BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (flaginfo->output_bfd)
3948	      && (reloff_ptr != &flaginfo->treloff
3949		  || (*reloff_ptr
3950		      <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
3951
3952  return true;
3953}
3954
3955/* Get the section corresponding to a reloc index.  */
3956
3957static inline asection *
3958aout_reloc_index_to_section (bfd *abfd, int indx)
3959{
3960  switch (indx & N_TYPE)
3961    {
3962    case N_TEXT:   return obj_textsec (abfd);
3963    case N_DATA:   return obj_datasec (abfd);
3964    case N_BSS:    return obj_bsssec (abfd);
3965    case N_ABS:
3966    case N_UNDF:   return bfd_abs_section_ptr;
3967    default:       abort ();
3968    }
3969  return NULL;
3970}
3971
3972/* Relocate an a.out section using standard a.out relocs.  */
3973
3974static bool
3975aout_link_input_section_std (struct aout_final_link_info *flaginfo,
3976			     bfd *input_bfd,
3977			     asection *input_section,
3978			     struct reloc_std_external *relocs,
3979			     bfd_size_type rel_size,
3980			     bfd_byte *contents)
3981{
3982  bool (*check_dynamic_reloc)
3983    (struct bfd_link_info *, bfd *, asection *,
3984     struct aout_link_hash_entry *, void *, bfd_byte *, bool *, bfd_vma *);
3985  bfd *output_bfd;
3986  bool relocatable;
3987  struct external_nlist *syms;
3988  char *strings;
3989  struct aout_link_hash_entry **sym_hashes;
3990  int *symbol_map;
3991  bfd_size_type reloc_count;
3992  struct reloc_std_external *rel;
3993  struct reloc_std_external *rel_end;
3994
3995  output_bfd = flaginfo->output_bfd;
3996  check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
3997
3998  BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
3999  BFD_ASSERT (input_bfd->xvec->header_byteorder
4000	      == output_bfd->xvec->header_byteorder);
4001
4002  relocatable = bfd_link_relocatable (flaginfo->info);
4003  syms = obj_aout_external_syms (input_bfd);
4004  strings = obj_aout_external_strings (input_bfd);
4005  sym_hashes = obj_aout_sym_hashes (input_bfd);
4006  symbol_map = flaginfo->symbol_map;
4007
4008  reloc_count = rel_size / RELOC_STD_SIZE;
4009  rel = relocs;
4010  rel_end = rel + reloc_count;
4011  for (; rel < rel_end; rel++)
4012    {
4013      bfd_vma r_addr;
4014      unsigned int r_index;
4015      int r_extern;
4016      int r_pcrel;
4017      int r_baserel = 0;
4018      reloc_howto_type *howto;
4019      struct aout_link_hash_entry *h = NULL;
4020      bfd_vma relocation;
4021      bfd_reloc_status_type r;
4022
4023      r_addr = GET_SWORD (input_bfd, rel->r_address);
4024
4025#ifdef MY_reloc_howto
4026      howto = MY_reloc_howto (input_bfd, rel, r_index, r_extern, r_pcrel);
4027#else
4028      {
4029	int r_jmptable;
4030	int r_relative;
4031	int r_length;
4032	unsigned int howto_idx;
4033
4034	if (bfd_header_big_endian (input_bfd))
4035	  {
4036	    r_index   =  (((unsigned int) rel->r_index[0] << 16)
4037			  | ((unsigned int) rel->r_index[1] << 8)
4038			  | rel->r_index[2]);
4039	    r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
4040	    r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
4041	    r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
4042	    r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
4043	    r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
4044	    r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
4045			 >> RELOC_STD_BITS_LENGTH_SH_BIG);
4046	  }
4047	else
4048	  {
4049	    r_index   = (((unsigned int) rel->r_index[2] << 16)
4050			 | ((unsigned int) rel->r_index[1] << 8)
4051			 | rel->r_index[0]);
4052	    r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
4053	    r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
4054	    r_baserel = (0 != (rel->r_type[0]
4055			       & RELOC_STD_BITS_BASEREL_LITTLE));
4056	    r_jmptable= (0 != (rel->r_type[0]
4057			       & RELOC_STD_BITS_JMPTABLE_LITTLE));
4058	    r_relative= (0 != (rel->r_type[0]
4059			       & RELOC_STD_BITS_RELATIVE_LITTLE));
4060	    r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
4061			 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
4062	  }
4063
4064	howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
4065		     + 16 * r_jmptable + 32 * r_relative);
4066	if (howto_idx < TABLE_SIZE (howto_table_std))
4067	  howto = howto_table_std + howto_idx;
4068	else
4069	  howto = NULL;
4070      }
4071#endif
4072
4073      if (howto == NULL)
4074	{
4075	  _bfd_error_handler (_("%pB: unsupported relocation type"),
4076			      input_bfd);
4077	  bfd_set_error (bfd_error_bad_value);
4078	  return false;
4079	}
4080
4081      if (relocatable)
4082	{
4083	  /* We are generating a relocatable output file, and must
4084	     modify the reloc accordingly.  */
4085	  if (r_extern)
4086	    {
4087	      /* If we know the symbol this relocation is against,
4088		 convert it into a relocation against a section.  This
4089		 is what the native linker does.  */
4090	      h = sym_hashes[r_index];
4091	      if (h != NULL
4092		  && (h->root.type == bfd_link_hash_defined
4093		      || h->root.type == bfd_link_hash_defweak))
4094		{
4095		  asection *output_section;
4096
4097		  /* Change the r_extern value.  */
4098		  if (bfd_header_big_endian (output_bfd))
4099		    rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
4100		  else
4101		    rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
4102
4103		  /* Compute a new r_index.  */
4104		  output_section = h->root.u.def.section->output_section;
4105		  if (output_section == obj_textsec (output_bfd))
4106		    r_index = N_TEXT;
4107		  else if (output_section == obj_datasec (output_bfd))
4108		    r_index = N_DATA;
4109		  else if (output_section == obj_bsssec (output_bfd))
4110		    r_index = N_BSS;
4111		  else
4112		    r_index = N_ABS;
4113
4114		  /* Add the symbol value and the section VMA to the
4115		     addend stored in the contents.  */
4116		  relocation = (h->root.u.def.value
4117				+ output_section->vma
4118				+ h->root.u.def.section->output_offset);
4119		}
4120	      else
4121		{
4122		  /* We must change r_index according to the symbol
4123		     map.  */
4124		  r_index = symbol_map[r_index];
4125
4126		  if (r_index == -1u)
4127		    {
4128		      if (h != NULL)
4129			{
4130			  /* We decided to strip this symbol, but it
4131			     turns out that we can't.  Note that we
4132			     lose the other and desc information here.
4133			     I don't think that will ever matter for a
4134			     global symbol.  */
4135			  if (h->indx < 0)
4136			    {
4137			      h->indx = -2;
4138			      h->written = false;
4139			      if (!aout_link_write_other_symbol (&h->root.root,
4140								 flaginfo))
4141				return false;
4142			    }
4143			  r_index = h->indx;
4144			}
4145		      else
4146			{
4147			  const char *name;
4148
4149			  name = strings + GET_WORD (input_bfd,
4150						     syms[r_index].e_strx);
4151			  (*flaginfo->info->callbacks->unattached_reloc)
4152			    (flaginfo->info, name,
4153			     input_bfd, input_section, r_addr);
4154			  r_index = 0;
4155			}
4156		    }
4157
4158		  relocation = 0;
4159		}
4160
4161	      /* Write out the new r_index value.  */
4162	      if (bfd_header_big_endian (output_bfd))
4163		{
4164		  rel->r_index[0] = r_index >> 16;
4165		  rel->r_index[1] = r_index >> 8;
4166		  rel->r_index[2] = r_index;
4167		}
4168	      else
4169		{
4170		  rel->r_index[2] = r_index >> 16;
4171		  rel->r_index[1] = r_index >> 8;
4172		  rel->r_index[0] = r_index;
4173		}
4174	    }
4175	  else
4176	    {
4177	      asection *section;
4178
4179	      /* This is a relocation against a section.  We must
4180		 adjust by the amount that the section moved.  */
4181	      section = aout_reloc_index_to_section (input_bfd, r_index);
4182	      relocation = (section->output_section->vma
4183			    + section->output_offset
4184			    - section->vma);
4185	    }
4186
4187	  /* Change the address of the relocation.  */
4188	  PUT_WORD (output_bfd,
4189		    r_addr + input_section->output_offset,
4190		    rel->r_address);
4191
4192	  /* Adjust a PC relative relocation by removing the reference
4193	     to the original address in the section and including the
4194	     reference to the new address.  */
4195	  if (r_pcrel)
4196	    relocation -= (input_section->output_section->vma
4197			   + input_section->output_offset
4198			   - input_section->vma);
4199
4200#ifdef MY_relocatable_reloc
4201	  MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
4202#endif
4203
4204	  if (relocation == 0)
4205	    r = bfd_reloc_ok;
4206	  else
4207	    r = MY_relocate_contents (howto,
4208					input_bfd, relocation,
4209					contents + r_addr);
4210	}
4211      else
4212	{
4213	  bool hundef;
4214
4215	  /* We are generating an executable, and must do a full
4216	     relocation.  */
4217	  hundef = false;
4218
4219	  if (r_extern)
4220	    {
4221	      h = sym_hashes[r_index];
4222
4223	      if (h != NULL
4224		  && (h->root.type == bfd_link_hash_defined
4225		      || h->root.type == bfd_link_hash_defweak))
4226		{
4227		  relocation = (h->root.u.def.value
4228				+ h->root.u.def.section->output_section->vma
4229				+ h->root.u.def.section->output_offset);
4230		}
4231	      else if (h != NULL
4232		       && h->root.type == bfd_link_hash_undefweak)
4233		relocation = 0;
4234	      else
4235		{
4236		  hundef = true;
4237		  relocation = 0;
4238		}
4239	    }
4240	  else
4241	    {
4242	      asection *section;
4243
4244	      section = aout_reloc_index_to_section (input_bfd, r_index);
4245	      relocation = (section->output_section->vma
4246			    + section->output_offset
4247			    - section->vma);
4248	      if (r_pcrel)
4249		relocation += input_section->vma;
4250	    }
4251
4252	  if (check_dynamic_reloc != NULL)
4253	    {
4254	      bool skip;
4255
4256	      if (! ((*check_dynamic_reloc)
4257		     (flaginfo->info, input_bfd, input_section, h,
4258		      (void *) rel, contents, &skip, &relocation)))
4259		return false;
4260	      if (skip)
4261		continue;
4262	    }
4263
4264	  /* Now warn if a global symbol is undefined.  We could not
4265	     do this earlier, because check_dynamic_reloc might want
4266	     to skip this reloc.  */
4267	  if (hundef && ! bfd_link_pic (flaginfo->info) && ! r_baserel)
4268	    {
4269	      const char *name;
4270
4271	      if (h != NULL)
4272		name = h->root.root.string;
4273	      else
4274		name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
4275	      (*flaginfo->info->callbacks->undefined_symbol)
4276		(flaginfo->info, name, input_bfd, input_section, r_addr, true);
4277	    }
4278
4279	  r = MY_final_link_relocate (howto,
4280				      input_bfd, input_section,
4281				      contents, r_addr, relocation,
4282				      (bfd_vma) 0);
4283	}
4284
4285      if (r != bfd_reloc_ok)
4286	{
4287	  switch (r)
4288	    {
4289	    default:
4290	    case bfd_reloc_outofrange:
4291	      abort ();
4292	    case bfd_reloc_overflow:
4293	      {
4294		const char *name;
4295
4296		if (h != NULL)
4297		  name = NULL;
4298		else if (r_extern)
4299		  name = strings + GET_WORD (input_bfd,
4300					     syms[r_index].e_strx);
4301		else
4302		  {
4303		    asection *s;
4304
4305		    s = aout_reloc_index_to_section (input_bfd, r_index);
4306		    name = bfd_section_name (s);
4307		  }
4308		(*flaginfo->info->callbacks->reloc_overflow)
4309		  (flaginfo->info, (h ? &h->root : NULL), name, howto->name,
4310		   (bfd_vma) 0, input_bfd, input_section, r_addr);
4311	      }
4312	      break;
4313	    }
4314	}
4315    }
4316
4317  return true;
4318}
4319
4320/* Relocate an a.out section using extended a.out relocs.  */
4321
4322static bool
4323aout_link_input_section_ext (struct aout_final_link_info *flaginfo,
4324			     bfd *input_bfd,
4325			     asection *input_section,
4326			     struct reloc_ext_external *relocs,
4327			     bfd_size_type rel_size,
4328			     bfd_byte *contents)
4329{
4330  bool (*check_dynamic_reloc)
4331    (struct bfd_link_info *, bfd *, asection *,
4332     struct aout_link_hash_entry *, void *, bfd_byte *, bool *, bfd_vma *);
4333  bfd *output_bfd;
4334  bool relocatable;
4335  struct external_nlist *syms;
4336  char *strings;
4337  struct aout_link_hash_entry **sym_hashes;
4338  int *symbol_map;
4339  bfd_size_type reloc_count;
4340  struct reloc_ext_external *rel;
4341  struct reloc_ext_external *rel_end;
4342
4343  output_bfd = flaginfo->output_bfd;
4344  check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
4345
4346  BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
4347  BFD_ASSERT (input_bfd->xvec->header_byteorder
4348	      == output_bfd->xvec->header_byteorder);
4349
4350  relocatable = bfd_link_relocatable (flaginfo->info);
4351  syms = obj_aout_external_syms (input_bfd);
4352  strings = obj_aout_external_strings (input_bfd);
4353  sym_hashes = obj_aout_sym_hashes (input_bfd);
4354  symbol_map = flaginfo->symbol_map;
4355
4356  reloc_count = rel_size / RELOC_EXT_SIZE;
4357  rel = relocs;
4358  rel_end = rel + reloc_count;
4359  for (; rel < rel_end; rel++)
4360    {
4361      bfd_vma r_addr;
4362      unsigned int r_index;
4363      int r_extern;
4364      unsigned int r_type;
4365      bfd_vma r_addend;
4366      struct aout_link_hash_entry *h = NULL;
4367      asection *r_section = NULL;
4368      bfd_vma relocation;
4369
4370      r_addr = GET_SWORD (input_bfd, rel->r_address);
4371
4372      if (bfd_header_big_endian (input_bfd))
4373	{
4374	  r_index  = (((unsigned int) rel->r_index[0] << 16)
4375		      | ((unsigned int) rel->r_index[1] << 8)
4376		      | rel->r_index[2]);
4377	  r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
4378	  r_type   = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
4379		      >> RELOC_EXT_BITS_TYPE_SH_BIG);
4380	}
4381      else
4382	{
4383	  r_index  = (((unsigned int) rel->r_index[2] << 16)
4384		      | ((unsigned int) rel->r_index[1] << 8)
4385		      | rel->r_index[0]);
4386	  r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
4387	  r_type   = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
4388		      >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
4389	}
4390
4391      r_addend = GET_SWORD (input_bfd, rel->r_addend);
4392
4393      if (r_type >= TABLE_SIZE (howto_table_ext))
4394	{
4395	  _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
4396			      input_bfd, r_type);
4397	  bfd_set_error (bfd_error_bad_value);
4398	  return false;
4399	}
4400
4401      if (relocatable)
4402	{
4403	  /* We are generating a relocatable output file, and must
4404	     modify the reloc accordingly.  */
4405	  if (r_extern
4406	      || r_type == (unsigned int) RELOC_BASE10
4407	      || r_type == (unsigned int) RELOC_BASE13
4408	      || r_type == (unsigned int) RELOC_BASE22)
4409	    {
4410	      /* If we know the symbol this relocation is against,
4411		 convert it into a relocation against a section.  This
4412		 is what the native linker does.  */
4413	      if (r_type == (unsigned int) RELOC_BASE10
4414		  || r_type == (unsigned int) RELOC_BASE13
4415		  || r_type == (unsigned int) RELOC_BASE22)
4416		h = NULL;
4417	      else
4418		h = sym_hashes[r_index];
4419	      if (h != NULL
4420		  && (h->root.type == bfd_link_hash_defined
4421		      || h->root.type == bfd_link_hash_defweak))
4422		{
4423		  asection *output_section;
4424
4425		  /* Change the r_extern value.  */
4426		  if (bfd_header_big_endian (output_bfd))
4427		    rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
4428		  else
4429		    rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
4430
4431		  /* Compute a new r_index.  */
4432		  output_section = h->root.u.def.section->output_section;
4433		  if (output_section == obj_textsec (output_bfd))
4434		    r_index = N_TEXT;
4435		  else if (output_section == obj_datasec (output_bfd))
4436		    r_index = N_DATA;
4437		  else if (output_section == obj_bsssec (output_bfd))
4438		    r_index = N_BSS;
4439		  else
4440		    r_index = N_ABS;
4441
4442		  /* Add the symbol value and the section VMA to the
4443		     addend.  */
4444		  relocation = (h->root.u.def.value
4445				+ output_section->vma
4446				+ h->root.u.def.section->output_offset);
4447
4448		  /* Now RELOCATION is the VMA of the final
4449		     destination.  If this is a PC relative reloc,
4450		     then ADDEND is the negative of the source VMA.
4451		     We want to set ADDEND to the difference between
4452		     the destination VMA and the source VMA, which
4453		     means we must adjust RELOCATION by the change in
4454		     the source VMA.  This is done below.  */
4455		}
4456	      else
4457		{
4458		  /* We must change r_index according to the symbol
4459		     map.  */
4460		  r_index = symbol_map[r_index];
4461
4462		  if (r_index == -1u)
4463		    {
4464		      if (h != NULL)
4465			{
4466			  /* We decided to strip this symbol, but it
4467			     turns out that we can't.  Note that we
4468			     lose the other and desc information here.
4469			     I don't think that will ever matter for a
4470			     global symbol.  */
4471			  if (h->indx < 0)
4472			    {
4473			      h->indx = -2;
4474			      h->written = false;
4475			      if (!aout_link_write_other_symbol (&h->root.root,
4476								 flaginfo))
4477				return false;
4478			    }
4479			  r_index = h->indx;
4480			}
4481		      else
4482			{
4483			  const char *name;
4484
4485			  name = strings + GET_WORD (input_bfd,
4486						     syms[r_index].e_strx);
4487			  (*flaginfo->info->callbacks->unattached_reloc)
4488			    (flaginfo->info, name,
4489			     input_bfd, input_section, r_addr);
4490			  r_index = 0;
4491			}
4492		    }
4493
4494		  relocation = 0;
4495
4496		  /* If this is a PC relative reloc, then the addend
4497		     is the negative of the source VMA.  We must
4498		     adjust it by the change in the source VMA.  This
4499		     is done below.  */
4500		}
4501
4502	      /* Write out the new r_index value.  */
4503	      if (bfd_header_big_endian (output_bfd))
4504		{
4505		  rel->r_index[0] = r_index >> 16;
4506		  rel->r_index[1] = r_index >> 8;
4507		  rel->r_index[2] = r_index;
4508		}
4509	      else
4510		{
4511		  rel->r_index[2] = r_index >> 16;
4512		  rel->r_index[1] = r_index >> 8;
4513		  rel->r_index[0] = r_index;
4514		}
4515	    }
4516	  else
4517	    {
4518	      /* This is a relocation against a section.  We must
4519		 adjust by the amount that the section moved.  */
4520	      r_section = aout_reloc_index_to_section (input_bfd, r_index);
4521	      relocation = (r_section->output_section->vma
4522			    + r_section->output_offset
4523			    - r_section->vma);
4524
4525	      /* If this is a PC relative reloc, then the addend is
4526		 the difference in VMA between the destination and the
4527		 source.  We have just adjusted for the change in VMA
4528		 of the destination, so we must also adjust by the
4529		 change in VMA of the source.  This is done below.  */
4530	    }
4531
4532	  /* As described above, we must always adjust a PC relative
4533	     reloc by the change in VMA of the source.  However, if
4534	     pcrel_offset is set, then the addend does not include the
4535	     location within the section, in which case we don't need
4536	     to adjust anything.  */
4537	  if (howto_table_ext[r_type].pc_relative
4538	      && ! howto_table_ext[r_type].pcrel_offset)
4539	    relocation -= (input_section->output_section->vma
4540			   + input_section->output_offset
4541			   - input_section->vma);
4542
4543	  /* Change the addend if necessary.  */
4544	  if (relocation != 0)
4545	    PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
4546
4547	  /* Change the address of the relocation.  */
4548	  PUT_WORD (output_bfd,
4549		    r_addr + input_section->output_offset,
4550		    rel->r_address);
4551	}
4552      else
4553	{
4554	  bool hundef;
4555	  bfd_reloc_status_type r;
4556
4557	  /* We are generating an executable, and must do a full
4558	     relocation.  */
4559	  hundef = false;
4560
4561	  if (r_extern)
4562	    {
4563	      h = sym_hashes[r_index];
4564
4565	      if (h != NULL
4566		  && (h->root.type == bfd_link_hash_defined
4567		      || h->root.type == bfd_link_hash_defweak))
4568		{
4569		  relocation = (h->root.u.def.value
4570				+ h->root.u.def.section->output_section->vma
4571				+ h->root.u.def.section->output_offset);
4572		}
4573	      else if (h != NULL
4574		       && h->root.type == bfd_link_hash_undefweak)
4575		relocation = 0;
4576	      else
4577		{
4578		  hundef = true;
4579		  relocation = 0;
4580		}
4581	    }
4582	  else if (r_type == (unsigned int) RELOC_BASE10
4583		   || r_type == (unsigned int) RELOC_BASE13
4584		   || r_type == (unsigned int) RELOC_BASE22)
4585	    {
4586	      struct external_nlist *sym;
4587	      int type;
4588
4589	      /* For base relative relocs, r_index is always an index
4590		 into the symbol table, even if r_extern is 0.  */
4591	      sym = syms + r_index;
4592	      type = H_GET_8 (input_bfd, sym->e_type);
4593	      if ((type & N_TYPE) == N_TEXT
4594		  || type == N_WEAKT)
4595		r_section = obj_textsec (input_bfd);
4596	      else if ((type & N_TYPE) == N_DATA
4597		       || type == N_WEAKD)
4598		r_section = obj_datasec (input_bfd);
4599	      else if ((type & N_TYPE) == N_BSS
4600		       || type == N_WEAKB)
4601		r_section = obj_bsssec (input_bfd);
4602	      else if ((type & N_TYPE) == N_ABS
4603		       || type == N_WEAKA)
4604		r_section = bfd_abs_section_ptr;
4605	      else
4606		abort ();
4607	      relocation = (r_section->output_section->vma
4608			    + r_section->output_offset
4609			    + (GET_WORD (input_bfd, sym->e_value)
4610			       - r_section->vma));
4611	    }
4612	  else
4613	    {
4614	      r_section = aout_reloc_index_to_section (input_bfd, r_index);
4615
4616	      /* If this is a PC relative reloc, then R_ADDEND is the
4617		 difference between the two vmas, or
4618		   old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
4619		 where
4620		   old_dest_sec == section->vma
4621		 and
4622		   old_src_sec == input_section->vma
4623		 and
4624		   old_src_off == r_addr
4625
4626		 _bfd_final_link_relocate expects RELOCATION +
4627		 R_ADDEND to be the VMA of the destination minus
4628		 r_addr (the minus r_addr is because this relocation
4629		 is not pcrel_offset, which is a bit confusing and
4630		 should, perhaps, be changed), or
4631		   new_dest_sec
4632		 where
4633		   new_dest_sec == output_section->vma + output_offset
4634		 We arrange for this to happen by setting RELOCATION to
4635		   new_dest_sec + old_src_sec - old_dest_sec
4636
4637		 If this is not a PC relative reloc, then R_ADDEND is
4638		 simply the VMA of the destination, so we set
4639		 RELOCATION to the change in the destination VMA, or
4640		   new_dest_sec - old_dest_sec
4641		 */
4642	      relocation = (r_section->output_section->vma
4643			    + r_section->output_offset
4644			    - r_section->vma);
4645	      if (howto_table_ext[r_type].pc_relative)
4646		relocation += input_section->vma;
4647	    }
4648
4649	  if (check_dynamic_reloc != NULL)
4650	    {
4651	      bool skip;
4652
4653	      if (! ((*check_dynamic_reloc)
4654		     (flaginfo->info, input_bfd, input_section, h,
4655		      (void *) rel, contents, &skip, &relocation)))
4656		return false;
4657	      if (skip)
4658		continue;
4659	    }
4660
4661	  /* Now warn if a global symbol is undefined.  We could not
4662	     do this earlier, because check_dynamic_reloc might want
4663	     to skip this reloc.  */
4664	  if (hundef
4665	      && ! bfd_link_pic (flaginfo->info)
4666	      && r_type != (unsigned int) RELOC_BASE10
4667	      && r_type != (unsigned int) RELOC_BASE13
4668	      && r_type != (unsigned int) RELOC_BASE22)
4669	    {
4670	      const char *name;
4671
4672	      if (h != NULL)
4673		name = h->root.root.string;
4674	      else
4675		name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
4676	      (*flaginfo->info->callbacks->undefined_symbol)
4677		(flaginfo->info, name, input_bfd, input_section, r_addr, true);
4678	    }
4679
4680	  if (r_type != (unsigned int) RELOC_SPARC_REV32)
4681	    r = MY_final_link_relocate (howto_table_ext + r_type,
4682					input_bfd, input_section,
4683					contents, r_addr, relocation,
4684					r_addend);
4685	  else
4686	    {
4687	      bfd_vma x;
4688
4689	      x = bfd_get_32 (input_bfd, contents + r_addr);
4690	      x = x + relocation + r_addend;
4691	      bfd_putl32 (/*input_bfd,*/ x, contents + r_addr);
4692	      r = bfd_reloc_ok;
4693	    }
4694
4695	  if (r != bfd_reloc_ok)
4696	    {
4697	      switch (r)
4698		{
4699		default:
4700		case bfd_reloc_outofrange:
4701		  abort ();
4702		case bfd_reloc_overflow:
4703		  {
4704		    const char *name;
4705
4706		    if (h != NULL)
4707		      name = NULL;
4708		    else if (r_extern
4709			     || r_type == (unsigned int) RELOC_BASE10
4710			     || r_type == (unsigned int) RELOC_BASE13
4711			     || r_type == (unsigned int) RELOC_BASE22)
4712		      name = strings + GET_WORD (input_bfd,
4713						 syms[r_index].e_strx);
4714		    else
4715		      {
4716			asection *s;
4717
4718			s = aout_reloc_index_to_section (input_bfd, r_index);
4719			name = bfd_section_name (s);
4720		      }
4721		    (*flaginfo->info->callbacks->reloc_overflow)
4722		      (flaginfo->info, (h ? &h->root : NULL), name,
4723		       howto_table_ext[r_type].name,
4724		       r_addend, input_bfd, input_section, r_addr);
4725		  }
4726		  break;
4727		}
4728	    }
4729	}
4730    }
4731
4732  return true;
4733}
4734
4735/* Link an a.out section into the output file.  */
4736
4737static bool
4738aout_link_input_section (struct aout_final_link_info *flaginfo,
4739			 bfd *input_bfd,
4740			 asection *input_section,
4741			 file_ptr *reloff_ptr,
4742			 bfd_size_type rel_size)
4743{
4744  bfd_size_type input_size;
4745  void * relocs;
4746
4747  /* Get the section contents.  */
4748  input_size = input_section->size;
4749  if (! bfd_get_section_contents (input_bfd, input_section,
4750				  (void *) flaginfo->contents,
4751				  (file_ptr) 0, input_size))
4752    return false;
4753
4754  /* Read in the relocs if we haven't already done it.  */
4755  if (aout_section_data (input_section) != NULL
4756      && aout_section_data (input_section)->relocs != NULL)
4757    relocs = aout_section_data (input_section)->relocs;
4758  else
4759    {
4760      relocs = flaginfo->relocs;
4761      if (rel_size > 0)
4762	{
4763	  if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
4764	      || bfd_bread (relocs, rel_size, input_bfd) != rel_size)
4765	    return false;
4766	}
4767    }
4768
4769  /* Relocate the section contents.  */
4770  if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
4771    {
4772      if (! aout_link_input_section_std (flaginfo, input_bfd, input_section,
4773					 (struct reloc_std_external *) relocs,
4774					 rel_size, flaginfo->contents))
4775	return false;
4776    }
4777  else
4778    {
4779      if (! aout_link_input_section_ext (flaginfo, input_bfd, input_section,
4780					 (struct reloc_ext_external *) relocs,
4781					 rel_size, flaginfo->contents))
4782	return false;
4783    }
4784
4785  /* Write out the section contents.  */
4786  if (! bfd_set_section_contents (flaginfo->output_bfd,
4787				  input_section->output_section,
4788				  (void *) flaginfo->contents,
4789				  (file_ptr) input_section->output_offset,
4790				  input_size))
4791    return false;
4792
4793  /* If we are producing relocatable output, the relocs were
4794     modified, and we now write them out.  */
4795  if (bfd_link_relocatable (flaginfo->info) && rel_size > 0)
4796    {
4797      if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
4798	return false;
4799      if (bfd_bwrite (relocs, rel_size, flaginfo->output_bfd) != rel_size)
4800	return false;
4801      *reloff_ptr += rel_size;
4802
4803      /* Assert that the relocs have not run into the symbols, and
4804	 that if these are the text relocs they have not run into the
4805	 data relocs.  */
4806      BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (flaginfo->output_bfd)
4807		  && (reloff_ptr != &flaginfo->treloff
4808		      || (*reloff_ptr
4809			  <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
4810    }
4811
4812  return true;
4813}
4814
4815/* Adjust and write out the symbols for an a.out file.  Set the new
4816   symbol indices into a symbol_map.  */
4817
4818static bool
4819aout_link_write_symbols (struct aout_final_link_info *flaginfo, bfd *input_bfd)
4820{
4821  bfd *output_bfd;
4822  bfd_size_type sym_count;
4823  char *strings;
4824  enum bfd_link_strip strip;
4825  enum bfd_link_discard discard;
4826  struct external_nlist *outsym;
4827  bfd_size_type strtab_index;
4828  struct external_nlist *sym;
4829  struct external_nlist *sym_end;
4830  struct aout_link_hash_entry **sym_hash;
4831  int *symbol_map;
4832  bool pass;
4833  bool skip_next;
4834
4835  output_bfd = flaginfo->output_bfd;
4836  sym_count = obj_aout_external_sym_count (input_bfd);
4837  strings = obj_aout_external_strings (input_bfd);
4838  strip = flaginfo->info->strip;
4839  discard = flaginfo->info->discard;
4840  outsym = flaginfo->output_syms;
4841
4842  /* First write out a symbol for this object file, unless we are
4843     discarding such symbols.  */
4844  if (strip != strip_all
4845      && (strip != strip_some
4846	  || bfd_hash_lookup (flaginfo->info->keep_hash,
4847			      bfd_get_filename (input_bfd),
4848			      false, false) != NULL)
4849      && discard != discard_all)
4850    {
4851      H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
4852      H_PUT_8 (output_bfd, 0, outsym->e_other);
4853      H_PUT_16 (output_bfd, 0, outsym->e_desc);
4854      strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab,
4855				       bfd_get_filename (input_bfd), false);
4856      if (strtab_index == (bfd_size_type) -1)
4857	return false;
4858      PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4859      PUT_WORD (output_bfd,
4860		(bfd_section_vma (obj_textsec (input_bfd)->output_section)
4861		 + obj_textsec (input_bfd)->output_offset),
4862		outsym->e_value);
4863      ++obj_aout_external_sym_count (output_bfd);
4864      ++outsym;
4865    }
4866
4867  pass = false;
4868  skip_next = false;
4869  sym = obj_aout_external_syms (input_bfd);
4870  sym_end = sym + sym_count;
4871  sym_hash = obj_aout_sym_hashes (input_bfd);
4872  symbol_map = flaginfo->symbol_map;
4873  memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map);
4874  for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
4875    {
4876      const char *name;
4877      int type;
4878      struct aout_link_hash_entry *h;
4879      bool skip;
4880      asection *symsec;
4881      bfd_vma val = 0;
4882      bool copy;
4883
4884      /* We set *symbol_map to 0 above for all symbols.  If it has
4885	 already been set to -1 for this symbol, it means that we are
4886	 discarding it because it appears in a duplicate header file.
4887	 See the N_BINCL code below.  */
4888      if (*symbol_map == -1)
4889	continue;
4890
4891      /* Initialize *symbol_map to -1, which means that the symbol was
4892	 not copied into the output file.  We will change it later if
4893	 we do copy the symbol over.  */
4894      *symbol_map = -1;
4895
4896      type = H_GET_8 (input_bfd, sym->e_type);
4897      name = strings + GET_WORD (input_bfd, sym->e_strx);
4898
4899      h = NULL;
4900
4901      if (pass)
4902	{
4903	  /* Pass this symbol through.  It is the target of an
4904	     indirect or warning symbol.  */
4905	  val = GET_WORD (input_bfd, sym->e_value);
4906	  pass = false;
4907	}
4908      else if (skip_next)
4909	{
4910	  /* Skip this symbol, which is the target of an indirect
4911	     symbol that we have changed to no longer be an indirect
4912	     symbol.  */
4913	  skip_next = false;
4914	  continue;
4915	}
4916      else
4917	{
4918	  struct aout_link_hash_entry *hresolve;
4919
4920	  /* We have saved the hash table entry for this symbol, if
4921	     there is one.  Note that we could just look it up again
4922	     in the hash table, provided we first check that it is an
4923	     external symbol.  */
4924	  h = *sym_hash;
4925
4926	  /* Use the name from the hash table, in case the symbol was
4927	     wrapped.  */
4928	  if (h != NULL
4929	      && h->root.type != bfd_link_hash_warning)
4930	    name = h->root.root.string;
4931
4932	  /* If this is an indirect or warning symbol, then change
4933	     hresolve to the base symbol.  We also change *sym_hash so
4934	     that the relocation routines relocate against the real
4935	     symbol.  */
4936	  hresolve = h;
4937	  if (h != (struct aout_link_hash_entry *) NULL
4938	      && (h->root.type == bfd_link_hash_indirect
4939		  || h->root.type == bfd_link_hash_warning))
4940	    {
4941	      hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
4942	      while (hresolve->root.type == bfd_link_hash_indirect
4943		     || hresolve->root.type == bfd_link_hash_warning)
4944		hresolve = ((struct aout_link_hash_entry *)
4945			    hresolve->root.u.i.link);
4946	      *sym_hash = hresolve;
4947	    }
4948
4949	  /* If the symbol has already been written out, skip it.  */
4950	  if (h != NULL
4951	      && h->written)
4952	    {
4953	      if ((type & N_TYPE) == N_INDR
4954		  || type == N_WARNING)
4955		skip_next = true;
4956	      *symbol_map = h->indx;
4957	      continue;
4958	    }
4959
4960	  /* See if we are stripping this symbol.  */
4961	  skip = false;
4962	  switch (strip)
4963	    {
4964	    case strip_none:
4965	      break;
4966	    case strip_debugger:
4967	      if ((type & N_STAB) != 0)
4968		skip = true;
4969	      break;
4970	    case strip_some:
4971	      if (bfd_hash_lookup (flaginfo->info->keep_hash, name, false, false)
4972		  == NULL)
4973		skip = true;
4974	      break;
4975	    case strip_all:
4976	      skip = true;
4977	      break;
4978	    }
4979	  if (skip)
4980	    {
4981	      if (h != NULL)
4982		h->written = true;
4983	      continue;
4984	    }
4985
4986	  /* Get the value of the symbol.  */
4987	  if ((type & N_TYPE) == N_TEXT
4988	      || type == N_WEAKT)
4989	    symsec = obj_textsec (input_bfd);
4990	  else if ((type & N_TYPE) == N_DATA
4991		   || type == N_WEAKD)
4992	    symsec = obj_datasec (input_bfd);
4993	  else if ((type & N_TYPE) == N_BSS
4994		   || type == N_WEAKB)
4995	    symsec = obj_bsssec (input_bfd);
4996	  else if ((type & N_TYPE) == N_ABS
4997		   || type == N_WEAKA)
4998	    symsec = bfd_abs_section_ptr;
4999	  else if (((type & N_TYPE) == N_INDR
5000		    && (hresolve == NULL
5001			|| (hresolve->root.type != bfd_link_hash_defined
5002			    && hresolve->root.type != bfd_link_hash_defweak
5003			    && hresolve->root.type != bfd_link_hash_common)))
5004		   || type == N_WARNING)
5005	    {
5006	      /* Pass the next symbol through unchanged.  The
5007		 condition above for indirect symbols is so that if
5008		 the indirect symbol was defined, we output it with
5009		 the correct definition so the debugger will
5010		 understand it.  */
5011	      pass = true;
5012	      val = GET_WORD (input_bfd, sym->e_value);
5013	      symsec = NULL;
5014	    }
5015	  else if ((type & N_STAB) != 0)
5016	    {
5017	      val = GET_WORD (input_bfd, sym->e_value);
5018	      symsec = NULL;
5019	    }
5020	  else
5021	    {
5022	      /* If we get here with an indirect symbol, it means that
5023		 we are outputting it with a real definition.  In such
5024		 a case we do not want to output the next symbol,
5025		 which is the target of the indirection.  */
5026	      if ((type & N_TYPE) == N_INDR)
5027		skip_next = true;
5028
5029	      symsec = NULL;
5030
5031	      /* We need to get the value from the hash table.  We use
5032		 hresolve so that if we have defined an indirect
5033		 symbol we output the final definition.  */
5034	      if (h == NULL)
5035		{
5036		  switch (type & N_TYPE)
5037		    {
5038		    case N_SETT:
5039		      symsec = obj_textsec (input_bfd);
5040		      break;
5041		    case N_SETD:
5042		      symsec = obj_datasec (input_bfd);
5043		      break;
5044		    case N_SETB:
5045		      symsec = obj_bsssec (input_bfd);
5046		      break;
5047		    case N_SETA:
5048		      symsec = bfd_abs_section_ptr;
5049		      break;
5050		    default:
5051		      val = 0;
5052		      break;
5053		    }
5054		}
5055	      else if (hresolve->root.type == bfd_link_hash_defined
5056		       || hresolve->root.type == bfd_link_hash_defweak)
5057		{
5058		  asection *input_section;
5059		  asection *output_section;
5060
5061		  /* This case usually means a common symbol which was
5062		     turned into a defined symbol.  */
5063		  input_section = hresolve->root.u.def.section;
5064		  output_section = input_section->output_section;
5065		  BFD_ASSERT (bfd_is_abs_section (output_section)
5066			      || output_section->owner == output_bfd);
5067		  val = (hresolve->root.u.def.value
5068			 + bfd_section_vma (output_section)
5069			 + input_section->output_offset);
5070
5071		  /* Get the correct type based on the section.  If
5072		     this is a constructed set, force it to be
5073		     globally visible.  */
5074		  if (type == N_SETT
5075		      || type == N_SETD
5076		      || type == N_SETB
5077		      || type == N_SETA)
5078		    type |= N_EXT;
5079
5080		  type &=~ N_TYPE;
5081
5082		  if (output_section == obj_textsec (output_bfd))
5083		    type |= (hresolve->root.type == bfd_link_hash_defined
5084			     ? N_TEXT
5085			     : N_WEAKT);
5086		  else if (output_section == obj_datasec (output_bfd))
5087		    type |= (hresolve->root.type == bfd_link_hash_defined
5088			     ? N_DATA
5089			     : N_WEAKD);
5090		  else if (output_section == obj_bsssec (output_bfd))
5091		    type |= (hresolve->root.type == bfd_link_hash_defined
5092			     ? N_BSS
5093			     : N_WEAKB);
5094		  else
5095		    type |= (hresolve->root.type == bfd_link_hash_defined
5096			     ? N_ABS
5097			     : N_WEAKA);
5098		}
5099	      else if (hresolve->root.type == bfd_link_hash_common)
5100		val = hresolve->root.u.c.size;
5101	      else if (hresolve->root.type == bfd_link_hash_undefweak)
5102		{
5103		  val = 0;
5104		  type = N_WEAKU;
5105		}
5106	      else
5107		val = 0;
5108	    }
5109	  if (symsec != NULL)
5110	    val = (symsec->output_section->vma
5111		   + symsec->output_offset
5112		   + (GET_WORD (input_bfd, sym->e_value)
5113		      - symsec->vma));
5114
5115	  /* If this is a global symbol set the written flag, and if
5116	     it is a local symbol see if we should discard it.  */
5117	  if (h != NULL)
5118	    {
5119	      h->written = true;
5120	      h->indx = obj_aout_external_sym_count (output_bfd);
5121	    }
5122	  else if ((type & N_TYPE) != N_SETT
5123		   && (type & N_TYPE) != N_SETD
5124		   && (type & N_TYPE) != N_SETB
5125		   && (type & N_TYPE) != N_SETA)
5126	    {
5127	      switch (discard)
5128		{
5129		case discard_none:
5130		case discard_sec_merge:
5131		  break;
5132		case discard_l:
5133		  if ((type & N_STAB) == 0
5134		      && bfd_is_local_label_name (input_bfd, name))
5135		    skip = true;
5136		  break;
5137		case discard_all:
5138		  skip = true;
5139		  break;
5140		}
5141	      if (skip)
5142		{
5143		  pass = false;
5144		  continue;
5145		}
5146	    }
5147
5148	  /* An N_BINCL symbol indicates the start of the stabs
5149	     entries for a header file.  We need to scan ahead to the
5150	     next N_EINCL symbol, ignoring nesting, adding up all the
5151	     characters in the symbol names, not including the file
5152	     numbers in types (the first number after an open
5153	     parenthesis).  */
5154	  if (type == (int) N_BINCL)
5155	    {
5156	      struct external_nlist *incl_sym;
5157	      int nest;
5158	      struct aout_link_includes_entry *incl_entry;
5159	      struct aout_link_includes_totals *t;
5160
5161	      val = 0;
5162	      nest = 0;
5163	      for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
5164		{
5165		  int incl_type;
5166
5167		  incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
5168		  if (incl_type == (int) N_EINCL)
5169		    {
5170		      if (nest == 0)
5171			break;
5172		      --nest;
5173		    }
5174		  else if (incl_type == (int) N_BINCL)
5175		    ++nest;
5176		  else if (nest == 0)
5177		    {
5178		      const char *s;
5179
5180		      s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
5181		      for (; *s != '\0'; s++)
5182			{
5183			  val += *s;
5184			  if (*s == '(')
5185			    {
5186			      /* Skip the file number.  */
5187			      ++s;
5188			      while (ISDIGIT (*s))
5189				++s;
5190			      --s;
5191			    }
5192			}
5193		    }
5194		}
5195
5196	      /* If we have already included a header file with the
5197		 same value, then replace this one with an N_EXCL
5198		 symbol.  */
5199	      copy = !flaginfo->info->keep_memory;
5200	      incl_entry = aout_link_includes_lookup (&flaginfo->includes,
5201						      name, true, copy);
5202	      if (incl_entry == NULL)
5203		return false;
5204	      for (t = incl_entry->totals; t != NULL; t = t->next)
5205		if (t->total == val)
5206		  break;
5207	      if (t == NULL)
5208		{
5209		  /* This is the first time we have seen this header
5210		     file with this set of stabs strings.  */
5211		  t = (struct aout_link_includes_totals *)
5212		      bfd_hash_allocate (&flaginfo->includes.root,
5213					 sizeof *t);
5214		  if (t == NULL)
5215		    return false;
5216		  t->total = val;
5217		  t->next = incl_entry->totals;
5218		  incl_entry->totals = t;
5219		}
5220	      else
5221		{
5222		  int *incl_map;
5223
5224		  /* This is a duplicate header file.  We must change
5225		     it to be an N_EXCL entry, and mark all the
5226		     included symbols to prevent outputting them.  */
5227		  type = (int) N_EXCL;
5228
5229		  nest = 0;
5230		  for (incl_sym = sym + 1, incl_map = symbol_map + 1;
5231		       incl_sym < sym_end;
5232		       incl_sym++, incl_map++)
5233		    {
5234		      int incl_type;
5235
5236		      incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
5237		      if (incl_type == (int) N_EINCL)
5238			{
5239			  if (nest == 0)
5240			    {
5241			      *incl_map = -1;
5242			      break;
5243			    }
5244			  --nest;
5245			}
5246		      else if (incl_type == (int) N_BINCL)
5247			++nest;
5248		      else if (nest == 0)
5249			*incl_map = -1;
5250		    }
5251		}
5252	    }
5253	}
5254
5255      /* Copy this symbol into the list of symbols we are going to
5256	 write out.  */
5257      H_PUT_8 (output_bfd, type, outsym->e_type);
5258      H_PUT_8 (output_bfd, H_GET_8 (input_bfd, sym->e_other), outsym->e_other);
5259      H_PUT_16 (output_bfd, H_GET_16 (input_bfd, sym->e_desc), outsym->e_desc);
5260      copy = false;
5261      if (! flaginfo->info->keep_memory)
5262	{
5263	  /* name points into a string table which we are going to
5264	     free.  If there is a hash table entry, use that string.
5265	     Otherwise, copy name into memory.  */
5266	  if (h != NULL)
5267	    name = h->root.root.string;
5268	  else
5269	    copy = true;
5270	}
5271      strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab,
5272				       name, copy);
5273      if (strtab_index == (bfd_size_type) -1)
5274	return false;
5275      PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
5276      PUT_WORD (output_bfd, val, outsym->e_value);
5277      *symbol_map = obj_aout_external_sym_count (output_bfd);
5278      ++obj_aout_external_sym_count (output_bfd);
5279      ++outsym;
5280    }
5281
5282  /* Write out the output symbols we have just constructed.  */
5283  if (outsym > flaginfo->output_syms)
5284    {
5285      bfd_size_type outsym_size;
5286
5287      if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0)
5288	return false;
5289      outsym_size = outsym - flaginfo->output_syms;
5290      outsym_size *= EXTERNAL_NLIST_SIZE;
5291      if (bfd_bwrite ((void *) flaginfo->output_syms, outsym_size, output_bfd)
5292	  != outsym_size)
5293	return false;
5294      flaginfo->symoff += outsym_size;
5295    }
5296
5297  return true;
5298}
5299
5300/* Link an a.out input BFD into the output file.  */
5301
5302static bool
5303aout_link_input_bfd (struct aout_final_link_info *flaginfo, bfd *input_bfd)
5304{
5305  BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
5306
5307  /* If this is a dynamic object, it may need special handling.  */
5308  if ((input_bfd->flags & DYNAMIC) != 0
5309      && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
5310    return ((*aout_backend_info (input_bfd)->link_dynamic_object)
5311	    (flaginfo->info, input_bfd));
5312
5313  /* Get the symbols.  We probably have them already, unless
5314     flaginfo->info->keep_memory is FALSE.  */
5315  if (! aout_get_external_symbols (input_bfd))
5316    return false;
5317
5318  /* Write out the symbols and get a map of the new indices.  The map
5319     is placed into flaginfo->symbol_map.  */
5320  if (! aout_link_write_symbols (flaginfo, input_bfd))
5321    return false;
5322
5323  /* Relocate and write out the sections.  These functions use the
5324     symbol map created by aout_link_write_symbols.  The linker_mark
5325     field will be set if these sections are to be included in the
5326     link, which will normally be the case.  */
5327  if (obj_textsec (input_bfd)->linker_mark)
5328    {
5329      if (! aout_link_input_section (flaginfo, input_bfd,
5330				     obj_textsec (input_bfd),
5331				     &flaginfo->treloff,
5332				     exec_hdr (input_bfd)->a_trsize))
5333	return false;
5334    }
5335  if (obj_datasec (input_bfd)->linker_mark)
5336    {
5337      if (! aout_link_input_section (flaginfo, input_bfd,
5338				     obj_datasec (input_bfd),
5339				     &flaginfo->dreloff,
5340				     exec_hdr (input_bfd)->a_drsize))
5341	return false;
5342    }
5343
5344  /* If we are not keeping memory, we don't need the symbols any
5345     longer.  We still need them if we are keeping memory, because the
5346     strings in the hash table point into them.  */
5347  if (! flaginfo->info->keep_memory)
5348    {
5349      if (! aout_link_free_symbols (input_bfd))
5350	return false;
5351    }
5352
5353  return true;
5354}
5355
5356/* Do the final link step.  This is called on the output BFD.  The
5357   INFO structure should point to a list of BFDs linked through the
5358   link.next field which can be used to find each BFD which takes part
5359   in the output.  Also, each section in ABFD should point to a list
5360   of bfd_link_order structures which list all the input sections for
5361   the output section.  */
5362
5363bool
5364NAME (aout, final_link) (bfd *abfd,
5365			 struct bfd_link_info *info,
5366			 void (*callback) (bfd *, file_ptr *, file_ptr *, file_ptr *))
5367{
5368  struct aout_final_link_info aout_info;
5369  bool includes_hash_initialized = false;
5370  bfd *sub;
5371  bfd_size_type trsize, drsize;
5372  bfd_size_type max_contents_size;
5373  bfd_size_type max_relocs_size;
5374  bfd_size_type max_sym_count;
5375  struct bfd_link_order *p;
5376  asection *o;
5377  bool have_link_order_relocs;
5378
5379  if (bfd_link_pic (info))
5380    abfd->flags |= DYNAMIC;
5381
5382  aout_info.info = info;
5383  aout_info.output_bfd = abfd;
5384  aout_info.contents = NULL;
5385  aout_info.relocs = NULL;
5386  aout_info.symbol_map = NULL;
5387  aout_info.output_syms = NULL;
5388
5389  if (!bfd_hash_table_init_n (&aout_info.includes.root,
5390			      aout_link_includes_newfunc,
5391			      sizeof (struct aout_link_includes_entry),
5392			      251))
5393    goto error_return;
5394  includes_hash_initialized = true;
5395
5396  /* Figure out the largest section size.  Also, if generating
5397     relocatable output, count the relocs.  */
5398  trsize = 0;
5399  drsize = 0;
5400  max_contents_size = 0;
5401  max_relocs_size = 0;
5402  max_sym_count = 0;
5403  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
5404    {
5405      bfd_size_type sz;
5406
5407      if (bfd_link_relocatable (info))
5408	{
5409	  if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
5410	    {
5411	      trsize += exec_hdr (sub)->a_trsize;
5412	      drsize += exec_hdr (sub)->a_drsize;
5413	    }
5414	  else
5415	    {
5416	      /* FIXME: We need to identify the .text and .data sections
5417		 and call get_reloc_upper_bound and canonicalize_reloc to
5418		 work out the number of relocs needed, and then multiply
5419		 by the reloc size.  */
5420	      _bfd_error_handler
5421		/* xgettext:c-format */
5422		(_("%pB: relocatable link from %s to %s not supported"),
5423		 abfd, sub->xvec->name, abfd->xvec->name);
5424	      bfd_set_error (bfd_error_invalid_operation);
5425	      goto error_return;
5426	    }
5427	}
5428
5429      if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
5430	{
5431	  sz = obj_textsec (sub)->size;
5432	  if (sz > max_contents_size)
5433	    max_contents_size = sz;
5434	  sz = obj_datasec (sub)->size;
5435	  if (sz > max_contents_size)
5436	    max_contents_size = sz;
5437
5438	  sz = exec_hdr (sub)->a_trsize;
5439	  if (sz > max_relocs_size)
5440	    max_relocs_size = sz;
5441	  sz = exec_hdr (sub)->a_drsize;
5442	  if (sz > max_relocs_size)
5443	    max_relocs_size = sz;
5444
5445	  sz = obj_aout_external_sym_count (sub);
5446	  if (sz > max_sym_count)
5447	    max_sym_count = sz;
5448	}
5449    }
5450
5451  if (bfd_link_relocatable (info))
5452    {
5453      if (obj_textsec (abfd) != NULL)
5454	trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
5455						 ->map_head.link_order)
5456		   * obj_reloc_entry_size (abfd));
5457      if (obj_datasec (abfd) != NULL)
5458	drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
5459						 ->map_head.link_order)
5460		   * obj_reloc_entry_size (abfd));
5461    }
5462
5463  exec_hdr (abfd)->a_trsize = trsize;
5464  exec_hdr (abfd)->a_drsize = drsize;
5465
5466  exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
5467
5468  /* Adjust the section sizes and vmas according to the magic number.
5469     This sets a_text, a_data and a_bss in the exec_hdr and sets the
5470     filepos for each section.  */
5471  if (! NAME (aout, adjust_sizes_and_vmas) (abfd))
5472    goto error_return;
5473
5474  /* The relocation and symbol file positions differ among a.out
5475     targets.  We are passed a callback routine from the backend
5476     specific code to handle this.
5477     FIXME: At this point we do not know how much space the symbol
5478     table will require.  This will not work for any (nonstandard)
5479     a.out target that needs to know the symbol table size before it
5480     can compute the relocation file positions.  */
5481  (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
5482	       &aout_info.symoff);
5483  obj_textsec (abfd)->rel_filepos = aout_info.treloff;
5484  obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
5485  obj_sym_filepos (abfd) = aout_info.symoff;
5486
5487  /* We keep a count of the symbols as we output them.  */
5488  obj_aout_external_sym_count (abfd) = 0;
5489
5490  /* We accumulate the string table as we write out the symbols.  */
5491  aout_info.strtab = _bfd_stringtab_init ();
5492  if (aout_info.strtab == NULL)
5493    goto error_return;
5494
5495  /* Allocate buffers to hold section contents and relocs.  */
5496  aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size);
5497  aout_info.relocs = bfd_malloc (max_relocs_size);
5498  aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int));
5499  aout_info.output_syms = (struct external_nlist *)
5500      bfd_malloc ((max_sym_count + 1) * sizeof (struct external_nlist));
5501  if ((aout_info.contents == NULL && max_contents_size != 0)
5502      || (aout_info.relocs == NULL && max_relocs_size != 0)
5503      || (aout_info.symbol_map == NULL && max_sym_count != 0)
5504      || aout_info.output_syms == NULL)
5505    goto error_return;
5506
5507  /* If we have a symbol named __DYNAMIC, force it out now.  This is
5508     required by SunOS.  Doing this here rather than in sunos.c is a
5509     hack, but it's easier than exporting everything which would be
5510     needed.  */
5511  {
5512    struct aout_link_hash_entry *h;
5513
5514    h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
5515			       false, false, false);
5516    if (h != NULL)
5517      aout_link_write_other_symbol (&h->root.root, &aout_info);
5518  }
5519
5520  /* The most time efficient way to do the link would be to read all
5521     the input object files into memory and then sort out the
5522     information into the output file.  Unfortunately, that will
5523     probably use too much memory.  Another method would be to step
5524     through everything that composes the text section and write it
5525     out, and then everything that composes the data section and write
5526     it out, and then write out the relocs, and then write out the
5527     symbols.  Unfortunately, that requires reading stuff from each
5528     input file several times, and we will not be able to keep all the
5529     input files open simultaneously, and reopening them will be slow.
5530
5531     What we do is basically process one input file at a time.  We do
5532     everything we need to do with an input file once--copy over the
5533     section contents, handle the relocation information, and write
5534     out the symbols--and then we throw away the information we read
5535     from it.  This approach requires a lot of lseeks of the output
5536     file, which is unfortunate but still faster than reopening a lot
5537     of files.
5538
5539     We use the output_has_begun field of the input BFDs to see
5540     whether we have already handled it.  */
5541  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
5542    sub->output_has_begun = false;
5543
5544  /* Mark all sections which are to be included in the link.  This
5545     will normally be every section.  We need to do this so that we
5546     can identify any sections which the linker has decided to not
5547     include.  */
5548  for (o = abfd->sections; o != NULL; o = o->next)
5549    {
5550      for (p = o->map_head.link_order; p != NULL; p = p->next)
5551	if (p->type == bfd_indirect_link_order)
5552	  p->u.indirect.section->linker_mark = true;
5553    }
5554
5555  have_link_order_relocs = false;
5556  for (o = abfd->sections; o != NULL; o = o->next)
5557    {
5558      for (p = o->map_head.link_order;
5559	   p != NULL;
5560	   p = p->next)
5561	{
5562	  if (p->type == bfd_indirect_link_order
5563	      && (bfd_get_flavour (p->u.indirect.section->owner)
5564		  == bfd_target_aout_flavour))
5565	    {
5566	      bfd *input_bfd;
5567
5568	      input_bfd = p->u.indirect.section->owner;
5569	      if (! input_bfd->output_has_begun)
5570		{
5571		  if (! aout_link_input_bfd (&aout_info, input_bfd))
5572		    goto error_return;
5573		  input_bfd->output_has_begun = true;
5574		}
5575	    }
5576	  else if (p->type == bfd_section_reloc_link_order
5577		   || p->type == bfd_symbol_reloc_link_order)
5578	    {
5579	      /* These are handled below.  */
5580	      have_link_order_relocs = true;
5581	    }
5582	  else
5583	    {
5584	      if (! _bfd_default_link_order (abfd, info, o, p))
5585		goto error_return;
5586	    }
5587	}
5588    }
5589
5590  /* Write out any symbols that we have not already written out.  */
5591  bfd_hash_traverse (&info->hash->table,
5592		     aout_link_write_other_symbol,
5593		     &aout_info);
5594
5595  /* Now handle any relocs we were asked to create by the linker.
5596     These did not come from any input file.  We must do these after
5597     we have written out all the symbols, so that we know the symbol
5598     indices to use.  */
5599  if (have_link_order_relocs)
5600    {
5601      for (o = abfd->sections; o != NULL; o = o->next)
5602	{
5603	  for (p = o->map_head.link_order;
5604	       p != NULL;
5605	       p = p->next)
5606	    {
5607	      if (p->type == bfd_section_reloc_link_order
5608		  || p->type == bfd_symbol_reloc_link_order)
5609		{
5610		  if (! aout_link_reloc_link_order (&aout_info, o, p))
5611		    goto error_return;
5612		}
5613	    }
5614	}
5615    }
5616
5617  free (aout_info.contents);
5618  aout_info.contents = NULL;
5619  free (aout_info.relocs);
5620  aout_info.relocs = NULL;
5621  free (aout_info.symbol_map);
5622  aout_info.symbol_map = NULL;
5623  free (aout_info.output_syms);
5624  aout_info.output_syms = NULL;
5625
5626  if (includes_hash_initialized)
5627    {
5628      bfd_hash_table_free (&aout_info.includes.root);
5629      includes_hash_initialized = false;
5630    }
5631
5632  /* Finish up any dynamic linking we may be doing.  */
5633  if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
5634    {
5635      if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
5636	goto error_return;
5637    }
5638
5639  /* Update the header information.  */
5640  abfd->symcount = obj_aout_external_sym_count (abfd);
5641  exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
5642  obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
5643  obj_textsec (abfd)->reloc_count =
5644    exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
5645  obj_datasec (abfd)->reloc_count =
5646    exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
5647
5648  /* Write out the string table, unless there are no symbols.  */
5649  if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
5650    goto error_return;
5651  if (abfd->symcount > 0)
5652    {
5653      if (!emit_stringtab (abfd, aout_info.strtab))
5654	goto error_return;
5655    }
5656  else
5657    {
5658      bfd_byte b[BYTES_IN_WORD];
5659
5660      memset (b, 0, BYTES_IN_WORD);
5661      if (bfd_bwrite (b, (bfd_size_type) BYTES_IN_WORD, abfd) != BYTES_IN_WORD)
5662	goto error_return;
5663    }
5664
5665  return true;
5666
5667 error_return:
5668  free (aout_info.contents);
5669  free (aout_info.relocs);
5670  free (aout_info.symbol_map);
5671  free (aout_info.output_syms);
5672  if (includes_hash_initialized)
5673    bfd_hash_table_free (&aout_info.includes.root);
5674  return false;
5675}
5676