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