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