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