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