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