* libaout.h (WRITE_HEADERS): Write out the relocs even if there
[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 = N_ABS;
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 = N_ABS;
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 (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
3186     {
3187       if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
3188              (abfd, info, &syms, &sym_count, &strings)))
3189         return false;
3190     }
3191
3192   /* We keep a list of the linker hash table entries that correspond
3193      to particular symbols.  We could just look them up in the hash
3194      table, but keeping the list is more efficient.  Perhaps this
3195      should be conditional on info->keep_memory.  */
3196   sym_hash = ((struct aout_link_hash_entry **)
3197               bfd_alloc (abfd,
3198                          ((size_t) sym_count
3199                           * sizeof (struct aout_link_hash_entry *))));
3200   if (sym_hash == NULL && sym_count != 0)
3201     return false;
3202   obj_aout_sym_hashes (abfd) = sym_hash;
3203
3204   add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
3205   if (add_one_symbol == NULL)
3206     add_one_symbol = _bfd_generic_link_add_one_symbol;
3207
3208   p = syms;
3209   pend = p + sym_count;
3210   for (; p < pend; p++, sym_hash++)
3211     {
3212       int type;
3213       const char *name;
3214       bfd_vma value;
3215       asection *section;
3216       flagword flags;
3217       const char *string;
3218
3219       *sym_hash = NULL;
3220
3221       type = bfd_h_get_8 (abfd, p->e_type);
3222
3223       /* Ignore debugging symbols.  */
3224       if ((type & N_STAB) != 0)
3225         continue;
3226
3227       name = strings + GET_WORD (abfd, p->e_strx);
3228       value = GET_WORD (abfd, p->e_value);
3229       flags = BSF_GLOBAL;
3230       string = NULL;
3231       switch (type)
3232         {
3233         default:
3234           abort ();
3235
3236         case N_UNDF:
3237         case N_ABS:
3238         case N_TEXT:
3239         case N_DATA:
3240         case N_BSS:
3241         case N_FN_SEQ:
3242         case N_COMM:
3243         case N_SETV:
3244         case N_FN:
3245           /* Ignore symbols that are not externally visible.  */
3246           continue;
3247         case N_INDR:
3248           /* Ignore local indirect symbol.  */
3249           ++p;
3250           ++sym_hash;
3251           continue;
3252
3253         case N_UNDF | N_EXT:
3254           if (value == 0)
3255             {
3256               section = bfd_und_section_ptr;
3257               flags = 0;
3258             }
3259           else
3260             section = bfd_com_section_ptr;
3261           break;
3262         case N_ABS | N_EXT:
3263           section = bfd_abs_section_ptr;
3264           break;
3265         case N_TEXT | N_EXT:
3266           section = obj_textsec (abfd);
3267           value -= bfd_get_section_vma (abfd, section);
3268           break;
3269         case N_DATA | N_EXT:
3270         case N_SETV | N_EXT:
3271           /* Treat N_SETV symbols as N_DATA symbol; see comment in
3272              translate_from_native_sym_flags.  */
3273           section = obj_datasec (abfd);
3274           value -= bfd_get_section_vma (abfd, section);
3275           break;
3276         case N_BSS | N_EXT:
3277           section = obj_bsssec (abfd);
3278           value -= bfd_get_section_vma (abfd, section);
3279           break;
3280         case N_INDR | N_EXT:
3281           /* An indirect symbol.  The next symbol is the symbol
3282              which this one really is.  */
3283           BFD_ASSERT (p + 1 < pend);
3284           ++p;
3285           string = strings + GET_WORD (abfd, p->e_strx);
3286           section = bfd_ind_section_ptr;
3287           flags |= BSF_INDIRECT;
3288           break;
3289         case N_COMM | N_EXT:
3290           section = bfd_com_section_ptr;
3291           break;
3292         case N_SETA: case N_SETA | N_EXT:
3293           section = bfd_abs_section_ptr;
3294           flags |= BSF_CONSTRUCTOR;
3295           break;
3296         case N_SETT: case N_SETT | N_EXT:
3297           section = obj_textsec (abfd);
3298           flags |= BSF_CONSTRUCTOR;
3299           value -= bfd_get_section_vma (abfd, section);
3300           break;
3301         case N_SETD: case N_SETD | N_EXT:
3302           section = obj_datasec (abfd);
3303           flags |= BSF_CONSTRUCTOR;
3304           value -= bfd_get_section_vma (abfd, section);
3305           break;
3306         case N_SETB: case N_SETB | N_EXT:
3307           section = obj_bsssec (abfd);
3308           flags |= BSF_CONSTRUCTOR;
3309           value -= bfd_get_section_vma (abfd, section);
3310           break;
3311         case N_WARNING:
3312           /* A warning symbol.  The next symbol is the one to warn
3313              about.  */
3314           BFD_ASSERT (p + 1 < pend);
3315           ++p;
3316           string = name;
3317           name = strings + GET_WORD (abfd, p->e_strx);
3318           section = bfd_und_section_ptr;
3319           flags |= BSF_WARNING;
3320           break;
3321         case N_WEAKU:
3322           section = bfd_und_section_ptr;
3323           flags = BSF_WEAK;
3324           break;
3325         case N_WEAKA:
3326           section = bfd_abs_section_ptr;
3327           flags = BSF_WEAK;
3328           break;
3329         case N_WEAKT:
3330           section = obj_textsec (abfd);
3331           value -= bfd_get_section_vma (abfd, section);
3332           flags = BSF_WEAK;
3333           break;
3334         case N_WEAKD:
3335           section = obj_datasec (abfd);
3336           value -= bfd_get_section_vma (abfd, section);
3337           flags = BSF_WEAK;
3338           break;
3339         case N_WEAKB:
3340           section = obj_bsssec (abfd);
3341           value -= bfd_get_section_vma (abfd, section);
3342           flags = BSF_WEAK;
3343           break;
3344         }
3345
3346       if (! ((*add_one_symbol)
3347              (info, abfd, name, flags, section, value, string, copy, false,
3348               (struct bfd_link_hash_entry **) sym_hash)))
3349         return false;
3350
3351       /* Restrict the maximum alignment of a common symbol based on
3352          the architecture, since a.out has no way to represent
3353          alignment requirements of a section in a .o file.  FIXME:
3354          This isn't quite right: it should use the architecture of the
3355          output file, not the input files.  */
3356       if ((*sym_hash)->root.type == bfd_link_hash_common
3357           && ((*sym_hash)->root.u.c.p->alignment_power >
3358               bfd_get_arch_info (abfd)->section_align_power))
3359         (*sym_hash)->root.u.c.p->alignment_power =
3360           bfd_get_arch_info (abfd)->section_align_power;
3361
3362       /* If this is a set symbol, and we are not building sets, then
3363          it is possible for the hash entry to not have been set.  In
3364          such a case, treat the symbol as not globally defined.  */
3365       if ((*sym_hash)->root.type == bfd_link_hash_new)
3366         {
3367           BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
3368           *sym_hash = NULL;
3369         }
3370
3371       if (type == (N_INDR | N_EXT) || type == N_WARNING)
3372         ++sym_hash;
3373     }
3374
3375   return true;
3376 }
3377 \f
3378 /* A hash table used for header files with N_BINCL entries.  */
3379
3380 struct aout_link_includes_table
3381 {
3382   struct bfd_hash_table root;
3383 };
3384
3385 /* A linked list of totals that we have found for a particular header
3386    file.  */
3387
3388 struct aout_link_includes_totals
3389 {
3390   struct aout_link_includes_totals *next;
3391   bfd_vma total;
3392 };
3393
3394 /* An entry in the header file hash table.  */
3395
3396 struct aout_link_includes_entry
3397 {
3398   struct bfd_hash_entry root;
3399   /* List of totals we have found for this file.  */
3400   struct aout_link_includes_totals *totals;
3401 };
3402
3403 /* Look up an entry in an the header file hash table.  */
3404
3405 #define aout_link_includes_lookup(table, string, create, copy) \
3406   ((struct aout_link_includes_entry *) \
3407    bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
3408
3409 /* During the final link step we need to pass around a bunch of
3410    information, so we do it in an instance of this structure.  */
3411
3412 struct aout_final_link_info
3413 {
3414   /* General link information.  */
3415   struct bfd_link_info *info;
3416   /* Output bfd.  */
3417   bfd *output_bfd;
3418   /* Reloc file positions.  */
3419   file_ptr treloff, dreloff;
3420   /* File position of symbols.  */
3421   file_ptr symoff;
3422   /* String table.  */
3423   struct bfd_strtab_hash *strtab;
3424   /* Header file hash table.  */
3425   struct aout_link_includes_table includes;
3426   /* A buffer large enough to hold the contents of any section.  */
3427   bfd_byte *contents;
3428   /* A buffer large enough to hold the relocs of any section.  */
3429   PTR relocs;
3430   /* A buffer large enough to hold the symbol map of any input BFD.  */
3431   int *symbol_map;
3432   /* A buffer large enough to hold output symbols of any input BFD.  */
3433   struct external_nlist *output_syms;
3434 };
3435
3436 static struct bfd_hash_entry *aout_link_includes_newfunc
3437   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
3438 static boolean aout_link_input_bfd
3439   PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3440 static boolean aout_link_write_symbols
3441   PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3442 static boolean aout_link_write_other_symbol
3443   PARAMS ((struct aout_link_hash_entry *, PTR));
3444 static boolean aout_link_input_section
3445   PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3446            asection *input_section, file_ptr *reloff_ptr,
3447            bfd_size_type rel_size));
3448 static boolean aout_link_input_section_std
3449   PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3450            asection *input_section, struct reloc_std_external *,
3451            bfd_size_type rel_size, bfd_byte *contents));
3452 static boolean aout_link_input_section_ext
3453   PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3454            asection *input_section, struct reloc_ext_external *,
3455            bfd_size_type rel_size, bfd_byte *contents));
3456 static INLINE asection *aout_reloc_index_to_section
3457   PARAMS ((bfd *, int));
3458 static boolean aout_link_reloc_link_order
3459   PARAMS ((struct aout_final_link_info *, asection *,
3460            struct bfd_link_order *));
3461
3462 /* The function to create a new entry in the header file hash table.  */
3463
3464 static struct bfd_hash_entry *
3465 aout_link_includes_newfunc (entry, table, string)
3466      struct bfd_hash_entry *entry;
3467      struct bfd_hash_table *table;
3468      const char *string;
3469 {
3470   struct aout_link_includes_entry *ret =
3471     (struct aout_link_includes_entry *) entry;
3472
3473   /* Allocate the structure if it has not already been allocated by a
3474      subclass.  */
3475   if (ret == (struct aout_link_includes_entry *) NULL)
3476     ret = ((struct aout_link_includes_entry *)
3477            bfd_hash_allocate (table,
3478                               sizeof (struct aout_link_includes_entry)));
3479   if (ret == (struct aout_link_includes_entry *) NULL)
3480     return (struct bfd_hash_entry *) ret;
3481
3482   /* Call the allocation method of the superclass.  */
3483   ret = ((struct aout_link_includes_entry *)
3484          bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
3485   if (ret)
3486     {
3487       /* Set local fields.  */
3488       ret->totals = NULL;
3489     }
3490
3491   return (struct bfd_hash_entry *) ret;
3492 }
3493
3494 /* Do the final link step.  This is called on the output BFD.  The
3495    INFO structure should point to a list of BFDs linked through the
3496    link_next field which can be used to find each BFD which takes part
3497    in the output.  Also, each section in ABFD should point to a list
3498    of bfd_link_order structures which list all the input sections for
3499    the output section.  */
3500
3501 boolean
3502 NAME(aout,final_link) (abfd, info, callback)
3503      bfd *abfd;
3504      struct bfd_link_info *info;
3505      void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
3506 {
3507   struct aout_final_link_info aout_info;
3508   boolean includes_hash_initialized = false;
3509   register bfd *sub;
3510   bfd_size_type trsize, drsize;
3511   size_t max_contents_size;
3512   size_t max_relocs_size;
3513   size_t max_sym_count;
3514   bfd_size_type text_size;
3515   file_ptr text_end;
3516   register struct bfd_link_order *p;
3517   asection *o;
3518   boolean have_link_order_relocs;
3519
3520   if (info->shared)
3521     abfd->flags |= DYNAMIC;
3522
3523   aout_info.info = info;
3524   aout_info.output_bfd = abfd;
3525   aout_info.contents = NULL;
3526   aout_info.relocs = NULL;
3527   aout_info.symbol_map = NULL;
3528   aout_info.output_syms = NULL;
3529
3530   if (! bfd_hash_table_init_n (&aout_info.includes.root,
3531                                aout_link_includes_newfunc,
3532                                251))
3533     goto error_return;
3534   includes_hash_initialized = true;
3535
3536   /* Figure out the largest section size.  Also, if generating
3537      relocateable output, count the relocs.  */
3538   trsize = 0;
3539   drsize = 0;
3540   max_contents_size = 0;
3541   max_relocs_size = 0;
3542   max_sym_count = 0;
3543   for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
3544     {
3545       size_t sz;
3546
3547       if (info->relocateable)
3548         {
3549           if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3550             {
3551               trsize += exec_hdr (sub)->a_trsize;
3552               drsize += exec_hdr (sub)->a_drsize;
3553             }
3554           else
3555             {
3556               /* FIXME: We need to identify the .text and .data sections
3557                  and call get_reloc_upper_bound and canonicalize_reloc to
3558                  work out the number of relocs needed, and then multiply
3559                  by the reloc size.  */
3560               (*_bfd_error_handler)
3561                 ("%s: relocateable link from %s to %s not supported",
3562                  bfd_get_filename (abfd),
3563                  sub->xvec->name, abfd->xvec->name);
3564               bfd_set_error (bfd_error_invalid_operation);
3565               goto error_return;
3566             }
3567         }
3568
3569       if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3570         {
3571           sz = bfd_section_size (sub, obj_textsec (sub));
3572           if (sz > max_contents_size)
3573             max_contents_size = sz;
3574           sz = bfd_section_size (sub, obj_datasec (sub));
3575           if (sz > max_contents_size)
3576             max_contents_size = sz;
3577
3578           sz = exec_hdr (sub)->a_trsize;
3579           if (sz > max_relocs_size)
3580             max_relocs_size = sz;
3581           sz = exec_hdr (sub)->a_drsize;
3582           if (sz > max_relocs_size)
3583             max_relocs_size = sz;
3584
3585           sz = obj_aout_external_sym_count (sub);
3586           if (sz > max_sym_count)
3587             max_sym_count = sz;
3588         }
3589     }
3590
3591   if (info->relocateable)
3592     {
3593       if (obj_textsec (abfd) != (asection *) NULL)
3594         trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
3595                                                  ->link_order_head)
3596                    * obj_reloc_entry_size (abfd));
3597       if (obj_datasec (abfd) != (asection *) NULL)
3598         drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
3599                                                  ->link_order_head)
3600                    * obj_reloc_entry_size (abfd));
3601     }
3602
3603   exec_hdr (abfd)->a_trsize = trsize;
3604   exec_hdr (abfd)->a_drsize = drsize;
3605
3606   exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
3607
3608   /* Adjust the section sizes and vmas according to the magic number.
3609      This sets a_text, a_data and a_bss in the exec_hdr and sets the
3610      filepos for each section.  */
3611   if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
3612     goto error_return;
3613
3614   /* The relocation and symbol file positions differ among a.out
3615      targets.  We are passed a callback routine from the backend
3616      specific code to handle this.
3617      FIXME: At this point we do not know how much space the symbol
3618      table will require.  This will not work for any (nonstandard)
3619      a.out target that needs to know the symbol table size before it
3620      can compute the relocation file positions.  This may or may not
3621      be the case for the hp300hpux target, for example.  */
3622   (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
3623                &aout_info.symoff);
3624   obj_textsec (abfd)->rel_filepos = aout_info.treloff;
3625   obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
3626   obj_sym_filepos (abfd) = aout_info.symoff;
3627
3628   /* We keep a count of the symbols as we output them.  */
3629   obj_aout_external_sym_count (abfd) = 0;
3630
3631   /* We accumulate the string table as we write out the symbols.  */
3632   aout_info.strtab = _bfd_stringtab_init ();
3633   if (aout_info.strtab == NULL)
3634     goto error_return;
3635
3636   /* Allocate buffers to hold section contents and relocs.  */
3637   aout_info.contents = (bfd_byte *) bfd_malloc (max_contents_size);
3638   aout_info.relocs = (PTR) bfd_malloc (max_relocs_size);
3639   aout_info.symbol_map = (int *) bfd_malloc (max_sym_count * sizeof (int *));
3640   aout_info.output_syms = ((struct external_nlist *)
3641                            bfd_malloc ((max_sym_count + 1)
3642                                        * sizeof (struct external_nlist)));
3643   if ((aout_info.contents == NULL && max_contents_size != 0)
3644       || (aout_info.relocs == NULL && max_relocs_size != 0)
3645       || (aout_info.symbol_map == NULL && max_sym_count != 0)
3646       || aout_info.output_syms == NULL)
3647     goto error_return;
3648
3649   /* If we have a symbol named __DYNAMIC, force it out now.  This is
3650      required by SunOS.  Doing this here rather than in sunos.c is a
3651      hack, but it's easier than exporting everything which would be
3652      needed.  */
3653   {
3654     struct aout_link_hash_entry *h;
3655
3656     h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
3657                                false, false, false);
3658     if (h != NULL)
3659       aout_link_write_other_symbol (h, &aout_info);
3660   }
3661
3662   /* The most time efficient way to do the link would be to read all
3663      the input object files into memory and then sort out the
3664      information into the output file.  Unfortunately, that will
3665      probably use too much memory.  Another method would be to step
3666      through everything that composes the text section and write it
3667      out, and then everything that composes the data section and write
3668      it out, and then write out the relocs, and then write out the
3669      symbols.  Unfortunately, that requires reading stuff from each
3670      input file several times, and we will not be able to keep all the
3671      input files open simultaneously, and reopening them will be slow.
3672
3673      What we do is basically process one input file at a time.  We do
3674      everything we need to do with an input file once--copy over the
3675      section contents, handle the relocation information, and write
3676      out the symbols--and then we throw away the information we read
3677      from it.  This approach requires a lot of lseeks of the output
3678      file, which is unfortunate but still faster than reopening a lot
3679      of files.
3680
3681      We use the output_has_begun field of the input BFDs to see
3682      whether we have already handled it.  */
3683   for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
3684     sub->output_has_begun = false;
3685
3686   /* Mark all sections which are to be included in the link.  This
3687      will normally be every section.  We need to do this so that we
3688      can identify any sections which the linker has decided to not
3689      include.  */
3690   for (o = abfd->sections; o != NULL; o = o->next)
3691     {
3692       for (p = o->link_order_head; p != NULL; p = p->next)
3693         {
3694           if (p->type == bfd_indirect_link_order)
3695             p->u.indirect.section->linker_mark = true;
3696         }
3697     }
3698
3699   have_link_order_relocs = false;
3700   for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3701     {
3702       for (p = o->link_order_head;
3703            p != (struct bfd_link_order *) NULL;
3704            p = p->next)
3705         {
3706           if (p->type == bfd_indirect_link_order
3707               && (bfd_get_flavour (p->u.indirect.section->owner)
3708                   == bfd_target_aout_flavour))
3709             {
3710               bfd *input_bfd;
3711
3712               input_bfd = p->u.indirect.section->owner;
3713               if (! input_bfd->output_has_begun)
3714                 {
3715                   if (! aout_link_input_bfd (&aout_info, input_bfd))
3716                     goto error_return;
3717                   input_bfd->output_has_begun = true;
3718                 }
3719             }
3720           else if (p->type == bfd_section_reloc_link_order
3721                    || p->type == bfd_symbol_reloc_link_order)
3722             {
3723               /* These are handled below.  */
3724               have_link_order_relocs = true;
3725             }
3726           else
3727             {
3728               if (! _bfd_default_link_order (abfd, info, o, p))
3729                 goto error_return;
3730             }
3731         }
3732     }
3733
3734   /* Write out any symbols that we have not already written out.  */
3735   aout_link_hash_traverse (aout_hash_table (info),
3736                            aout_link_write_other_symbol,
3737                            (PTR) &aout_info);
3738
3739   /* Now handle any relocs we were asked to create by the linker.
3740      These did not come from any input file.  We must do these after
3741      we have written out all the symbols, so that we know the symbol
3742      indices to use.  */
3743   if (have_link_order_relocs)
3744     {
3745       for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3746         {
3747           for (p = o->link_order_head;
3748                p != (struct bfd_link_order *) NULL;
3749                p = p->next)
3750             {
3751               if (p->type == bfd_section_reloc_link_order
3752                   || p->type == bfd_symbol_reloc_link_order)
3753                 {
3754                   if (! aout_link_reloc_link_order (&aout_info, o, p))
3755                     goto error_return;
3756                 }
3757             }
3758         }
3759     }
3760
3761   if (aout_info.contents != NULL)
3762     {
3763       free (aout_info.contents);
3764       aout_info.contents = NULL;
3765     }
3766   if (aout_info.relocs != NULL)
3767     {
3768       free (aout_info.relocs);
3769       aout_info.relocs = NULL;
3770     }
3771   if (aout_info.symbol_map != NULL)
3772     {
3773       free (aout_info.symbol_map);
3774       aout_info.symbol_map = NULL;
3775     }
3776   if (aout_info.output_syms != NULL)
3777     {
3778       free (aout_info.output_syms);
3779       aout_info.output_syms = NULL;
3780     }
3781   if (includes_hash_initialized)
3782     {
3783       bfd_hash_table_free (&aout_info.includes.root);
3784       includes_hash_initialized = false;
3785     }
3786
3787   /* Finish up any dynamic linking we may be doing.  */
3788   if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
3789     {
3790       if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
3791         goto error_return;
3792     }
3793
3794   /* Update the header information.  */
3795   abfd->symcount = obj_aout_external_sym_count (abfd);
3796   exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
3797   obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
3798   obj_textsec (abfd)->reloc_count =
3799     exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
3800   obj_datasec (abfd)->reloc_count =
3801     exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
3802
3803   /* Write out the string table.  */
3804   if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
3805     goto error_return;
3806   return emit_stringtab (abfd, aout_info.strtab);
3807
3808  error_return:
3809   if (aout_info.contents != NULL)
3810     free (aout_info.contents);
3811   if (aout_info.relocs != NULL)
3812     free (aout_info.relocs);
3813   if (aout_info.symbol_map != NULL)
3814     free (aout_info.symbol_map);
3815   if (aout_info.output_syms != NULL)
3816     free (aout_info.output_syms);
3817   if (includes_hash_initialized)
3818     bfd_hash_table_free (&aout_info.includes.root);
3819   return false;
3820 }
3821
3822 /* Link an a.out input BFD into the output file.  */
3823
3824 static boolean
3825 aout_link_input_bfd (finfo, input_bfd)
3826      struct aout_final_link_info *finfo;
3827      bfd *input_bfd;
3828 {
3829   bfd_size_type sym_count;
3830
3831   BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
3832
3833   /* If this is a dynamic object, it may need special handling.  */
3834   if ((input_bfd->flags & DYNAMIC) != 0
3835       && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
3836     {
3837       return ((*aout_backend_info (input_bfd)->link_dynamic_object)
3838               (finfo->info, input_bfd));
3839     }
3840
3841   /* Get the symbols.  We probably have them already, unless
3842      finfo->info->keep_memory is false.  */
3843   if (! aout_get_external_symbols (input_bfd))
3844     return false;
3845
3846   sym_count = obj_aout_external_sym_count (input_bfd);
3847
3848   /* Write out the symbols and get a map of the new indices.  The map
3849      is placed into finfo->symbol_map.  */
3850   if (! aout_link_write_symbols (finfo, input_bfd))
3851     return false;
3852
3853   /* Relocate and write out the sections.  These functions use the
3854      symbol map created by aout_link_write_symbols.  The linker_mark
3855      field will be set if these sections are to be included in the
3856      link, which will normally be the case.  */
3857   if (obj_textsec (input_bfd)->linker_mark)
3858     {
3859       if (! aout_link_input_section (finfo, input_bfd,
3860                                      obj_textsec (input_bfd),
3861                                      &finfo->treloff,
3862                                      exec_hdr (input_bfd)->a_trsize))
3863         return false;
3864     }
3865   if (obj_datasec (input_bfd)->linker_mark)
3866     {
3867       if (! aout_link_input_section (finfo, input_bfd,
3868                                      obj_datasec (input_bfd),
3869                                      &finfo->dreloff,
3870                                      exec_hdr (input_bfd)->a_drsize))
3871         return false;
3872     }
3873
3874   /* If we are not keeping memory, we don't need the symbols any
3875      longer.  We still need them if we are keeping memory, because the
3876      strings in the hash table point into them.  */
3877   if (! finfo->info->keep_memory)
3878     {
3879       if (! aout_link_free_symbols (input_bfd))
3880         return false;
3881     }
3882
3883   return true;
3884 }
3885
3886 /* Adjust and write out the symbols for an a.out file.  Set the new
3887    symbol indices into a symbol_map.  */
3888
3889 static boolean
3890 aout_link_write_symbols (finfo, input_bfd)
3891      struct aout_final_link_info *finfo;
3892      bfd *input_bfd;
3893 {
3894   bfd *output_bfd;
3895   bfd_size_type sym_count;
3896   char *strings;
3897   enum bfd_link_strip strip;
3898   enum bfd_link_discard discard;
3899   struct external_nlist *outsym;
3900   bfd_size_type strtab_index;
3901   register struct external_nlist *sym;
3902   struct external_nlist *sym_end;
3903   struct aout_link_hash_entry **sym_hash;
3904   int *symbol_map;
3905   boolean pass;
3906   boolean skip_next;
3907
3908   output_bfd = finfo->output_bfd;
3909   sym_count = obj_aout_external_sym_count (input_bfd);
3910   strings = obj_aout_external_strings (input_bfd);
3911   strip = finfo->info->strip;
3912   discard = finfo->info->discard;
3913   outsym = finfo->output_syms;
3914
3915   /* First write out a symbol for this object file, unless we are
3916      discarding such symbols.  */
3917   if (strip != strip_all
3918       && (strip != strip_some
3919           || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
3920                               false, false) != NULL)
3921       && discard != discard_all)
3922     {
3923       bfd_h_put_8 (output_bfd, N_TEXT, outsym->e_type);
3924       bfd_h_put_8 (output_bfd, 0, outsym->e_other);
3925       bfd_h_put_16 (output_bfd, (bfd_vma) 0, outsym->e_desc);
3926       strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
3927                                        input_bfd->filename, false);
3928       if (strtab_index == (bfd_size_type) -1)
3929         return false;
3930       PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
3931       PUT_WORD (output_bfd,
3932                 (bfd_get_section_vma (output_bfd,
3933                                       obj_textsec (input_bfd)->output_section)
3934                  + obj_textsec (input_bfd)->output_offset),
3935                 outsym->e_value);
3936       ++obj_aout_external_sym_count (output_bfd);
3937       ++outsym;
3938     }
3939
3940   pass = false;
3941   skip_next = false;
3942   sym = obj_aout_external_syms (input_bfd);
3943   sym_end = sym + sym_count;
3944   sym_hash = obj_aout_sym_hashes (input_bfd);
3945   symbol_map = finfo->symbol_map;
3946   memset (symbol_map, 0, sym_count * sizeof *symbol_map);
3947   for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
3948     {
3949       const char *name;
3950       int type;
3951       struct aout_link_hash_entry *h;
3952       boolean skip;
3953       asection *symsec;
3954       bfd_vma val = 0;
3955       boolean copy;
3956
3957       /* We set *symbol_map to 0 above for all symbols.  If it has
3958          already been set to -1 for this symbol, it means that we are
3959          discarding it because it appears in a duplicate header file.
3960          See the N_BINCL code below.  */
3961       if (*symbol_map == -1)
3962         continue;
3963
3964       /* Initialize *symbol_map to -1, which means that the symbol was
3965          not copied into the output file.  We will change it later if
3966          we do copy the symbol over.  */
3967       *symbol_map = -1;
3968
3969       type = bfd_h_get_8 (input_bfd, sym->e_type);
3970       name = strings + GET_WORD (input_bfd, sym->e_strx);
3971
3972       h = NULL;
3973
3974       if (pass)
3975         {
3976           /* Pass this symbol through.  It is the target of an
3977              indirect or warning symbol.  */
3978           val = GET_WORD (input_bfd, sym->e_value);
3979           pass = false;
3980         }
3981       else if (skip_next)
3982         {
3983           /* Skip this symbol, which is the target of an indirect
3984              symbol that we have changed to no longer be an indirect
3985              symbol.  */
3986           skip_next = false;
3987           continue;
3988         }
3989       else
3990         {
3991           struct aout_link_hash_entry *hresolve;
3992
3993           /* We have saved the hash table entry for this symbol, if
3994              there is one.  Note that we could just look it up again
3995              in the hash table, provided we first check that it is an
3996              external symbol. */
3997           h = *sym_hash;
3998
3999           /* Use the name from the hash table, in case the symbol was
4000              wrapped.  */
4001           if (h != NULL)
4002             name = h->root.root.string;
4003
4004           /* If this is an indirect or warning symbol, then change
4005              hresolve to the base symbol.  We also change *sym_hash so
4006              that the relocation routines relocate against the real
4007              symbol.  */
4008           hresolve = h;
4009           if (h != (struct aout_link_hash_entry *) NULL
4010               && (h->root.type == bfd_link_hash_indirect
4011                   || h->root.type == bfd_link_hash_warning))
4012             {
4013               hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
4014               while (hresolve->root.type == bfd_link_hash_indirect
4015                      || hresolve->root.type == bfd_link_hash_warning)
4016                 hresolve = ((struct aout_link_hash_entry *)
4017                             hresolve->root.u.i.link);
4018               *sym_hash = hresolve;
4019             }
4020
4021           /* If the symbol has already been written out, skip it.  */
4022           if (h != (struct aout_link_hash_entry *) NULL
4023               && h->root.type != bfd_link_hash_warning
4024               && h->written)
4025             {
4026               if ((type & N_TYPE) == N_INDR
4027                   || type == N_WARNING)
4028                 skip_next = true;
4029               *symbol_map = h->indx;
4030               continue;
4031             }
4032
4033           /* See if we are stripping this symbol.  */
4034           skip = false;
4035           switch (strip)
4036             {
4037             case strip_none:
4038               break;
4039             case strip_debugger:
4040               if ((type & N_STAB) != 0)
4041                 skip = true;
4042               break;
4043             case strip_some:
4044               if (bfd_hash_lookup (finfo->info->keep_hash, name, false, false)
4045                   == NULL)
4046                 skip = true;
4047               break;
4048             case strip_all:
4049               skip = true;
4050               break;
4051             }
4052           if (skip)
4053             {
4054               if (h != (struct aout_link_hash_entry *) NULL)
4055                 h->written = true;
4056               continue;
4057             }
4058
4059           /* Get the value of the symbol.  */
4060           if ((type & N_TYPE) == N_TEXT
4061               || type == N_WEAKT)
4062             symsec = obj_textsec (input_bfd);
4063           else if ((type & N_TYPE) == N_DATA
4064                    || type == N_WEAKD)
4065             symsec = obj_datasec (input_bfd);
4066           else if ((type & N_TYPE) == N_BSS
4067                    || type == N_WEAKB)
4068             symsec = obj_bsssec (input_bfd);
4069           else if ((type & N_TYPE) == N_ABS
4070                    || type == N_WEAKA)
4071             symsec = bfd_abs_section_ptr;
4072           else if (((type & N_TYPE) == N_INDR
4073                     && (hresolve == (struct aout_link_hash_entry *) NULL
4074                         || (hresolve->root.type != bfd_link_hash_defined
4075                             && hresolve->root.type != bfd_link_hash_defweak
4076                             && hresolve->root.type != bfd_link_hash_common)))
4077                    || type == N_WARNING)
4078             {
4079               /* Pass the next symbol through unchanged.  The
4080                  condition above for indirect symbols is so that if
4081                  the indirect symbol was defined, we output it with
4082                  the correct definition so the debugger will
4083                  understand it.  */
4084               pass = true;
4085               val = GET_WORD (input_bfd, sym->e_value);
4086               symsec = NULL;
4087             }
4088           else if ((type & N_STAB) != 0)
4089             {
4090               val = GET_WORD (input_bfd, sym->e_value);
4091               symsec = NULL;
4092             }
4093           else
4094             {
4095               /* If we get here with an indirect symbol, it means that
4096                  we are outputting it with a real definition.  In such
4097                  a case we do not want to output the next symbol,
4098                  which is the target of the indirection.  */
4099               if ((type & N_TYPE) == N_INDR)
4100                 skip_next = true;
4101
4102               symsec = NULL;
4103
4104               /* We need to get the value from the hash table.  We use
4105                  hresolve so that if we have defined an indirect
4106                  symbol we output the final definition.  */
4107               if (h == (struct aout_link_hash_entry *) NULL)
4108                 {
4109                   switch (type & N_TYPE)
4110                     {
4111                     case N_SETT:
4112                       symsec = obj_textsec (input_bfd);
4113                       break;
4114                     case N_SETD:
4115                       symsec = obj_datasec (input_bfd);
4116                       break;
4117                     case N_SETB:
4118                       symsec = obj_bsssec (input_bfd);
4119                       break;
4120                     case N_SETA:
4121                       symsec = bfd_abs_section_ptr;
4122                       break;
4123                     default:
4124                       val = 0;
4125                       break;
4126                     }
4127                 }
4128               else if (hresolve->root.type == bfd_link_hash_defined
4129                        || hresolve->root.type == bfd_link_hash_defweak)
4130                 {
4131                   asection *input_section;
4132                   asection *output_section;
4133
4134                   /* This case usually means a common symbol which was
4135                      turned into a defined symbol.  */
4136                   input_section = hresolve->root.u.def.section;
4137                   output_section = input_section->output_section;
4138                   BFD_ASSERT (bfd_is_abs_section (output_section)
4139                               || output_section->owner == output_bfd);
4140                   val = (hresolve->root.u.def.value
4141                          + bfd_get_section_vma (output_bfd, output_section)
4142                          + input_section->output_offset);
4143
4144                   /* Get the correct type based on the section.  If
4145                      this is a constructed set, force it to be
4146                      globally visible.  */
4147                   if (type == N_SETT
4148                       || type == N_SETD
4149                       || type == N_SETB
4150                       || type == N_SETA)
4151                     type |= N_EXT;
4152
4153                   type &=~ N_TYPE;
4154
4155                   if (output_section == obj_textsec (output_bfd))
4156                     type |= (hresolve->root.type == bfd_link_hash_defined
4157                              ? N_TEXT
4158                              : N_WEAKT);
4159                   else if (output_section == obj_datasec (output_bfd))
4160                     type |= (hresolve->root.type == bfd_link_hash_defined
4161                              ? N_DATA
4162                              : N_WEAKD);
4163                   else if (output_section == obj_bsssec (output_bfd))
4164                     type |= (hresolve->root.type == bfd_link_hash_defined
4165                              ? N_BSS
4166                              : N_WEAKB);
4167                   else
4168                     type |= (hresolve->root.type == bfd_link_hash_defined
4169                              ? N_ABS
4170                              : N_WEAKA);
4171                 }
4172               else if (hresolve->root.type == bfd_link_hash_common)
4173                 val = hresolve->root.u.c.size;
4174               else if (hresolve->root.type == bfd_link_hash_undefweak)
4175                 {
4176                   val = 0;
4177                   type = N_WEAKU;
4178                 }
4179               else
4180                 val = 0;
4181             }
4182           if (symsec != (asection *) NULL)
4183             val = (symsec->output_section->vma
4184                    + symsec->output_offset
4185                    + (GET_WORD (input_bfd, sym->e_value)
4186                       - symsec->vma));
4187
4188           /* If this is a global symbol set the written flag, and if
4189              it is a local symbol see if we should discard it.  */
4190           if (h != (struct aout_link_hash_entry *) NULL)
4191             {
4192               h->written = true;
4193               h->indx = obj_aout_external_sym_count (output_bfd);
4194             }
4195           else if ((type & N_TYPE) != N_SETT
4196                    && (type & N_TYPE) != N_SETD
4197                    && (type & N_TYPE) != N_SETB
4198                    && (type & N_TYPE) != N_SETA)
4199             {
4200               switch (discard)
4201                 {
4202                 case discard_none:
4203                   break;
4204                 case discard_l:
4205                   if (*name == *finfo->info->lprefix
4206                       && (finfo->info->lprefix_len == 1
4207                           || strncmp (name, finfo->info->lprefix,
4208                                       finfo->info->lprefix_len) == 0))
4209                     skip = true;
4210                   break;
4211                 case discard_all:
4212                   skip = true;
4213                   break;
4214                 }
4215               if (skip)
4216                 {
4217                   pass = false;
4218                   continue;
4219                 }
4220             }
4221
4222           /* An N_BINCL symbol indicates the start of the stabs
4223              entries for a header file.  We need to scan ahead to the
4224              next N_EINCL symbol, ignoring nesting, adding up all the
4225              characters in the symbol names, not including the file
4226              numbers in types (the first number after an open
4227              parenthesis).  */
4228           if (type == N_BINCL)
4229             {
4230               struct external_nlist *incl_sym;
4231               int nest;
4232               struct aout_link_includes_entry *incl_entry;
4233               struct aout_link_includes_totals *t;
4234
4235               val = 0;
4236               nest = 0;
4237               for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
4238                 {
4239                   int incl_type;
4240
4241                   incl_type = bfd_h_get_8 (input_bfd, incl_sym->e_type);
4242                   if (incl_type == N_EINCL)
4243                     {
4244                       if (nest == 0)
4245                         break;
4246                       --nest;
4247                     }
4248                   else if (incl_type == N_BINCL)
4249                     ++nest;
4250                   else if (nest == 0)
4251                     {
4252                       const char *s;
4253
4254                       s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
4255                       for (; *s != '\0'; s++)
4256                         {
4257                           val += *s;
4258                           if (*s == '(')
4259                             {
4260                               /* Skip the file number.  */
4261                               ++s;
4262                               while (isdigit ((unsigned char) *s))
4263                                 ++s;
4264                               --s;
4265                             }
4266                         }
4267                     }
4268                 }
4269
4270               /* If we have already included a header file with the
4271                  same value, then replace this one with an N_EXCL
4272                  symbol.  */
4273               copy = ! finfo->info->keep_memory;
4274               incl_entry = aout_link_includes_lookup (&finfo->includes,
4275                                                       name, true, copy);
4276               if (incl_entry == NULL)
4277                 return false;
4278               for (t = incl_entry->totals; t != NULL; t = t->next)
4279                 if (t->total == val)
4280                   break;
4281               if (t == NULL)
4282                 {
4283                   /* This is the first time we have seen this header
4284                      file with this set of stabs strings.  */
4285                   t = ((struct aout_link_includes_totals *)
4286                        bfd_hash_allocate (&finfo->includes.root,
4287                                           sizeof *t));
4288                   if (t == NULL)
4289                     return false;
4290                   t->total = val;
4291                   t->next = incl_entry->totals;
4292                   incl_entry->totals = t;
4293                 }
4294               else
4295                 {
4296                   int *incl_map;
4297
4298                   /* This is a duplicate header file.  We must change
4299                      it to be an N_EXCL entry, and mark all the
4300                      included symbols to prevent outputting them.  */
4301                   type = N_EXCL;
4302
4303                   nest = 0;
4304                   for (incl_sym = sym + 1, incl_map = symbol_map + 1;
4305                        incl_sym < sym_end;
4306                        incl_sym++, incl_map++)
4307                     {
4308                       int incl_type;
4309
4310                       incl_type = bfd_h_get_8 (input_bfd, incl_sym->e_type);
4311                       if (incl_type == N_EINCL)
4312                         {
4313                           if (nest == 0)
4314                             {
4315                               *incl_map = -1;
4316                               break;
4317                             }
4318                           --nest;
4319                         }
4320                       else if (incl_type == N_BINCL)
4321                         ++nest;
4322                       else if (nest == 0)
4323                         *incl_map = -1;
4324                     }
4325                 }
4326             }
4327         }
4328
4329       /* Copy this symbol into the list of symbols we are going to
4330          write out.  */
4331       bfd_h_put_8 (output_bfd, type, outsym->e_type);
4332       bfd_h_put_8 (output_bfd, bfd_h_get_8 (input_bfd, sym->e_other),
4333                    outsym->e_other);
4334       bfd_h_put_16 (output_bfd, bfd_h_get_16 (input_bfd, sym->e_desc),
4335                     outsym->e_desc);
4336       copy = false;
4337       if (! finfo->info->keep_memory)
4338         {
4339           /* name points into a string table which we are going to
4340              free.  If there is a hash table entry, use that string.
4341              Otherwise, copy name into memory.  */
4342           if (h != (struct aout_link_hash_entry *) NULL)
4343             name = h->root.root.string;
4344           else
4345             copy = true;
4346         }
4347       strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4348                                        name, copy);
4349       if (strtab_index == (bfd_size_type) -1)
4350         return false;
4351       PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4352       PUT_WORD (output_bfd, val, outsym->e_value);
4353       *symbol_map = obj_aout_external_sym_count (output_bfd);
4354       ++obj_aout_external_sym_count (output_bfd);
4355       ++outsym;
4356     }
4357
4358   /* Write out the output symbols we have just constructed.  */
4359   if (outsym > finfo->output_syms)
4360     {
4361       bfd_size_type outsym_count;
4362
4363       if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
4364         return false;
4365       outsym_count = outsym - finfo->output_syms;
4366       if (bfd_write ((PTR) finfo->output_syms,
4367                      (bfd_size_type) EXTERNAL_NLIST_SIZE,
4368                      (bfd_size_type) outsym_count, output_bfd)
4369           != outsym_count * EXTERNAL_NLIST_SIZE)
4370         return false;
4371       finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE;
4372     }
4373
4374   return true;
4375 }
4376
4377 /* Write out a symbol that was not associated with an a.out input
4378    object.  */
4379
4380 static boolean
4381 aout_link_write_other_symbol (h, data)
4382      struct aout_link_hash_entry *h;
4383      PTR data;
4384 {
4385   struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
4386   bfd *output_bfd;
4387   int type;
4388   bfd_vma val;
4389   struct external_nlist outsym;
4390   bfd_size_type indx;
4391
4392   output_bfd = finfo->output_bfd;
4393
4394   if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
4395     {
4396       if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
4397              (output_bfd, finfo->info, h)))
4398         {
4399           /* FIXME: No way to handle errors.  */
4400           abort ();
4401         }
4402     }
4403
4404   if (h->written)
4405     return true;
4406
4407   h->written = true;
4408
4409   /* An indx of -2 means the symbol must be written.  */
4410   if (h->indx != -2
4411       && (finfo->info->strip == strip_all
4412           || (finfo->info->strip == strip_some
4413               && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
4414                                   false, false) == NULL)))
4415     return true;
4416
4417   switch (h->root.type)
4418     {
4419     default:
4420       abort ();
4421       /* Avoid variable not initialized warnings.  */
4422       return true;
4423     case bfd_link_hash_new:
4424       /* This can happen for set symbols when sets are not being
4425          built.  */
4426       return true;
4427     case bfd_link_hash_undefined:
4428       type = N_UNDF | N_EXT;
4429       val = 0;
4430       break;
4431     case bfd_link_hash_defined:
4432     case bfd_link_hash_defweak:
4433       {
4434         asection *sec;
4435
4436         sec = h->root.u.def.section->output_section;
4437         BFD_ASSERT (bfd_is_abs_section (sec)
4438                     || sec->owner == output_bfd);
4439         if (sec == obj_textsec (output_bfd))
4440           type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
4441         else if (sec == obj_datasec (output_bfd))
4442           type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
4443         else if (sec == obj_bsssec (output_bfd))
4444           type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
4445         else
4446           type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
4447         type |= N_EXT;
4448         val = (h->root.u.def.value
4449                + sec->vma
4450                + h->root.u.def.section->output_offset);
4451       }
4452       break;
4453     case bfd_link_hash_common:
4454       type = N_UNDF | N_EXT;
4455       val = h->root.u.c.size;
4456       break;
4457     case bfd_link_hash_undefweak:
4458       type = N_WEAKU;
4459       val = 0;
4460     case bfd_link_hash_indirect:
4461     case bfd_link_hash_warning:
4462       /* FIXME: Ignore these for now.  The circumstances under which
4463          they should be written out are not clear to me.  */
4464       return true;
4465     }
4466
4467   bfd_h_put_8 (output_bfd, type, outsym.e_type);
4468   bfd_h_put_8 (output_bfd, 0, outsym.e_other);
4469   bfd_h_put_16 (output_bfd, 0, outsym.e_desc);
4470   indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
4471                            false);
4472   if (indx == (bfd_size_type) -1)
4473     {
4474       /* FIXME: No way to handle errors.  */
4475       abort ();
4476     }
4477   PUT_WORD (output_bfd, indx, outsym.e_strx);
4478   PUT_WORD (output_bfd, val, outsym.e_value);
4479
4480   if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
4481       || bfd_write ((PTR) &outsym, (bfd_size_type) EXTERNAL_NLIST_SIZE,
4482                     (bfd_size_type) 1, output_bfd) != EXTERNAL_NLIST_SIZE)
4483     {
4484       /* FIXME: No way to handle errors.  */
4485       abort ();
4486     }
4487
4488   finfo->symoff += EXTERNAL_NLIST_SIZE;
4489   h->indx = obj_aout_external_sym_count (output_bfd);
4490   ++obj_aout_external_sym_count (output_bfd);
4491
4492   return true;
4493 }
4494
4495 /* Link an a.out section into the output file.  */
4496
4497 static boolean
4498 aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
4499                          rel_size)
4500      struct aout_final_link_info *finfo;
4501      bfd *input_bfd;
4502      asection *input_section;
4503      file_ptr *reloff_ptr;
4504      bfd_size_type rel_size;
4505 {
4506   bfd_size_type input_size;
4507   PTR relocs;
4508
4509   /* Get the section contents.  */
4510   input_size = bfd_section_size (input_bfd, input_section);
4511   if (! bfd_get_section_contents (input_bfd, input_section,
4512                                   (PTR) finfo->contents,
4513                                   (file_ptr) 0, input_size))
4514     return false;
4515
4516   /* Read in the relocs if we haven't already done it.  */
4517   if (aout_section_data (input_section) != NULL
4518       && aout_section_data (input_section)->relocs != NULL)
4519     relocs = aout_section_data (input_section)->relocs;
4520   else
4521     {
4522       relocs = finfo->relocs;
4523       if (rel_size > 0)
4524         {
4525           if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
4526               || bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
4527             return false;
4528         }
4529     }
4530
4531   /* Relocate the section contents.  */
4532   if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
4533     {
4534       if (! aout_link_input_section_std (finfo, input_bfd, input_section,
4535                                          (struct reloc_std_external *) relocs,
4536                                          rel_size, finfo->contents))
4537         return false;
4538     }
4539   else
4540     {
4541       if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
4542                                          (struct reloc_ext_external *) relocs,
4543                                          rel_size, finfo->contents))
4544         return false;
4545     }
4546
4547   /* Write out the section contents.  */
4548   if (! bfd_set_section_contents (finfo->output_bfd,
4549                                   input_section->output_section,
4550                                   (PTR) finfo->contents,
4551                                   input_section->output_offset,
4552                                   input_size))
4553     return false;
4554
4555   /* If we are producing relocateable output, the relocs were
4556      modified, and we now write them out.  */
4557   if (finfo->info->relocateable && rel_size > 0)
4558     {
4559       if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
4560         return false;
4561       if (bfd_write (relocs, (bfd_size_type) 1, rel_size, finfo->output_bfd)
4562           != rel_size)
4563         return false;
4564       *reloff_ptr += rel_size;
4565
4566       /* Assert that the relocs have not run into the symbols, and
4567          that if these are the text relocs they have not run into the
4568          data relocs.  */
4569       BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
4570                   && (reloff_ptr != &finfo->treloff
4571                       || (*reloff_ptr
4572                           <= obj_datasec (finfo->output_bfd)->rel_filepos)));
4573     }
4574
4575   return true;
4576 }
4577
4578 /* Get the section corresponding to a reloc index.  */
4579
4580 static INLINE asection *
4581 aout_reloc_index_to_section (abfd, indx)
4582      bfd *abfd;
4583      int indx;
4584 {
4585   switch (indx & N_TYPE)
4586     {
4587     case N_TEXT:
4588       return obj_textsec (abfd);
4589     case N_DATA:
4590       return obj_datasec (abfd);
4591     case N_BSS:
4592       return obj_bsssec (abfd);
4593     case N_ABS:
4594     case N_UNDF:
4595       return bfd_abs_section_ptr;
4596     default:
4597       abort ();
4598     }
4599 }
4600
4601 /* Relocate an a.out section using standard a.out relocs.  */
4602
4603 static boolean
4604 aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
4605                              rel_size, contents)
4606      struct aout_final_link_info *finfo;
4607      bfd *input_bfd;
4608      asection *input_section;
4609      struct reloc_std_external *relocs;
4610      bfd_size_type rel_size;
4611      bfd_byte *contents;
4612 {
4613   boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
4614                                           bfd *, asection *,
4615                                           struct aout_link_hash_entry *,
4616                                           PTR, bfd_byte *, boolean *,
4617                                           bfd_vma *));
4618   bfd *output_bfd;
4619   boolean relocateable;
4620   struct external_nlist *syms;
4621   char *strings;
4622   struct aout_link_hash_entry **sym_hashes;
4623   int *symbol_map;
4624   bfd_size_type reloc_count;
4625   register struct reloc_std_external *rel;
4626   struct reloc_std_external *rel_end;
4627
4628   output_bfd = finfo->output_bfd;
4629   check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
4630
4631   BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
4632   BFD_ASSERT (input_bfd->xvec->header_byteorder
4633               == output_bfd->xvec->header_byteorder);
4634
4635   relocateable = finfo->info->relocateable;
4636   syms = obj_aout_external_syms (input_bfd);
4637   strings = obj_aout_external_strings (input_bfd);
4638   sym_hashes = obj_aout_sym_hashes (input_bfd);
4639   symbol_map = finfo->symbol_map;
4640
4641   reloc_count = rel_size / RELOC_STD_SIZE;
4642   rel = relocs;
4643   rel_end = rel + reloc_count;
4644   for (; rel < rel_end; rel++)
4645     {
4646       bfd_vma r_addr;
4647       int r_index;
4648       int r_extern;
4649       int r_pcrel;
4650       int r_baserel = 0;
4651       reloc_howto_type *howto;
4652       struct aout_link_hash_entry *h = NULL;
4653       bfd_vma relocation;
4654       bfd_reloc_status_type r;
4655
4656       r_addr = GET_SWORD (input_bfd, rel->r_address);
4657
4658 #ifdef MY_reloc_howto
4659       howto = MY_reloc_howto(input_bfd, rel, r_index, r_extern, r_pcrel);
4660 #else      
4661       {
4662         int r_jmptable;
4663         int r_relative;
4664         int r_length;
4665         unsigned int howto_idx;
4666
4667         if (bfd_header_big_endian (input_bfd))
4668           {
4669             r_index   =  ((rel->r_index[0] << 16)
4670                           | (rel->r_index[1] << 8)
4671                           | rel->r_index[2]);
4672             r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
4673             r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
4674             r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
4675             r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
4676             r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
4677             r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
4678                          >> RELOC_STD_BITS_LENGTH_SH_BIG);
4679           }
4680         else
4681           {
4682             r_index   = ((rel->r_index[2] << 16)
4683                          | (rel->r_index[1] << 8)
4684                          | rel->r_index[0]);
4685             r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
4686             r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
4687             r_baserel = (0 != (rel->r_type[0]
4688                                & RELOC_STD_BITS_BASEREL_LITTLE));
4689             r_jmptable= (0 != (rel->r_type[0]
4690                                & RELOC_STD_BITS_JMPTABLE_LITTLE));
4691             r_relative= (0 != (rel->r_type[0]
4692                                & RELOC_STD_BITS_RELATIVE_LITTLE));
4693             r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
4694                          >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
4695           }
4696
4697         howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
4698                      + 16 * r_jmptable + 32 * r_relative);
4699         BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
4700         howto = howto_table_std + howto_idx;
4701       }
4702 #endif
4703
4704       if (relocateable)
4705         {
4706           /* We are generating a relocateable output file, and must
4707              modify the reloc accordingly.  */
4708           if (r_extern)
4709             {
4710               /* If we know the symbol this relocation is against,
4711                  convert it into a relocation against a section.  This
4712                  is what the native linker does.  */
4713               h = sym_hashes[r_index];
4714               if (h != (struct aout_link_hash_entry *) NULL
4715                   && (h->root.type == bfd_link_hash_defined
4716                       || h->root.type == bfd_link_hash_defweak))
4717                 {
4718                   asection *output_section;
4719
4720                   /* Change the r_extern value.  */
4721                   if (bfd_header_big_endian (output_bfd))
4722                     rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
4723                   else
4724                     rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
4725
4726                   /* Compute a new r_index.  */
4727                   output_section = h->root.u.def.section->output_section;
4728                   if (output_section == obj_textsec (output_bfd))
4729                     r_index = N_TEXT;
4730                   else if (output_section == obj_datasec (output_bfd))
4731                     r_index = N_DATA;
4732                   else if (output_section == obj_bsssec (output_bfd))
4733                     r_index = N_BSS;
4734                   else
4735                     r_index = N_ABS;
4736
4737                   /* Add the symbol value and the section VMA to the
4738                      addend stored in the contents.  */
4739                   relocation = (h->root.u.def.value
4740                                 + output_section->vma
4741                                 + h->root.u.def.section->output_offset);
4742                 }
4743               else
4744                 {
4745                   /* We must change r_index according to the symbol
4746                      map.  */
4747                   r_index = symbol_map[r_index];
4748
4749                   if (r_index == -1)
4750                     {
4751                       if (h != NULL)
4752                         {
4753                           /* We decided to strip this symbol, but it
4754                              turns out that we can't.  Note that we
4755                              lose the other and desc information here.
4756                              I don't think that will ever matter for a
4757                              global symbol.  */
4758                           if (h->indx < 0)
4759                             {
4760                               h->indx = -2;
4761                               h->written = false;
4762                               if (! aout_link_write_other_symbol (h,
4763                                                                   (PTR) finfo))
4764                                 return false;
4765                             }
4766                           r_index = h->indx;
4767                         }
4768                       else
4769                         {
4770                           const char *name;
4771
4772                           name = strings + GET_WORD (input_bfd,
4773                                                      syms[r_index].e_strx);
4774                           if (! ((*finfo->info->callbacks->unattached_reloc)
4775                                  (finfo->info, name, input_bfd, input_section,
4776                                   r_addr)))
4777                             return false;
4778                           r_index = 0;
4779                         }
4780                     }
4781
4782                   relocation = 0;
4783                 }
4784
4785               /* Write out the new r_index value.  */
4786               if (bfd_header_big_endian (output_bfd))
4787                 {
4788                   rel->r_index[0] = r_index >> 16;
4789                   rel->r_index[1] = r_index >> 8;
4790                   rel->r_index[2] = r_index;
4791                 }
4792               else
4793                 {
4794                   rel->r_index[2] = r_index >> 16;
4795                   rel->r_index[1] = r_index >> 8;
4796                   rel->r_index[0] = r_index;
4797                 }
4798             }
4799           else
4800             {
4801               asection *section;
4802
4803               /* This is a relocation against a section.  We must
4804                  adjust by the amount that the section moved.  */
4805               section = aout_reloc_index_to_section (input_bfd, r_index);
4806               relocation = (section->output_section->vma
4807                             + section->output_offset
4808                             - section->vma);
4809             }
4810
4811           /* Change the address of the relocation.  */
4812           PUT_WORD (output_bfd,
4813                     r_addr + input_section->output_offset,
4814                     rel->r_address);
4815
4816           /* Adjust a PC relative relocation by removing the reference
4817              to the original address in the section and including the
4818              reference to the new address.  */
4819           if (r_pcrel)
4820             relocation -= (input_section->output_section->vma
4821                            + input_section->output_offset
4822                            - input_section->vma);
4823
4824 #ifdef MY_relocatable_reloc
4825           MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
4826 #endif
4827
4828           if (relocation == 0)
4829             r = bfd_reloc_ok;
4830           else
4831             r = MY_relocate_contents (howto,
4832                                         input_bfd, relocation,
4833                                         contents + r_addr);
4834         }
4835       else
4836         {
4837           boolean hundef;
4838
4839           /* We are generating an executable, and must do a full
4840              relocation.  */
4841           hundef = false;
4842           if (r_extern)
4843             {
4844               h = sym_hashes[r_index];
4845
4846               if (h != (struct aout_link_hash_entry *) NULL
4847                   && (h->root.type == bfd_link_hash_defined
4848                       || h->root.type == bfd_link_hash_defweak))
4849                 {
4850                   relocation = (h->root.u.def.value
4851                                 + h->root.u.def.section->output_section->vma
4852                                 + h->root.u.def.section->output_offset);
4853                 }
4854               else if (h != (struct aout_link_hash_entry *) NULL
4855                        && h->root.type == bfd_link_hash_undefweak)
4856                 relocation = 0;
4857               else
4858                 {
4859                   hundef = true;
4860                   relocation = 0;
4861                 }
4862             }
4863           else
4864             {
4865               asection *section;
4866
4867               section = aout_reloc_index_to_section (input_bfd, r_index);
4868               relocation = (section->output_section->vma
4869                             + section->output_offset
4870                             - section->vma);
4871               if (r_pcrel)
4872                 relocation += input_section->vma;
4873             }
4874
4875           if (check_dynamic_reloc != NULL)
4876             {
4877               boolean skip;
4878
4879               if (! ((*check_dynamic_reloc)
4880                      (finfo->info, input_bfd, input_section, h,
4881                       (PTR) rel, contents, &skip, &relocation)))
4882                 return false;
4883               if (skip)
4884                 continue;
4885             }
4886
4887           /* Now warn if a global symbol is undefined.  We could not
4888              do this earlier, because check_dynamic_reloc might want
4889              to skip this reloc.  */
4890           if (hundef && ! finfo->info->shared && ! r_baserel)
4891             {
4892               const char *name;
4893
4894               if (h != NULL)
4895                 name = h->root.root.string;
4896               else
4897                 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
4898               if (! ((*finfo->info->callbacks->undefined_symbol)
4899                      (finfo->info, name, input_bfd, input_section, r_addr)))
4900                 return false;
4901             }
4902
4903           r = MY_final_link_relocate (howto,
4904                                       input_bfd, input_section,
4905                                       contents, r_addr, relocation,
4906                                       (bfd_vma) 0);
4907         }
4908
4909       if (r != bfd_reloc_ok)
4910         {
4911           switch (r)
4912             {
4913             default:
4914             case bfd_reloc_outofrange:
4915               abort ();
4916             case bfd_reloc_overflow:
4917               {
4918                 const char *name;
4919
4920                 if (h != NULL)
4921                   name = h->root.root.string;
4922                 else if (r_extern)
4923                   name = strings + GET_WORD (input_bfd,
4924                                              syms[r_index].e_strx);
4925                 else
4926                   {
4927                     asection *s;
4928
4929                     s = aout_reloc_index_to_section (input_bfd, r_index);
4930                     name = bfd_section_name (input_bfd, s);
4931                   }
4932                 if (! ((*finfo->info->callbacks->reloc_overflow)
4933                        (finfo->info, name, howto->name,
4934                         (bfd_vma) 0, input_bfd, input_section, r_addr)))
4935                   return false;
4936               }
4937               break;
4938             }
4939         }
4940     }
4941
4942   return true;
4943 }
4944
4945 /* Relocate an a.out section using extended a.out relocs.  */
4946
4947 static boolean
4948 aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
4949                              rel_size, contents)
4950      struct aout_final_link_info *finfo;
4951      bfd *input_bfd;
4952      asection *input_section;
4953      struct reloc_ext_external *relocs;
4954      bfd_size_type rel_size;
4955      bfd_byte *contents;
4956 {
4957   boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
4958                                           bfd *, asection *,
4959                                           struct aout_link_hash_entry *,
4960                                           PTR, bfd_byte *, boolean *,
4961                                           bfd_vma *));
4962   bfd *output_bfd;
4963   boolean relocateable;
4964   struct external_nlist *syms;
4965   char *strings;
4966   struct aout_link_hash_entry **sym_hashes;
4967   int *symbol_map;
4968   bfd_size_type reloc_count;
4969   register struct reloc_ext_external *rel;
4970   struct reloc_ext_external *rel_end;
4971
4972   output_bfd = finfo->output_bfd;
4973   check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
4974
4975   BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
4976   BFD_ASSERT (input_bfd->xvec->header_byteorder
4977               == output_bfd->xvec->header_byteorder);
4978
4979   relocateable = finfo->info->relocateable;
4980   syms = obj_aout_external_syms (input_bfd);
4981   strings = obj_aout_external_strings (input_bfd);
4982   sym_hashes = obj_aout_sym_hashes (input_bfd);
4983   symbol_map = finfo->symbol_map;
4984
4985   reloc_count = rel_size / RELOC_EXT_SIZE;
4986   rel = relocs;
4987   rel_end = rel + reloc_count;
4988   for (; rel < rel_end; rel++)
4989     {
4990       bfd_vma r_addr;
4991       int r_index;
4992       int r_extern;
4993       unsigned int r_type;
4994       bfd_vma r_addend;
4995       struct aout_link_hash_entry *h = NULL;
4996       asection *r_section = NULL;
4997       bfd_vma relocation;
4998
4999       r_addr = GET_SWORD (input_bfd, rel->r_address);
5000
5001       if (bfd_header_big_endian (input_bfd))
5002         {
5003           r_index  = ((rel->r_index[0] << 16)
5004                       | (rel->r_index[1] << 8)
5005                       | rel->r_index[2]);
5006           r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
5007           r_type   = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
5008                       >> RELOC_EXT_BITS_TYPE_SH_BIG);
5009         }
5010       else
5011         {
5012           r_index  = ((rel->r_index[2] << 16)
5013                       | (rel->r_index[1] << 8)
5014                       | rel->r_index[0]);
5015           r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
5016           r_type   = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
5017                       >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
5018         }
5019
5020       r_addend = GET_SWORD (input_bfd, rel->r_addend);
5021
5022       BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext));
5023
5024       if (relocateable)
5025         {
5026           /* We are generating a relocateable output file, and must
5027              modify the reloc accordingly.  */
5028           if (r_extern)
5029             {
5030               /* If we know the symbol this relocation is against,
5031                  convert it into a relocation against a section.  This
5032                  is what the native linker does.  */
5033               h = sym_hashes[r_index];
5034               if (h != (struct aout_link_hash_entry *) NULL
5035                   && (h->root.type == bfd_link_hash_defined
5036                       || h->root.type == bfd_link_hash_defweak))
5037                 {
5038                   asection *output_section;
5039
5040                   /* Change the r_extern value.  */
5041                   if (bfd_header_big_endian (output_bfd))
5042                     rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
5043                   else
5044                     rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
5045
5046                   /* Compute a new r_index.  */
5047                   output_section = h->root.u.def.section->output_section;
5048                   if (output_section == obj_textsec (output_bfd))
5049                     r_index = N_TEXT;
5050                   else if (output_section == obj_datasec (output_bfd))
5051                     r_index = N_DATA;
5052                   else if (output_section == obj_bsssec (output_bfd))
5053                     r_index = N_BSS;
5054                   else
5055                     r_index = N_ABS;
5056
5057                   /* Add the symbol value and the section VMA to the
5058                      addend.  */
5059                   relocation = (h->root.u.def.value
5060                                 + output_section->vma
5061                                 + h->root.u.def.section->output_offset);
5062
5063                   /* Now RELOCATION is the VMA of the final
5064                      destination.  If this is a PC relative reloc,
5065                      then ADDEND is the negative of the source VMA.
5066                      We want to set ADDEND to the difference between
5067                      the destination VMA and the source VMA, which
5068                      means we must adjust RELOCATION by the change in
5069                      the source VMA.  This is done below.  */
5070                 }
5071               else
5072                 {
5073                   /* We must change r_index according to the symbol
5074                      map.  */
5075                   r_index = symbol_map[r_index];
5076
5077                   if (r_index == -1)
5078                     {
5079                       if (h != NULL)
5080                         {
5081                           /* We decided to strip this symbol, but it
5082                              turns out that we can't.  Note that we
5083                              lose the other and desc information here.
5084                              I don't think that will ever matter for a
5085                              global symbol.  */
5086                           if (h->indx < 0)
5087                             {
5088                               h->indx = -2;
5089                               h->written = false;
5090                               if (! aout_link_write_other_symbol (h,
5091                                                                   (PTR) finfo))
5092                                 return false;
5093                             }
5094                           r_index = h->indx;
5095                         }
5096                       else
5097                         {
5098                           const char *name;
5099
5100                           name = strings + GET_WORD (input_bfd,
5101                                                      syms[r_index].e_strx);
5102                           if (! ((*finfo->info->callbacks->unattached_reloc)
5103                                  (finfo->info, name, input_bfd, input_section,
5104                                   r_addr)))
5105                             return false;
5106                           r_index = 0;
5107                         }
5108                     }
5109
5110                   relocation = 0;
5111
5112                   /* If this is a PC relative reloc, then the addend
5113                      is the negative of the source VMA.  We must
5114                      adjust it by the change in the source VMA.  This
5115                      is done below.  */
5116                 }
5117
5118               /* Write out the new r_index value.  */
5119               if (bfd_header_big_endian (output_bfd))
5120                 {
5121                   rel->r_index[0] = r_index >> 16;
5122                   rel->r_index[1] = r_index >> 8;
5123                   rel->r_index[2] = r_index;
5124                 }
5125               else
5126                 {
5127                   rel->r_index[2] = r_index >> 16;
5128                   rel->r_index[1] = r_index >> 8;
5129                   rel->r_index[0] = r_index;
5130                 }
5131             }
5132           else
5133             {
5134               /* This is a relocation against a section.  We must
5135                  adjust by the amount that the section moved.  */
5136               r_section = aout_reloc_index_to_section (input_bfd, r_index);
5137               relocation = (r_section->output_section->vma
5138                             + r_section->output_offset
5139                             - r_section->vma);
5140
5141               /* If this is a PC relative reloc, then the addend is
5142                  the difference in VMA between the destination and the
5143                  source.  We have just adjusted for the change in VMA
5144                  of the destination, so we must also adjust by the
5145                  change in VMA of the source.  This is done below.  */
5146             }
5147
5148           /* As described above, we must always adjust a PC relative
5149              reloc by the change in VMA of the source.  */
5150           if (howto_table_ext[r_type].pc_relative)
5151             relocation -= (input_section->output_section->vma
5152                            + input_section->output_offset
5153                            - input_section->vma);
5154
5155           /* Change the addend if necessary.  */
5156           if (relocation != 0)
5157             PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
5158
5159           /* Change the address of the relocation.  */
5160           PUT_WORD (output_bfd,
5161                     r_addr + input_section->output_offset,
5162                     rel->r_address);
5163         }
5164       else
5165         {
5166           boolean hundef;
5167           bfd_reloc_status_type r;
5168
5169           /* We are generating an executable, and must do a full
5170              relocation.  */
5171           hundef = false;
5172           if (r_extern)
5173             {
5174               h = sym_hashes[r_index];
5175
5176               if (h != (struct aout_link_hash_entry *) NULL
5177                   && (h->root.type == bfd_link_hash_defined
5178                       || h->root.type == bfd_link_hash_defweak))
5179                 {
5180                   relocation = (h->root.u.def.value
5181                                 + h->root.u.def.section->output_section->vma
5182                                 + h->root.u.def.section->output_offset);
5183                 }
5184               else if (h != (struct aout_link_hash_entry *) NULL
5185                        && h->root.type == bfd_link_hash_undefweak)
5186                 relocation = 0;
5187               else
5188                 {
5189                   hundef = true;
5190                   relocation = 0;
5191                 }
5192             }
5193           else if (r_type == RELOC_BASE10
5194                    || r_type == RELOC_BASE13
5195                    || r_type == RELOC_BASE22)
5196             {
5197               struct external_nlist *sym;
5198               int type;
5199
5200               /* For base relative relocs, r_index is always an index
5201                  into the symbol table, even if r_extern is 0.  */
5202               sym = syms + r_index;
5203               type = bfd_h_get_8 (input_bfd, sym->e_type);
5204               if ((type & N_TYPE) == N_TEXT
5205                   || type == N_WEAKT)
5206                 r_section = obj_textsec (input_bfd);
5207               else if ((type & N_TYPE) == N_DATA
5208                        || type == N_WEAKD)
5209                 r_section = obj_datasec (input_bfd);
5210               else if ((type & N_TYPE) == N_BSS
5211                        || type == N_WEAKB)
5212                 r_section = obj_bsssec (input_bfd);
5213               else if ((type & N_TYPE) == N_ABS
5214                        || type == N_WEAKA)
5215                 r_section = bfd_abs_section_ptr;
5216               else
5217                 abort ();
5218               relocation = (r_section->output_section->vma
5219                             + r_section->output_offset
5220                             + (GET_WORD (input_bfd, sym->e_value)
5221                                - r_section->vma));
5222             }
5223           else
5224             {
5225               r_section = aout_reloc_index_to_section (input_bfd, r_index);
5226
5227               /* If this is a PC relative reloc, then R_ADDEND is the
5228                  difference between the two vmas, or
5229                    old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
5230                  where
5231                    old_dest_sec == section->vma
5232                  and
5233                    old_src_sec == input_section->vma
5234                  and
5235                    old_src_off == r_addr
5236
5237                  _bfd_final_link_relocate expects RELOCATION +
5238                  R_ADDEND to be the VMA of the destination minus
5239                  r_addr (the minus r_addr is because this relocation
5240                  is not pcrel_offset, which is a bit confusing and
5241                  should, perhaps, be changed), or
5242                    new_dest_sec
5243                  where
5244                    new_dest_sec == output_section->vma + output_offset
5245                  We arrange for this to happen by setting RELOCATION to
5246                    new_dest_sec + old_src_sec - old_dest_sec
5247
5248                  If this is not a PC relative reloc, then R_ADDEND is
5249                  simply the VMA of the destination, so we set
5250                  RELOCATION to the change in the destination VMA, or
5251                    new_dest_sec - old_dest_sec
5252                  */
5253               relocation = (r_section->output_section->vma
5254                             + r_section->output_offset
5255                             - r_section->vma);
5256               if (howto_table_ext[r_type].pc_relative)
5257                 relocation += input_section->vma;
5258             }
5259
5260           if (check_dynamic_reloc != NULL)
5261             {
5262               boolean skip;
5263
5264               if (! ((*check_dynamic_reloc)
5265                      (finfo->info, input_bfd, input_section, h,
5266                       (PTR) rel, contents, &skip, &relocation)))
5267                 return false;
5268               if (skip)
5269                 continue;
5270             }
5271
5272           /* Now warn if a global symbol is undefined.  We could not
5273              do this earlier, because check_dynamic_reloc might want
5274              to skip this reloc.  */
5275           if (hundef
5276               && ! finfo->info->shared
5277               && r_type != RELOC_BASE10
5278               && r_type != RELOC_BASE13
5279               && r_type != RELOC_BASE22)
5280             {
5281               const char *name;
5282
5283               if (h != NULL)
5284                 name = h->root.root.string;
5285               else
5286                 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
5287               if (! ((*finfo->info->callbacks->undefined_symbol)
5288                      (finfo->info, name, input_bfd, input_section, r_addr)))
5289                 return false;
5290             }
5291
5292           r = MY_final_link_relocate (howto_table_ext + r_type,
5293                                       input_bfd, input_section,
5294                                       contents, r_addr, relocation,
5295                                       r_addend);
5296           if (r != bfd_reloc_ok)
5297             {
5298               switch (r)
5299                 {
5300                 default:
5301                 case bfd_reloc_outofrange:
5302                   abort ();
5303                 case bfd_reloc_overflow:
5304                   {
5305                     const char *name;
5306
5307                     if (h != NULL)
5308                       name = h->root.root.string;
5309                     else if (r_extern
5310                              || r_type == RELOC_BASE10
5311                              || r_type == RELOC_BASE13
5312                              || r_type == RELOC_BASE22)
5313                       name = strings + GET_WORD (input_bfd,
5314                                                  syms[r_index].e_strx);
5315                     else
5316                       {
5317                         asection *s;
5318
5319                         s = aout_reloc_index_to_section (input_bfd, r_index);
5320                         name = bfd_section_name (input_bfd, s);
5321                       }
5322                     if (! ((*finfo->info->callbacks->reloc_overflow)
5323                            (finfo->info, name, howto_table_ext[r_type].name,
5324                             r_addend, input_bfd, input_section, r_addr)))
5325                       return false;
5326                   }
5327                   break;
5328                 }
5329             }
5330         }
5331     }
5332
5333   return true;
5334 }
5335
5336 /* Handle a link order which is supposed to generate a reloc.  */
5337
5338 static boolean
5339 aout_link_reloc_link_order (finfo, o, p)
5340      struct aout_final_link_info *finfo;
5341      asection *o;
5342      struct bfd_link_order *p;
5343 {
5344   struct bfd_link_order_reloc *pr;
5345   int r_index;
5346   int r_extern;
5347   reloc_howto_type *howto;
5348   file_ptr *reloff_ptr;
5349   struct reloc_std_external srel;
5350   struct reloc_ext_external erel;
5351   PTR rel_ptr;
5352
5353   pr = p->u.reloc.p;
5354
5355   if (p->type == bfd_section_reloc_link_order)
5356     {
5357       r_extern = 0;
5358       if (bfd_is_abs_section (pr->u.section))
5359         r_index = N_ABS | N_EXT;
5360       else
5361         {
5362           BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
5363           r_index = pr->u.section->target_index;
5364         }
5365     }
5366   else
5367     {
5368       struct aout_link_hash_entry *h;
5369
5370       BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
5371       r_extern = 1;
5372       h = ((struct aout_link_hash_entry *)
5373            bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
5374                                          pr->u.name, false, false, true));
5375       if (h != (struct aout_link_hash_entry *) NULL
5376           && h->indx >= 0)
5377         r_index = h->indx;
5378       else if (h != NULL)
5379         {
5380           /* We decided to strip this symbol, but it turns out that we
5381              can't.  Note that we lose the other and desc information
5382              here.  I don't think that will ever matter for a global
5383              symbol.  */
5384           h->indx = -2;
5385           h->written = false;
5386           if (! aout_link_write_other_symbol (h, (PTR) finfo))
5387             return false;
5388           r_index = h->indx;
5389         }
5390       else
5391         {
5392           if (! ((*finfo->info->callbacks->unattached_reloc)
5393                  (finfo->info, pr->u.name, (bfd *) NULL,
5394                   (asection *) NULL, (bfd_vma) 0)))
5395             return false;
5396           r_index = 0;
5397         }
5398     }
5399
5400   howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
5401   if (howto == 0)
5402     {
5403       bfd_set_error (bfd_error_bad_value);
5404       return false;
5405     }
5406
5407   if (o == obj_textsec (finfo->output_bfd))
5408     reloff_ptr = &finfo->treloff;
5409   else if (o == obj_datasec (finfo->output_bfd))
5410     reloff_ptr = &finfo->dreloff;
5411   else
5412     abort ();
5413
5414   if (obj_reloc_entry_size (finfo->output_bfd) == RELOC_STD_SIZE)
5415     {
5416 #ifdef MY_put_reloc
5417       MY_put_reloc(finfo->output_bfd, r_extern, r_index, p->offset, howto,
5418                    &srel);
5419 #else
5420       {
5421         int r_pcrel;
5422         int r_baserel;
5423         int r_jmptable;
5424         int r_relative;
5425         int r_length;
5426
5427         r_pcrel = howto->pc_relative;
5428         r_baserel = (howto->type & 8) != 0;
5429         r_jmptable = (howto->type & 16) != 0;
5430         r_relative = (howto->type & 32) != 0;
5431         r_length = howto->size;
5432
5433         PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
5434         if (bfd_header_big_endian (finfo->output_bfd))
5435           {
5436             srel.r_index[0] = r_index >> 16;
5437             srel.r_index[1] = r_index >> 8;
5438             srel.r_index[2] = r_index;
5439             srel.r_type[0] =
5440               ((r_extern ?     RELOC_STD_BITS_EXTERN_BIG : 0)
5441                | (r_pcrel ?    RELOC_STD_BITS_PCREL_BIG : 0)
5442                | (r_baserel ?  RELOC_STD_BITS_BASEREL_BIG : 0)
5443                | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
5444                | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
5445                | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG));
5446           }
5447         else
5448           {
5449             srel.r_index[2] = r_index >> 16;
5450             srel.r_index[1] = r_index >> 8;
5451             srel.r_index[0] = r_index;
5452             srel.r_type[0] =
5453               ((r_extern ?     RELOC_STD_BITS_EXTERN_LITTLE : 0)
5454                | (r_pcrel ?    RELOC_STD_BITS_PCREL_LITTLE : 0)
5455                | (r_baserel ?  RELOC_STD_BITS_BASEREL_LITTLE : 0)
5456                | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
5457                | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
5458                | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE));
5459           }
5460       }
5461 #endif
5462       rel_ptr = (PTR) &srel;
5463
5464       /* We have to write the addend into the object file, since
5465          standard a.out relocs are in place.  It would be more
5466          reliable if we had the current contents of the file here,
5467          rather than assuming zeroes, but we can't read the file since
5468          it was opened using bfd_openw.  */
5469       if (pr->addend != 0)
5470         {
5471           bfd_size_type size;
5472           bfd_reloc_status_type r;
5473           bfd_byte *buf;
5474           boolean ok;
5475
5476           size = bfd_get_reloc_size (howto);
5477           buf = (bfd_byte *) bfd_zmalloc (size);
5478           if (buf == (bfd_byte *) NULL)
5479             return false;
5480           r = MY_relocate_contents (howto, finfo->output_bfd,
5481                                       pr->addend, buf);
5482           switch (r)
5483             {
5484             case bfd_reloc_ok:
5485               break;
5486             default:
5487             case bfd_reloc_outofrange:
5488               abort ();
5489             case bfd_reloc_overflow:
5490               if (! ((*finfo->info->callbacks->reloc_overflow)
5491                      (finfo->info,
5492                       (p->type == bfd_section_reloc_link_order
5493                        ? bfd_section_name (finfo->output_bfd,
5494                                            pr->u.section)
5495                        : pr->u.name),
5496                       howto->name, pr->addend, (bfd *) NULL,
5497                       (asection *) NULL, (bfd_vma) 0)))
5498                 {
5499                   free (buf);
5500                   return false;
5501                 }
5502               break;
5503             }
5504           ok = bfd_set_section_contents (finfo->output_bfd, o,
5505                                          (PTR) buf,
5506                                          (file_ptr) p->offset,
5507                                          size);
5508           free (buf);
5509           if (! ok)
5510             return false;
5511         }
5512     }
5513   else
5514     {
5515       PUT_WORD (finfo->output_bfd, p->offset, erel.r_address);
5516
5517       if (bfd_header_big_endian (finfo->output_bfd))
5518         {
5519           erel.r_index[0] = r_index >> 16;
5520           erel.r_index[1] = r_index >> 8;
5521           erel.r_index[2] = r_index;
5522           erel.r_type[0] =
5523             ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
5524              | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG));
5525         }
5526       else
5527         {
5528           erel.r_index[2] = r_index >> 16;
5529           erel.r_index[1] = r_index >> 8;
5530           erel.r_index[0] = r_index;
5531           erel.r_type[0] =
5532             (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
5533               | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
5534         }
5535
5536       PUT_WORD (finfo->output_bfd, pr->addend, erel.r_addend);
5537
5538       rel_ptr = (PTR) &erel;
5539     }
5540
5541   if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
5542       || (bfd_write (rel_ptr, (bfd_size_type) 1,
5543                      obj_reloc_entry_size (finfo->output_bfd),
5544                      finfo->output_bfd)
5545           != obj_reloc_entry_size (finfo->output_bfd)))
5546     return false;
5547
5548   *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd);
5549
5550   /* Assert that the relocs have not run into the symbols, and that n
5551      the text relocs have not run into the data relocs.  */
5552   BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
5553               && (reloff_ptr != &finfo->treloff
5554                   || (*reloff_ptr
5555                       <= obj_datasec (finfo->output_bfd)->rel_filepos)));
5556
5557   return true;
5558 }