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