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