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