1319780Sdim/* BFD semi-generic back-end for a.out binaries.
2319780Sdim   Copyright (C) 1990-2022 Free Software Foundation, Inc.
3319780Sdim   Written by Cygnus Support.
4319780Sdim
5319780Sdim   This file is part of BFD, the Binary File Descriptor library.
6319780Sdim
7319780Sdim   This program is free software; you can redistribute it and/or modify
8319780Sdim   it under the terms of the GNU General Public License as published by
9319780Sdim   the Free Software Foundation; either version 3 of the License, or
10319780Sdim   (at your option) any later version.
11319780Sdim
12319780Sdim   This program is distributed in the hope that it will be useful,
13319780Sdim   but WITHOUT ANY WARRANTY; without even the implied warranty of
14319780Sdim   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15319780Sdim   GNU General Public License for more details.
16319780Sdim
17319780Sdim   You should have received a copy of the GNU General Public License
18319780Sdim   along with this program; if not, write to the Free Software
19319780Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20319780Sdim   MA 02110-1301, USA.  */
21319780Sdim
22319780Sdim/*
23319780SdimSECTION
24319780Sdim	a.out backends
25319780Sdim
26319780SdimDESCRIPTION
27319780Sdim
28319780Sdim	BFD supports a number of different flavours of a.out format,
29319780Sdim	though the major differences are only the sizes of the
30320041Sdim	structures on disk, and the shape of the relocation
31320041Sdim	information.
32319780Sdim
33319780Sdim	The support is split into a basic support file @file{aoutx.h}
34319780Sdim	and other files which derive functions from the base. One
35319780Sdim	derivation file is @file{aoutf1.h} (for a.out flavour 1), and
36319780Sdim	adds to the basic a.out functions support for sun3, sun4, and
37319780Sdim	386 a.out files, to create a target jump vector for a specific
38319780Sdim	target.
39319780Sdim
40319780Sdim	This information is further split out into more specific files
41319780Sdim	for each machine, including @file{sunos.c} for sun3 and sun4,
42319780Sdim	and @file{demo64.c} for a demonstration of a 64 bit a.out format.
43319780Sdim
44319780Sdim	The base file @file{aoutx.h} defines general mechanisms for
45319780Sdim	reading and writing records to and from disk and various
46319780Sdim	other methods which BFD requires. It is included by
47319780Sdim	@file{aout32.c} and @file{aout64.c} to form the names
48319780Sdim	<<aout_32_swap_exec_header_in>>, <<aout_64_swap_exec_header_in>>, etc.
49319780Sdim
50319780Sdim	As an example, this is what goes on to make the back end for a
51319780Sdim	sun4, from @file{aout32.c}:
52319780Sdim
53319780Sdim|	#define ARCH_SIZE 32
54319780Sdim|	#include "aoutx.h"
55319780Sdim
56319780Sdim	Which exports names:
57319780Sdim
58319780Sdim|	...
59319780Sdim|	aout_32_canonicalize_reloc
60319780Sdim|	aout_32_find_nearest_line
61319780Sdim|	aout_32_get_lineno
62319780Sdim|	aout_32_get_reloc_upper_bound
63319780Sdim|	...
64319780Sdim
65319780Sdim	from @file{sunos.c}:
66319780Sdim
67319780Sdim|	#define TARGET_NAME "a.out-sunos-big"
68319780Sdim|	#define VECNAME    sparc_aout_sunos_be_vec
69319780Sdim|	#include "aoutf1.h"
70319780Sdim
71319780Sdim	requires all the names from @file{aout32.c}, and produces the jump vector
72319780Sdim
73319780Sdim|	sparc_aout_sunos_be_vec
74319780Sdim
75319780Sdim	The file @file{host-aout.c} is a special case.  It is for a large set
76319780Sdim	of hosts that use ``more or less standard'' a.out files, and
77319780Sdim	for which cross-debugging is not interesting.  It uses the
78319780Sdim	standard 32-bit a.out support routines, but determines the
79319780Sdim	file offsets and addresses of the text, data, and BSS
80319780Sdim	sections, the machine architecture and machine type, and the
81319780Sdim	entry point address, in a host-dependent manner.  Once these
82319780Sdim	values have been determined, generic code is used to handle
83319780Sdim	the  object file.
84319780Sdim
85319780Sdim	When porting it to run on a new system, you must supply:
86319780Sdim
87319780Sdim|        HOST_PAGE_SIZE
88319780Sdim|        HOST_SEGMENT_SIZE
89319780Sdim|        HOST_MACHINE_ARCH       (optional)
90319780Sdim|        HOST_MACHINE_MACHINE    (optional)
91319780Sdim|        HOST_TEXT_START_ADDR
92319780Sdim|        HOST_STACK_END_ADDR
93319780Sdim
94319780Sdim	in the file @file{../include/sys/h-@var{XXX}.h} (for your host).  These
95320397Sdim	values, plus the structures and macros defined in @file{a.out.h} on
96320397Sdim	your host system, will produce a BFD target that will access
97320397Sdim	ordinary a.out files on your host. To configure a new machine
98320397Sdim	to use @file{host-aout.c}, specify:
99319780Sdim
100319780Sdim|	TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
101320397Sdim|	TDEPFILES= host-aout.o trad-core.o
102320397Sdim
103320397Sdim	in the @file{config/@var{XXX}.mt} file, and modify @file{configure.ac}
104320397Sdim	to use the
105320397Sdim	@file{@var{XXX}.mt} file (by setting "<<bfd_target=XXX>>") when your
106320397Sdim	configuration is selected.  */
107320397Sdim
108320397Sdim/* Some assumptions:
109320397Sdim   * Any BFD with D_PAGED set is ZMAGIC, and vice versa.
110320397Sdim     Doesn't matter what the setting of WP_TEXT is on output, but it'll
111320397Sdim     get set on input.
112320397Sdim   * Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC.
113320397Sdim   * Any BFD with both flags clear is OMAGIC.
114320397Sdim   (Just want to make these explicit, so the conditions tested in this
115320397Sdim   file make sense if you're more familiar with a.out than with BFD.)  */
116320397Sdim
117320397Sdim#define KEEPIT udata.i
118320397Sdim
119320397Sdim#include "sysdep.h"
120320397Sdim#include <limits.h>
121320397Sdim#include "bfd.h"
122320397Sdim#include "safe-ctype.h"
123320397Sdim#include "bfdlink.h"
124320397Sdim
125320041Sdim#include "libaout.h"
126320041Sdim#include "libbfd.h"
127320397Sdim#include "aout/aout64.h"
128319780Sdim#include "aout/stab_gnu.h"
129320041Sdim#include "aout/ar.h"
130320041Sdim
131320041Sdim#ifdef BMAGIC
132320041Sdim#define N_IS_BMAGIC(x) (N_MAGIC (x) == BMAGIC)
133320041Sdim#else
134320041Sdim#define N_IS_BMAGIC(x) (0)
135320041Sdim#endif
136320041Sdim
137320397Sdim#ifdef QMAGIC
138320397Sdim#define N_SET_QMAGIC(x) N_SET_MAGIC (x, QMAGIC)
139320041Sdim#else
140320041Sdim#define N_SET_QMAGIC(x) do { /**/ } while (0)
141320041Sdim#endif
142320397Sdim
143320041Sdim/*
144320041SdimSUBSECTION
145319780Sdim	Relocations
146319780Sdim
147319780SdimDESCRIPTION
148320041Sdim	The file @file{aoutx.h} provides for both the @emph{standard}
149320041Sdim	and @emph{extended} forms of a.out relocation records.
150320041Sdim
151319780Sdim	The standard records contain only an address, a symbol index,
152319780Sdim	and a type field.  The extended records also have a full
153319780Sdim	integer for an addend.  */
154319780Sdim
155319780Sdim#ifndef CTOR_TABLE_RELOC_HOWTO
156319780Sdim#define CTOR_TABLE_RELOC_IDX 2
157319780Sdim#define CTOR_TABLE_RELOC_HOWTO(BFD)					\
158319780Sdim  ((obj_reloc_entry_size (BFD) == RELOC_EXT_SIZE			\
159319780Sdim    ? howto_table_ext : howto_table_std)				\
160319780Sdim   + CTOR_TABLE_RELOC_IDX)
161319780Sdim#endif
162319780Sdim
163319780Sdim#ifndef MY_swap_std_reloc_in
164319780Sdim#define MY_swap_std_reloc_in NAME (aout, swap_std_reloc_in)
165319780Sdim#endif
166319780Sdim
167319780Sdim#ifndef MY_swap_ext_reloc_in
168319780Sdim#define MY_swap_ext_reloc_in NAME (aout, swap_ext_reloc_in)
169320041Sdim#endif
170319780Sdim
171319780Sdim#ifndef MY_swap_std_reloc_out
172319780Sdim#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	bfd_cleanup aout_@var{size}_some_aout_object_p
455	 (bfd *abfd,
456	  struct internal_exec *execp,
457	  bfd_cleanup (*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)
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 (symbols != NULL && r_index < bfd_get_symcount (abfd))		\
2126	cache_ptr->sym_ptr_ptr = symbols + r_index;			\
2127      else								\
2128	cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;	\
2129      cache_ptr->addend = ad;						\
2130    }									\
2131   else									\
2132    {									\
2133      /* Defined, section relative.  Replace symbol with pointer to	\
2134	 symbol which points to section.  */				\
2135      switch (r_index)							\
2136	{								\
2137	case N_TEXT:							\
2138	case N_TEXT | N_EXT:						\
2139	  cache_ptr->sym_ptr_ptr = obj_textsec (abfd)->symbol_ptr_ptr;	\
2140	  cache_ptr->addend = ad - su->textsec->vma;			\
2141	  break;							\
2142	case N_DATA:							\
2143	case N_DATA | N_EXT:						\
2144	  cache_ptr->sym_ptr_ptr = obj_datasec (abfd)->symbol_ptr_ptr;	\
2145	  cache_ptr->addend = ad - su->datasec->vma;			\
2146	  break;							\
2147	case N_BSS:							\
2148	case N_BSS | N_EXT:						\
2149	  cache_ptr->sym_ptr_ptr = obj_bsssec (abfd)->symbol_ptr_ptr;	\
2150	  cache_ptr->addend = ad - su->bsssec->vma;			\
2151	  break;							\
2152	default:							\
2153	case N_ABS:							\
2154	case N_ABS | N_EXT:						\
2155	  cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;	\
2156	  cache_ptr->addend = ad;					\
2157	  break;							\
2158	}								\
2159    }
2160
2161void
2162NAME (aout, swap_ext_reloc_in) (bfd *abfd,
2163				struct reloc_ext_external *bytes,
2164				arelent *cache_ptr,
2165				asymbol **symbols,
2166				bfd_size_type symcount)
2167{
2168  unsigned int r_index;
2169  int r_extern;
2170  unsigned int r_type;
2171  struct aoutdata *su = &(abfd->tdata.aout_data->a);
2172
2173  cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
2174
2175  /* Now the fun stuff.  */
2176  if (bfd_header_big_endian (abfd))
2177    {
2178      r_index = (((unsigned int) bytes->r_index[0] << 16)
2179		 | ((unsigned int) bytes->r_index[1] << 8)
2180		 | bytes->r_index[2]);
2181      r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
2182      r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
2183		>> RELOC_EXT_BITS_TYPE_SH_BIG);
2184    }
2185  else
2186    {
2187      r_index =  (((unsigned int) bytes->r_index[2] << 16)
2188		  | ((unsigned int) bytes->r_index[1] << 8)
2189		  | bytes->r_index[0]);
2190      r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
2191      r_type = ((bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
2192		>> RELOC_EXT_BITS_TYPE_SH_LITTLE);
2193    }
2194
2195  if (r_type < TABLE_SIZE (howto_table_ext))
2196    cache_ptr->howto = howto_table_ext + r_type;
2197  else
2198    cache_ptr->howto = NULL;
2199
2200  /* Base relative relocs are always against the symbol table,
2201     regardless of the setting of r_extern.  r_extern just reflects
2202     whether the symbol the reloc is against is local or global.  */
2203  if (r_type == (unsigned int) RELOC_BASE10
2204      || r_type == (unsigned int) RELOC_BASE13
2205      || r_type == (unsigned int) RELOC_BASE22)
2206    r_extern = 1;
2207
2208  if (r_extern && r_index > symcount)
2209    {
2210      /* We could arrange to return an error, but it might be useful
2211	 to see the file even if it is bad.  */
2212      r_extern = 0;
2213      r_index = N_ABS;
2214    }
2215
2216  MOVE_ADDRESS (GET_SWORD (abfd, bytes->r_addend));
2217}
2218
2219void
2220NAME (aout, swap_std_reloc_in) (bfd *abfd,
2221				struct reloc_std_external *bytes,
2222				arelent *cache_ptr,
2223				asymbol **symbols,
2224				bfd_size_type symcount)
2225{
2226  unsigned int r_index;
2227  int r_extern;
2228  unsigned int r_length;
2229  int r_pcrel;
2230  int r_baserel, r_jmptable, r_relative;
2231  struct aoutdata  *su = &(abfd->tdata.aout_data->a);
2232  unsigned int howto_idx;
2233
2234  cache_ptr->address = H_GET_32 (abfd, bytes->r_address);
2235
2236  /* Now the fun stuff.  */
2237  if (bfd_header_big_endian (abfd))
2238    {
2239      r_index = (((unsigned int) bytes->r_index[0] << 16)
2240		 | ((unsigned int) bytes->r_index[1] << 8)
2241		 | bytes->r_index[2]);
2242      r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
2243      r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
2244      r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
2245      r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
2246      r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
2247      r_length  = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
2248		   >> RELOC_STD_BITS_LENGTH_SH_BIG);
2249    }
2250  else
2251    {
2252      r_index = (((unsigned int) bytes->r_index[2] << 16)
2253		 | ((unsigned int) bytes->r_index[1] << 8)
2254		 | bytes->r_index[0]);
2255      r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
2256      r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
2257      r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
2258      r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
2259      r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
2260      r_length  = ((bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
2261		   >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
2262    }
2263
2264  howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
2265	       + 16 * r_jmptable + 32 * r_relative);
2266  if (howto_idx < TABLE_SIZE (howto_table_std))
2267    {
2268      cache_ptr->howto = howto_table_std + howto_idx;
2269      if (cache_ptr->howto->type == (unsigned int) -1)
2270	cache_ptr->howto = NULL;
2271    }
2272  else
2273    cache_ptr->howto = NULL;
2274
2275  /* Base relative relocs are always against the symbol table,
2276     regardless of the setting of r_extern.  r_extern just reflects
2277     whether the symbol the reloc is against is local or global.  */
2278  if (r_baserel)
2279    r_extern = 1;
2280
2281  if (r_extern && r_index >= symcount)
2282    {
2283      /* We could arrange to return an error, but it might be useful
2284	 to see the file even if it is bad.  FIXME: Of course this
2285	 means that objdump -r *doesn't* see the actual reloc, and
2286	 objcopy silently writes a different reloc.  */
2287      r_extern = 0;
2288      r_index = N_ABS;
2289    }
2290
2291  MOVE_ADDRESS (0);
2292}
2293
2294/* Read and swap the relocs for a section.  */
2295
2296bool
2297NAME (aout, slurp_reloc_table) (bfd *abfd, sec_ptr asect, asymbol **symbols)
2298{
2299  bfd_size_type count;
2300  bfd_size_type reloc_size;
2301  void * relocs;
2302  arelent *reloc_cache;
2303  size_t each_size;
2304  unsigned int counter = 0;
2305  arelent *cache_ptr;
2306  bfd_size_type amt;
2307
2308  if (asect->relocation)
2309    return true;
2310
2311  if (asect->flags & SEC_CONSTRUCTOR)
2312    return true;
2313
2314  if (asect == obj_datasec (abfd))
2315    reloc_size = exec_hdr (abfd)->a_drsize;
2316  else if (asect == obj_textsec (abfd))
2317    reloc_size = exec_hdr (abfd)->a_trsize;
2318  else if (asect == obj_bsssec (abfd))
2319    reloc_size = 0;
2320  else
2321    {
2322      bfd_set_error (bfd_error_invalid_operation);
2323      return false;
2324    }
2325
2326  each_size = obj_reloc_entry_size (abfd);
2327  count = reloc_size / each_size;
2328  if (count == 0)
2329    return true;		/* Nothing to be done.  */
2330
2331  if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
2332    return false;
2333  relocs = _bfd_malloc_and_read (abfd, reloc_size, reloc_size);
2334  if (relocs == NULL)
2335    return false;
2336
2337  amt = count * sizeof (arelent);
2338  reloc_cache = (arelent *) bfd_zmalloc (amt);
2339  if (reloc_cache == NULL)
2340    {
2341      free (relocs);
2342      return false;
2343    }
2344
2345  cache_ptr = reloc_cache;
2346  if (each_size == RELOC_EXT_SIZE)
2347    {
2348      struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
2349
2350      for (; counter < count; counter++, rptr++, cache_ptr++)
2351	MY_swap_ext_reloc_in (abfd, rptr, cache_ptr, symbols,
2352			      (bfd_size_type) bfd_get_symcount (abfd));
2353    }
2354  else
2355    {
2356      struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
2357
2358      for (; counter < count; counter++, rptr++, cache_ptr++)
2359	MY_swap_std_reloc_in (abfd, rptr, cache_ptr, symbols,
2360			      (bfd_size_type) bfd_get_symcount (abfd));
2361    }
2362
2363  free (relocs);
2364
2365  asect->relocation = reloc_cache;
2366  asect->reloc_count = cache_ptr - reloc_cache;
2367
2368  return true;
2369}
2370
2371/* Write out a relocation section into an object file.  */
2372
2373bool
2374NAME (aout, squirt_out_relocs) (bfd *abfd, asection *section)
2375{
2376  arelent **generic;
2377  unsigned char *native, *natptr;
2378  size_t each_size;
2379
2380  unsigned int count = section->reloc_count;
2381  bfd_size_type natsize;
2382
2383  if (count == 0 || section->orelocation == NULL)
2384    return true;
2385
2386  each_size = obj_reloc_entry_size (abfd);
2387  natsize = (bfd_size_type) each_size * count;
2388  native = (unsigned char *) bfd_zalloc (abfd, natsize);
2389  if (!native)
2390    return false;
2391
2392  generic = section->orelocation;
2393
2394  if (each_size == RELOC_EXT_SIZE)
2395    {
2396      for (natptr = native;
2397	   count != 0;
2398	   --count, natptr += each_size, ++generic)
2399	{
2400	  /* PR 20921: If the howto field has not been initialised then skip
2401	     this reloc.
2402	     PR 20929: Similarly for the symbol field.  */
2403	  if ((*generic)->howto == NULL
2404	      || (*generic)->sym_ptr_ptr == NULL)
2405	    {
2406	      bfd_set_error (bfd_error_invalid_operation);
2407	      _bfd_error_handler (_("%pB: attempt to write out "
2408				    "unknown reloc type"), abfd);
2409	      return false;
2410	    }
2411	  MY_swap_ext_reloc_out (abfd, *generic,
2412				 (struct reloc_ext_external *) natptr);
2413	}
2414    }
2415  else
2416    {
2417      for (natptr = native;
2418	   count != 0;
2419	   --count, natptr += each_size, ++generic)
2420	{
2421	  if ((*generic)->howto == NULL
2422	      || (*generic)->sym_ptr_ptr == NULL)
2423	    {
2424	      bfd_set_error (bfd_error_invalid_operation);
2425	      _bfd_error_handler (_("%pB: attempt to write out "
2426				    "unknown reloc type"), abfd);
2427	      return false;
2428	    }
2429	  MY_swap_std_reloc_out (abfd, *generic,
2430				 (struct reloc_std_external *) natptr);
2431	}
2432    }
2433
2434  if (bfd_bwrite ((void *) native, natsize, abfd) != natsize)
2435    {
2436      bfd_release (abfd, native);
2437      return false;
2438    }
2439  bfd_release (abfd, native);
2440
2441  return true;
2442}
2443
2444/* This is stupid.  This function should be a boolean predicate.  */
2445
2446long
2447NAME (aout, canonicalize_reloc) (bfd *abfd,
2448				 sec_ptr section,
2449				 arelent **relptr,
2450				 asymbol **symbols)
2451{
2452  arelent *tblptr = section->relocation;
2453  unsigned int count;
2454
2455  if (section == obj_bsssec (abfd))
2456    {
2457      *relptr = NULL;
2458      return 0;
2459    }
2460
2461  if (!(tblptr || NAME (aout, slurp_reloc_table) (abfd, section, symbols)))
2462    return -1;
2463
2464  if (section->flags & SEC_CONSTRUCTOR)
2465    {
2466      arelent_chain *chain = section->constructor_chain;
2467      for (count = 0; count < section->reloc_count; count ++)
2468	{
2469	  *relptr ++ = &chain->relent;
2470	  chain = chain->next;
2471	}
2472    }
2473  else
2474    {
2475      tblptr = section->relocation;
2476
2477      for (count = 0; count++ < section->reloc_count; )
2478	{
2479	  *relptr++ = tblptr++;
2480	}
2481    }
2482  *relptr = 0;
2483
2484  return section->reloc_count;
2485}
2486
2487long
2488NAME (aout, get_reloc_upper_bound) (bfd *abfd, sec_ptr asect)
2489{
2490  size_t count, raw;
2491
2492  if (asect->flags & SEC_CONSTRUCTOR)
2493    count = asect->reloc_count;
2494  else if (asect == obj_datasec (abfd))
2495    count = exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
2496  else if (asect == obj_textsec (abfd))
2497    count = exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
2498  else if (asect == obj_bsssec (abfd))
2499    count = 0;
2500  else
2501    {
2502      bfd_set_error (bfd_error_invalid_operation);
2503      return -1;
2504    }
2505
2506  if (count >= LONG_MAX / sizeof (arelent *)
2507      || _bfd_mul_overflow (count, obj_reloc_entry_size (abfd), &raw))
2508    {
2509      bfd_set_error (bfd_error_file_too_big);
2510      return -1;
2511    }
2512  if (!bfd_write_p (abfd))
2513    {
2514      ufile_ptr filesize = bfd_get_file_size (abfd);
2515      if (filesize != 0 && raw > filesize)
2516	{
2517	  bfd_set_error (bfd_error_file_truncated);
2518	  return -1;
2519	}
2520    }
2521  return (count + 1) * sizeof (arelent *);
2522}
2523
2524long
2525NAME (aout, get_symtab_upper_bound) (bfd *abfd)
2526{
2527  if (!NAME (aout, slurp_symbol_table) (abfd))
2528    return -1;
2529
2530  return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
2531}
2532
2533alent *
2534NAME (aout, get_lineno) (bfd *ignore_abfd ATTRIBUTE_UNUSED,
2535			 asymbol *ignore_symbol ATTRIBUTE_UNUSED)
2536{
2537  return NULL;
2538}
2539
2540void
2541NAME (aout, get_symbol_info) (bfd *ignore_abfd ATTRIBUTE_UNUSED,
2542			      asymbol *symbol,
2543			      symbol_info *ret)
2544{
2545  bfd_symbol_info (symbol, ret);
2546
2547  if (ret->type == '?')
2548    {
2549      int type_code = aout_symbol (symbol)->type & 0xff;
2550      const char *stab_name = bfd_get_stab_name (type_code);
2551      static char buf[10];
2552
2553      if (stab_name == NULL)
2554	{
2555	  sprintf (buf, "(%d)", type_code);
2556	  stab_name = buf;
2557	}
2558      ret->type = '-';
2559      ret->stab_type = type_code;
2560      ret->stab_other = (unsigned) (aout_symbol (symbol)->other & 0xff);
2561      ret->stab_desc = (unsigned) (aout_symbol (symbol)->desc & 0xffff);
2562      ret->stab_name = stab_name;
2563    }
2564}
2565
2566void
2567NAME (aout, print_symbol) (bfd *abfd,
2568			   void * afile,
2569			   asymbol *symbol,
2570			   bfd_print_symbol_type how)
2571{
2572  FILE *file = (FILE *)afile;
2573
2574  switch (how)
2575    {
2576    case bfd_print_symbol_name:
2577      if (symbol->name)
2578	fprintf (file,"%s", symbol->name);
2579      break;
2580    case bfd_print_symbol_more:
2581      fprintf (file,"%4x %2x %2x",
2582	       (unsigned) (aout_symbol (symbol)->desc & 0xffff),
2583	       (unsigned) (aout_symbol (symbol)->other & 0xff),
2584	       (unsigned) (aout_symbol (symbol)->type));
2585      break;
2586    case bfd_print_symbol_all:
2587      {
2588	const char *section_name = symbol->section->name;
2589
2590	bfd_print_symbol_vandf (abfd, (void *)file, symbol);
2591
2592	fprintf (file," %-5s %04x %02x %02x",
2593		 section_name,
2594		 (unsigned) (aout_symbol (symbol)->desc & 0xffff),
2595		 (unsigned) (aout_symbol (symbol)->other & 0xff),
2596		 (unsigned) (aout_symbol (symbol)->type & 0xff));
2597	if (symbol->name)
2598	  fprintf (file," %s", symbol->name);
2599      }
2600      break;
2601    }
2602}
2603
2604/* If we don't have to allocate more than 1MB to hold the generic
2605   symbols, we use the generic minisymbol methord: it's faster, since
2606   it only translates the symbols once, not multiple times.  */
2607#define MINISYM_THRESHOLD (1000000 / sizeof (asymbol))
2608
2609/* Read minisymbols.  For minisymbols, we use the unmodified a.out
2610   symbols.  The minisymbol_to_symbol function translates these into
2611   BFD asymbol structures.  */
2612
2613long
2614NAME (aout, read_minisymbols) (bfd *abfd,
2615			       bool dynamic,
2616			       void * *minisymsp,
2617			       unsigned int *sizep)
2618{
2619  if (dynamic)
2620    /* We could handle the dynamic symbols here as well, but it's
2621       easier to hand them off.  */
2622    return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2623
2624  if (! aout_get_external_symbols (abfd))
2625    return -1;
2626
2627  if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2628    return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2629
2630  *minisymsp = (void *) obj_aout_external_syms (abfd);
2631
2632  /* By passing the external symbols back from this routine, we are
2633     giving up control over the memory block.  Clear
2634     obj_aout_external_syms, so that we do not try to free it
2635     ourselves.  */
2636  obj_aout_external_syms (abfd) = NULL;
2637
2638  *sizep = EXTERNAL_NLIST_SIZE;
2639  return obj_aout_external_sym_count (abfd);
2640}
2641
2642/* Convert a minisymbol to a BFD asymbol.  A minisymbol is just an
2643   unmodified a.out symbol.  The SYM argument is a structure returned
2644   by bfd_make_empty_symbol, which we fill in here.  */
2645
2646asymbol *
2647NAME (aout, minisymbol_to_symbol) (bfd *abfd,
2648				   bool dynamic,
2649				   const void * minisym,
2650				   asymbol *sym)
2651{
2652  if (dynamic
2653      || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2654    return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
2655
2656  memset (sym, 0, sizeof (aout_symbol_type));
2657
2658  /* We call translate_symbol_table to translate a single symbol.  */
2659  if (! (NAME (aout, translate_symbol_table)
2660	 (abfd,
2661	  (aout_symbol_type *) sym,
2662	  (struct external_nlist *) minisym,
2663	  (bfd_size_type) 1,
2664	  obj_aout_external_strings (abfd),
2665	  obj_aout_external_string_size (abfd),
2666	  false)))
2667    return NULL;
2668
2669  return sym;
2670}
2671
2672/* Provided a BFD, a section and an offset into the section, calculate
2673   and return the name of the source file and the line nearest to the
2674   wanted location.  */
2675
2676bool
2677NAME (aout, find_nearest_line) (bfd *abfd,
2678				asymbol **symbols,
2679				asection *section,
2680				bfd_vma offset,
2681				const char **filename_ptr,
2682				const char **functionname_ptr,
2683				unsigned int *line_ptr,
2684				unsigned int *disriminator_ptr)
2685{
2686  /* Run down the file looking for the filename, function and linenumber.  */
2687  asymbol **p;
2688  const char *directory_name = NULL;
2689  const char *main_file_name = NULL;
2690  const char *current_file_name = NULL;
2691  const char *line_file_name = NULL;      /* Value of current_file_name at line number.  */
2692  const char *line_directory_name = NULL; /* Value of directory_name at line number.  */
2693  bfd_vma low_line_vma = 0;
2694  bfd_vma low_func_vma = 0;
2695  asymbol *func = 0;
2696  bfd_size_type filelen, funclen;
2697  char *buf;
2698
2699  *filename_ptr = bfd_get_filename (abfd);
2700  *functionname_ptr = NULL;
2701  *line_ptr = 0;
2702  if (disriminator_ptr)
2703    *disriminator_ptr = 0;
2704
2705  if (symbols != NULL)
2706    {
2707      for (p = symbols; *p; p++)
2708	{
2709	  aout_symbol_type  *q = (aout_symbol_type *) (*p);
2710	next:
2711	  switch (q->type)
2712	    {
2713	    case N_TEXT:
2714	      /* If this looks like a file name symbol, and it comes after
2715		 the line number we have found so far, but before the
2716		 offset, then we have probably not found the right line
2717		 number.  */
2718	      if (q->symbol.value <= offset
2719		  && ((q->symbol.value > low_line_vma
2720		       && (line_file_name != NULL
2721			   || *line_ptr != 0))
2722		      || (q->symbol.value > low_func_vma
2723			  && func != NULL)))
2724		{
2725		  const char *symname;
2726
2727		  symname = q->symbol.name;
2728
2729		  if (symname != NULL
2730		      && strlen (symname) > 2
2731		      && strcmp (symname + strlen (symname) - 2, ".o") == 0)
2732		    {
2733		      if (q->symbol.value > low_line_vma)
2734			{
2735			  *line_ptr = 0;
2736			  line_file_name = NULL;
2737			}
2738		      if (q->symbol.value > low_func_vma)
2739			func = NULL;
2740		    }
2741		}
2742	      break;
2743
2744	    case N_SO:
2745	      /* If this symbol is less than the offset, but greater than
2746		 the line number we have found so far, then we have not
2747		 found the right line number.  */
2748	      if (q->symbol.value <= offset)
2749		{
2750		  if (q->symbol.value > low_line_vma)
2751		    {
2752		      *line_ptr = 0;
2753		      line_file_name = NULL;
2754		    }
2755		  if (q->symbol.value > low_func_vma)
2756		    func = NULL;
2757		}
2758
2759	      main_file_name = current_file_name = q->symbol.name;
2760	      /* Look ahead to next symbol to check if that too is an N_SO.  */
2761	      p++;
2762	      if (*p == NULL)
2763		goto done;
2764	      q = (aout_symbol_type *) (*p);
2765	      if (q->type != (int)N_SO)
2766		goto next;
2767
2768	      /* Found a second N_SO  First is directory; second is filename.  */
2769	      directory_name = current_file_name;
2770	      main_file_name = current_file_name = q->symbol.name;
2771	      if (obj_textsec (abfd) != section)
2772		goto done;
2773	      break;
2774	    case N_SOL:
2775	      current_file_name = q->symbol.name;
2776	      break;
2777
2778	    case N_SLINE:
2779
2780	    case N_DSLINE:
2781	    case N_BSLINE:
2782	      /* We'll keep this if it resolves nearer than the one we have
2783		 already.  */
2784	      if (q->symbol.value >= low_line_vma
2785		  && q->symbol.value <= offset)
2786		{
2787		  *line_ptr = q->desc;
2788		  low_line_vma = q->symbol.value;
2789		  line_file_name = current_file_name;
2790		  line_directory_name = directory_name;
2791		}
2792	      break;
2793	    case N_FUN:
2794	      {
2795		/* We'll keep this if it is nearer than the one we have already.  */
2796		if (q->symbol.value >= low_func_vma
2797		    && q->symbol.value <= offset)
2798		  {
2799		    low_func_vma = q->symbol.value;
2800		    func = (asymbol *)q;
2801		  }
2802		else if (q->symbol.value > offset)
2803		  goto done;
2804	      }
2805	      break;
2806	    }
2807	}
2808    }
2809
2810 done:
2811  if (*line_ptr != 0)
2812    {
2813      main_file_name = line_file_name;
2814      directory_name = line_directory_name;
2815    }
2816
2817  if (main_file_name == NULL
2818      || IS_ABSOLUTE_PATH (main_file_name)
2819      || directory_name == NULL)
2820    filelen = 0;
2821  else
2822    filelen = strlen (directory_name) + strlen (main_file_name);
2823
2824  if (func == NULL)
2825    funclen = 0;
2826  else
2827    funclen = strlen (bfd_asymbol_name (func));
2828
2829  free (adata (abfd).line_buf);
2830
2831  if (filelen + funclen == 0)
2832    adata (abfd).line_buf = buf = NULL;
2833  else
2834    {
2835      buf = (char *) bfd_malloc (filelen + funclen + 3);
2836      adata (abfd).line_buf = buf;
2837      if (buf == NULL)
2838	return false;
2839    }
2840
2841  if (main_file_name != NULL)
2842    {
2843      if (IS_ABSOLUTE_PATH (main_file_name) || directory_name == NULL)
2844	*filename_ptr = main_file_name;
2845      else
2846	{
2847	  if (buf == NULL)
2848	    /* PR binutils/20891: In a corrupt input file both
2849	       main_file_name and directory_name can be empty...  */
2850	    * filename_ptr = NULL;
2851	  else
2852	    {
2853	      snprintf (buf, filelen + 1, "%s%s", directory_name,
2854			main_file_name);
2855	      *filename_ptr = buf;
2856	      buf += filelen + 1;
2857	    }
2858	}
2859    }
2860
2861  if (func)
2862    {
2863      const char *function = func->name;
2864      char *colon;
2865
2866      if (buf == NULL)
2867	{
2868	  /* PR binutils/20892: In a corrupt input file func can be empty.  */
2869	  * functionname_ptr = NULL;
2870	  return true;
2871	}
2872      /* The caller expects a symbol name.  We actually have a
2873	 function name, without the leading underscore.  Put the
2874	 underscore back in, so that the caller gets a symbol name.  */
2875      if (bfd_get_symbol_leading_char (abfd) == '\0')
2876	strcpy (buf, function);
2877      else
2878	{
2879	  buf[0] = bfd_get_symbol_leading_char (abfd);
2880	  strcpy (buf + 1, function);
2881	}
2882      /* Have to remove : stuff.  */
2883      colon = strchr (buf, ':');
2884      if (colon != NULL)
2885	*colon = '\0';
2886      *functionname_ptr = buf;
2887    }
2888
2889  return true;
2890}
2891
2892int
2893NAME (aout, sizeof_headers) (bfd *abfd,
2894			     struct bfd_link_info *info ATTRIBUTE_UNUSED)
2895{
2896  return adata (abfd).exec_bytes_size;
2897}
2898
2899/* Free all information we have cached for this BFD.  We can always
2900   read it again later if we need it.  */
2901
2902bool
2903NAME (aout, bfd_free_cached_info) (bfd *abfd)
2904{
2905  asection *o;
2906
2907  if (bfd_get_format (abfd) != bfd_object
2908      || abfd->tdata.aout_data == NULL)
2909    return true;
2910
2911#define BFCI_FREE(x) do { free (x); x = NULL; } while (0)
2912  BFCI_FREE (obj_aout_symbols (abfd));
2913#ifdef USE_MMAP
2914  obj_aout_external_syms (abfd) = 0;
2915  bfd_free_window (&obj_aout_sym_window (abfd));
2916  bfd_free_window (&obj_aout_string_window (abfd));
2917  obj_aout_external_strings (abfd) = 0;
2918#else
2919  BFCI_FREE (obj_aout_external_syms (abfd));
2920  BFCI_FREE (obj_aout_external_strings (abfd));
2921#endif
2922  for (o = abfd->sections; o != NULL; o = o->next)
2923    BFCI_FREE (o->relocation);
2924#undef BFCI_FREE
2925
2926  return true;
2927}
2928
2929/* a.out link code.  */
2930
2931/* Routine to create an entry in an a.out link hash table.  */
2932
2933struct bfd_hash_entry *
2934NAME (aout, link_hash_newfunc) (struct bfd_hash_entry *entry,
2935				struct bfd_hash_table *table,
2936				const char *string)
2937{
2938  struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
2939
2940  /* Allocate the structure if it has not already been allocated by a
2941     subclass.  */
2942  if (ret == NULL)
2943    ret = (struct aout_link_hash_entry *) bfd_hash_allocate (table,
2944							     sizeof (* ret));
2945  if (ret == NULL)
2946    return NULL;
2947
2948  /* Call the allocation method of the superclass.  */
2949  ret = ((struct aout_link_hash_entry *)
2950	 _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
2951				 table, string));
2952  if (ret)
2953    {
2954      /* Set local fields.  */
2955      ret->written = false;
2956      ret->indx = -1;
2957    }
2958
2959  return (struct bfd_hash_entry *) ret;
2960}
2961
2962/* Initialize an a.out link hash table.  */
2963
2964bool
2965NAME (aout, link_hash_table_init) (struct aout_link_hash_table *table,
2966				   bfd *abfd,
2967				   struct bfd_hash_entry *(*newfunc)
2968				   (struct bfd_hash_entry *, struct bfd_hash_table *,
2969				    const char *),
2970				   unsigned int entsize)
2971{
2972  return _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
2973}
2974
2975/* Create an a.out link hash table.  */
2976
2977struct bfd_link_hash_table *
2978NAME (aout, link_hash_table_create) (bfd *abfd)
2979{
2980  struct aout_link_hash_table *ret;
2981  size_t amt = sizeof (* ret);
2982
2983  ret = (struct aout_link_hash_table *) bfd_malloc (amt);
2984  if (ret == NULL)
2985    return NULL;
2986
2987  if (!NAME (aout, link_hash_table_init) (ret, abfd,
2988					  NAME (aout, link_hash_newfunc),
2989					  sizeof (struct aout_link_hash_entry)))
2990    {
2991      free (ret);
2992      return NULL;
2993    }
2994  return &ret->root;
2995}
2996
2997/* Add all symbols from an object file to the hash table.  */
2998
2999static bool
3000aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
3001{
3002  bool (*add_one_symbol)
3003    (struct bfd_link_info *, bfd *, const char *, flagword, asection *,
3004     bfd_vma, const char *, bool, bool, struct bfd_link_hash_entry **);
3005  struct external_nlist *syms;
3006  bfd_size_type sym_count;
3007  char *strings;
3008  bool copy;
3009  struct aout_link_hash_entry **sym_hash;
3010  struct external_nlist *p;
3011  struct external_nlist *pend;
3012  bfd_size_type amt;
3013
3014  syms = obj_aout_external_syms (abfd);
3015  sym_count = obj_aout_external_sym_count (abfd);
3016  strings = obj_aout_external_strings (abfd);
3017  if (info->keep_memory)
3018    copy = false;
3019  else
3020    copy = true;
3021
3022  if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
3023    {
3024      if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
3025	     (abfd, info, &syms, &sym_count, &strings)))
3026	return false;
3027    }
3028
3029  if (sym_count == 0)
3030    return true;		/* Nothing to do.  */
3031
3032  /* We keep a list of the linker hash table entries that correspond
3033     to particular symbols.  We could just look them up in the hash
3034     table, but keeping the list is more efficient.  Perhaps this
3035     should be conditional on info->keep_memory.  */
3036  amt = sym_count * sizeof (struct aout_link_hash_entry *);
3037  sym_hash = (struct aout_link_hash_entry **) bfd_alloc (abfd, amt);
3038  if (sym_hash == NULL)
3039    return false;
3040  obj_aout_sym_hashes (abfd) = sym_hash;
3041
3042  add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
3043  if (add_one_symbol == NULL)
3044    add_one_symbol = _bfd_generic_link_add_one_symbol;
3045
3046  p = syms;
3047  pend = p + sym_count;
3048  for (; p < pend; p++, sym_hash++)
3049    {
3050      int type;
3051      const char *name;
3052      bfd_vma value;
3053      asection *section;
3054      flagword flags;
3055      const char *string;
3056
3057      *sym_hash = NULL;
3058
3059      type = H_GET_8 (abfd, p->e_type);
3060
3061      /* Ignore debugging symbols.  */
3062      if ((type & N_STAB) != 0)
3063	continue;
3064
3065      /* PR 19629: Corrupt binaries can contain illegal string offsets.  */
3066      if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd))
3067	return false;
3068      name = strings + GET_WORD (abfd, p->e_strx);
3069      value = GET_WORD (abfd, p->e_value);
3070      flags = BSF_GLOBAL;
3071      string = NULL;
3072      switch (type)
3073	{
3074	default:
3075	  abort ();
3076
3077	case N_UNDF:
3078	case N_ABS:
3079	case N_TEXT:
3080	case N_DATA:
3081	case N_BSS:
3082	case N_FN_SEQ:
3083	case N_COMM:
3084	case N_SETV:
3085	case N_FN:
3086	  /* Ignore symbols that are not externally visible.  */
3087	  continue;
3088	case N_INDR:
3089	  /* Ignore local indirect symbol.  */
3090	  ++p;
3091	  ++sym_hash;
3092	  continue;
3093
3094	case N_UNDF | N_EXT:
3095	  if (value == 0)
3096	    {
3097	      section = bfd_und_section_ptr;
3098	      flags = 0;
3099	    }
3100	  else
3101	    section = bfd_com_section_ptr;
3102	  break;
3103	case N_ABS | N_EXT:
3104	  section = bfd_abs_section_ptr;
3105	  break;
3106	case N_TEXT | N_EXT:
3107	  section = obj_textsec (abfd);
3108	  value -= bfd_section_vma (section);
3109	  break;
3110	case N_DATA | N_EXT:
3111	case N_SETV | N_EXT:
3112	  /* Treat N_SETV symbols as N_DATA symbol; see comment in
3113	     translate_from_native_sym_flags.  */
3114	  section = obj_datasec (abfd);
3115	  value -= bfd_section_vma (section);
3116	  break;
3117	case N_BSS | N_EXT:
3118	  section = obj_bsssec (abfd);
3119	  value -= bfd_section_vma (section);
3120	  break;
3121	case N_INDR | N_EXT:
3122	  /* An indirect symbol.  The next symbol is the symbol
3123	     which this one really is.  */
3124	  /* See PR 20925 for a reproducer.  */
3125	  if (p + 1 >= pend)
3126	    return false;
3127	  ++p;
3128	  /* PR 19629: Corrupt binaries can contain illegal string offsets.  */
3129	  if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd))
3130	    return false;
3131	  string = strings + GET_WORD (abfd, p->e_strx);
3132	  section = bfd_ind_section_ptr;
3133	  flags |= BSF_INDIRECT;
3134	  break;
3135	case N_COMM | N_EXT:
3136	  section = bfd_com_section_ptr;
3137	  break;
3138	case N_SETA: case N_SETA | N_EXT:
3139	  section = bfd_abs_section_ptr;
3140	  flags |= BSF_CONSTRUCTOR;
3141	  break;
3142	case N_SETT: case N_SETT | N_EXT:
3143	  section = obj_textsec (abfd);
3144	  flags |= BSF_CONSTRUCTOR;
3145	  value -= bfd_section_vma (section);
3146	  break;
3147	case N_SETD: case N_SETD | N_EXT:
3148	  section = obj_datasec (abfd);
3149	  flags |= BSF_CONSTRUCTOR;
3150	  value -= bfd_section_vma (section);
3151	  break;
3152	case N_SETB: case N_SETB | N_EXT:
3153	  section = obj_bsssec (abfd);
3154	  flags |= BSF_CONSTRUCTOR;
3155	  value -= bfd_section_vma (section);
3156	  break;
3157	case N_WARNING:
3158	  /* A warning symbol.  The next symbol is the one to warn
3159	     about.  If there is no next symbol, just look away.  */
3160	  if (p + 1 >= pend)
3161	    return true;
3162	  ++p;
3163	  string = name;
3164	  /* PR 19629: Corrupt binaries can contain illegal string offsets.  */
3165	  if (GET_WORD (abfd, p->e_strx) >= obj_aout_external_string_size (abfd))
3166	    return false;
3167	  name = strings + GET_WORD (abfd, p->e_strx);
3168	  section = bfd_und_section_ptr;
3169	  flags |= BSF_WARNING;
3170	  break;
3171	case N_WEAKU:
3172	  section = bfd_und_section_ptr;
3173	  flags = BSF_WEAK;
3174	  break;
3175	case N_WEAKA:
3176	  section = bfd_abs_section_ptr;
3177	  flags = BSF_WEAK;
3178	  break;
3179	case N_WEAKT:
3180	  section = obj_textsec (abfd);
3181	  value -= bfd_section_vma (section);
3182	  flags = BSF_WEAK;
3183	  break;
3184	case N_WEAKD:
3185	  section = obj_datasec (abfd);
3186	  value -= bfd_section_vma (section);
3187	  flags = BSF_WEAK;
3188	  break;
3189	case N_WEAKB:
3190	  section = obj_bsssec (abfd);
3191	  value -= bfd_section_vma (section);
3192	  flags = BSF_WEAK;
3193	  break;
3194	}
3195
3196      if (! ((*add_one_symbol)
3197	     (info, abfd, name, flags, section, value, string, copy, false,
3198	      (struct bfd_link_hash_entry **) sym_hash)))
3199	return false;
3200
3201      /* Restrict the maximum alignment of a common symbol based on
3202	 the architecture, since a.out has no way to represent
3203	 alignment requirements of a section in a .o file.  FIXME:
3204	 This isn't quite right: it should use the architecture of the
3205	 output file, not the input files.  */
3206      if ((*sym_hash)->root.type == bfd_link_hash_common
3207	  && ((*sym_hash)->root.u.c.p->alignment_power >
3208	      bfd_get_arch_info (abfd)->section_align_power))
3209	(*sym_hash)->root.u.c.p->alignment_power =
3210	  bfd_get_arch_info (abfd)->section_align_power;
3211
3212      /* If this is a set symbol, and we are not building sets, then
3213	 it is possible for the hash entry to not have been set.  In
3214	 such a case, treat the symbol as not globally defined.  */
3215      if ((*sym_hash)->root.type == bfd_link_hash_new)
3216	{
3217	  BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
3218	  *sym_hash = NULL;
3219	}
3220
3221      if (type == (N_INDR | N_EXT) || type == N_WARNING)
3222	++sym_hash;
3223    }
3224
3225  return true;
3226}
3227
3228/* Free up the internal symbols read from an a.out file.  */
3229
3230static bool
3231aout_link_free_symbols (bfd *abfd)
3232{
3233  if (obj_aout_external_syms (abfd) != NULL)
3234    {
3235#ifdef USE_MMAP
3236      bfd_free_window (&obj_aout_sym_window (abfd));
3237#else
3238      free ((void *) obj_aout_external_syms (abfd));
3239#endif
3240      obj_aout_external_syms (abfd) = NULL;
3241    }
3242  if (obj_aout_external_strings (abfd) != NULL)
3243    {
3244#ifdef USE_MMAP
3245      bfd_free_window (&obj_aout_string_window (abfd));
3246#else
3247      free ((void *) obj_aout_external_strings (abfd));
3248#endif
3249      obj_aout_external_strings (abfd) = NULL;
3250    }
3251  return true;
3252}
3253
3254/* Add symbols from an a.out object file.  */
3255
3256static bool
3257aout_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
3258{
3259  if (! aout_get_external_symbols (abfd))
3260    return false;
3261  if (! aout_link_add_symbols (abfd, info))
3262    return false;
3263  if (! info->keep_memory)
3264    {
3265      if (! aout_link_free_symbols (abfd))
3266	return false;
3267    }
3268  return true;
3269}
3270
3271/* Look through the internal symbols to see if this object file should
3272   be included in the link.  We should include this object file if it
3273   defines any symbols which are currently undefined.  If this object
3274   file defines a common symbol, then we may adjust the size of the
3275   known symbol but we do not include the object file in the link
3276   (unless there is some other reason to include it).  */
3277
3278static bool
3279aout_link_check_ar_symbols (bfd *abfd,
3280			    struct bfd_link_info *info,
3281			    bool *pneeded,
3282			    bfd **subsbfd)
3283{
3284  struct external_nlist *p;
3285  struct external_nlist *pend;
3286  char *strings;
3287
3288  *pneeded = false;
3289
3290  /* Look through all the symbols.  */
3291  p = obj_aout_external_syms (abfd);
3292  pend = p + obj_aout_external_sym_count (abfd);
3293  strings = obj_aout_external_strings (abfd);
3294  for (; p < pend; p++)
3295    {
3296      int type = H_GET_8 (abfd, p->e_type);
3297      const char *name;
3298      struct bfd_link_hash_entry *h;
3299
3300      /* Ignore symbols that are not externally visible.  This is an
3301	 optimization only, as we check the type more thoroughly
3302	 below.  */
3303      if (((type & N_EXT) == 0
3304	   || (type & N_STAB) != 0
3305	   || type == N_FN)
3306	  && type != N_WEAKA
3307	  && type != N_WEAKT
3308	  && type != N_WEAKD
3309	  && type != N_WEAKB)
3310	{
3311	  if (type == N_WARNING
3312	      || type == N_INDR)
3313	    ++p;
3314	  continue;
3315	}
3316
3317      name = strings + GET_WORD (abfd, p->e_strx);
3318      h = bfd_link_hash_lookup (info->hash, name, false, false, true);
3319
3320      /* We are only interested in symbols that are currently
3321	 undefined or common.  */
3322      if (h == NULL
3323	  || (h->type != bfd_link_hash_undefined
3324	      && h->type != bfd_link_hash_common))
3325	{
3326	  if (type == (N_INDR | N_EXT))
3327	    ++p;
3328	  continue;
3329	}
3330
3331      if (type == (N_TEXT | N_EXT)
3332	  || type == (N_DATA | N_EXT)
3333	  || type == (N_BSS | N_EXT)
3334	  || type == (N_ABS | N_EXT)
3335	  || type == (N_INDR | N_EXT))
3336	{
3337	  /* This object file defines this symbol.  We must link it
3338	     in.  This is true regardless of whether the current
3339	     definition of the symbol is undefined or common.
3340
3341	     If the current definition is common, we have a case in
3342	     which we have already seen an object file including:
3343		 int a;
3344	     and this object file from the archive includes:
3345		 int a = 5;
3346	     In such a case, whether to include this object is target
3347	     dependant for backward compatibility.
3348
3349	     FIXME: The SunOS 4.1.3 linker will pull in the archive
3350	     element if the symbol is defined in the .data section,
3351	     but not if it is defined in the .text section.  That
3352	     seems a bit crazy to me, and it has not been implemented
3353	     yet.  However, it might be correct.  */
3354	  if (h->type == bfd_link_hash_common)
3355	    {
3356	      int skip = 0;
3357
3358	      switch (info->common_skip_ar_symbols)
3359		{
3360		case bfd_link_common_skip_none:
3361		  break;
3362		case bfd_link_common_skip_text:
3363		  skip = (type == (N_TEXT | N_EXT));
3364		  break;
3365		case bfd_link_common_skip_data:
3366		  skip = (type == (N_DATA | N_EXT));
3367		  break;
3368		case bfd_link_common_skip_all:
3369		  skip = 1;
3370		  break;
3371		}
3372
3373	      if (skip)
3374		continue;
3375	    }
3376
3377	  if (!(*info->callbacks
3378		->add_archive_element) (info, abfd, name, subsbfd))
3379	    return false;
3380	  *pneeded = true;
3381	  return true;
3382	}
3383
3384      if (type == (N_UNDF | N_EXT))
3385	{
3386	  bfd_vma value;
3387
3388	  value = GET_WORD (abfd, p->e_value);
3389	  if (value != 0)
3390	    {
3391	      /* This symbol is common in the object from the archive
3392		 file.  */
3393	      if (h->type == bfd_link_hash_undefined)
3394		{
3395		  bfd *symbfd;
3396		  unsigned int power;
3397
3398		  symbfd = h->u.undef.abfd;
3399		  if (symbfd == NULL)
3400		    {
3401		      /* This symbol was created as undefined from
3402			 outside BFD.  We assume that we should link
3403			 in the object file.  This is done for the -u
3404			 option in the linker.  */
3405		      if (!(*info->callbacks
3406			    ->add_archive_element) (info, abfd, name, subsbfd))
3407			return false;
3408		      *pneeded = true;
3409		      return true;
3410		    }
3411		  /* Turn the current link symbol into a common
3412		     symbol.  It is already on the undefs list.  */
3413		  h->type = bfd_link_hash_common;
3414		  h->u.c.p = (struct bfd_link_hash_common_entry *)
3415		    bfd_hash_allocate (&info->hash->table,
3416				       sizeof (struct bfd_link_hash_common_entry));
3417		  if (h->u.c.p == NULL)
3418		    return false;
3419
3420		  h->u.c.size = value;
3421
3422		  /* FIXME: This isn't quite right.  The maximum
3423		     alignment of a common symbol should be set by the
3424		     architecture of the output file, not of the input
3425		     file.  */
3426		  power = bfd_log2 (value);
3427		  if (power > bfd_get_arch_info (abfd)->section_align_power)
3428		    power = bfd_get_arch_info (abfd)->section_align_power;
3429		  h->u.c.p->alignment_power = power;
3430
3431		  h->u.c.p->section = bfd_make_section_old_way (symbfd,
3432								"COMMON");
3433		}
3434	      else
3435		{
3436		  /* Adjust the size of the common symbol if
3437		     necessary.  */
3438		  if (value > h->u.c.size)
3439		    h->u.c.size = value;
3440		}
3441	    }
3442	}
3443
3444      if (type == N_WEAKA
3445	  || type == N_WEAKT
3446	  || type == N_WEAKD
3447	  || type == N_WEAKB)
3448	{
3449	  /* This symbol is weak but defined.  We must pull it in if
3450	     the current link symbol is undefined, but we don't want
3451	     it if the current link symbol is common.  */
3452	  if (h->type == bfd_link_hash_undefined)
3453	    {
3454	      if (!(*info->callbacks
3455		    ->add_archive_element) (info, abfd, name, subsbfd))
3456		return false;
3457	      *pneeded = true;
3458	      return true;
3459	    }
3460	}
3461    }
3462
3463  /* We do not need this object file.  */
3464  return true;
3465}
3466/* Check a single archive element to see if we need to include it in
3467   the link.  *PNEEDED is set according to whether this element is
3468   needed in the link or not.  This is called from
3469   _bfd_generic_link_add_archive_symbols.  */
3470
3471static bool
3472aout_link_check_archive_element (bfd *abfd,
3473				 struct bfd_link_info *info,
3474				 struct bfd_link_hash_entry *h ATTRIBUTE_UNUSED,
3475				 const char *name ATTRIBUTE_UNUSED,
3476				 bool *pneeded)
3477{
3478  bfd *oldbfd;
3479  bool needed;
3480
3481  if (!aout_get_external_symbols (abfd))
3482    return false;
3483
3484  oldbfd = abfd;
3485  if (!aout_link_check_ar_symbols (abfd, info, pneeded, &abfd))
3486    return false;
3487
3488  needed = *pneeded;
3489  if (needed)
3490    {
3491      /* Potentially, the add_archive_element hook may have set a
3492	 substitute BFD for us.  */
3493      if (abfd != oldbfd)
3494	{
3495	  if (!info->keep_memory
3496	      && !aout_link_free_symbols (oldbfd))
3497	    return false;
3498	  if (!aout_get_external_symbols (abfd))
3499	    return false;
3500	}
3501      if (!aout_link_add_symbols (abfd, info))
3502	return false;
3503    }
3504
3505  if (!info->keep_memory || !needed)
3506    {
3507      if (!aout_link_free_symbols (abfd))
3508	return false;
3509    }
3510
3511  return true;
3512}
3513
3514/* Given an a.out BFD, add symbols to the global hash table as
3515   appropriate.  */
3516
3517bool
3518NAME (aout, link_add_symbols) (bfd *abfd, struct bfd_link_info *info)
3519{
3520  switch (bfd_get_format (abfd))
3521    {
3522    case bfd_object:
3523      return aout_link_add_object_symbols (abfd, info);
3524    case bfd_archive:
3525      return _bfd_generic_link_add_archive_symbols
3526	(abfd, info, aout_link_check_archive_element);
3527    default:
3528      bfd_set_error (bfd_error_wrong_format);
3529      return false;
3530    }
3531}
3532
3533/* A hash table used for header files with N_BINCL entries.  */
3534
3535struct aout_link_includes_table
3536{
3537  struct bfd_hash_table root;
3538};
3539
3540/* A linked list of totals that we have found for a particular header
3541   file.  */
3542
3543struct aout_link_includes_totals
3544{
3545  struct aout_link_includes_totals *next;
3546  bfd_vma total;
3547};
3548
3549/* An entry in the header file hash table.  */
3550
3551struct aout_link_includes_entry
3552{
3553  struct bfd_hash_entry root;
3554  /* List of totals we have found for this file.  */
3555  struct aout_link_includes_totals *totals;
3556};
3557
3558/* Look up an entry in an the header file hash table.  */
3559
3560#define aout_link_includes_lookup(table, string, create, copy)		\
3561  ((struct aout_link_includes_entry *)					\
3562   bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
3563
3564/* During the final link step we need to pass around a bunch of
3565   information, so we do it in an instance of this structure.  */
3566
3567struct aout_final_link_info
3568{
3569  /* General link information.  */
3570  struct bfd_link_info *info;
3571  /* Output bfd.  */
3572  bfd *output_bfd;
3573  /* Reloc file positions.  */
3574  file_ptr treloff, dreloff;
3575  /* File position of symbols.  */
3576  file_ptr symoff;
3577  /* String table.  */
3578  struct bfd_strtab_hash *strtab;
3579  /* Header file hash table.  */
3580  struct aout_link_includes_table includes;
3581  /* A buffer large enough to hold the contents of any section.  */
3582  bfd_byte *contents;
3583  /* A buffer large enough to hold the relocs of any section.  */
3584  void * relocs;
3585  /* A buffer large enough to hold the symbol map of any input BFD.  */
3586  int *symbol_map;
3587  /* A buffer large enough to hold output symbols of any input BFD.  */
3588  struct external_nlist *output_syms;
3589};
3590
3591/* The function to create a new entry in the header file hash table.  */
3592
3593static struct bfd_hash_entry *
3594aout_link_includes_newfunc (struct bfd_hash_entry *entry,
3595			    struct bfd_hash_table *table,
3596			    const char *string)
3597{
3598  struct aout_link_includes_entry *ret =
3599    (struct aout_link_includes_entry *) entry;
3600
3601  /* Allocate the structure if it has not already been allocated by a
3602     subclass.  */
3603  if (ret == NULL)
3604    ret = (struct aout_link_includes_entry *)
3605	bfd_hash_allocate (table, sizeof (* ret));
3606  if (ret == NULL)
3607    return NULL;
3608
3609  /* Call the allocation method of the superclass.  */
3610  ret = ((struct aout_link_includes_entry *)
3611	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
3612  if (ret)
3613    {
3614      /* Set local fields.  */
3615      ret->totals = NULL;
3616    }
3617
3618  return (struct bfd_hash_entry *) ret;
3619}
3620
3621/* Write out a symbol that was not associated with an a.out input
3622   object.  */
3623
3624static bool
3625aout_link_write_other_symbol (struct bfd_hash_entry *bh, void *data)
3626{
3627  struct aout_link_hash_entry *h = (struct aout_link_hash_entry *) bh;
3628  struct aout_final_link_info *flaginfo = (struct aout_final_link_info *) data;
3629  bfd *output_bfd;
3630  int type;
3631  bfd_vma val;
3632  struct external_nlist outsym;
3633  bfd_size_type indx;
3634  size_t amt;
3635
3636  if (h->root.type == bfd_link_hash_warning)
3637    {
3638      h = (struct aout_link_hash_entry *) h->root.u.i.link;
3639      if (h->root.type == bfd_link_hash_new)
3640	return true;
3641    }
3642
3643  output_bfd = flaginfo->output_bfd;
3644
3645  if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
3646    {
3647      if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
3648	     (output_bfd, flaginfo->info, h)))
3649	{
3650	  /* FIXME: No way to handle errors.  */
3651	  abort ();
3652	}
3653    }
3654
3655  if (h->written)
3656    return true;
3657
3658  h->written = true;
3659
3660  /* An indx of -2 means the symbol must be written.  */
3661  if (h->indx != -2
3662      && (flaginfo->info->strip == strip_all
3663	  || (flaginfo->info->strip == strip_some
3664	      && bfd_hash_lookup (flaginfo->info->keep_hash, h->root.root.string,
3665				  false, false) == NULL)))
3666    return true;
3667
3668  switch (h->root.type)
3669    {
3670    default:
3671    case bfd_link_hash_warning:
3672      abort ();
3673      /* Avoid variable not initialized warnings.  */
3674      return true;
3675    case bfd_link_hash_new:
3676      /* This can happen for set symbols when sets are not being
3677	 built.  */
3678      return true;
3679    case bfd_link_hash_undefined:
3680      type = N_UNDF | N_EXT;
3681      val = 0;
3682      break;
3683    case bfd_link_hash_defined:
3684    case bfd_link_hash_defweak:
3685      {
3686	asection *sec;
3687
3688	sec = h->root.u.def.section->output_section;
3689	BFD_ASSERT (bfd_is_abs_section (sec)
3690		    || sec->owner == output_bfd);
3691	if (sec == obj_textsec (output_bfd))
3692	  type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
3693	else if (sec == obj_datasec (output_bfd))
3694	  type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
3695	else if (sec == obj_bsssec (output_bfd))
3696	  type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
3697	else
3698	  type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
3699	type |= N_EXT;
3700	val = (h->root.u.def.value
3701	       + sec->vma
3702	       + h->root.u.def.section->output_offset);
3703      }
3704      break;
3705    case bfd_link_hash_common:
3706      type = N_UNDF | N_EXT;
3707      val = h->root.u.c.size;
3708      break;
3709    case bfd_link_hash_undefweak:
3710      type = N_WEAKU;
3711      val = 0;
3712      break;
3713    case bfd_link_hash_indirect:
3714      /* We ignore these symbols, since the indirected symbol is
3715	 already in the hash table.  */
3716      return true;
3717    }
3718
3719  H_PUT_8 (output_bfd, type, outsym.e_type);
3720  H_PUT_8 (output_bfd, 0, outsym.e_other);
3721  H_PUT_16 (output_bfd, 0, outsym.e_desc);
3722  indx = add_to_stringtab (output_bfd, flaginfo->strtab, h->root.root.string,
3723			   false);
3724  if (indx == - (bfd_size_type) 1)
3725    /* FIXME: No way to handle errors.  */
3726    abort ();
3727
3728  PUT_WORD (output_bfd, indx, outsym.e_strx);
3729  PUT_WORD (output_bfd, val, outsym.e_value);
3730
3731  amt = EXTERNAL_NLIST_SIZE;
3732  if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0
3733      || bfd_bwrite ((void *) &outsym, amt, output_bfd) != amt)
3734    /* FIXME: No way to handle errors.  */
3735    abort ();
3736
3737  flaginfo->symoff += EXTERNAL_NLIST_SIZE;
3738  h->indx = obj_aout_external_sym_count (output_bfd);
3739  ++obj_aout_external_sym_count (output_bfd);
3740
3741  return true;
3742}
3743
3744/* Handle a link order which is supposed to generate a reloc.  */
3745
3746static bool
3747aout_link_reloc_link_order (struct aout_final_link_info *flaginfo,
3748			    asection *o,
3749			    struct bfd_link_order *p)
3750{
3751  struct bfd_link_order_reloc *pr;
3752  int r_index;
3753  int r_extern;
3754  reloc_howto_type *howto;
3755  file_ptr *reloff_ptr = NULL;
3756  struct reloc_std_external srel;
3757  struct reloc_ext_external erel;
3758  void * rel_ptr;
3759  size_t amt;
3760
3761  pr = p->u.reloc.p;
3762
3763  if (p->type == bfd_section_reloc_link_order)
3764    {
3765      r_extern = 0;
3766      if (bfd_is_abs_section (pr->u.section))
3767	r_index = N_ABS | N_EXT;
3768      else
3769	{
3770	  BFD_ASSERT (pr->u.section->owner == flaginfo->output_bfd);
3771	  r_index = pr->u.section->target_index;
3772	}
3773    }
3774  else
3775    {
3776      struct aout_link_hash_entry *h;
3777
3778      BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
3779      r_extern = 1;
3780      h = ((struct aout_link_hash_entry *)
3781	   bfd_wrapped_link_hash_lookup (flaginfo->output_bfd, flaginfo->info,
3782					 pr->u.name, false, false, true));
3783      if (h != NULL
3784	  && h->indx >= 0)
3785	r_index = h->indx;
3786      else if (h != NULL)
3787	{
3788	  /* We decided to strip this symbol, but it turns out that we
3789	     can't.  Note that we lose the other and desc information
3790	     here.  I don't think that will ever matter for a global
3791	     symbol.  */
3792	  h->indx = -2;
3793	  h->written = false;
3794	  if (!aout_link_write_other_symbol (&h->root.root, flaginfo))
3795	    return false;
3796	  r_index = h->indx;
3797	}
3798      else
3799	{
3800	  (*flaginfo->info->callbacks->unattached_reloc)
3801	    (flaginfo->info, pr->u.name, NULL, NULL, (bfd_vma) 0);
3802	  r_index = 0;
3803	}
3804    }
3805
3806  howto = bfd_reloc_type_lookup (flaginfo->output_bfd, pr->reloc);
3807  if (howto == 0)
3808    {
3809      bfd_set_error (bfd_error_bad_value);
3810      return false;
3811    }
3812
3813  if (o == obj_textsec (flaginfo->output_bfd))
3814    reloff_ptr = &flaginfo->treloff;
3815  else if (o == obj_datasec (flaginfo->output_bfd))
3816    reloff_ptr = &flaginfo->dreloff;
3817  else
3818    abort ();
3819
3820  if (obj_reloc_entry_size (flaginfo->output_bfd) == RELOC_STD_SIZE)
3821    {
3822#ifdef MY_put_reloc
3823      MY_put_reloc (flaginfo->output_bfd, r_extern, r_index, p->offset, howto,
3824		    &srel);
3825#else
3826      {
3827	int r_pcrel;
3828	int r_baserel;
3829	int r_jmptable;
3830	int r_relative;
3831	unsigned int r_length;
3832
3833	r_pcrel = (int) howto->pc_relative;
3834	r_baserel = (howto->type & 8) != 0;
3835	r_jmptable = (howto->type & 16) != 0;
3836	r_relative = (howto->type & 32) != 0;
3837	r_length = bfd_log2 (bfd_get_reloc_size (howto));
3838
3839	PUT_WORD (flaginfo->output_bfd, p->offset, srel.r_address);
3840	if (bfd_header_big_endian (flaginfo->output_bfd))
3841	  {
3842	    srel.r_index[0] = r_index >> 16;
3843	    srel.r_index[1] = r_index >> 8;
3844	    srel.r_index[2] = r_index;
3845	    srel.r_type[0] =
3846	      ((r_extern ?     RELOC_STD_BITS_EXTERN_BIG : 0)
3847	       | (r_pcrel ?    RELOC_STD_BITS_PCREL_BIG : 0)
3848	       | (r_baserel ?  RELOC_STD_BITS_BASEREL_BIG : 0)
3849	       | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
3850	       | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
3851	       | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG));
3852	  }
3853	else
3854	  {
3855	    srel.r_index[2] = r_index >> 16;
3856	    srel.r_index[1] = r_index >> 8;
3857	    srel.r_index[0] = r_index;
3858	    srel.r_type[0] =
3859	      ((r_extern ?     RELOC_STD_BITS_EXTERN_LITTLE : 0)
3860	       | (r_pcrel ?    RELOC_STD_BITS_PCREL_LITTLE : 0)
3861	       | (r_baserel ?  RELOC_STD_BITS_BASEREL_LITTLE : 0)
3862	       | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
3863	       | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
3864	       | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE));
3865	  }
3866      }
3867#endif
3868      rel_ptr = (void *) &srel;
3869
3870      /* We have to write the addend into the object file, since
3871	 standard a.out relocs are in place.  It would be more
3872	 reliable if we had the current contents of the file here,
3873	 rather than assuming zeroes, but we can't read the file since
3874	 it was opened using bfd_openw.  */
3875      if (pr->addend != 0)
3876	{
3877	  bfd_size_type size;
3878	  bfd_reloc_status_type r;
3879	  bfd_byte *buf;
3880	  bool ok;
3881
3882	  size = bfd_get_reloc_size (howto);
3883	  buf = (bfd_byte *) bfd_zmalloc (size);
3884	  if (buf == NULL && size != 0)
3885	    return false;
3886	  r = MY_relocate_contents (howto, flaginfo->output_bfd,
3887				    (bfd_vma) pr->addend, buf);
3888	  switch (r)
3889	    {
3890	    case bfd_reloc_ok:
3891	      break;
3892	    default:
3893	    case bfd_reloc_outofrange:
3894	      abort ();
3895	    case bfd_reloc_overflow:
3896	      (*flaginfo->info->callbacks->reloc_overflow)
3897		(flaginfo->info, NULL,
3898		 (p->type == bfd_section_reloc_link_order
3899		  ? bfd_section_name (pr->u.section)
3900		  : pr->u.name),
3901		 howto->name, pr->addend, NULL, NULL, (bfd_vma) 0);
3902	      break;
3903	    }
3904	  ok = bfd_set_section_contents (flaginfo->output_bfd, o, (void *) buf,
3905					 (file_ptr) p->offset, size);
3906	  free (buf);
3907	  if (! ok)
3908	    return false;
3909	}
3910    }
3911  else
3912    {
3913#ifdef MY_put_ext_reloc
3914      MY_put_ext_reloc (flaginfo->output_bfd, r_extern, r_index, p->offset,
3915			howto, &erel, pr->addend);
3916#else
3917      PUT_WORD (flaginfo->output_bfd, p->offset, erel.r_address);
3918
3919      if (bfd_header_big_endian (flaginfo->output_bfd))
3920	{
3921	  erel.r_index[0] = r_index >> 16;
3922	  erel.r_index[1] = r_index >> 8;
3923	  erel.r_index[2] = r_index;
3924	  erel.r_type[0] =
3925	    ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
3926	     | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG));
3927	}
3928      else
3929	{
3930	  erel.r_index[2] = r_index >> 16;
3931	  erel.r_index[1] = r_index >> 8;
3932	  erel.r_index[0] = r_index;
3933	  erel.r_type[0] =
3934	    (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
3935	      | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
3936	}
3937
3938      PUT_WORD (flaginfo->output_bfd, (bfd_vma) pr->addend, erel.r_addend);
3939#endif /* MY_put_ext_reloc */
3940
3941      rel_ptr = (void *) &erel;
3942    }
3943
3944  amt = obj_reloc_entry_size (flaginfo->output_bfd);
3945  if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
3946      || bfd_bwrite (rel_ptr, amt, flaginfo->output_bfd) != amt)
3947    return false;
3948
3949  *reloff_ptr += obj_reloc_entry_size (flaginfo->output_bfd);
3950
3951  /* Assert that the relocs have not run into the symbols, and that n
3952     the text relocs have not run into the data relocs.  */
3953  BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (flaginfo->output_bfd)
3954	      && (reloff_ptr != &flaginfo->treloff
3955		  || (*reloff_ptr
3956		      <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
3957
3958  return true;
3959}
3960
3961/* Get the section corresponding to a reloc index.  */
3962
3963static inline asection *
3964aout_reloc_index_to_section (bfd *abfd, int indx)
3965{
3966  switch (indx & N_TYPE)
3967    {
3968    case N_TEXT:   return obj_textsec (abfd);
3969    case N_DATA:   return obj_datasec (abfd);
3970    case N_BSS:    return obj_bsssec (abfd);
3971    case N_ABS:
3972    case N_UNDF:   return bfd_abs_section_ptr;
3973    default:       abort ();
3974    }
3975  return NULL;
3976}
3977
3978/* Relocate an a.out section using standard a.out relocs.  */
3979
3980static bool
3981aout_link_input_section_std (struct aout_final_link_info *flaginfo,
3982			     bfd *input_bfd,
3983			     asection *input_section,
3984			     struct reloc_std_external *relocs,
3985			     bfd_size_type rel_size,
3986			     bfd_byte *contents)
3987{
3988  bool (*check_dynamic_reloc)
3989    (struct bfd_link_info *, bfd *, asection *,
3990     struct aout_link_hash_entry *, void *, bfd_byte *, bool *, bfd_vma *);
3991  bfd *output_bfd;
3992  bool relocatable;
3993  struct external_nlist *syms;
3994  char *strings;
3995  struct aout_link_hash_entry **sym_hashes;
3996  int *symbol_map;
3997  bfd_size_type reloc_count;
3998  struct reloc_std_external *rel;
3999  struct reloc_std_external *rel_end;
4000
4001  output_bfd = flaginfo->output_bfd;
4002  check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
4003
4004  BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
4005  BFD_ASSERT (input_bfd->xvec->header_byteorder
4006	      == output_bfd->xvec->header_byteorder);
4007
4008  relocatable = bfd_link_relocatable (flaginfo->info);
4009  syms = obj_aout_external_syms (input_bfd);
4010  strings = obj_aout_external_strings (input_bfd);
4011  sym_hashes = obj_aout_sym_hashes (input_bfd);
4012  symbol_map = flaginfo->symbol_map;
4013
4014  reloc_count = rel_size / RELOC_STD_SIZE;
4015  rel = relocs;
4016  rel_end = rel + reloc_count;
4017  for (; rel < rel_end; rel++)
4018    {
4019      bfd_vma r_addr;
4020      unsigned int r_index;
4021      int r_extern;
4022      int r_pcrel;
4023      int r_baserel = 0;
4024      reloc_howto_type *howto;
4025      struct aout_link_hash_entry *h = NULL;
4026      bfd_vma relocation;
4027      bfd_reloc_status_type r;
4028
4029      r_addr = GET_SWORD (input_bfd, rel->r_address);
4030
4031#ifdef MY_reloc_howto
4032      howto = MY_reloc_howto (input_bfd, rel, r_index, r_extern, r_pcrel);
4033#else
4034      {
4035	int r_jmptable;
4036	int r_relative;
4037	int r_length;
4038	unsigned int howto_idx;
4039
4040	if (bfd_header_big_endian (input_bfd))
4041	  {
4042	    r_index   =  (((unsigned int) rel->r_index[0] << 16)
4043			  | ((unsigned int) rel->r_index[1] << 8)
4044			  | rel->r_index[2]);
4045	    r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
4046	    r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
4047	    r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
4048	    r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
4049	    r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
4050	    r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
4051			 >> RELOC_STD_BITS_LENGTH_SH_BIG);
4052	  }
4053	else
4054	  {
4055	    r_index   = (((unsigned int) rel->r_index[2] << 16)
4056			 | ((unsigned int) rel->r_index[1] << 8)
4057			 | rel->r_index[0]);
4058	    r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
4059	    r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
4060	    r_baserel = (0 != (rel->r_type[0]
4061			       & RELOC_STD_BITS_BASEREL_LITTLE));
4062	    r_jmptable= (0 != (rel->r_type[0]
4063			       & RELOC_STD_BITS_JMPTABLE_LITTLE));
4064	    r_relative= (0 != (rel->r_type[0]
4065			       & RELOC_STD_BITS_RELATIVE_LITTLE));
4066	    r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
4067			 >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
4068	  }
4069
4070	howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
4071		     + 16 * r_jmptable + 32 * r_relative);
4072	if (howto_idx < TABLE_SIZE (howto_table_std))
4073	  howto = howto_table_std + howto_idx;
4074	else
4075	  howto = NULL;
4076      }
4077#endif
4078
4079      if (howto == NULL)
4080	{
4081	  _bfd_error_handler (_("%pB: unsupported relocation type"),
4082			      input_bfd);
4083	  bfd_set_error (bfd_error_bad_value);
4084	  return false;
4085	}
4086
4087      if (relocatable)
4088	{
4089	  /* We are generating a relocatable output file, and must
4090	     modify the reloc accordingly.  */
4091	  if (r_extern)
4092	    {
4093	      /* If we know the symbol this relocation is against,
4094		 convert it into a relocation against a section.  This
4095		 is what the native linker does.  */
4096	      h = sym_hashes[r_index];
4097	      if (h != NULL
4098		  && (h->root.type == bfd_link_hash_defined
4099		      || h->root.type == bfd_link_hash_defweak))
4100		{
4101		  asection *output_section;
4102
4103		  /* Change the r_extern value.  */
4104		  if (bfd_header_big_endian (output_bfd))
4105		    rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
4106		  else
4107		    rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
4108
4109		  /* Compute a new r_index.  */
4110		  output_section = h->root.u.def.section->output_section;
4111		  if (output_section == obj_textsec (output_bfd))
4112		    r_index = N_TEXT;
4113		  else if (output_section == obj_datasec (output_bfd))
4114		    r_index = N_DATA;
4115		  else if (output_section == obj_bsssec (output_bfd))
4116		    r_index = N_BSS;
4117		  else
4118		    r_index = N_ABS;
4119
4120		  /* Add the symbol value and the section VMA to the
4121		     addend stored in the contents.  */
4122		  relocation = (h->root.u.def.value
4123				+ output_section->vma
4124				+ h->root.u.def.section->output_offset);
4125		}
4126	      else
4127		{
4128		  /* We must change r_index according to the symbol
4129		     map.  */
4130		  r_index = symbol_map[r_index];
4131
4132		  if (r_index == -1u)
4133		    {
4134		      if (h != NULL)
4135			{
4136			  /* We decided to strip this symbol, but it
4137			     turns out that we can't.  Note that we
4138			     lose the other and desc information here.
4139			     I don't think that will ever matter for a
4140			     global symbol.  */
4141			  if (h->indx < 0)
4142			    {
4143			      h->indx = -2;
4144			      h->written = false;
4145			      if (!aout_link_write_other_symbol (&h->root.root,
4146								 flaginfo))
4147				return false;
4148			    }
4149			  r_index = h->indx;
4150			}
4151		      else
4152			{
4153			  const char *name;
4154
4155			  name = strings + GET_WORD (input_bfd,
4156						     syms[r_index].e_strx);
4157			  (*flaginfo->info->callbacks->unattached_reloc)
4158			    (flaginfo->info, name,
4159			     input_bfd, input_section, r_addr);
4160			  r_index = 0;
4161			}
4162		    }
4163
4164		  relocation = 0;
4165		}
4166
4167	      /* Write out the new r_index value.  */
4168	      if (bfd_header_big_endian (output_bfd))
4169		{
4170		  rel->r_index[0] = r_index >> 16;
4171		  rel->r_index[1] = r_index >> 8;
4172		  rel->r_index[2] = r_index;
4173		}
4174	      else
4175		{
4176		  rel->r_index[2] = r_index >> 16;
4177		  rel->r_index[1] = r_index >> 8;
4178		  rel->r_index[0] = r_index;
4179		}
4180	    }
4181	  else
4182	    {
4183	      asection *section;
4184
4185	      /* This is a relocation against a section.  We must
4186		 adjust by the amount that the section moved.  */
4187	      section = aout_reloc_index_to_section (input_bfd, r_index);
4188	      relocation = (section->output_section->vma
4189			    + section->output_offset
4190			    - section->vma);
4191	    }
4192
4193	  /* Change the address of the relocation.  */
4194	  PUT_WORD (output_bfd,
4195		    r_addr + input_section->output_offset,
4196		    rel->r_address);
4197
4198	  /* Adjust a PC relative relocation by removing the reference
4199	     to the original address in the section and including the
4200	     reference to the new address.  */
4201	  if (r_pcrel)
4202	    relocation -= (input_section->output_section->vma
4203			   + input_section->output_offset
4204			   - input_section->vma);
4205
4206#ifdef MY_relocatable_reloc
4207	  MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
4208#endif
4209
4210	  if (relocation == 0)
4211	    r = bfd_reloc_ok;
4212	  else
4213	    r = MY_relocate_contents (howto,
4214					input_bfd, relocation,
4215					contents + r_addr);
4216	}
4217      else
4218	{
4219	  bool hundef;
4220
4221	  /* We are generating an executable, and must do a full
4222	     relocation.  */
4223	  hundef = false;
4224
4225	  if (r_extern)
4226	    {
4227	      h = sym_hashes[r_index];
4228
4229	      if (h != NULL
4230		  && (h->root.type == bfd_link_hash_defined
4231		      || h->root.type == bfd_link_hash_defweak))
4232		{
4233		  relocation = (h->root.u.def.value
4234				+ h->root.u.def.section->output_section->vma
4235				+ h->root.u.def.section->output_offset);
4236		}
4237	      else if (h != NULL
4238		       && h->root.type == bfd_link_hash_undefweak)
4239		relocation = 0;
4240	      else
4241		{
4242		  hundef = true;
4243		  relocation = 0;
4244		}
4245	    }
4246	  else
4247	    {
4248	      asection *section;
4249
4250	      section = aout_reloc_index_to_section (input_bfd, r_index);
4251	      relocation = (section->output_section->vma
4252			    + section->output_offset
4253			    - section->vma);
4254	      if (r_pcrel)
4255		relocation += input_section->vma;
4256	    }
4257
4258	  if (check_dynamic_reloc != NULL)
4259	    {
4260	      bool skip;
4261
4262	      if (! ((*check_dynamic_reloc)
4263		     (flaginfo->info, input_bfd, input_section, h,
4264		      (void *) rel, contents, &skip, &relocation)))
4265		return false;
4266	      if (skip)
4267		continue;
4268	    }
4269
4270	  /* Now warn if a global symbol is undefined.  We could not
4271	     do this earlier, because check_dynamic_reloc might want
4272	     to skip this reloc.  */
4273	  if (hundef && ! bfd_link_pic (flaginfo->info) && ! r_baserel)
4274	    {
4275	      const char *name;
4276
4277	      if (h != NULL)
4278		name = h->root.root.string;
4279	      else
4280		name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
4281	      (*flaginfo->info->callbacks->undefined_symbol)
4282		(flaginfo->info, name, input_bfd, input_section, r_addr, true);
4283	    }
4284
4285	  r = MY_final_link_relocate (howto,
4286				      input_bfd, input_section,
4287				      contents, r_addr, relocation,
4288				      (bfd_vma) 0);
4289	}
4290
4291      if (r != bfd_reloc_ok)
4292	{
4293	  switch (r)
4294	    {
4295	    default:
4296	    case bfd_reloc_outofrange:
4297	      abort ();
4298	    case bfd_reloc_overflow:
4299	      {
4300		const char *name;
4301
4302		if (h != NULL)
4303		  name = NULL;
4304		else if (r_extern)
4305		  name = strings + GET_WORD (input_bfd,
4306					     syms[r_index].e_strx);
4307		else
4308		  {
4309		    asection *s;
4310
4311		    s = aout_reloc_index_to_section (input_bfd, r_index);
4312		    name = bfd_section_name (s);
4313		  }
4314		(*flaginfo->info->callbacks->reloc_overflow)
4315		  (flaginfo->info, (h ? &h->root : NULL), name, howto->name,
4316		   (bfd_vma) 0, input_bfd, input_section, r_addr);
4317	      }
4318	      break;
4319	    }
4320	}
4321    }
4322
4323  return true;
4324}
4325
4326/* Relocate an a.out section using extended a.out relocs.  */
4327
4328static bool
4329aout_link_input_section_ext (struct aout_final_link_info *flaginfo,
4330			     bfd *input_bfd,
4331			     asection *input_section,
4332			     struct reloc_ext_external *relocs,
4333			     bfd_size_type rel_size,
4334			     bfd_byte *contents)
4335{
4336  bool (*check_dynamic_reloc)
4337    (struct bfd_link_info *, bfd *, asection *,
4338     struct aout_link_hash_entry *, void *, bfd_byte *, bool *, bfd_vma *);
4339  bfd *output_bfd;
4340  bool relocatable;
4341  struct external_nlist *syms;
4342  char *strings;
4343  struct aout_link_hash_entry **sym_hashes;
4344  int *symbol_map;
4345  bfd_size_type reloc_count;
4346  struct reloc_ext_external *rel;
4347  struct reloc_ext_external *rel_end;
4348
4349  output_bfd = flaginfo->output_bfd;
4350  check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
4351
4352  BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
4353  BFD_ASSERT (input_bfd->xvec->header_byteorder
4354	      == output_bfd->xvec->header_byteorder);
4355
4356  relocatable = bfd_link_relocatable (flaginfo->info);
4357  syms = obj_aout_external_syms (input_bfd);
4358  strings = obj_aout_external_strings (input_bfd);
4359  sym_hashes = obj_aout_sym_hashes (input_bfd);
4360  symbol_map = flaginfo->symbol_map;
4361
4362  reloc_count = rel_size / RELOC_EXT_SIZE;
4363  rel = relocs;
4364  rel_end = rel + reloc_count;
4365  for (; rel < rel_end; rel++)
4366    {
4367      bfd_vma r_addr;
4368      unsigned int r_index;
4369      int r_extern;
4370      unsigned int r_type;
4371      bfd_vma r_addend;
4372      struct aout_link_hash_entry *h = NULL;
4373      asection *r_section = NULL;
4374      bfd_vma relocation;
4375
4376      r_addr = GET_SWORD (input_bfd, rel->r_address);
4377
4378      if (bfd_header_big_endian (input_bfd))
4379	{
4380	  r_index  = (((unsigned int) rel->r_index[0] << 16)
4381		      | ((unsigned int) rel->r_index[1] << 8)
4382		      | rel->r_index[2]);
4383	  r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
4384	  r_type   = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
4385		      >> RELOC_EXT_BITS_TYPE_SH_BIG);
4386	}
4387      else
4388	{
4389	  r_index  = (((unsigned int) rel->r_index[2] << 16)
4390		      | ((unsigned int) rel->r_index[1] << 8)
4391		      | rel->r_index[0]);
4392	  r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
4393	  r_type   = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
4394		      >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
4395	}
4396
4397      r_addend = GET_SWORD (input_bfd, rel->r_addend);
4398
4399      if (r_type >= TABLE_SIZE (howto_table_ext))
4400	{
4401	  _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
4402			      input_bfd, r_type);
4403	  bfd_set_error (bfd_error_bad_value);
4404	  return false;
4405	}
4406
4407      if (relocatable)
4408	{
4409	  /* We are generating a relocatable output file, and must
4410	     modify the reloc accordingly.  */
4411	  if (r_extern
4412	      || r_type == (unsigned int) RELOC_BASE10
4413	      || r_type == (unsigned int) RELOC_BASE13
4414	      || r_type == (unsigned int) RELOC_BASE22)
4415	    {
4416	      /* If we know the symbol this relocation is against,
4417		 convert it into a relocation against a section.  This
4418		 is what the native linker does.  */
4419	      if (r_type == (unsigned int) RELOC_BASE10
4420		  || r_type == (unsigned int) RELOC_BASE13
4421		  || r_type == (unsigned int) RELOC_BASE22)
4422		h = NULL;
4423	      else
4424		h = sym_hashes[r_index];
4425	      if (h != NULL
4426		  && (h->root.type == bfd_link_hash_defined
4427		      || h->root.type == bfd_link_hash_defweak))
4428		{
4429		  asection *output_section;
4430
4431		  /* Change the r_extern value.  */
4432		  if (bfd_header_big_endian (output_bfd))
4433		    rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
4434		  else
4435		    rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
4436
4437		  /* Compute a new r_index.  */
4438		  output_section = h->root.u.def.section->output_section;
4439		  if (output_section == obj_textsec (output_bfd))
4440		    r_index = N_TEXT;
4441		  else if (output_section == obj_datasec (output_bfd))
4442		    r_index = N_DATA;
4443		  else if (output_section == obj_bsssec (output_bfd))
4444		    r_index = N_BSS;
4445		  else
4446		    r_index = N_ABS;
4447
4448		  /* Add the symbol value and the section VMA to the
4449		     addend.  */
4450		  relocation = (h->root.u.def.value
4451				+ output_section->vma
4452				+ h->root.u.def.section->output_offset);
4453
4454		  /* Now RELOCATION is the VMA of the final
4455		     destination.  If this is a PC relative reloc,
4456		     then ADDEND is the negative of the source VMA.
4457		     We want to set ADDEND to the difference between
4458		     the destination VMA and the source VMA, which
4459		     means we must adjust RELOCATION by the change in
4460		     the source VMA.  This is done below.  */
4461		}
4462	      else
4463		{
4464		  /* We must change r_index according to the symbol
4465		     map.  */
4466		  r_index = symbol_map[r_index];
4467
4468		  if (r_index == -1u)
4469		    {
4470		      if (h != NULL)
4471			{
4472			  /* We decided to strip this symbol, but it
4473			     turns out that we can't.  Note that we
4474			     lose the other and desc information here.
4475			     I don't think that will ever matter for a
4476			     global symbol.  */
4477			  if (h->indx < 0)
4478			    {
4479			      h->indx = -2;
4480			      h->written = false;
4481			      if (!aout_link_write_other_symbol (&h->root.root,
4482								 flaginfo))
4483				return false;
4484			    }
4485			  r_index = h->indx;
4486			}
4487		      else
4488			{
4489			  const char *name;
4490
4491			  name = strings + GET_WORD (input_bfd,
4492						     syms[r_index].e_strx);
4493			  (*flaginfo->info->callbacks->unattached_reloc)
4494			    (flaginfo->info, name,
4495			     input_bfd, input_section, r_addr);
4496			  r_index = 0;
4497			}
4498		    }
4499
4500		  relocation = 0;
4501
4502		  /* If this is a PC relative reloc, then the addend
4503		     is the negative of the source VMA.  We must
4504		     adjust it by the change in the source VMA.  This
4505		     is done below.  */
4506		}
4507
4508	      /* Write out the new r_index value.  */
4509	      if (bfd_header_big_endian (output_bfd))
4510		{
4511		  rel->r_index[0] = r_index >> 16;
4512		  rel->r_index[1] = r_index >> 8;
4513		  rel->r_index[2] = r_index;
4514		}
4515	      else
4516		{
4517		  rel->r_index[2] = r_index >> 16;
4518		  rel->r_index[1] = r_index >> 8;
4519		  rel->r_index[0] = r_index;
4520		}
4521	    }
4522	  else
4523	    {
4524	      /* This is a relocation against a section.  We must
4525		 adjust by the amount that the section moved.  */
4526	      r_section = aout_reloc_index_to_section (input_bfd, r_index);
4527	      relocation = (r_section->output_section->vma
4528			    + r_section->output_offset
4529			    - r_section->vma);
4530
4531	      /* If this is a PC relative reloc, then the addend is
4532		 the difference in VMA between the destination and the
4533		 source.  We have just adjusted for the change in VMA
4534		 of the destination, so we must also adjust by the
4535		 change in VMA of the source.  This is done below.  */
4536	    }
4537
4538	  /* As described above, we must always adjust a PC relative
4539	     reloc by the change in VMA of the source.  However, if
4540	     pcrel_offset is set, then the addend does not include the
4541	     location within the section, in which case we don't need
4542	     to adjust anything.  */
4543	  if (howto_table_ext[r_type].pc_relative
4544	      && ! howto_table_ext[r_type].pcrel_offset)
4545	    relocation -= (input_section->output_section->vma
4546			   + input_section->output_offset
4547			   - input_section->vma);
4548
4549	  /* Change the addend if necessary.  */
4550	  if (relocation != 0)
4551	    PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
4552
4553	  /* Change the address of the relocation.  */
4554	  PUT_WORD (output_bfd,
4555		    r_addr + input_section->output_offset,
4556		    rel->r_address);
4557	}
4558      else
4559	{
4560	  bool hundef;
4561	  bfd_reloc_status_type r;
4562
4563	  /* We are generating an executable, and must do a full
4564	     relocation.  */
4565	  hundef = false;
4566
4567	  if (r_extern)
4568	    {
4569	      h = sym_hashes[r_index];
4570
4571	      if (h != NULL
4572		  && (h->root.type == bfd_link_hash_defined
4573		      || h->root.type == bfd_link_hash_defweak))
4574		{
4575		  relocation = (h->root.u.def.value
4576				+ h->root.u.def.section->output_section->vma
4577				+ h->root.u.def.section->output_offset);
4578		}
4579	      else if (h != NULL
4580		       && h->root.type == bfd_link_hash_undefweak)
4581		relocation = 0;
4582	      else
4583		{
4584		  hundef = true;
4585		  relocation = 0;
4586		}
4587	    }
4588	  else if (r_type == (unsigned int) RELOC_BASE10
4589		   || r_type == (unsigned int) RELOC_BASE13
4590		   || r_type == (unsigned int) RELOC_BASE22)
4591	    {
4592	      struct external_nlist *sym;
4593	      int type;
4594
4595	      /* For base relative relocs, r_index is always an index
4596		 into the symbol table, even if r_extern is 0.  */
4597	      sym = syms + r_index;
4598	      type = H_GET_8 (input_bfd, sym->e_type);
4599	      if ((type & N_TYPE) == N_TEXT
4600		  || type == N_WEAKT)
4601		r_section = obj_textsec (input_bfd);
4602	      else if ((type & N_TYPE) == N_DATA
4603		       || type == N_WEAKD)
4604		r_section = obj_datasec (input_bfd);
4605	      else if ((type & N_TYPE) == N_BSS
4606		       || type == N_WEAKB)
4607		r_section = obj_bsssec (input_bfd);
4608	      else if ((type & N_TYPE) == N_ABS
4609		       || type == N_WEAKA)
4610		r_section = bfd_abs_section_ptr;
4611	      else
4612		abort ();
4613	      relocation = (r_section->output_section->vma
4614			    + r_section->output_offset
4615			    + (GET_WORD (input_bfd, sym->e_value)
4616			       - r_section->vma));
4617	    }
4618	  else
4619	    {
4620	      r_section = aout_reloc_index_to_section (input_bfd, r_index);
4621
4622	      /* If this is a PC relative reloc, then R_ADDEND is the
4623		 difference between the two vmas, or
4624		   old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
4625		 where
4626		   old_dest_sec == section->vma
4627		 and
4628		   old_src_sec == input_section->vma
4629		 and
4630		   old_src_off == r_addr
4631
4632		 _bfd_final_link_relocate expects RELOCATION +
4633		 R_ADDEND to be the VMA of the destination minus
4634		 r_addr (the minus r_addr is because this relocation
4635		 is not pcrel_offset, which is a bit confusing and
4636		 should, perhaps, be changed), or
4637		   new_dest_sec
4638		 where
4639		   new_dest_sec == output_section->vma + output_offset
4640		 We arrange for this to happen by setting RELOCATION to
4641		   new_dest_sec + old_src_sec - old_dest_sec
4642
4643		 If this is not a PC relative reloc, then R_ADDEND is
4644		 simply the VMA of the destination, so we set
4645		 RELOCATION to the change in the destination VMA, or
4646		   new_dest_sec - old_dest_sec
4647		 */
4648	      relocation = (r_section->output_section->vma
4649			    + r_section->output_offset
4650			    - r_section->vma);
4651	      if (howto_table_ext[r_type].pc_relative)
4652		relocation += input_section->vma;
4653	    }
4654
4655	  if (check_dynamic_reloc != NULL)
4656	    {
4657	      bool skip;
4658
4659	      if (! ((*check_dynamic_reloc)
4660		     (flaginfo->info, input_bfd, input_section, h,
4661		      (void *) rel, contents, &skip, &relocation)))
4662		return false;
4663	      if (skip)
4664		continue;
4665	    }
4666
4667	  /* Now warn if a global symbol is undefined.  We could not
4668	     do this earlier, because check_dynamic_reloc might want
4669	     to skip this reloc.  */
4670	  if (hundef
4671	      && ! bfd_link_pic (flaginfo->info)
4672	      && r_type != (unsigned int) RELOC_BASE10
4673	      && r_type != (unsigned int) RELOC_BASE13
4674	      && r_type != (unsigned int) RELOC_BASE22)
4675	    {
4676	      const char *name;
4677
4678	      if (h != NULL)
4679		name = h->root.root.string;
4680	      else
4681		name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
4682	      (*flaginfo->info->callbacks->undefined_symbol)
4683		(flaginfo->info, name, input_bfd, input_section, r_addr, true);
4684	    }
4685
4686	  if (r_type != (unsigned int) RELOC_SPARC_REV32)
4687	    r = MY_final_link_relocate (howto_table_ext + r_type,
4688					input_bfd, input_section,
4689					contents, r_addr, relocation,
4690					r_addend);
4691	  else
4692	    {
4693	      bfd_vma x;
4694
4695	      x = bfd_get_32 (input_bfd, contents + r_addr);
4696	      x = x + relocation + r_addend;
4697	      bfd_putl32 (/*input_bfd,*/ x, contents + r_addr);
4698	      r = bfd_reloc_ok;
4699	    }
4700
4701	  if (r != bfd_reloc_ok)
4702	    {
4703	      switch (r)
4704		{
4705		default:
4706		case bfd_reloc_outofrange:
4707		  abort ();
4708		case bfd_reloc_overflow:
4709		  {
4710		    const char *name;
4711
4712		    if (h != NULL)
4713		      name = NULL;
4714		    else if (r_extern
4715			     || r_type == (unsigned int) RELOC_BASE10
4716			     || r_type == (unsigned int) RELOC_BASE13
4717			     || r_type == (unsigned int) RELOC_BASE22)
4718		      name = strings + GET_WORD (input_bfd,
4719						 syms[r_index].e_strx);
4720		    else
4721		      {
4722			asection *s;
4723
4724			s = aout_reloc_index_to_section (input_bfd, r_index);
4725			name = bfd_section_name (s);
4726		      }
4727		    (*flaginfo->info->callbacks->reloc_overflow)
4728		      (flaginfo->info, (h ? &h->root : NULL), name,
4729		       howto_table_ext[r_type].name,
4730		       r_addend, input_bfd, input_section, r_addr);
4731		  }
4732		  break;
4733		}
4734	    }
4735	}
4736    }
4737
4738  return true;
4739}
4740
4741/* Link an a.out section into the output file.  */
4742
4743static bool
4744aout_link_input_section (struct aout_final_link_info *flaginfo,
4745			 bfd *input_bfd,
4746			 asection *input_section,
4747			 file_ptr *reloff_ptr,
4748			 bfd_size_type rel_size)
4749{
4750  bfd_size_type input_size;
4751  void * relocs;
4752
4753  /* Get the section contents.  */
4754  input_size = input_section->size;
4755  if (! bfd_get_section_contents (input_bfd, input_section,
4756				  (void *) flaginfo->contents,
4757				  (file_ptr) 0, input_size))
4758    return false;
4759
4760  /* Read in the relocs if we haven't already done it.  */
4761  if (aout_section_data (input_section) != NULL
4762      && aout_section_data (input_section)->relocs != NULL)
4763    relocs = aout_section_data (input_section)->relocs;
4764  else
4765    {
4766      relocs = flaginfo->relocs;
4767      if (rel_size > 0)
4768	{
4769	  if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
4770	      || bfd_bread (relocs, rel_size, input_bfd) != rel_size)
4771	    return false;
4772	}
4773    }
4774
4775  /* Relocate the section contents.  */
4776  if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
4777    {
4778      if (! aout_link_input_section_std (flaginfo, input_bfd, input_section,
4779					 (struct reloc_std_external *) relocs,
4780					 rel_size, flaginfo->contents))
4781	return false;
4782    }
4783  else
4784    {
4785      if (! aout_link_input_section_ext (flaginfo, input_bfd, input_section,
4786					 (struct reloc_ext_external *) relocs,
4787					 rel_size, flaginfo->contents))
4788	return false;
4789    }
4790
4791  /* Write out the section contents.  */
4792  if (! bfd_set_section_contents (flaginfo->output_bfd,
4793				  input_section->output_section,
4794				  (void *) flaginfo->contents,
4795				  (file_ptr) input_section->output_offset,
4796				  input_size))
4797    return false;
4798
4799  /* If we are producing relocatable output, the relocs were
4800     modified, and we now write them out.  */
4801  if (bfd_link_relocatable (flaginfo->info) && rel_size > 0)
4802    {
4803      if (bfd_seek (flaginfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
4804	return false;
4805      if (bfd_bwrite (relocs, rel_size, flaginfo->output_bfd) != rel_size)
4806	return false;
4807      *reloff_ptr += rel_size;
4808
4809      /* Assert that the relocs have not run into the symbols, and
4810	 that if these are the text relocs they have not run into the
4811	 data relocs.  */
4812      BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (flaginfo->output_bfd)
4813		  && (reloff_ptr != &flaginfo->treloff
4814		      || (*reloff_ptr
4815			  <= obj_datasec (flaginfo->output_bfd)->rel_filepos)));
4816    }
4817
4818  return true;
4819}
4820
4821/* Adjust and write out the symbols for an a.out file.  Set the new
4822   symbol indices into a symbol_map.  */
4823
4824static bool
4825aout_link_write_symbols (struct aout_final_link_info *flaginfo, bfd *input_bfd)
4826{
4827  bfd *output_bfd;
4828  bfd_size_type sym_count;
4829  char *strings;
4830  enum bfd_link_strip strip;
4831  enum bfd_link_discard discard;
4832  struct external_nlist *outsym;
4833  bfd_size_type strtab_index;
4834  struct external_nlist *sym;
4835  struct external_nlist *sym_end;
4836  struct aout_link_hash_entry **sym_hash;
4837  int *symbol_map;
4838  bool pass;
4839  bool skip_next;
4840
4841  output_bfd = flaginfo->output_bfd;
4842  sym_count = obj_aout_external_sym_count (input_bfd);
4843  strings = obj_aout_external_strings (input_bfd);
4844  strip = flaginfo->info->strip;
4845  discard = flaginfo->info->discard;
4846  outsym = flaginfo->output_syms;
4847
4848  /* First write out a symbol for this object file, unless we are
4849     discarding such symbols.  */
4850  if (strip != strip_all
4851      && (strip != strip_some
4852	  || bfd_hash_lookup (flaginfo->info->keep_hash,
4853			      bfd_get_filename (input_bfd),
4854			      false, false) != NULL)
4855      && discard != discard_all)
4856    {
4857      H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
4858      H_PUT_8 (output_bfd, 0, outsym->e_other);
4859      H_PUT_16 (output_bfd, 0, outsym->e_desc);
4860      strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab,
4861				       bfd_get_filename (input_bfd), false);
4862      if (strtab_index == (bfd_size_type) -1)
4863	return false;
4864      PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4865      PUT_WORD (output_bfd,
4866		(bfd_section_vma (obj_textsec (input_bfd)->output_section)
4867		 + obj_textsec (input_bfd)->output_offset),
4868		outsym->e_value);
4869      ++obj_aout_external_sym_count (output_bfd);
4870      ++outsym;
4871    }
4872
4873  pass = false;
4874  skip_next = false;
4875  sym = obj_aout_external_syms (input_bfd);
4876  sym_end = sym + sym_count;
4877  sym_hash = obj_aout_sym_hashes (input_bfd);
4878  symbol_map = flaginfo->symbol_map;
4879  memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map);
4880  for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
4881    {
4882      const char *name;
4883      int type;
4884      struct aout_link_hash_entry *h;
4885      bool skip;
4886      asection *symsec;
4887      bfd_vma val = 0;
4888      bool copy;
4889
4890      /* We set *symbol_map to 0 above for all symbols.  If it has
4891	 already been set to -1 for this symbol, it means that we are
4892	 discarding it because it appears in a duplicate header file.
4893	 See the N_BINCL code below.  */
4894      if (*symbol_map == -1)
4895	continue;
4896
4897      /* Initialize *symbol_map to -1, which means that the symbol was
4898	 not copied into the output file.  We will change it later if
4899	 we do copy the symbol over.  */
4900      *symbol_map = -1;
4901
4902      type = H_GET_8 (input_bfd, sym->e_type);
4903      name = strings + GET_WORD (input_bfd, sym->e_strx);
4904
4905      h = NULL;
4906
4907      if (pass)
4908	{
4909	  /* Pass this symbol through.  It is the target of an
4910	     indirect or warning symbol.  */
4911	  val = GET_WORD (input_bfd, sym->e_value);
4912	  pass = false;
4913	}
4914      else if (skip_next)
4915	{
4916	  /* Skip this symbol, which is the target of an indirect
4917	     symbol that we have changed to no longer be an indirect
4918	     symbol.  */
4919	  skip_next = false;
4920	  continue;
4921	}
4922      else
4923	{
4924	  struct aout_link_hash_entry *hresolve;
4925
4926	  /* We have saved the hash table entry for this symbol, if
4927	     there is one.  Note that we could just look it up again
4928	     in the hash table, provided we first check that it is an
4929	     external symbol.  */
4930	  h = *sym_hash;
4931
4932	  /* Use the name from the hash table, in case the symbol was
4933	     wrapped.  */
4934	  if (h != NULL
4935	      && h->root.type != bfd_link_hash_warning)
4936	    name = h->root.root.string;
4937
4938	  /* If this is an indirect or warning symbol, then change
4939	     hresolve to the base symbol.  We also change *sym_hash so
4940	     that the relocation routines relocate against the real
4941	     symbol.  */
4942	  hresolve = h;
4943	  if (h != (struct aout_link_hash_entry *) NULL
4944	      && (h->root.type == bfd_link_hash_indirect
4945		  || h->root.type == bfd_link_hash_warning))
4946	    {
4947	      hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
4948	      while (hresolve->root.type == bfd_link_hash_indirect
4949		     || hresolve->root.type == bfd_link_hash_warning)
4950		hresolve = ((struct aout_link_hash_entry *)
4951			    hresolve->root.u.i.link);
4952	      *sym_hash = hresolve;
4953	    }
4954
4955	  /* If the symbol has already been written out, skip it.  */
4956	  if (h != NULL
4957	      && h->written)
4958	    {
4959	      if ((type & N_TYPE) == N_INDR
4960		  || type == N_WARNING)
4961		skip_next = true;
4962	      *symbol_map = h->indx;
4963	      continue;
4964	    }
4965
4966	  /* See if we are stripping this symbol.  */
4967	  skip = false;
4968	  switch (strip)
4969	    {
4970	    case strip_none:
4971	      break;
4972	    case strip_debugger:
4973	      if ((type & N_STAB) != 0)
4974		skip = true;
4975	      break;
4976	    case strip_some:
4977	      if (bfd_hash_lookup (flaginfo->info->keep_hash, name, false, false)
4978		  == NULL)
4979		skip = true;
4980	      break;
4981	    case strip_all:
4982	      skip = true;
4983	      break;
4984	    }
4985	  if (skip)
4986	    {
4987	      if (h != NULL)
4988		h->written = true;
4989	      continue;
4990	    }
4991
4992	  /* Get the value of the symbol.  */
4993	  if ((type & N_TYPE) == N_TEXT
4994	      || type == N_WEAKT)
4995	    symsec = obj_textsec (input_bfd);
4996	  else if ((type & N_TYPE) == N_DATA
4997		   || type == N_WEAKD)
4998	    symsec = obj_datasec (input_bfd);
4999	  else if ((type & N_TYPE) == N_BSS
5000		   || type == N_WEAKB)
5001	    symsec = obj_bsssec (input_bfd);
5002	  else if ((type & N_TYPE) == N_ABS
5003		   || type == N_WEAKA)
5004	    symsec = bfd_abs_section_ptr;
5005	  else if (((type & N_TYPE) == N_INDR
5006		    && (hresolve == NULL
5007			|| (hresolve->root.type != bfd_link_hash_defined
5008			    && hresolve->root.type != bfd_link_hash_defweak
5009			    && hresolve->root.type != bfd_link_hash_common)))
5010		   || type == N_WARNING)
5011	    {
5012	      /* Pass the next symbol through unchanged.  The
5013		 condition above for indirect symbols is so that if
5014		 the indirect symbol was defined, we output it with
5015		 the correct definition so the debugger will
5016		 understand it.  */
5017	      pass = true;
5018	      val = GET_WORD (input_bfd, sym->e_value);
5019	      symsec = NULL;
5020	    }
5021	  else if ((type & N_STAB) != 0)
5022	    {
5023	      val = GET_WORD (input_bfd, sym->e_value);
5024	      symsec = NULL;
5025	    }
5026	  else
5027	    {
5028	      /* If we get here with an indirect symbol, it means that
5029		 we are outputting it with a real definition.  In such
5030		 a case we do not want to output the next symbol,
5031		 which is the target of the indirection.  */
5032	      if ((type & N_TYPE) == N_INDR)
5033		skip_next = true;
5034
5035	      symsec = NULL;
5036
5037	      /* We need to get the value from the hash table.  We use
5038		 hresolve so that if we have defined an indirect
5039		 symbol we output the final definition.  */
5040	      if (h == NULL)
5041		{
5042		  switch (type & N_TYPE)
5043		    {
5044		    case N_SETT:
5045		      symsec = obj_textsec (input_bfd);
5046		      break;
5047		    case N_SETD:
5048		      symsec = obj_datasec (input_bfd);
5049		      break;
5050		    case N_SETB:
5051		      symsec = obj_bsssec (input_bfd);
5052		      break;
5053		    case N_SETA:
5054		      symsec = bfd_abs_section_ptr;
5055		      break;
5056		    default:
5057		      val = 0;
5058		      break;
5059		    }
5060		}
5061	      else if (hresolve->root.type == bfd_link_hash_defined
5062		       || hresolve->root.type == bfd_link_hash_defweak)
5063		{
5064		  asection *input_section;
5065		  asection *output_section;
5066
5067		  /* This case usually means a common symbol which was
5068		     turned into a defined symbol.  */
5069		  input_section = hresolve->root.u.def.section;
5070		  output_section = input_section->output_section;
5071		  BFD_ASSERT (bfd_is_abs_section (output_section)
5072			      || output_section->owner == output_bfd);
5073		  val = (hresolve->root.u.def.value
5074			 + bfd_section_vma (output_section)
5075			 + input_section->output_offset);
5076
5077		  /* Get the correct type based on the section.  If
5078		     this is a constructed set, force it to be
5079		     globally visible.  */
5080		  if (type == N_SETT
5081		      || type == N_SETD
5082		      || type == N_SETB
5083		      || type == N_SETA)
5084		    type |= N_EXT;
5085
5086		  type &=~ N_TYPE;
5087
5088		  if (output_section == obj_textsec (output_bfd))
5089		    type |= (hresolve->root.type == bfd_link_hash_defined
5090			     ? N_TEXT
5091			     : N_WEAKT);
5092		  else if (output_section == obj_datasec (output_bfd))
5093		    type |= (hresolve->root.type == bfd_link_hash_defined
5094			     ? N_DATA
5095			     : N_WEAKD);
5096		  else if (output_section == obj_bsssec (output_bfd))
5097		    type |= (hresolve->root.type == bfd_link_hash_defined
5098			     ? N_BSS
5099			     : N_WEAKB);
5100		  else
5101		    type |= (hresolve->root.type == bfd_link_hash_defined
5102			     ? N_ABS
5103			     : N_WEAKA);
5104		}
5105	      else if (hresolve->root.type == bfd_link_hash_common)
5106		val = hresolve->root.u.c.size;
5107	      else if (hresolve->root.type == bfd_link_hash_undefweak)
5108		{
5109		  val = 0;
5110		  type = N_WEAKU;
5111		}
5112	      else
5113		val = 0;
5114	    }
5115	  if (symsec != NULL)
5116	    val = (symsec->output_section->vma
5117		   + symsec->output_offset
5118		   + (GET_WORD (input_bfd, sym->e_value)
5119		      - symsec->vma));
5120
5121	  /* If this is a global symbol set the written flag, and if
5122	     it is a local symbol see if we should discard it.  */
5123	  if (h != NULL)
5124	    {
5125	      h->written = true;
5126	      h->indx = obj_aout_external_sym_count (output_bfd);
5127	    }
5128	  else if ((type & N_TYPE) != N_SETT
5129		   && (type & N_TYPE) != N_SETD
5130		   && (type & N_TYPE) != N_SETB
5131		   && (type & N_TYPE) != N_SETA)
5132	    {
5133	      switch (discard)
5134		{
5135		case discard_none:
5136		case discard_sec_merge:
5137		  break;
5138		case discard_l:
5139		  if ((type & N_STAB) == 0
5140		      && bfd_is_local_label_name (input_bfd, name))
5141		    skip = true;
5142		  break;
5143		case discard_all:
5144		  skip = true;
5145		  break;
5146		}
5147	      if (skip)
5148		{
5149		  pass = false;
5150		  continue;
5151		}
5152	    }
5153
5154	  /* An N_BINCL symbol indicates the start of the stabs
5155	     entries for a header file.  We need to scan ahead to the
5156	     next N_EINCL symbol, ignoring nesting, adding up all the
5157	     characters in the symbol names, not including the file
5158	     numbers in types (the first number after an open
5159	     parenthesis).  */
5160	  if (type == (int) N_BINCL)
5161	    {
5162	      struct external_nlist *incl_sym;
5163	      int nest;
5164	      struct aout_link_includes_entry *incl_entry;
5165	      struct aout_link_includes_totals *t;
5166
5167	      val = 0;
5168	      nest = 0;
5169	      for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
5170		{
5171		  int incl_type;
5172
5173		  incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
5174		  if (incl_type == (int) N_EINCL)
5175		    {
5176		      if (nest == 0)
5177			break;
5178		      --nest;
5179		    }
5180		  else if (incl_type == (int) N_BINCL)
5181		    ++nest;
5182		  else if (nest == 0)
5183		    {
5184		      const char *s;
5185
5186		      s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
5187		      for (; *s != '\0'; s++)
5188			{
5189			  val += *s;
5190			  if (*s == '(')
5191			    {
5192			      /* Skip the file number.  */
5193			      ++s;
5194			      while (ISDIGIT (*s))
5195				++s;
5196			      --s;
5197			    }
5198			}
5199		    }
5200		}
5201
5202	      /* If we have already included a header file with the
5203		 same value, then replace this one with an N_EXCL
5204		 symbol.  */
5205	      copy = !flaginfo->info->keep_memory;
5206	      incl_entry = aout_link_includes_lookup (&flaginfo->includes,
5207						      name, true, copy);
5208	      if (incl_entry == NULL)
5209		return false;
5210	      for (t = incl_entry->totals; t != NULL; t = t->next)
5211		if (t->total == val)
5212		  break;
5213	      if (t == NULL)
5214		{
5215		  /* This is the first time we have seen this header
5216		     file with this set of stabs strings.  */
5217		  t = (struct aout_link_includes_totals *)
5218		      bfd_hash_allocate (&flaginfo->includes.root,
5219					 sizeof *t);
5220		  if (t == NULL)
5221		    return false;
5222		  t->total = val;
5223		  t->next = incl_entry->totals;
5224		  incl_entry->totals = t;
5225		}
5226	      else
5227		{
5228		  int *incl_map;
5229
5230		  /* This is a duplicate header file.  We must change
5231		     it to be an N_EXCL entry, and mark all the
5232		     included symbols to prevent outputting them.  */
5233		  type = (int) N_EXCL;
5234
5235		  nest = 0;
5236		  for (incl_sym = sym + 1, incl_map = symbol_map + 1;
5237		       incl_sym < sym_end;
5238		       incl_sym++, incl_map++)
5239		    {
5240		      int incl_type;
5241
5242		      incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
5243		      if (incl_type == (int) N_EINCL)
5244			{
5245			  if (nest == 0)
5246			    {
5247			      *incl_map = -1;
5248			      break;
5249			    }
5250			  --nest;
5251			}
5252		      else if (incl_type == (int) N_BINCL)
5253			++nest;
5254		      else if (nest == 0)
5255			*incl_map = -1;
5256		    }
5257		}
5258	    }
5259	}
5260
5261      /* Copy this symbol into the list of symbols we are going to
5262	 write out.  */
5263      H_PUT_8 (output_bfd, type, outsym->e_type);
5264      H_PUT_8 (output_bfd, H_GET_8 (input_bfd, sym->e_other), outsym->e_other);
5265      H_PUT_16 (output_bfd, H_GET_16 (input_bfd, sym->e_desc), outsym->e_desc);
5266      copy = false;
5267      if (! flaginfo->info->keep_memory)
5268	{
5269	  /* name points into a string table which we are going to
5270	     free.  If there is a hash table entry, use that string.
5271	     Otherwise, copy name into memory.  */
5272	  if (h != NULL)
5273	    name = h->root.root.string;
5274	  else
5275	    copy = true;
5276	}
5277      strtab_index = add_to_stringtab (output_bfd, flaginfo->strtab,
5278				       name, copy);
5279      if (strtab_index == (bfd_size_type) -1)
5280	return false;
5281      PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
5282      PUT_WORD (output_bfd, val, outsym->e_value);
5283      *symbol_map = obj_aout_external_sym_count (output_bfd);
5284      ++obj_aout_external_sym_count (output_bfd);
5285      ++outsym;
5286    }
5287
5288  /* Write out the output symbols we have just constructed.  */
5289  if (outsym > flaginfo->output_syms)
5290    {
5291      bfd_size_type outsym_size;
5292
5293      if (bfd_seek (output_bfd, flaginfo->symoff, SEEK_SET) != 0)
5294	return false;
5295      outsym_size = outsym - flaginfo->output_syms;
5296      outsym_size *= EXTERNAL_NLIST_SIZE;
5297      if (bfd_bwrite ((void *) flaginfo->output_syms, outsym_size, output_bfd)
5298	  != outsym_size)
5299	return false;
5300      flaginfo->symoff += outsym_size;
5301    }
5302
5303  return true;
5304}
5305
5306/* Link an a.out input BFD into the output file.  */
5307
5308static bool
5309aout_link_input_bfd (struct aout_final_link_info *flaginfo, bfd *input_bfd)
5310{
5311  BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
5312
5313  /* If this is a dynamic object, it may need special handling.  */
5314  if ((input_bfd->flags & DYNAMIC) != 0
5315      && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
5316    return ((*aout_backend_info (input_bfd)->link_dynamic_object)
5317	    (flaginfo->info, input_bfd));
5318
5319  /* Get the symbols.  We probably have them already, unless
5320     flaginfo->info->keep_memory is FALSE.  */
5321  if (! aout_get_external_symbols (input_bfd))
5322    return false;
5323
5324  /* Write out the symbols and get a map of the new indices.  The map
5325     is placed into flaginfo->symbol_map.  */
5326  if (! aout_link_write_symbols (flaginfo, input_bfd))
5327    return false;
5328
5329  /* Relocate and write out the sections.  These functions use the
5330     symbol map created by aout_link_write_symbols.  The linker_mark
5331     field will be set if these sections are to be included in the
5332     link, which will normally be the case.  */
5333  if (obj_textsec (input_bfd)->linker_mark)
5334    {
5335      if (! aout_link_input_section (flaginfo, input_bfd,
5336				     obj_textsec (input_bfd),
5337				     &flaginfo->treloff,
5338				     exec_hdr (input_bfd)->a_trsize))
5339	return false;
5340    }
5341  if (obj_datasec (input_bfd)->linker_mark)
5342    {
5343      if (! aout_link_input_section (flaginfo, input_bfd,
5344				     obj_datasec (input_bfd),
5345				     &flaginfo->dreloff,
5346				     exec_hdr (input_bfd)->a_drsize))
5347	return false;
5348    }
5349
5350  /* If we are not keeping memory, we don't need the symbols any
5351     longer.  We still need them if we are keeping memory, because the
5352     strings in the hash table point into them.  */
5353  if (! flaginfo->info->keep_memory)
5354    {
5355      if (! aout_link_free_symbols (input_bfd))
5356	return false;
5357    }
5358
5359  return true;
5360}
5361
5362/* Do the final link step.  This is called on the output BFD.  The
5363   INFO structure should point to a list of BFDs linked through the
5364   link.next field which can be used to find each BFD which takes part
5365   in the output.  Also, each section in ABFD should point to a list
5366   of bfd_link_order structures which list all the input sections for
5367   the output section.  */
5368
5369bool
5370NAME (aout, final_link) (bfd *abfd,
5371			 struct bfd_link_info *info,
5372			 void (*callback) (bfd *, file_ptr *, file_ptr *, file_ptr *))
5373{
5374  struct aout_final_link_info aout_info;
5375  bool includes_hash_initialized = false;
5376  bfd *sub;
5377  bfd_size_type trsize, drsize;
5378  bfd_size_type max_contents_size;
5379  bfd_size_type max_relocs_size;
5380  bfd_size_type max_sym_count;
5381  struct bfd_link_order *p;
5382  asection *o;
5383  bool have_link_order_relocs;
5384
5385  if (bfd_link_pic (info))
5386    abfd->flags |= DYNAMIC;
5387
5388  aout_info.info = info;
5389  aout_info.output_bfd = abfd;
5390  aout_info.contents = NULL;
5391  aout_info.relocs = NULL;
5392  aout_info.symbol_map = NULL;
5393  aout_info.output_syms = NULL;
5394
5395  if (!bfd_hash_table_init_n (&aout_info.includes.root,
5396			      aout_link_includes_newfunc,
5397			      sizeof (struct aout_link_includes_entry),
5398			      251))
5399    goto error_return;
5400  includes_hash_initialized = true;
5401
5402  /* Figure out the largest section size.  Also, if generating
5403     relocatable output, count the relocs.  */
5404  trsize = 0;
5405  drsize = 0;
5406  max_contents_size = 0;
5407  max_relocs_size = 0;
5408  max_sym_count = 0;
5409  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
5410    {
5411      bfd_size_type sz;
5412
5413      if (bfd_link_relocatable (info))
5414	{
5415	  if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
5416	    {
5417	      trsize += exec_hdr (sub)->a_trsize;
5418	      drsize += exec_hdr (sub)->a_drsize;
5419	    }
5420	  else
5421	    {
5422	      /* FIXME: We need to identify the .text and .data sections
5423		 and call get_reloc_upper_bound and canonicalize_reloc to
5424		 work out the number of relocs needed, and then multiply
5425		 by the reloc size.  */
5426	      _bfd_error_handler
5427		/* xgettext:c-format */
5428		(_("%pB: relocatable link from %s to %s not supported"),
5429		 abfd, sub->xvec->name, abfd->xvec->name);
5430	      bfd_set_error (bfd_error_invalid_operation);
5431	      goto error_return;
5432	    }
5433	}
5434
5435      if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
5436	{
5437	  sz = obj_textsec (sub)->size;
5438	  if (sz > max_contents_size)
5439	    max_contents_size = sz;
5440	  sz = obj_datasec (sub)->size;
5441	  if (sz > max_contents_size)
5442	    max_contents_size = sz;
5443
5444	  sz = exec_hdr (sub)->a_trsize;
5445	  if (sz > max_relocs_size)
5446	    max_relocs_size = sz;
5447	  sz = exec_hdr (sub)->a_drsize;
5448	  if (sz > max_relocs_size)
5449	    max_relocs_size = sz;
5450
5451	  sz = obj_aout_external_sym_count (sub);
5452	  if (sz > max_sym_count)
5453	    max_sym_count = sz;
5454	}
5455    }
5456
5457  if (bfd_link_relocatable (info))
5458    {
5459      if (obj_textsec (abfd) != NULL)
5460	trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
5461						 ->map_head.link_order)
5462		   * obj_reloc_entry_size (abfd));
5463      if (obj_datasec (abfd) != NULL)
5464	drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
5465						 ->map_head.link_order)
5466		   * obj_reloc_entry_size (abfd));
5467    }
5468
5469  exec_hdr (abfd)->a_trsize = trsize;
5470  exec_hdr (abfd)->a_drsize = drsize;
5471
5472  exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
5473
5474  /* Adjust the section sizes and vmas according to the magic number.
5475     This sets a_text, a_data and a_bss in the exec_hdr and sets the
5476     filepos for each section.  */
5477  if (! NAME (aout, adjust_sizes_and_vmas) (abfd))
5478    goto error_return;
5479
5480  /* The relocation and symbol file positions differ among a.out
5481     targets.  We are passed a callback routine from the backend
5482     specific code to handle this.
5483     FIXME: At this point we do not know how much space the symbol
5484     table will require.  This will not work for any (nonstandard)
5485     a.out target that needs to know the symbol table size before it
5486     can compute the relocation file positions.  */
5487  (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
5488	       &aout_info.symoff);
5489  obj_textsec (abfd)->rel_filepos = aout_info.treloff;
5490  obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
5491  obj_sym_filepos (abfd) = aout_info.symoff;
5492
5493  /* We keep a count of the symbols as we output them.  */
5494  obj_aout_external_sym_count (abfd) = 0;
5495
5496  /* We accumulate the string table as we write out the symbols.  */
5497  aout_info.strtab = _bfd_stringtab_init ();
5498  if (aout_info.strtab == NULL)
5499    goto error_return;
5500
5501  /* Allocate buffers to hold section contents and relocs.  */
5502  aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size);
5503  aout_info.relocs = bfd_malloc (max_relocs_size);
5504  aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int));
5505  aout_info.output_syms = (struct external_nlist *)
5506      bfd_malloc ((max_sym_count + 1) * sizeof (struct external_nlist));
5507  if ((aout_info.contents == NULL && max_contents_size != 0)
5508      || (aout_info.relocs == NULL && max_relocs_size != 0)
5509      || (aout_info.symbol_map == NULL && max_sym_count != 0)
5510      || aout_info.output_syms == NULL)
5511    goto error_return;
5512
5513  /* If we have a symbol named __DYNAMIC, force it out now.  This is
5514     required by SunOS.  Doing this here rather than in sunos.c is a
5515     hack, but it's easier than exporting everything which would be
5516     needed.  */
5517  {
5518    struct aout_link_hash_entry *h;
5519
5520    h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
5521			       false, false, false);
5522    if (h != NULL)
5523      aout_link_write_other_symbol (&h->root.root, &aout_info);
5524  }
5525
5526  /* The most time efficient way to do the link would be to read all
5527     the input object files into memory and then sort out the
5528     information into the output file.  Unfortunately, that will
5529     probably use too much memory.  Another method would be to step
5530     through everything that composes the text section and write it
5531     out, and then everything that composes the data section and write
5532     it out, and then write out the relocs, and then write out the
5533     symbols.  Unfortunately, that requires reading stuff from each
5534     input file several times, and we will not be able to keep all the
5535     input files open simultaneously, and reopening them will be slow.
5536
5537     What we do is basically process one input file at a time.  We do
5538     everything we need to do with an input file once--copy over the
5539     section contents, handle the relocation information, and write
5540     out the symbols--and then we throw away the information we read
5541     from it.  This approach requires a lot of lseeks of the output
5542     file, which is unfortunate but still faster than reopening a lot
5543     of files.
5544
5545     We use the output_has_begun field of the input BFDs to see
5546     whether we have already handled it.  */
5547  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
5548    sub->output_has_begun = false;
5549
5550  /* Mark all sections which are to be included in the link.  This
5551     will normally be every section.  We need to do this so that we
5552     can identify any sections which the linker has decided to not
5553     include.  */
5554  for (o = abfd->sections; o != NULL; o = o->next)
5555    {
5556      for (p = o->map_head.link_order; p != NULL; p = p->next)
5557	if (p->type == bfd_indirect_link_order)
5558	  p->u.indirect.section->linker_mark = true;
5559    }
5560
5561  have_link_order_relocs = false;
5562  for (o = abfd->sections; o != NULL; o = o->next)
5563    {
5564      for (p = o->map_head.link_order;
5565	   p != NULL;
5566	   p = p->next)
5567	{
5568	  if (p->type == bfd_indirect_link_order
5569	      && (bfd_get_flavour (p->u.indirect.section->owner)
5570		  == bfd_target_aout_flavour))
5571	    {
5572	      bfd *input_bfd;
5573
5574	      input_bfd = p->u.indirect.section->owner;
5575	      if (! input_bfd->output_has_begun)
5576		{
5577		  if (! aout_link_input_bfd (&aout_info, input_bfd))
5578		    goto error_return;
5579		  input_bfd->output_has_begun = true;
5580		}
5581	    }
5582	  else if (p->type == bfd_section_reloc_link_order
5583		   || p->type == bfd_symbol_reloc_link_order)
5584	    {
5585	      /* These are handled below.  */
5586	      have_link_order_relocs = true;
5587	    }
5588	  else
5589	    {
5590	      if (! _bfd_default_link_order (abfd, info, o, p))
5591		goto error_return;
5592	    }
5593	}
5594    }
5595
5596  /* Write out any symbols that we have not already written out.  */
5597  bfd_hash_traverse (&info->hash->table,
5598		     aout_link_write_other_symbol,
5599		     &aout_info);
5600
5601  /* Now handle any relocs we were asked to create by the linker.
5602     These did not come from any input file.  We must do these after
5603     we have written out all the symbols, so that we know the symbol
5604     indices to use.  */
5605  if (have_link_order_relocs)
5606    {
5607      for (o = abfd->sections; o != NULL; o = o->next)
5608	{
5609	  for (p = o->map_head.link_order;
5610	       p != NULL;
5611	       p = p->next)
5612	    {
5613	      if (p->type == bfd_section_reloc_link_order
5614		  || p->type == bfd_symbol_reloc_link_order)
5615		{
5616		  if (! aout_link_reloc_link_order (&aout_info, o, p))
5617		    goto error_return;
5618		}
5619	    }
5620	}
5621    }
5622
5623  free (aout_info.contents);
5624  aout_info.contents = NULL;
5625  free (aout_info.relocs);
5626  aout_info.relocs = NULL;
5627  free (aout_info.symbol_map);
5628  aout_info.symbol_map = NULL;
5629  free (aout_info.output_syms);
5630  aout_info.output_syms = NULL;
5631
5632  if (includes_hash_initialized)
5633    {
5634      bfd_hash_table_free (&aout_info.includes.root);
5635      includes_hash_initialized = false;
5636    }
5637
5638  /* Finish up any dynamic linking we may be doing.  */
5639  if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
5640    {
5641      if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
5642	goto error_return;
5643    }
5644
5645  /* Update the header information.  */
5646  abfd->symcount = obj_aout_external_sym_count (abfd);
5647  exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
5648  obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
5649  obj_textsec (abfd)->reloc_count =
5650    exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
5651  obj_datasec (abfd)->reloc_count =
5652    exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
5653
5654  /* Write out the string table, unless there are no symbols.  */
5655  if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
5656    goto error_return;
5657  if (abfd->symcount > 0)
5658    {
5659      if (!emit_stringtab (abfd, aout_info.strtab))
5660	goto error_return;
5661    }
5662  else
5663    {
5664      bfd_byte b[BYTES_IN_WORD];
5665
5666      memset (b, 0, BYTES_IN_WORD);
5667      if (bfd_bwrite (b, (bfd_size_type) BYTES_IN_WORD, abfd) != BYTES_IN_WORD)
5668	goto error_return;
5669    }
5670
5671  return true;
5672
5673 error_return:
5674  free (aout_info.contents);
5675  free (aout_info.relocs);
5676  free (aout_info.symbol_map);
5677  free (aout_info.output_syms);
5678  if (includes_hash_initialized)
5679    bfd_hash_table_free (&aout_info.includes.root);
5680  return false;
5681}
5682