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