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