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