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