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