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