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