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