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