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