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