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