* aoutx.h (translate_from_native_sym_flags): Don't try to stuff
[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       cache_ptr->symbol.section = bfd_abs_section_ptr;
1485       break;
1486
1487     case N_INDR: case N_INDR | N_EXT:
1488       /* An indirect symbol.  This consists of two symbols in a row.
1489          The first symbol is the name of the indirection.  The second
1490          symbol is the name of the target.  A reference to the first
1491          symbol becomes a reference to the second.  */
1492       cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT | visible;
1493       cache_ptr->symbol.section = bfd_ind_section_ptr;
1494       break;
1495
1496     case N_WEAKU:
1497       cache_ptr->symbol.section = bfd_und_section_ptr;
1498       cache_ptr->symbol.flags = BSF_WEAK;
1499       break;
1500
1501     case N_WEAKA:
1502       cache_ptr->symbol.section = bfd_abs_section_ptr;
1503       cache_ptr->symbol.flags = BSF_WEAK;
1504       break;
1505
1506     case N_WEAKT:
1507       cache_ptr->symbol.section = obj_textsec (abfd);
1508       cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1509       cache_ptr->symbol.flags = BSF_WEAK;
1510       break;
1511
1512     case N_WEAKD:
1513       cache_ptr->symbol.section = obj_datasec (abfd);
1514       cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1515       cache_ptr->symbol.flags = BSF_WEAK;
1516       break;
1517
1518     case N_WEAKB:
1519       cache_ptr->symbol.section = obj_bsssec (abfd);
1520       cache_ptr->symbol.value -= cache_ptr->symbol.section->vma;
1521       cache_ptr->symbol.flags = BSF_WEAK;
1522       break;
1523     }
1524
1525   return true;
1526 }
1527
1528 /* Set the fields of SYM_POINTER according to CACHE_PTR.  */
1529
1530 static boolean
1531 translate_to_native_sym_flags (abfd, cache_ptr, sym_pointer)
1532      bfd *abfd;
1533      asymbol *cache_ptr;
1534      struct external_nlist *sym_pointer;
1535 {
1536   bfd_vma value = cache_ptr->value;
1537   asection *sec;
1538   bfd_vma off;
1539
1540   /* Mask out any existing type bits in case copying from one section
1541      to another.  */
1542   sym_pointer->e_type[0] &= ~N_TYPE;
1543
1544   sec = bfd_get_section (cache_ptr);
1545   off = 0;
1546
1547   if (sec == NULL)
1548     {
1549       /* This case occurs, e.g., for the *DEBUG* section of a COFF
1550          file.  */
1551       bfd_set_error (bfd_error_nonrepresentable_section);
1552       return false;
1553     }
1554
1555   if (sec->output_section != NULL)
1556     {
1557       off = sec->output_offset;
1558       sec = sec->output_section;
1559     }
1560
1561   if (bfd_is_abs_section (sec))
1562     sym_pointer->e_type[0] |= N_ABS;
1563   else if (sec == obj_textsec (abfd))
1564     sym_pointer->e_type[0] |= N_TEXT;
1565   else if (sec == obj_datasec (abfd))
1566     sym_pointer->e_type[0] |= N_DATA;
1567   else if (sec == obj_bsssec (abfd))
1568     sym_pointer->e_type[0] |= N_BSS;
1569   else if (bfd_is_und_section (sec))
1570     sym_pointer->e_type[0] = N_UNDF | N_EXT;
1571   else if (bfd_is_ind_section (sec))
1572     sym_pointer->e_type[0] = N_INDR;
1573   else if (bfd_is_com_section (sec))
1574     sym_pointer->e_type[0] = N_UNDF | N_EXT;
1575   else
1576     {
1577       bfd_set_error (bfd_error_nonrepresentable_section);
1578       return false;
1579     }
1580
1581   /* Turn the symbol from section relative to absolute again */
1582   value += sec->vma + off;
1583
1584   if ((cache_ptr->flags & BSF_WARNING) != 0)
1585     sym_pointer->e_type[0] = N_WARNING;
1586
1587   if ((cache_ptr->flags & BSF_DEBUGGING) != 0)
1588     sym_pointer->e_type[0] = ((aout_symbol_type *) cache_ptr)->type;
1589   else if ((cache_ptr->flags & BSF_GLOBAL) != 0)
1590     sym_pointer->e_type[0] |= N_EXT;
1591
1592   if ((cache_ptr->flags & BSF_CONSTRUCTOR) != 0)
1593     {
1594       int type = ((aout_symbol_type *) cache_ptr)->type;
1595       switch (type)
1596         {
1597         case N_ABS:     type = N_SETA; break;
1598         case N_TEXT:    type = N_SETT; break;
1599         case N_DATA:    type = N_SETD; break;
1600         case N_BSS:     type = N_SETB; break;
1601         }
1602       sym_pointer->e_type[0] = type;
1603     }
1604
1605   if ((cache_ptr->flags & BSF_WEAK) != 0)
1606     {
1607       int type;
1608
1609       switch (sym_pointer->e_type[0] & N_TYPE)
1610         {
1611         default:
1612         case N_ABS:     type = N_WEAKA; break;
1613         case N_TEXT:    type = N_WEAKT; break;
1614         case N_DATA:    type = N_WEAKD; break;
1615         case N_BSS:     type = N_WEAKB; break;
1616         case N_UNDF:    type = N_WEAKU; break;
1617         }
1618       sym_pointer->e_type[0] = type;
1619     }
1620
1621   PUT_WORD(abfd, value, sym_pointer->e_value);
1622
1623   return true;
1624 }
1625 \f
1626 /* Native-level interface to symbols. */
1627
1628 asymbol *
1629 NAME(aout,make_empty_symbol) (abfd)
1630      bfd *abfd;
1631 {
1632   aout_symbol_type  *new =
1633     (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1634   if (!new)
1635     {
1636       bfd_set_error (bfd_error_no_memory);
1637       return NULL;
1638     }
1639   new->symbol.the_bfd = abfd;
1640
1641   return &new->symbol;
1642 }
1643
1644 /* Translate a set of internal symbols into external symbols.  */
1645
1646 boolean
1647 NAME(aout,translate_symbol_table) (abfd, in, ext, count, str, strsize, dynamic)
1648      bfd *abfd;
1649      aout_symbol_type *in;
1650      struct external_nlist *ext;
1651      bfd_size_type count;
1652      char *str;
1653      bfd_size_type strsize;
1654      boolean dynamic;
1655 {
1656   struct external_nlist *ext_end;
1657
1658   ext_end = ext + count;
1659   for (; ext < ext_end; ext++, in++)
1660     {
1661       bfd_vma x;
1662
1663       x = GET_WORD (abfd, ext->e_strx);
1664       in->symbol.the_bfd = abfd;
1665
1666       /* For the normal symbols, the zero index points at the number
1667          of bytes in the string table but is to be interpreted as the
1668          null string.  For the dynamic symbols, the number of bytes in
1669          the string table is stored in the __DYNAMIC structure and the
1670          zero index points at an actual string.  */
1671       if (x == 0 && ! dynamic)
1672         in->symbol.name = "";
1673       else if (x < strsize)
1674         in->symbol.name = str + x;
1675       else
1676         return false;
1677
1678       in->symbol.value = GET_SWORD (abfd,  ext->e_value);
1679       in->desc = bfd_h_get_16 (abfd, ext->e_desc);
1680       in->other = bfd_h_get_8 (abfd, ext->e_other);
1681       in->type = bfd_h_get_8 (abfd,  ext->e_type);
1682       in->symbol.udata.p = NULL;
1683
1684       if (! translate_from_native_sym_flags (abfd, in))
1685         return false;
1686
1687       if (dynamic)
1688         in->symbol.flags |= BSF_DYNAMIC;
1689     }
1690
1691   return true;
1692 }
1693
1694 /* We read the symbols into a buffer, which is discarded when this
1695    function exits.  We read the strings into a buffer large enough to
1696    hold them all plus all the cached symbol entries. */
1697
1698 boolean
1699 NAME(aout,slurp_symbol_table) (abfd)
1700      bfd *abfd;
1701 {
1702   struct external_nlist *old_external_syms;
1703   aout_symbol_type *cached;
1704   size_t cached_size;
1705
1706   /* If there's no work to be done, don't do any */
1707   if (obj_aout_symbols (abfd) != (aout_symbol_type *) NULL)
1708     return true;
1709
1710   old_external_syms = obj_aout_external_syms (abfd);
1711
1712   if (! aout_get_external_symbols (abfd))
1713     return false;
1714
1715   cached_size = (obj_aout_external_sym_count (abfd)
1716                  * sizeof (aout_symbol_type));
1717   cached = (aout_symbol_type *) malloc (cached_size);
1718   if (cached == NULL && cached_size != 0)
1719     {
1720       bfd_set_error (bfd_error_no_memory);
1721       return false;
1722     }
1723   if (cached_size != 0)
1724     memset (cached, 0, cached_size);
1725
1726   /* Convert from external symbol information to internal.  */
1727   if (! (NAME(aout,translate_symbol_table)
1728          (abfd, cached,
1729           obj_aout_external_syms (abfd),
1730           obj_aout_external_sym_count (abfd),
1731           obj_aout_external_strings (abfd),
1732           obj_aout_external_string_size (abfd),
1733           false)))
1734     {
1735       free (cached);
1736       return false;
1737     }
1738
1739   bfd_get_symcount (abfd) = obj_aout_external_sym_count (abfd);
1740
1741   obj_aout_symbols (abfd) = cached;
1742
1743   /* It is very likely that anybody who calls this function will not
1744      want the external symbol information, so if it was allocated
1745      because of our call to aout_get_external_symbols, we free it up
1746      right away to save space.  */
1747   if (old_external_syms == (struct external_nlist *) NULL
1748       && obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
1749     {
1750       free (obj_aout_external_syms (abfd));
1751       obj_aout_external_syms (abfd) = NULL;
1752     }
1753
1754   return true;
1755 }
1756 \f
1757 /* We use a hash table when writing out symbols so that we only write
1758    out a particular string once.  This helps particularly when the
1759    linker writes out stabs debugging entries, because each different
1760    contributing object file tends to have many duplicate stabs
1761    strings.
1762
1763    This hash table code breaks dbx on SunOS 4.1.3, so we don't do it
1764    if BFD_TRADITIONAL_FORMAT is set.  */
1765
1766 static bfd_size_type add_to_stringtab
1767   PARAMS ((bfd *, struct bfd_strtab_hash *, const char *, boolean));
1768 static boolean emit_stringtab PARAMS ((bfd *, struct bfd_strtab_hash *));
1769
1770 /* Get the index of a string in a strtab, adding it if it is not
1771    already present.  */
1772
1773 static INLINE bfd_size_type
1774 add_to_stringtab (abfd, tab, str, copy)
1775      bfd *abfd;
1776      struct bfd_strtab_hash *tab;
1777      const char *str;
1778      boolean copy;
1779 {
1780   boolean hash;
1781   bfd_size_type index;
1782
1783   /* An index of 0 always means the empty string.  */
1784   if (str == 0 || *str == '\0')
1785     return 0;
1786
1787   /* Don't hash if BFD_TRADITIONAL_FORMAT is set, because SunOS dbx
1788      doesn't understand a hashed string table.  */
1789   hash = true;
1790   if ((abfd->flags & BFD_TRADITIONAL_FORMAT) != 0)
1791     hash = false;
1792
1793   index = _bfd_stringtab_add (tab, str, hash, copy);
1794
1795   if (index != (bfd_size_type) -1)
1796     {
1797       /* Add BYTES_IN_WORD to the return value to account for the
1798          space taken up by the string table size.  */
1799       index += BYTES_IN_WORD;
1800     }
1801
1802   return index;
1803 }
1804
1805 /* Write out a strtab.  ABFD is already at the right location in the
1806    file.  */
1807
1808 static boolean
1809 emit_stringtab (abfd, tab)
1810      register bfd *abfd;
1811      struct bfd_strtab_hash *tab;
1812 {
1813   bfd_byte buffer[BYTES_IN_WORD];
1814
1815   /* The string table starts with the size.  */
1816   PUT_WORD (abfd, _bfd_stringtab_size (tab) + BYTES_IN_WORD, buffer);
1817   if (bfd_write ((PTR) buffer, 1, BYTES_IN_WORD, abfd) != BYTES_IN_WORD)
1818     return false;
1819
1820   return _bfd_stringtab_emit (abfd, tab);
1821 }
1822 \f
1823 boolean
1824 NAME(aout,write_syms) (abfd)
1825      bfd *abfd;
1826 {
1827   unsigned int count ;
1828   asymbol **generic = bfd_get_outsymbols (abfd);
1829   struct bfd_strtab_hash *strtab;
1830
1831   strtab = _bfd_stringtab_init ();
1832   if (strtab == NULL)
1833     return false;
1834
1835   for (count = 0; count < bfd_get_symcount (abfd); count++)
1836     {
1837       asymbol *g = generic[count];
1838       bfd_size_type indx;
1839       struct external_nlist nsp;
1840
1841       indx = add_to_stringtab (abfd, strtab, g->name, false);
1842       if (indx == (bfd_size_type) -1)
1843         goto error_return;
1844       PUT_WORD (abfd, indx, (bfd_byte *) nsp.e_strx);
1845
1846       if (bfd_asymbol_flavour(g) == abfd->xvec->flavour)
1847         {
1848           bfd_h_put_16(abfd, aout_symbol(g)->desc,  nsp.e_desc);
1849           bfd_h_put_8(abfd, aout_symbol(g)->other,  nsp.e_other);
1850           bfd_h_put_8(abfd, aout_symbol(g)->type,  nsp.e_type);
1851         }
1852       else
1853         {
1854           bfd_h_put_16(abfd,0, nsp.e_desc);
1855           bfd_h_put_8(abfd, 0, nsp.e_other);
1856           bfd_h_put_8(abfd, 0, nsp.e_type);
1857         }
1858
1859       if (! translate_to_native_sym_flags (abfd, g, &nsp))
1860         goto error_return;
1861
1862       if (bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd)
1863           != EXTERNAL_NLIST_SIZE)
1864         goto error_return;
1865
1866       /* NB: `KEEPIT' currently overlays `udata.p', so set this only
1867          here, at the end.  */
1868       g->KEEPIT = count;
1869     }
1870
1871   if (! emit_stringtab (abfd, strtab))
1872     goto error_return;
1873
1874   _bfd_stringtab_free (strtab);
1875
1876   return true;
1877
1878 error_return:
1879   _bfd_stringtab_free (strtab);
1880   return false;
1881 }
1882
1883 \f
1884 long
1885 NAME(aout,get_symtab) (abfd, location)
1886      bfd *abfd;
1887      asymbol **location;
1888 {
1889     unsigned int counter = 0;
1890     aout_symbol_type *symbase;
1891
1892     if (!NAME(aout,slurp_symbol_table)(abfd))
1893       return -1;
1894
1895     for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1896       *(location++) = (asymbol *)( symbase++);
1897     *location++ =0;
1898     return bfd_get_symcount (abfd);
1899 }
1900
1901 \f
1902 /* Standard reloc stuff */
1903 /* Output standard relocation information to a file in target byte order. */
1904
1905 void
1906 NAME(aout,swap_std_reloc_out) (abfd, g, natptr)
1907      bfd *abfd;
1908      arelent *g;
1909      struct reloc_std_external *natptr;
1910 {
1911   int r_index;
1912   asymbol *sym = *(g->sym_ptr_ptr);
1913   int r_extern;
1914   unsigned int r_length;
1915   int r_pcrel;
1916   int r_baserel, r_jmptable, r_relative;
1917   asection *output_section = sym->section->output_section;
1918
1919   PUT_WORD(abfd, g->address, natptr->r_address);
1920
1921   r_length = g->howto->size ;   /* Size as a power of two */
1922   r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC? */
1923   /* XXX This relies on relocs coming from a.out files.  */
1924   r_baserel = (g->howto->type & 8) != 0;
1925   r_jmptable = (g->howto->type & 16) != 0;
1926   r_relative = (g->howto->type & 32) != 0;
1927
1928 #if 0
1929   /* For a standard reloc, the addend is in the object file.  */
1930   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
1931 #endif
1932
1933   /* name was clobbered by aout_write_syms to be symbol index */
1934
1935   /* If this relocation is relative to a symbol then set the
1936      r_index to the symbols index, and the r_extern bit.
1937
1938      Absolute symbols can come in in two ways, either as an offset
1939      from the abs section, or as a symbol which has an abs value.
1940      check for that here
1941      */
1942
1943
1944   if (bfd_is_com_section (output_section)
1945       || bfd_is_abs_section (output_section)
1946       || bfd_is_und_section (output_section))
1947     {
1948       if (bfd_abs_section_ptr->symbol == sym)
1949       {
1950         /* Whoops, looked like an abs symbol, but is really an offset
1951            from the abs section */
1952         r_index = 0;
1953         r_extern = 0;
1954        }
1955       else
1956       {
1957         /* Fill in symbol */
1958         r_extern = 1;
1959         r_index = (*(g->sym_ptr_ptr))->KEEPIT;
1960
1961       }
1962     }
1963   else
1964     {
1965       /* Just an ordinary section */
1966       r_extern = 0;
1967       r_index  = output_section->target_index;
1968     }
1969
1970   /* now the fun stuff */
1971   if (abfd->xvec->header_byteorder_big_p != false) {
1972       natptr->r_index[0] = r_index >> 16;
1973       natptr->r_index[1] = r_index >> 8;
1974       natptr->r_index[2] = r_index;
1975       natptr->r_type[0] =
1976        (r_extern?    RELOC_STD_BITS_EXTERN_BIG: 0)
1977         | (r_pcrel?     RELOC_STD_BITS_PCREL_BIG: 0)
1978          | (r_baserel?   RELOC_STD_BITS_BASEREL_BIG: 0)
1979           | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_BIG: 0)
1980            | (r_relative?  RELOC_STD_BITS_RELATIVE_BIG: 0)
1981             | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG);
1982     } else {
1983         natptr->r_index[2] = r_index >> 16;
1984         natptr->r_index[1] = r_index >> 8;
1985         natptr->r_index[0] = r_index;
1986         natptr->r_type[0] =
1987          (r_extern?    RELOC_STD_BITS_EXTERN_LITTLE: 0)
1988           | (r_pcrel?     RELOC_STD_BITS_PCREL_LITTLE: 0)
1989            | (r_baserel?   RELOC_STD_BITS_BASEREL_LITTLE: 0)
1990             | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1991              | (r_relative?  RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1992               | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE);
1993       }
1994 }
1995
1996
1997 /* Extended stuff */
1998 /* Output extended relocation information to a file in target byte order. */
1999
2000 void
2001 NAME(aout,swap_ext_reloc_out) (abfd, g, natptr)
2002      bfd *abfd;
2003      arelent *g;
2004      register struct reloc_ext_external *natptr;
2005 {
2006   int r_index;
2007   int r_extern;
2008   unsigned int r_type;
2009   unsigned int r_addend;
2010   asymbol *sym = *(g->sym_ptr_ptr);
2011   asection *output_section = sym->section->output_section;
2012
2013   PUT_WORD (abfd, g->address, natptr->r_address);
2014
2015   r_type = (unsigned int) g->howto->type;
2016
2017   r_addend = g->addend;
2018   if ((sym->flags & BSF_SECTION_SYM) != 0)
2019     r_addend += (*(g->sym_ptr_ptr))->section->output_section->vma;
2020
2021   /* If this relocation is relative to a symbol then set the
2022      r_index to the symbols index, and the r_extern bit.
2023
2024      Absolute symbols can come in in two ways, either as an offset
2025      from the abs section, or as a symbol which has an abs value.
2026      check for that here.  */
2027
2028   if (bfd_is_abs_section (bfd_get_section (sym)))
2029     {
2030       r_extern = 0;
2031       r_index = 0;
2032     }
2033   else if ((sym->flags & BSF_SECTION_SYM) == 0)
2034     {
2035       if (bfd_is_und_section (bfd_get_section (sym))
2036           || (sym->flags & BSF_GLOBAL) != 0)
2037         r_extern = 1;
2038       else
2039         r_extern = 0;
2040       r_index = (*(g->sym_ptr_ptr))->KEEPIT;
2041     }
2042   else
2043     {
2044       /* Just an ordinary section */
2045       r_extern = 0;
2046       r_index = output_section->target_index;
2047     }
2048
2049   /* now the fun stuff */
2050   if (abfd->xvec->header_byteorder_big_p != false) {
2051     natptr->r_index[0] = r_index >> 16;
2052     natptr->r_index[1] = r_index >> 8;
2053     natptr->r_index[2] = r_index;
2054     natptr->r_type[0] =
2055       ((r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
2056        | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
2057   } else {
2058     natptr->r_index[2] = r_index >> 16;
2059     natptr->r_index[1] = r_index >> 8;
2060     natptr->r_index[0] = r_index;
2061     natptr->r_type[0] =
2062      (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
2063       | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
2064   }
2065
2066   PUT_WORD (abfd, r_addend, natptr->r_addend);
2067 }
2068
2069 /* BFD deals internally with all things based from the section they're
2070    in. so, something in 10 bytes into a text section  with a base of
2071    50 would have a symbol (.text+10) and know .text vma was 50.
2072
2073    Aout keeps all it's symbols based from zero, so the symbol would
2074    contain 60. This macro subs the base of each section from the value
2075    to give the true offset from the section */
2076
2077
2078 #define MOVE_ADDRESS(ad)                                                \
2079   if (r_extern) {                                                       \
2080    /* undefined symbol */                                               \
2081      cache_ptr->sym_ptr_ptr = symbols + r_index;                        \
2082      cache_ptr->addend = ad;                                            \
2083      } else {                                                           \
2084     /* defined, section relative. replace symbol with pointer to        \
2085        symbol which points to section  */                               \
2086     switch (r_index) {                                                  \
2087     case N_TEXT:                                                        \
2088     case N_TEXT | N_EXT:                                                \
2089       cache_ptr->sym_ptr_ptr  = obj_textsec(abfd)->symbol_ptr_ptr;      \
2090       cache_ptr->addend = ad  - su->textsec->vma;                       \
2091       break;                                                            \
2092     case N_DATA:                                                        \
2093     case N_DATA | N_EXT:                                                \
2094       cache_ptr->sym_ptr_ptr  = obj_datasec(abfd)->symbol_ptr_ptr;      \
2095       cache_ptr->addend = ad - su->datasec->vma;                        \
2096       break;                                                            \
2097     case N_BSS:                                                         \
2098     case N_BSS | N_EXT:                                                 \
2099       cache_ptr->sym_ptr_ptr  = obj_bsssec(abfd)->symbol_ptr_ptr;       \
2100       cache_ptr->addend = ad - su->bsssec->vma;                         \
2101       break;                                                            \
2102     default:                                                            \
2103     case N_ABS:                                                         \
2104     case N_ABS | N_EXT:                                                 \
2105      cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;      \
2106       cache_ptr->addend = ad;                                           \
2107       break;                                                            \
2108     }                                                                   \
2109   }                                                                     \
2110
2111 void
2112 NAME(aout,swap_ext_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
2113      bfd *abfd;
2114      struct reloc_ext_external *bytes;
2115      arelent *cache_ptr;
2116      asymbol **symbols;
2117      bfd_size_type symcount;
2118 {
2119   unsigned int r_index;
2120   int r_extern;
2121   unsigned int r_type;
2122   struct aoutdata *su = &(abfd->tdata.aout_data->a);
2123
2124   cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
2125
2126   /* now the fun stuff */
2127   if (abfd->xvec->header_byteorder_big_p != false) {
2128     r_index =  (bytes->r_index[0] << 16)
2129              | (bytes->r_index[1] << 8)
2130              |  bytes->r_index[2];
2131     r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
2132     r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
2133                                       >> RELOC_EXT_BITS_TYPE_SH_BIG;
2134   } else {
2135     r_index =  (bytes->r_index[2] << 16)
2136              | (bytes->r_index[1] << 8)
2137              |  bytes->r_index[0];
2138     r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
2139     r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
2140                                       >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
2141   }
2142
2143   cache_ptr->howto =  howto_table_ext + r_type;
2144
2145   /* Base relative relocs are always against the symbol table,
2146      regardless of the setting of r_extern.  r_extern just reflects
2147      whether the symbol the reloc is against is local or global.  */
2148   if (r_type == RELOC_BASE10
2149       || r_type == RELOC_BASE13
2150       || r_type == RELOC_BASE22)
2151     r_extern = 1;
2152
2153   if (r_extern && r_index > symcount)
2154     {
2155       /* We could arrange to return an error, but it might be useful
2156          to see the file even if it is bad.  */
2157       r_extern = 0;
2158       r_index = N_ABS;
2159     }
2160
2161   MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend));
2162 }
2163
2164 void
2165 NAME(aout,swap_std_reloc_in) (abfd, bytes, cache_ptr, symbols, symcount)
2166      bfd *abfd;
2167      struct reloc_std_external *bytes;
2168      arelent *cache_ptr;
2169      asymbol **symbols;
2170      bfd_size_type symcount;
2171 {
2172   unsigned int r_index;
2173   int r_extern;
2174   unsigned int r_length;
2175   int r_pcrel;
2176   int r_baserel, r_jmptable, r_relative;
2177   struct aoutdata  *su = &(abfd->tdata.aout_data->a);
2178   unsigned int howto_idx;
2179
2180   cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
2181
2182   /* now the fun stuff */
2183   if (abfd->xvec->header_byteorder_big_p != false) {
2184     r_index =  (bytes->r_index[0] << 16)
2185       | (bytes->r_index[1] << 8)
2186         |  bytes->r_index[2];
2187     r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
2188     r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
2189     r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
2190     r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
2191     r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
2192     r_length  =       (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
2193                         >> RELOC_STD_BITS_LENGTH_SH_BIG;
2194   } else {
2195     r_index =  (bytes->r_index[2] << 16)
2196       | (bytes->r_index[1] << 8)
2197         |  bytes->r_index[0];
2198     r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
2199     r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
2200     r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
2201     r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
2202     r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
2203     r_length  =       (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
2204                         >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
2205   }
2206
2207   howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel
2208               + 16 * r_jmptable + 32 * r_relative;
2209   BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
2210   cache_ptr->howto =  howto_table_std + howto_idx;
2211   BFD_ASSERT (cache_ptr->howto->type != (unsigned int) -1);
2212
2213   /* Base relative relocs are always against the symbol table,
2214      regardless of the setting of r_extern.  r_extern just reflects
2215      whether the symbol the reloc is against is local or global.  */
2216   if (r_baserel)
2217     r_extern = 1;
2218
2219   if (r_extern && r_index > symcount)
2220     {
2221       /* We could arrange to return an error, but it might be useful
2222          to see the file even if it is bad.  */
2223       r_extern = 0;
2224       r_index = N_ABS;
2225     }
2226
2227   MOVE_ADDRESS(0);
2228 }
2229
2230 /* Read and swap the relocs for a section.  */
2231
2232 boolean
2233 NAME(aout,slurp_reloc_table) (abfd, asect, symbols)
2234      bfd *abfd;
2235      sec_ptr asect;
2236      asymbol **symbols;
2237 {
2238   unsigned int count;
2239   bfd_size_type reloc_size;
2240   PTR relocs;
2241   arelent *reloc_cache;
2242   size_t each_size;
2243   unsigned int counter = 0;
2244   arelent *cache_ptr;
2245
2246   if (asect->relocation)
2247     return true;
2248
2249   if (asect->flags & SEC_CONSTRUCTOR)
2250     return true;
2251
2252   if (asect == obj_datasec (abfd))
2253     reloc_size = exec_hdr(abfd)->a_drsize;
2254   else if (asect == obj_textsec (abfd))
2255     reloc_size = exec_hdr(abfd)->a_trsize;
2256   else if (asect == obj_bsssec (abfd))
2257     reloc_size = 0;
2258   else
2259     {
2260       bfd_set_error (bfd_error_invalid_operation);
2261       return false;
2262     }
2263
2264   if (bfd_seek (abfd, asect->rel_filepos, SEEK_SET) != 0)
2265     return false;
2266
2267   each_size = obj_reloc_entry_size (abfd);
2268
2269   count = reloc_size / each_size;
2270
2271   reloc_cache = (arelent *) malloc ((size_t) (count * sizeof (arelent)));
2272   if (reloc_cache == NULL && count != 0)
2273     {
2274       bfd_set_error (bfd_error_no_memory);
2275       return false;
2276     }
2277   memset (reloc_cache, 0, count * sizeof (arelent));
2278
2279   relocs = malloc ((size_t) reloc_size);
2280   if (relocs == NULL && reloc_size != 0)
2281     {
2282       free (reloc_cache);
2283       bfd_set_error (bfd_error_no_memory);
2284       return false;
2285     }
2286
2287   if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size)
2288     {
2289       free (relocs);
2290       free (reloc_cache);
2291       return false;
2292     }
2293
2294   cache_ptr = reloc_cache;
2295   if (each_size == RELOC_EXT_SIZE)
2296     {
2297       register struct reloc_ext_external *rptr =
2298         (struct reloc_ext_external *) relocs;
2299
2300       for (; counter < count; counter++, rptr++, cache_ptr++)
2301         NAME(aout,swap_ext_reloc_in) (abfd, rptr, cache_ptr, symbols,
2302                                       bfd_get_symcount (abfd));
2303     }
2304   else
2305     {
2306       register struct reloc_std_external *rptr =
2307         (struct reloc_std_external *) relocs;
2308
2309       for (; counter < count; counter++, rptr++, cache_ptr++)
2310         MY_swap_std_reloc_in (abfd, rptr, cache_ptr, symbols,
2311                               bfd_get_symcount (abfd));
2312     }
2313
2314   free (relocs);
2315
2316   asect->relocation = reloc_cache;
2317   asect->reloc_count = cache_ptr - reloc_cache;
2318
2319   return true;
2320 }
2321
2322 /* Write out a relocation section into an object file.  */
2323
2324 boolean
2325 NAME(aout,squirt_out_relocs) (abfd, section)
2326      bfd *abfd;
2327      asection *section;
2328 {
2329   arelent **generic;
2330   unsigned char *native, *natptr;
2331   size_t each_size;
2332
2333   unsigned int count = section->reloc_count;
2334   size_t natsize;
2335
2336   if (count == 0) return true;
2337
2338   each_size = obj_reloc_entry_size (abfd);
2339   natsize = each_size * count;
2340   native = (unsigned char *) bfd_zalloc (abfd, natsize);
2341   if (!native) {
2342     bfd_set_error (bfd_error_no_memory);
2343     return false;
2344   }
2345
2346   generic = section->orelocation;
2347
2348   if (each_size == RELOC_EXT_SIZE)
2349     {
2350       for (natptr = native;
2351            count != 0;
2352            --count, natptr += each_size, ++generic)
2353         NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
2354     }
2355   else
2356     {
2357       for (natptr = native;
2358            count != 0;
2359            --count, natptr += each_size, ++generic)
2360         MY_swap_std_reloc_out(abfd, *generic, (struct reloc_std_external *)natptr);
2361     }
2362
2363   if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
2364     bfd_release(abfd, native);
2365     return false;
2366   }
2367   bfd_release (abfd, native);
2368
2369   return true;
2370 }
2371
2372 /* This is stupid.  This function should be a boolean predicate */
2373 long
2374 NAME(aout,canonicalize_reloc) (abfd, section, relptr, symbols)
2375      bfd *abfd;
2376      sec_ptr section;
2377      arelent **relptr;
2378      asymbol **symbols;
2379 {
2380   arelent *tblptr = section->relocation;
2381   unsigned int count;
2382
2383   if (section == obj_bsssec (abfd))
2384     {
2385       *relptr = NULL;
2386       return 0;
2387     }
2388
2389   if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
2390     return -1;
2391
2392   if (section->flags & SEC_CONSTRUCTOR) {
2393     arelent_chain *chain = section->constructor_chain;
2394     for (count = 0; count < section->reloc_count; count ++) {
2395       *relptr ++ = &chain->relent;
2396       chain = chain->next;
2397     }
2398   }
2399   else {
2400     tblptr = section->relocation;
2401
2402     for (count = 0; count++ < section->reloc_count;)
2403       {
2404         *relptr++ = tblptr++;
2405       }
2406   }
2407   *relptr = 0;
2408
2409   return section->reloc_count;
2410 }
2411
2412 long
2413 NAME(aout,get_reloc_upper_bound) (abfd, asect)
2414      bfd *abfd;
2415      sec_ptr asect;
2416 {
2417   if (bfd_get_format (abfd) != bfd_object) {
2418     bfd_set_error (bfd_error_invalid_operation);
2419     return -1;
2420   }
2421   if (asect->flags & SEC_CONSTRUCTOR) {
2422     return (sizeof (arelent *) * (asect->reloc_count+1));
2423   }
2424
2425   if (asect == obj_datasec (abfd))
2426     return (sizeof (arelent *)
2427             * ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
2428                + 1));
2429
2430   if (asect == obj_textsec (abfd))
2431     return (sizeof (arelent *)
2432             * ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
2433                + 1));
2434
2435   if (asect == obj_bsssec (abfd))
2436     return sizeof (arelent *);
2437
2438   if (asect == obj_bsssec (abfd))
2439     return 0;
2440
2441   bfd_set_error (bfd_error_invalid_operation);
2442   return -1;
2443 }
2444
2445 \f
2446 long
2447 NAME(aout,get_symtab_upper_bound) (abfd)
2448      bfd *abfd;
2449 {
2450   if (!NAME(aout,slurp_symbol_table)(abfd))
2451     return -1;
2452
2453   return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
2454 }
2455
2456 /*ARGSUSED*/
2457  alent *
2458 NAME(aout,get_lineno) (ignore_abfd, ignore_symbol)
2459      bfd *ignore_abfd;
2460      asymbol *ignore_symbol;
2461 {
2462 return (alent *)NULL;
2463 }
2464
2465 /*ARGSUSED*/
2466 void
2467 NAME(aout,get_symbol_info) (ignore_abfd, symbol, ret)
2468      bfd *ignore_abfd;
2469      asymbol *symbol;
2470      symbol_info *ret;
2471 {
2472   bfd_symbol_info (symbol, ret);
2473
2474   if (ret->type == '?')
2475     {
2476       int type_code = aout_symbol(symbol)->type & 0xff;
2477       CONST char *stab_name = aout_stab_name(type_code);
2478       static char buf[10];
2479
2480       if (stab_name == NULL)
2481         {
2482           sprintf(buf, "(%d)", type_code);
2483           stab_name = buf;
2484         }
2485       ret->type = '-';
2486       ret->stab_other = (unsigned)(aout_symbol(symbol)->other & 0xff);
2487       ret->stab_desc = (unsigned)(aout_symbol(symbol)->desc & 0xffff);
2488       ret->stab_name = stab_name;
2489     }
2490 }
2491
2492 /*ARGSUSED*/
2493 void
2494 NAME(aout,print_symbol) (ignore_abfd, afile, symbol, how)
2495      bfd *ignore_abfd;
2496      PTR afile;
2497      asymbol *symbol;
2498      bfd_print_symbol_type how;
2499 {
2500   FILE *file = (FILE *)afile;
2501
2502   switch (how) {
2503   case bfd_print_symbol_name:
2504     if (symbol->name)
2505       fprintf(file,"%s", symbol->name);
2506     break;
2507   case bfd_print_symbol_more:
2508     fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
2509             (unsigned)(aout_symbol(symbol)->other & 0xff),
2510             (unsigned)(aout_symbol(symbol)->type));
2511     break;
2512   case bfd_print_symbol_all:
2513     {
2514    CONST char *section_name = symbol->section->name;
2515
2516
2517       bfd_print_symbol_vandf((PTR)file,symbol);
2518
2519       fprintf(file," %-5s %04x %02x %02x",
2520               section_name,
2521               (unsigned)(aout_symbol(symbol)->desc & 0xffff),
2522               (unsigned)(aout_symbol(symbol)->other & 0xff),
2523               (unsigned)(aout_symbol(symbol)->type  & 0xff));
2524       if (symbol->name)
2525         fprintf(file," %s", symbol->name);
2526     }
2527     break;
2528   }
2529 }
2530
2531 /* If we don't have to allocate more than 1MB to hold the generic
2532    symbols, we use the generic minisymbol methord: it's faster, since
2533    it only translates the symbols once, not multiple times.  */
2534 #define MINISYM_THRESHOLD (1000000 / sizeof (asymbol))
2535
2536 /* Read minisymbols.  For minisymbols, we use the unmodified a.out
2537    symbols.  The minisymbol_to_symbol function translates these into
2538    BFD asymbol structures.  */
2539
2540 long
2541 NAME(aout,read_minisymbols) (abfd, dynamic, minisymsp, sizep)
2542      bfd *abfd;
2543      boolean dynamic;
2544      PTR *minisymsp;
2545      unsigned int *sizep;
2546 {
2547   if (dynamic)
2548     {
2549       /* We could handle the dynamic symbols here as well, but it's
2550          easier to hand them off.  */
2551       return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2552     }
2553
2554   if (! aout_get_external_symbols (abfd))
2555     return -1;
2556
2557   if (obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2558     return _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep);
2559
2560   *minisymsp = (PTR) obj_aout_external_syms (abfd);
2561
2562   /* By passing the external symbols back from this routine, we are
2563      giving up control over the memory block.  Clear
2564      obj_aout_external_syms, so that we do not try to free it
2565      ourselves.  */
2566   obj_aout_external_syms (abfd) = NULL;
2567
2568   *sizep = EXTERNAL_NLIST_SIZE;
2569   return obj_aout_external_sym_count (abfd);
2570 }
2571
2572 /* Convert a minisymbol to a BFD asymbol.  A minisymbol is just an
2573    unmodified a.out symbol.  The SYM argument is a structure returned
2574    by bfd_make_empty_symbol, which we fill in here.  */
2575
2576 asymbol *
2577 NAME(aout,minisymbol_to_symbol) (abfd, dynamic, minisym, sym)
2578      bfd *abfd;
2579      boolean dynamic;
2580      const PTR minisym;
2581      asymbol *sym;
2582 {
2583   if (dynamic
2584       || obj_aout_external_sym_count (abfd) < MINISYM_THRESHOLD)
2585     return _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym);
2586
2587   memset (sym, 0, sizeof (aout_symbol_type));
2588
2589   /* We call translate_symbol_table to translate a single symbol.  */
2590   if (! (NAME(aout,translate_symbol_table)
2591          (abfd,
2592           (aout_symbol_type *) sym,
2593           (struct external_nlist *) minisym,
2594           (bfd_size_type) 1,
2595           obj_aout_external_strings (abfd),
2596           obj_aout_external_string_size (abfd),
2597           false)))
2598     return NULL;
2599
2600   return sym;
2601 }
2602
2603 /*
2604  provided a BFD, a section and an offset into the section, calculate
2605  and return the name of the source file and the line nearest to the
2606  wanted location.
2607 */
2608
2609 boolean
2610 NAME(aout,find_nearest_line)
2611      (abfd, section, symbols, offset, filename_ptr, functionname_ptr, line_ptr)
2612      bfd *abfd;
2613      asection *section;
2614      asymbol **symbols;
2615      bfd_vma offset;
2616      CONST char **filename_ptr;
2617      CONST char **functionname_ptr;
2618      unsigned int *line_ptr;
2619 {
2620   /* Run down the file looking for the filename, function and linenumber */
2621   asymbol **p;
2622   CONST char *directory_name = NULL;
2623   CONST char *main_file_name = NULL;
2624   CONST char *current_file_name = NULL;
2625   CONST char *line_file_name = NULL; /* Value of current_file_name at line number. */
2626   bfd_vma low_line_vma = 0;
2627   bfd_vma low_func_vma = 0;
2628   asymbol *func = 0;
2629   size_t filelen, funclen;
2630   char *buf;
2631
2632   *filename_ptr = abfd->filename;
2633   *functionname_ptr = 0;
2634   *line_ptr = 0;
2635   if (symbols != (asymbol **)NULL) {
2636     for (p = symbols; *p; p++) {
2637       aout_symbol_type  *q = (aout_symbol_type *)(*p);
2638     next:
2639       switch (q->type){
2640       case N_SO:
2641         main_file_name = current_file_name = q->symbol.name;
2642         /* Look ahead to next symbol to check if that too is an N_SO. */
2643         p++;
2644         if (*p == NULL)
2645           break;
2646         q = (aout_symbol_type *)(*p);
2647         if (q->type != (int)N_SO)
2648           goto next;
2649
2650         /* Found a second N_SO  First is directory; second is filename. */
2651         directory_name = current_file_name;
2652         main_file_name = current_file_name = q->symbol.name;
2653         if (obj_textsec(abfd) != section)
2654           goto done;
2655         break;
2656       case N_SOL:
2657         current_file_name = q->symbol.name;
2658         break;
2659
2660       case N_SLINE:
2661
2662       case N_DSLINE:
2663       case N_BSLINE:
2664         /* We'll keep this if it resolves nearer than the one we have
2665            already.  */
2666         if (q->symbol.value >= low_line_vma
2667             && q->symbol.value <= offset)
2668           {
2669             *line_ptr = q->desc;
2670             low_line_vma = q->symbol.value;
2671             line_file_name = current_file_name;
2672           }
2673         break;
2674       case N_FUN:
2675         {
2676           /* We'll keep this if it is nearer than the one we have already */
2677           if (q->symbol.value >= low_func_vma &&
2678               q->symbol.value <= offset) {
2679             low_func_vma = q->symbol.value;
2680             func = (asymbol *)q;
2681           }
2682           else if (q->symbol.value > offset)
2683             goto done;
2684         }
2685         break;
2686       }
2687     }
2688   }
2689
2690  done:
2691   if (*line_ptr != 0)
2692     main_file_name = line_file_name;
2693
2694   if (main_file_name == NULL
2695       || main_file_name[0] == '/'
2696       || directory_name == NULL)
2697     filelen = 0;
2698   else
2699     filelen = strlen (directory_name) + strlen (main_file_name);
2700   if (func == NULL)
2701     funclen = 0;
2702   else
2703     funclen = strlen (bfd_asymbol_name (func));
2704
2705   if (adata (abfd).line_buf != NULL)
2706     free (adata (abfd).line_buf);
2707   if (filelen + funclen == 0)
2708     adata (abfd).line_buf = buf = NULL;
2709   else
2710     {
2711       adata (abfd).line_buf = buf = (char *) malloc (filelen + funclen + 2);
2712       if (adata (abfd).line_buf == NULL)
2713         {
2714           bfd_set_error (bfd_error_no_memory);
2715           return false;
2716         }
2717     }
2718
2719   if (main_file_name != NULL)
2720     {
2721       if (main_file_name[0] == '/' || directory_name == NULL)
2722         *filename_ptr = main_file_name;
2723       else
2724         {
2725           sprintf (buf, "%s%s", directory_name, main_file_name);
2726           *filename_ptr = buf;
2727           buf += filelen + 1;
2728         }
2729     }
2730
2731   if (func)
2732     {
2733       const char *function = func->name;
2734       char *p;
2735
2736       /* The caller expects a symbol name.  We actually have a
2737          function name, without the leading underscore.  Put the
2738          underscore back in, so that the caller gets a symbol name.  */
2739       if (bfd_get_symbol_leading_char (abfd) == '\0')
2740         strcpy (buf, function);
2741       else
2742         {
2743           buf[0] = bfd_get_symbol_leading_char (abfd);
2744           strcpy (buf + 1, function);
2745         }
2746       /* Have to remove : stuff */
2747       p = strchr (buf, ':');
2748       if (p != NULL)
2749         *p = '\0';
2750       *functionname_ptr = buf;
2751     }
2752
2753   return true;
2754 }
2755
2756 /*ARGSUSED*/
2757 int
2758 NAME(aout,sizeof_headers) (abfd, execable)
2759      bfd *abfd;
2760      boolean execable;
2761 {
2762   return adata(abfd).exec_bytes_size;
2763 }
2764
2765 /* Free all information we have cached for this BFD.  We can always
2766    read it again later if we need it.  */
2767
2768 boolean
2769 NAME(aout,bfd_free_cached_info) (abfd)
2770      bfd *abfd;
2771 {
2772   asection *o;
2773
2774   if (bfd_get_format (abfd) != bfd_object)
2775     return true;
2776
2777 #define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; }
2778   BFCI_FREE (obj_aout_symbols (abfd));
2779   BFCI_FREE (obj_aout_external_syms (abfd));
2780   BFCI_FREE (obj_aout_external_strings (abfd));
2781   for (o = abfd->sections; o != (asection *) NULL; o = o->next)
2782     BFCI_FREE (o->relocation);
2783 #undef BFCI_FREE
2784
2785   return true;
2786 }
2787 \f
2788 /* a.out link code.  */
2789
2790 static boolean aout_link_add_object_symbols
2791   PARAMS ((bfd *, struct bfd_link_info *));
2792 static boolean aout_link_check_archive_element
2793   PARAMS ((bfd *, struct bfd_link_info *, boolean *));
2794 static boolean aout_link_free_symbols PARAMS ((bfd *));
2795 static boolean aout_link_check_ar_symbols
2796   PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded));
2797 static boolean aout_link_add_symbols
2798   PARAMS ((bfd *, struct bfd_link_info *));
2799
2800 /* Routine to create an entry in an a.out link hash table.  */
2801
2802 struct bfd_hash_entry *
2803 NAME(aout,link_hash_newfunc) (entry, table, string)
2804      struct bfd_hash_entry *entry;
2805      struct bfd_hash_table *table;
2806      const char *string;
2807 {
2808   struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
2809
2810   /* Allocate the structure if it has not already been allocated by a
2811      subclass.  */
2812   if (ret == (struct aout_link_hash_entry *) NULL)
2813     ret = ((struct aout_link_hash_entry *)
2814            bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry)));
2815   if (ret == (struct aout_link_hash_entry *) NULL)
2816     {
2817       bfd_set_error (bfd_error_no_memory);
2818       return (struct bfd_hash_entry *) ret;
2819     }
2820
2821   /* Call the allocation method of the superclass.  */
2822   ret = ((struct aout_link_hash_entry *)
2823          _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
2824                                  table, string));
2825   if (ret)
2826     {
2827       /* Set local fields.  */
2828       ret->written = false;
2829       ret->indx = -1;
2830     }
2831
2832   return (struct bfd_hash_entry *) ret;
2833 }
2834
2835 /* Initialize an a.out link hash table.  */
2836
2837 boolean
2838 NAME(aout,link_hash_table_init) (table, abfd, newfunc)
2839      struct aout_link_hash_table *table;
2840      bfd *abfd;
2841      struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
2842                                                 struct bfd_hash_table *,
2843                                                 const char *));
2844 {
2845   return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
2846 }
2847
2848 /* Create an a.out link hash table.  */
2849
2850 struct bfd_link_hash_table *
2851 NAME(aout,link_hash_table_create) (abfd)
2852      bfd *abfd;
2853 {
2854   struct aout_link_hash_table *ret;
2855
2856   ret = ((struct aout_link_hash_table *)
2857          bfd_alloc (abfd, sizeof (struct aout_link_hash_table)));
2858   if (ret == NULL)
2859     {
2860       bfd_set_error (bfd_error_no_memory);
2861       return (struct bfd_link_hash_table *) NULL;
2862     }
2863   if (! NAME(aout,link_hash_table_init) (ret, abfd,
2864                                          NAME(aout,link_hash_newfunc)))
2865     {
2866       free (ret);
2867       return (struct bfd_link_hash_table *) NULL;
2868     }
2869   return &ret->root;
2870 }
2871
2872 /* Given an a.out BFD, add symbols to the global hash table as
2873    appropriate.  */
2874
2875 boolean
2876 NAME(aout,link_add_symbols) (abfd, info)
2877      bfd *abfd;
2878      struct bfd_link_info *info;
2879 {
2880   switch (bfd_get_format (abfd))
2881     {
2882     case bfd_object:
2883       return aout_link_add_object_symbols (abfd, info);
2884     case bfd_archive:
2885       return _bfd_generic_link_add_archive_symbols
2886         (abfd, info, aout_link_check_archive_element);
2887     default:
2888       bfd_set_error (bfd_error_wrong_format);
2889       return false;
2890     }
2891 }
2892
2893 /* Add symbols from an a.out object file.  */
2894
2895 static boolean
2896 aout_link_add_object_symbols (abfd, info)
2897      bfd *abfd;
2898      struct bfd_link_info *info;
2899 {
2900   if (! aout_get_external_symbols (abfd))
2901     return false;
2902   if (! aout_link_add_symbols (abfd, info))
2903     return false;
2904   if (! info->keep_memory)
2905     {
2906       if (! aout_link_free_symbols (abfd))
2907         return false;
2908     }
2909   return true;
2910 }
2911
2912 /* Check a single archive element to see if we need to include it in
2913    the link.  *PNEEDED is set according to whether this element is
2914    needed in the link or not.  This is called from
2915    _bfd_generic_link_add_archive_symbols.  */
2916
2917 static boolean
2918 aout_link_check_archive_element (abfd, info, pneeded)
2919      bfd *abfd;
2920      struct bfd_link_info *info;
2921      boolean *pneeded;
2922 {
2923   if (! aout_get_external_symbols (abfd))
2924     return false;
2925
2926   if (! aout_link_check_ar_symbols (abfd, info, pneeded))
2927     return false;
2928
2929   if (*pneeded)
2930     {
2931       if (! aout_link_add_symbols (abfd, info))
2932         return false;
2933     }
2934
2935   if (! info->keep_memory || ! *pneeded)
2936     {
2937       if (! aout_link_free_symbols (abfd))
2938         return false;
2939     }
2940
2941   return true;
2942 }
2943
2944 /* Free up the internal symbols read from an a.out file.  */
2945
2946 static boolean
2947 aout_link_free_symbols (abfd)
2948      bfd *abfd;
2949 {
2950   if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
2951     {
2952       free ((PTR) obj_aout_external_syms (abfd));
2953       obj_aout_external_syms (abfd) = (struct external_nlist *) NULL;
2954     }
2955   if (obj_aout_external_strings (abfd) != (char *) NULL)
2956     {
2957       free ((PTR) obj_aout_external_strings (abfd));
2958       obj_aout_external_strings (abfd) = (char *) NULL;
2959     }
2960   return true;
2961 }
2962
2963 /* Look through the internal symbols to see if this object file should
2964    be included in the link.  We should include this object file if it
2965    defines any symbols which are currently undefined.  If this object
2966    file defines a common symbol, then we may adjust the size of the
2967    known symbol but we do not include the object file in the link
2968    (unless there is some other reason to include it).  */
2969
2970 static boolean
2971 aout_link_check_ar_symbols (abfd, info, pneeded)
2972      bfd *abfd;
2973      struct bfd_link_info *info;
2974      boolean *pneeded;
2975 {
2976   register struct external_nlist *p;
2977   struct external_nlist *pend;
2978   char *strings;
2979
2980   *pneeded = false;
2981
2982   /* Look through all the symbols.  */
2983   p = obj_aout_external_syms (abfd);
2984   pend = p + obj_aout_external_sym_count (abfd);
2985   strings = obj_aout_external_strings (abfd);
2986   for (; p < pend; p++)
2987     {
2988       int type = bfd_h_get_8 (abfd, p->e_type);
2989       const char *name;
2990       struct bfd_link_hash_entry *h;
2991
2992       /* Ignore symbols that are not externally visible.  This is an
2993          optimization only, as we check the type more thoroughly
2994          below.  */
2995       if (((type & N_EXT) == 0
2996            || (type & N_STAB) != 0
2997            || type == N_FN)
2998           && type != N_WEAKA
2999           && type != N_WEAKT
3000           && type != N_WEAKD
3001           && type != N_WEAKB)
3002         {
3003           if (type == N_WARNING
3004               || type == N_INDR)
3005             ++p;
3006           continue;
3007         }
3008
3009       name = strings + GET_WORD (abfd, p->e_strx);
3010       h = bfd_link_hash_lookup (info->hash, name, false, false, true);
3011
3012       /* We are only interested in symbols that are currently
3013          undefined or common.  */
3014       if (h == (struct bfd_link_hash_entry *) NULL
3015           || (h->type != bfd_link_hash_undefined
3016               && h->type != bfd_link_hash_common))
3017         {
3018           if (type == (N_INDR | N_EXT))
3019             ++p;
3020           continue;
3021         }
3022
3023       if (type == (N_TEXT | N_EXT)
3024           || type == (N_DATA | N_EXT)
3025           || type == (N_BSS | N_EXT)
3026           || type == (N_ABS | N_EXT)
3027           || type == (N_INDR | N_EXT))
3028         {
3029           /* This object file defines this symbol.  We must link it
3030              in.  This is true regardless of whether the current
3031              definition of the symbol is undefined or common.  If the
3032              current definition is common, we have a case in which we
3033              have already seen an object file including
3034                  int a;
3035              and this object file from the archive includes
3036                  int a = 5;
3037              In such a case we must include this object file.
3038
3039              FIXME: The SunOS 4.1.3 linker will pull in the archive
3040              element if the symbol is defined in the .data section,
3041              but not if it is defined in the .text section.  That
3042              seems a bit crazy to me, and I haven't implemented it.
3043              However, it might be correct.  */
3044           if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3045             return false;
3046           *pneeded = true;
3047           return true;
3048         }
3049
3050       if (type == (N_UNDF | N_EXT))
3051         {
3052           bfd_vma value;
3053
3054           value = GET_WORD (abfd, p->e_value);
3055           if (value != 0)
3056             {
3057               /* This symbol is common in the object from the archive
3058                  file.  */
3059               if (h->type == bfd_link_hash_undefined)
3060                 {
3061                   bfd *symbfd;
3062                   unsigned int power;
3063
3064                   symbfd = h->u.undef.abfd;
3065                   if (symbfd == (bfd *) NULL)
3066                     {
3067                       /* This symbol was created as undefined from
3068                          outside BFD.  We assume that we should link
3069                          in the object file.  This is done for the -u
3070                          option in the linker.  */
3071                       if (! (*info->callbacks->add_archive_element) (info,
3072                                                                      abfd,
3073                                                                      name))
3074                         return false;
3075                       *pneeded = true;
3076                       return true;
3077                     }
3078                   /* Turn the current link symbol into a common
3079                      symbol.  It is already on the undefs list.  */
3080                   h->type = bfd_link_hash_common;
3081                   h->u.c.p = ((struct bfd_link_hash_common_entry *)
3082                               bfd_hash_allocate (&info->hash->table,
3083                                   sizeof (struct bfd_link_hash_common_entry)));
3084                   if (h->u.c.p == NULL)
3085                     return false;
3086
3087                   h->u.c.size = value;
3088
3089                   /* FIXME: This isn't quite right.  The maximum
3090                      alignment of a common symbol should be set by the
3091                      architecture of the output file, not of the input
3092                      file.  */
3093                   power = bfd_log2 (value);
3094                   if (power > bfd_get_arch_info (abfd)->section_align_power)
3095                     power = bfd_get_arch_info (abfd)->section_align_power;
3096                   h->u.c.p->alignment_power = power;
3097
3098                   h->u.c.p->section = bfd_make_section_old_way (symbfd,
3099                                                                 "COMMON");
3100                 }
3101               else
3102                 {
3103                   /* Adjust the size of the common symbol if
3104                      necessary.  */
3105                   if (value > h->u.c.size)
3106                     h->u.c.size = value;
3107                 }
3108             }
3109         }
3110
3111       if (type == N_WEAKA
3112           || type == N_WEAKT
3113           || type == N_WEAKD
3114           || type == N_WEAKB)
3115         {
3116           /* This symbol is weak but defined.  We must pull it in if
3117              the current link symbol is undefined, but we don't want
3118              it if the current link symbol is common.  */
3119           if (h->type == bfd_link_hash_undefined)
3120             {
3121               if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3122                 return false;
3123               *pneeded = true;
3124               return true;
3125             }
3126         }
3127     }
3128
3129   /* We do not need this object file.  */
3130   return true;
3131 }
3132
3133 /* Add all symbols from an object file to the hash table.  */
3134
3135 static boolean
3136 aout_link_add_symbols (abfd, info)
3137      bfd *abfd;
3138      struct bfd_link_info *info;
3139 {
3140   boolean (*add_one_symbol) PARAMS ((struct bfd_link_info *, bfd *,
3141                                      const char *, flagword, asection *,
3142                                      bfd_vma, const char *, boolean,
3143                                      boolean,
3144                                      struct bfd_link_hash_entry **));
3145   struct external_nlist *syms;
3146   bfd_size_type sym_count;
3147   char *strings;
3148   boolean copy;
3149   struct aout_link_hash_entry **sym_hash;
3150   register struct external_nlist *p;
3151   struct external_nlist *pend;
3152
3153   syms = obj_aout_external_syms (abfd);
3154   sym_count = obj_aout_external_sym_count (abfd);
3155   strings = obj_aout_external_strings (abfd);
3156   if (info->keep_memory)
3157     copy = false;
3158   else
3159     copy = true;
3160
3161   if ((abfd->flags & DYNAMIC) != 0
3162       && aout_backend_info (abfd)->add_dynamic_symbols != NULL)
3163     {
3164       if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
3165              (abfd, info, &syms, &sym_count, &strings)))
3166         return false;
3167     }
3168
3169   /* We keep a list of the linker hash table entries that correspond
3170      to particular symbols.  We could just look them up in the hash
3171      table, but keeping the list is more efficient.  Perhaps this
3172      should be conditional on info->keep_memory.  */
3173   sym_hash = ((struct aout_link_hash_entry **)
3174               bfd_alloc (abfd,
3175                          ((size_t) sym_count
3176                           * sizeof (struct aout_link_hash_entry *))));
3177   if (sym_hash == NULL && sym_count != 0)
3178     {
3179       bfd_set_error (bfd_error_no_memory);
3180       return false;
3181     }
3182   obj_aout_sym_hashes (abfd) = sym_hash;
3183
3184   add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
3185   if (add_one_symbol == NULL)
3186     add_one_symbol = _bfd_generic_link_add_one_symbol;
3187
3188   p = syms;
3189   pend = p + sym_count;
3190   for (; p < pend; p++, sym_hash++)
3191     {
3192       int type;
3193       const char *name;
3194       bfd_vma value;
3195       asection *section;
3196       flagword flags;
3197       const char *string;
3198
3199       *sym_hash = NULL;
3200
3201       type = bfd_h_get_8 (abfd, p->e_type);
3202
3203       /* Ignore debugging symbols.  */
3204       if ((type & N_STAB) != 0)
3205         continue;
3206
3207       name = strings + GET_WORD (abfd, p->e_strx);
3208       value = GET_WORD (abfd, p->e_value);
3209       flags = BSF_GLOBAL;
3210       string = NULL;
3211       switch (type)
3212         {
3213         default:
3214           abort ();
3215
3216         case N_UNDF:
3217         case N_ABS:
3218         case N_TEXT:
3219         case N_DATA:
3220         case N_BSS:
3221         case N_FN_SEQ:
3222         case N_COMM:
3223         case N_SETV:
3224         case N_FN:
3225           /* Ignore symbols that are not externally visible.  */
3226           continue;
3227         case N_INDR:
3228           /* Ignore local indirect symbol.  */
3229           ++p;
3230           ++sym_hash;
3231           continue;
3232
3233         case N_UNDF | N_EXT:
3234           if (value == 0)
3235             {
3236               section = bfd_und_section_ptr;
3237               flags = 0;
3238             }
3239           else
3240             section = bfd_com_section_ptr;
3241           break;
3242         case N_ABS | N_EXT:
3243           section = bfd_abs_section_ptr;
3244           break;
3245         case N_TEXT | N_EXT:
3246           section = obj_textsec (abfd);
3247           value -= bfd_get_section_vma (abfd, section);
3248           break;
3249         case N_DATA | N_EXT:
3250         case N_SETV | N_EXT:
3251           /* Treat N_SETV symbols as N_DATA symbol; see comment in
3252              translate_from_native_sym_flags.  */
3253           section = obj_datasec (abfd);
3254           value -= bfd_get_section_vma (abfd, section);
3255           break;
3256         case N_BSS | N_EXT:
3257           section = obj_bsssec (abfd);
3258           value -= bfd_get_section_vma (abfd, section);
3259           break;
3260         case N_INDR | N_EXT:
3261           /* An indirect symbol.  The next symbol is the symbol
3262              which this one really is.  */
3263           BFD_ASSERT (p + 1 < pend);
3264           ++p;
3265           string = strings + GET_WORD (abfd, p->e_strx);
3266           section = bfd_ind_section_ptr;
3267           flags |= BSF_INDIRECT;
3268           break;
3269         case N_COMM | N_EXT:
3270           section = bfd_com_section_ptr;
3271           break;
3272         case N_SETA: case N_SETA | N_EXT:
3273           section = bfd_abs_section_ptr;
3274           flags |= BSF_CONSTRUCTOR;
3275           break;
3276         case N_SETT: case N_SETT | N_EXT:
3277           section = obj_textsec (abfd);
3278           flags |= BSF_CONSTRUCTOR;
3279           value -= bfd_get_section_vma (abfd, section);
3280           break;
3281         case N_SETD: case N_SETD | N_EXT:
3282           section = obj_datasec (abfd);
3283           flags |= BSF_CONSTRUCTOR;
3284           value -= bfd_get_section_vma (abfd, section);
3285           break;
3286         case N_SETB: case N_SETB | N_EXT:
3287           section = obj_bsssec (abfd);
3288           flags |= BSF_CONSTRUCTOR;
3289           value -= bfd_get_section_vma (abfd, section);
3290           break;
3291         case N_WARNING:
3292           /* A warning symbol.  The next symbol is the one to warn
3293              about.  */
3294           BFD_ASSERT (p + 1 < pend);
3295           ++p;
3296           string = name;
3297           name = strings + GET_WORD (abfd, p->e_strx);
3298           section = bfd_und_section_ptr;
3299           flags |= BSF_WARNING;
3300           break;
3301         case N_WEAKU:
3302           section = bfd_und_section_ptr;
3303           flags = BSF_WEAK;
3304           break;
3305         case N_WEAKA:
3306           section = bfd_abs_section_ptr;
3307           flags = BSF_WEAK;
3308           break;
3309         case N_WEAKT:
3310           section = obj_textsec (abfd);
3311           value -= bfd_get_section_vma (abfd, section);
3312           flags = BSF_WEAK;
3313           break;
3314         case N_WEAKD:
3315           section = obj_datasec (abfd);
3316           value -= bfd_get_section_vma (abfd, section);
3317           flags = BSF_WEAK;
3318           break;
3319         case N_WEAKB:
3320           section = obj_bsssec (abfd);
3321           value -= bfd_get_section_vma (abfd, section);
3322           flags = BSF_WEAK;
3323           break;
3324         }
3325
3326       if (! ((*add_one_symbol)
3327              (info, abfd, name, flags, section, value, string, copy, false,
3328               (struct bfd_link_hash_entry **) sym_hash)))
3329         return false;
3330
3331       /* Restrict the maximum alignment of a common symbol based on
3332          the architecture, since a.out has no way to represent
3333          alignment requirements of a section in a .o file.  FIXME:
3334          This isn't quite right: it should use the architecture of the
3335          output file, not the input files.  */
3336       if ((*sym_hash)->root.type == bfd_link_hash_common
3337           && ((*sym_hash)->root.u.c.p->alignment_power >
3338               bfd_get_arch_info (abfd)->section_align_power))
3339         (*sym_hash)->root.u.c.p->alignment_power =
3340           bfd_get_arch_info (abfd)->section_align_power;
3341
3342       /* If this is a set symbol, and we are not building sets, then
3343          it is possible for the hash entry to not have been set.  In
3344          such a case, treat the symbol as not globally defined.  */
3345       if ((*sym_hash)->root.type == bfd_link_hash_new)
3346         {
3347           BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
3348           *sym_hash = NULL;
3349         }
3350
3351       if (type == (N_INDR | N_EXT) || type == N_WARNING)
3352         ++sym_hash;
3353     }
3354
3355   return true;
3356 }
3357
3358 /* During the final link step we need to pass around a bunch of
3359    information, so we do it in an instance of this structure.  */
3360
3361 struct aout_final_link_info
3362 {
3363   /* General link information.  */
3364   struct bfd_link_info *info;
3365   /* Output bfd.  */
3366   bfd *output_bfd;
3367   /* Reloc file positions.  */
3368   file_ptr treloff, dreloff;
3369   /* File position of symbols.  */
3370   file_ptr symoff;
3371   /* String table.  */
3372   struct bfd_strtab_hash *strtab;
3373   /* A buffer large enough to hold the contents of any section.  */
3374   bfd_byte *contents;
3375   /* A buffer large enough to hold the relocs of any section.  */
3376   PTR relocs;
3377   /* A buffer large enough to hold the symbol map of any input BFD.  */
3378   int *symbol_map;
3379   /* A buffer large enough to hold output symbols of any input BFD.  */
3380   struct external_nlist *output_syms;
3381 };
3382
3383 static boolean aout_link_input_bfd
3384   PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3385 static boolean aout_link_write_symbols
3386   PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3387 static boolean aout_link_write_other_symbol
3388   PARAMS ((struct aout_link_hash_entry *, PTR));
3389 static boolean aout_link_input_section
3390   PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3391            asection *input_section, file_ptr *reloff_ptr,
3392            bfd_size_type rel_size));
3393 static boolean aout_link_input_section_std
3394   PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3395            asection *input_section, struct reloc_std_external *,
3396            bfd_size_type rel_size, bfd_byte *contents));
3397 static boolean aout_link_input_section_ext
3398   PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3399            asection *input_section, struct reloc_ext_external *,
3400            bfd_size_type rel_size, bfd_byte *contents));
3401 static INLINE asection *aout_reloc_index_to_section
3402   PARAMS ((bfd *, int));
3403 static boolean aout_link_reloc_link_order
3404   PARAMS ((struct aout_final_link_info *, asection *,
3405            struct bfd_link_order *));
3406
3407 /* Do the final link step.  This is called on the output BFD.  The
3408    INFO structure should point to a list of BFDs linked through the
3409    link_next field which can be used to find each BFD which takes part
3410    in the output.  Also, each section in ABFD should point to a list
3411    of bfd_link_order structures which list all the input sections for
3412    the output section.  */
3413
3414 boolean
3415 NAME(aout,final_link) (abfd, info, callback)
3416      bfd *abfd;
3417      struct bfd_link_info *info;
3418      void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
3419 {
3420   struct aout_final_link_info aout_info;
3421   register bfd *sub;
3422   bfd_size_type trsize, drsize;
3423   size_t max_contents_size;
3424   size_t max_relocs_size;
3425   size_t max_sym_count;
3426   bfd_size_type text_size;
3427   file_ptr text_end;
3428   register struct bfd_link_order *p;
3429   asection *o;
3430   boolean have_link_order_relocs;
3431
3432   if (info->shared)
3433     abfd->flags |= DYNAMIC;
3434
3435   aout_info.info = info;
3436   aout_info.output_bfd = abfd;
3437   aout_info.contents = NULL;
3438   aout_info.relocs = NULL;
3439
3440   /* Figure out the largest section size.  Also, if generating
3441      relocateable output, count the relocs.  */
3442   trsize = 0;
3443   drsize = 0;
3444   max_contents_size = 0;
3445   max_relocs_size = 0;
3446   max_sym_count = 0;
3447   for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
3448     {
3449       size_t sz;
3450
3451       if (info->relocateable)
3452         {
3453           if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3454             {
3455               trsize += exec_hdr (sub)->a_trsize;
3456               drsize += exec_hdr (sub)->a_drsize;
3457             }
3458           else
3459             {
3460               /* FIXME: We need to identify the .text and .data sections
3461                  and call get_reloc_upper_bound and canonicalize_reloc to
3462                  work out the number of relocs needed, and then multiply
3463                  by the reloc size.  */
3464               abort ();
3465             }
3466         }
3467
3468       if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
3469         {
3470           sz = bfd_section_size (sub, obj_textsec (sub));
3471           if (sz > max_contents_size)
3472             max_contents_size = sz;
3473           sz = bfd_section_size (sub, obj_datasec (sub));
3474           if (sz > max_contents_size)
3475             max_contents_size = sz;
3476
3477           sz = exec_hdr (sub)->a_trsize;
3478           if (sz > max_relocs_size)
3479             max_relocs_size = sz;
3480           sz = exec_hdr (sub)->a_drsize;
3481           if (sz > max_relocs_size)
3482             max_relocs_size = sz;
3483
3484           sz = obj_aout_external_sym_count (sub);
3485           if (sz > max_sym_count)
3486             max_sym_count = sz;
3487         }
3488     }
3489
3490   if (info->relocateable)
3491     {
3492       if (obj_textsec (abfd) != (asection *) NULL)
3493         trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
3494                                                  ->link_order_head)
3495                    * obj_reloc_entry_size (abfd));
3496       if (obj_datasec (abfd) != (asection *) NULL)
3497         drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
3498                                                  ->link_order_head)
3499                    * obj_reloc_entry_size (abfd));
3500     }
3501
3502   exec_hdr (abfd)->a_trsize = trsize;
3503   exec_hdr (abfd)->a_drsize = drsize;
3504
3505   exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
3506
3507   /* Adjust the section sizes and vmas according to the magic number.
3508      This sets a_text, a_data and a_bss in the exec_hdr and sets the
3509      filepos for each section.  */
3510   if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
3511     goto error_return;
3512
3513   /* The relocation and symbol file positions differ among a.out
3514      targets.  We are passed a callback routine from the backend
3515      specific code to handle this.
3516      FIXME: At this point we do not know how much space the symbol
3517      table will require.  This will not work for any (nonstandard)
3518      a.out target that needs to know the symbol table size before it
3519      can compute the relocation file positions.  This may or may not
3520      be the case for the hp300hpux target, for example.  */
3521   (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
3522                &aout_info.symoff);
3523   obj_textsec (abfd)->rel_filepos = aout_info.treloff;
3524   obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
3525   obj_sym_filepos (abfd) = aout_info.symoff;
3526
3527   /* We keep a count of the symbols as we output them.  */
3528   obj_aout_external_sym_count (abfd) = 0;
3529
3530   /* We accumulate the string table as we write out the symbols.  */
3531   aout_info.strtab = _bfd_stringtab_init ();
3532   if (aout_info.strtab == NULL)
3533     goto error_return;
3534
3535   /* Allocate buffers to hold section contents and relocs.  */
3536   aout_info.contents = (bfd_byte *) malloc (max_contents_size);
3537   aout_info.relocs = (PTR) malloc (max_relocs_size);
3538   aout_info.symbol_map = (int *) malloc (max_sym_count * sizeof (int *));
3539   aout_info.output_syms = ((struct external_nlist *)
3540                            malloc ((max_sym_count + 1)
3541                                    * sizeof (struct external_nlist)));
3542   if ((aout_info.contents == NULL && max_contents_size != 0)
3543       || (aout_info.relocs == NULL && max_relocs_size != 0)
3544       || (aout_info.symbol_map == NULL && max_sym_count != 0)
3545       || aout_info.output_syms == NULL)
3546     {
3547       bfd_set_error (bfd_error_no_memory);
3548       goto error_return;
3549     }
3550
3551   /* The most time efficient way to do the link would be to read all
3552      the input object files into memory and then sort out the
3553      information into the output file.  Unfortunately, that will
3554      probably use too much memory.  Another method would be to step
3555      through everything that composes the text section and write it
3556      out, and then everything that composes the data section and write
3557      it out, and then write out the relocs, and then write out the
3558      symbols.  Unfortunately, that requires reading stuff from each
3559      input file several times, and we will not be able to keep all the
3560      input files open simultaneously, and reopening them will be slow.
3561
3562      What we do is basically process one input file at a time.  We do
3563      everything we need to do with an input file once--copy over the
3564      section contents, handle the relocation information, and write
3565      out the symbols--and then we throw away the information we read
3566      from it.  This approach requires a lot of lseeks of the output
3567      file, which is unfortunate but still faster than reopening a lot
3568      of files.
3569
3570      We use the output_has_begun field of the input BFDs to see
3571      whether we have already handled it.  */
3572   for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
3573     sub->output_has_begun = false;
3574
3575   have_link_order_relocs = false;
3576   for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3577     {
3578       for (p = o->link_order_head;
3579            p != (struct bfd_link_order *) NULL;
3580            p = p->next)
3581         {
3582           if (p->type == bfd_indirect_link_order
3583               && (bfd_get_flavour (p->u.indirect.section->owner)
3584                   == bfd_target_aout_flavour))
3585             {
3586               bfd *input_bfd;
3587
3588               input_bfd = p->u.indirect.section->owner;
3589               if (! input_bfd->output_has_begun)
3590                 {
3591                   if (! aout_link_input_bfd (&aout_info, input_bfd))
3592                     goto error_return;
3593                   input_bfd->output_has_begun = true;
3594                 }
3595             }
3596           else if (p->type == bfd_section_reloc_link_order
3597                    || p->type == bfd_symbol_reloc_link_order)
3598             {
3599               /* These are handled below.  */
3600               have_link_order_relocs = true;
3601             }
3602           else
3603             {
3604               if (! _bfd_default_link_order (abfd, info, o, p))
3605                 goto error_return;
3606             }
3607         }
3608     }
3609
3610   /* Write out any symbols that we have not already written out.  */
3611   aout_link_hash_traverse (aout_hash_table (info),
3612                            aout_link_write_other_symbol,
3613                            (PTR) &aout_info);
3614
3615   /* Now handle any relocs we were asked to create by the linker.
3616      These did not come from any input file.  We must do these after
3617      we have written out all the symbols, so that we know the symbol
3618      indices to use.  */
3619   if (have_link_order_relocs)
3620     {
3621       for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3622         {
3623           for (p = o->link_order_head;
3624                p != (struct bfd_link_order *) NULL;
3625                p = p->next)
3626             {
3627               if (p->type == bfd_section_reloc_link_order
3628                   || p->type == bfd_symbol_reloc_link_order)
3629                 {
3630                   if (! aout_link_reloc_link_order (&aout_info, o, p))
3631                     goto error_return;
3632                 }
3633             }
3634         }
3635     }
3636
3637   if (aout_info.contents != NULL)
3638     {
3639       free (aout_info.contents);
3640       aout_info.contents = NULL;
3641     }
3642   if (aout_info.relocs != NULL)
3643     {
3644       free (aout_info.relocs);
3645       aout_info.relocs = NULL;
3646     }
3647   if (aout_info.symbol_map != NULL)
3648     {
3649       free (aout_info.symbol_map);
3650       aout_info.symbol_map = NULL;
3651     }
3652   if (aout_info.output_syms != NULL)
3653     {
3654       free (aout_info.output_syms);
3655       aout_info.output_syms = NULL;
3656     }
3657
3658   /* Finish up any dynamic linking we may be doing.  */
3659   if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
3660     {
3661       if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
3662         goto error_return;
3663     }
3664
3665   /* Update the header information.  */
3666   abfd->symcount = obj_aout_external_sym_count (abfd);
3667   exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
3668   obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
3669   obj_textsec (abfd)->reloc_count =
3670     exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
3671   obj_datasec (abfd)->reloc_count =
3672     exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
3673
3674   /* Write out the string table.  */
3675   if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
3676     goto error_return;
3677   return emit_stringtab (abfd, aout_info.strtab);
3678
3679  error_return:
3680   if (aout_info.contents != NULL)
3681     free (aout_info.contents);
3682   if (aout_info.relocs != NULL)
3683     free (aout_info.relocs);
3684   if (aout_info.symbol_map != NULL)
3685     free (aout_info.symbol_map);
3686   if (aout_info.output_syms != NULL)
3687     free (aout_info.output_syms);
3688   return false;
3689 }
3690
3691 /* Link an a.out input BFD into the output file.  */
3692
3693 static boolean
3694 aout_link_input_bfd (finfo, input_bfd)
3695      struct aout_final_link_info *finfo;
3696      bfd *input_bfd;
3697 {
3698   bfd_size_type sym_count;
3699
3700   BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
3701
3702   /* If this is a dynamic object, it may need special handling.  */
3703   if ((input_bfd->flags & DYNAMIC) != 0
3704       && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
3705     {
3706       return ((*aout_backend_info (input_bfd)->link_dynamic_object)
3707               (finfo->info, input_bfd));
3708     }
3709
3710   /* Get the symbols.  We probably have them already, unless
3711      finfo->info->keep_memory is false.  */
3712   if (! aout_get_external_symbols (input_bfd))
3713     return false;
3714
3715   sym_count = obj_aout_external_sym_count (input_bfd);
3716
3717   /* Write out the symbols and get a map of the new indices.  The map
3718      is placed into finfo->symbol_map.  */
3719   if (! aout_link_write_symbols (finfo, input_bfd))
3720     return false;
3721
3722   /* Relocate and write out the sections.  These functions use the
3723      symbol map created by aout_link_write_symbols.  */
3724   if (! aout_link_input_section (finfo, input_bfd,
3725                                  obj_textsec (input_bfd),
3726                                  &finfo->treloff,
3727                                  exec_hdr (input_bfd)->a_trsize)
3728       || ! aout_link_input_section (finfo, input_bfd,
3729                                     obj_datasec (input_bfd),
3730                                     &finfo->dreloff,
3731                                     exec_hdr (input_bfd)->a_drsize))
3732     return false;
3733
3734   /* If we are not keeping memory, we don't need the symbols any
3735      longer.  We still need them if we are keeping memory, because the
3736      strings in the hash table point into them.  */
3737   if (! finfo->info->keep_memory)
3738     {
3739       if (! aout_link_free_symbols (input_bfd))
3740         return false;
3741     }
3742
3743   return true;
3744 }
3745
3746 /* Adjust and write out the symbols for an a.out file.  Set the new
3747    symbol indices into a symbol_map.  */
3748
3749 static boolean
3750 aout_link_write_symbols (finfo, input_bfd)
3751      struct aout_final_link_info *finfo;
3752      bfd *input_bfd;
3753 {
3754   bfd *output_bfd;
3755   bfd_size_type sym_count;
3756   char *strings;
3757   enum bfd_link_strip strip;
3758   enum bfd_link_discard discard;
3759   struct external_nlist *outsym;
3760   bfd_size_type strtab_index;
3761   register struct external_nlist *sym;
3762   struct external_nlist *sym_end;
3763   struct aout_link_hash_entry **sym_hash;
3764   int *symbol_map;
3765   boolean pass;
3766   boolean skip_next;
3767
3768   output_bfd = finfo->output_bfd;
3769   sym_count = obj_aout_external_sym_count (input_bfd);
3770   strings = obj_aout_external_strings (input_bfd);
3771   strip = finfo->info->strip;
3772   discard = finfo->info->discard;
3773   outsym = finfo->output_syms;
3774
3775   /* First write out a symbol for this object file, unless we are
3776      discarding such symbols.  */
3777   if (strip != strip_all
3778       && (strip != strip_some
3779           || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
3780                               false, false) != NULL)
3781       && discard != discard_all)
3782     {
3783       bfd_h_put_8 (output_bfd, N_TEXT, outsym->e_type);
3784       bfd_h_put_8 (output_bfd, 0, outsym->e_other);
3785       bfd_h_put_16 (output_bfd, (bfd_vma) 0, outsym->e_desc);
3786       strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
3787                                        input_bfd->filename, false);
3788       if (strtab_index == (bfd_size_type) -1)
3789         return false;
3790       PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
3791       PUT_WORD (output_bfd,
3792                 (bfd_get_section_vma (output_bfd,
3793                                       obj_textsec (input_bfd)->output_section)
3794                  + obj_textsec (input_bfd)->output_offset),
3795                 outsym->e_value);
3796       ++obj_aout_external_sym_count (output_bfd);
3797       ++outsym;
3798     }
3799
3800   pass = false;
3801   skip_next = false;
3802   sym = obj_aout_external_syms (input_bfd);
3803   sym_end = sym + sym_count;
3804   sym_hash = obj_aout_sym_hashes (input_bfd);
3805   symbol_map = finfo->symbol_map;
3806   for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
3807     {
3808       const char *name;
3809       int type;
3810       struct aout_link_hash_entry *h;
3811       boolean skip;
3812       asection *symsec;
3813       bfd_vma val = 0;
3814       boolean copy;
3815
3816       *symbol_map = -1;
3817
3818       type = bfd_h_get_8 (input_bfd, sym->e_type);
3819       name = strings + GET_WORD (input_bfd, sym->e_strx);
3820
3821       h = NULL;
3822
3823       if (pass)
3824         {
3825           /* Pass this symbol through.  It is the target of an
3826              indirect or warning symbol.  */
3827           val = GET_WORD (input_bfd, sym->e_value);
3828           pass = false;
3829         }
3830       else if (skip_next)
3831         {
3832           /* Skip this symbol, which is the target of an indirect
3833              symbol that we have changed to no longer be an indirect
3834              symbol.  */
3835           skip_next = false;
3836           continue;
3837         }
3838       else
3839         {
3840           struct aout_link_hash_entry *hresolve;
3841
3842           /* We have saved the hash table entry for this symbol, if
3843              there is one.  Note that we could just look it up again
3844              in the hash table, provided we first check that it is an
3845              external symbol. */
3846           h = *sym_hash;
3847
3848           /* If this is an indirect or warning symbol, then change
3849              hresolve to the base symbol.  We also change *sym_hash so
3850              that the relocation routines relocate against the real
3851              symbol.  */
3852           hresolve = h;
3853           if (h != (struct aout_link_hash_entry *) NULL
3854               && (h->root.type == bfd_link_hash_indirect
3855                   || h->root.type == bfd_link_hash_warning))
3856             {
3857               hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
3858               while (hresolve->root.type == bfd_link_hash_indirect
3859                      || hresolve->root.type == bfd_link_hash_warning)
3860                 hresolve = ((struct aout_link_hash_entry *)
3861                             hresolve->root.u.i.link);
3862               *sym_hash = hresolve;
3863             }
3864
3865           /* If the symbol has already been written out, skip it.  */
3866           if (h != (struct aout_link_hash_entry *) NULL
3867               && h->root.type != bfd_link_hash_warning
3868               && h->written)
3869             {
3870               if ((type & N_TYPE) == N_INDR
3871                   || type == N_WARNING)
3872                 skip_next = true;
3873               *symbol_map = h->indx;
3874               continue;
3875             }
3876
3877           /* See if we are stripping this symbol.  */
3878           skip = false;
3879           switch (strip)
3880             {
3881             case strip_none:
3882               break;
3883             case strip_debugger:
3884               if ((type & N_STAB) != 0)
3885                 skip = true;
3886               break;
3887             case strip_some:
3888               if (bfd_hash_lookup (finfo->info->keep_hash, name, false, false)
3889                   == NULL)
3890                 skip = true;
3891               break;
3892             case strip_all:
3893               skip = true;
3894               break;
3895             }
3896           if (skip)
3897             {
3898               if (h != (struct aout_link_hash_entry *) NULL)
3899                 h->written = true;
3900               continue;
3901             }
3902
3903           /* Get the value of the symbol.  */
3904           if ((type & N_TYPE) == N_TEXT
3905               || type == N_WEAKT)
3906             symsec = obj_textsec (input_bfd);
3907           else if ((type & N_TYPE) == N_DATA
3908                    || type == N_WEAKD)
3909             symsec = obj_datasec (input_bfd);
3910           else if ((type & N_TYPE) == N_BSS
3911                    || type == N_WEAKB)
3912             symsec = obj_bsssec (input_bfd);
3913           else if ((type & N_TYPE) == N_ABS
3914                    || type == N_WEAKA)
3915             symsec = bfd_abs_section_ptr;
3916           else if (((type & N_TYPE) == N_INDR
3917                     && (hresolve == (struct aout_link_hash_entry *) NULL
3918                         || (hresolve->root.type != bfd_link_hash_defined
3919                             && hresolve->root.type != bfd_link_hash_defweak
3920                             && hresolve->root.type != bfd_link_hash_common)))
3921                    || type == N_WARNING)
3922             {
3923               /* Pass the next symbol through unchanged.  The
3924                  condition above for indirect symbols is so that if
3925                  the indirect symbol was defined, we output it with
3926                  the correct definition so the debugger will
3927                  understand it.  */
3928               pass = true;
3929               val = GET_WORD (input_bfd, sym->e_value);
3930               symsec = NULL;
3931             }
3932           else if ((type & N_STAB) != 0)
3933             {
3934               val = GET_WORD (input_bfd, sym->e_value);
3935               symsec = NULL;
3936             }
3937           else
3938             {
3939               /* If we get here with an indirect symbol, it means that
3940                  we are outputting it with a real definition.  In such
3941                  a case we do not want to output the next symbol,
3942                  which is the target of the indirection.  */
3943               if ((type & N_TYPE) == N_INDR)
3944                 skip_next = true;
3945
3946               symsec = NULL;
3947
3948               /* We need to get the value from the hash table.  We use
3949                  hresolve so that if we have defined an indirect
3950                  symbol we output the final definition.  */
3951               if (h == (struct aout_link_hash_entry *) NULL)
3952                 {
3953                   switch (type & N_TYPE)
3954                     {
3955                     case N_SETT:
3956                       symsec = obj_textsec (input_bfd);
3957                       break;
3958                     case N_SETD:
3959                       symsec = obj_datasec (input_bfd);
3960                       break;
3961                     case N_SETB:
3962                       symsec = obj_bsssec (input_bfd);
3963                       break;
3964                     case N_SETA:
3965                       symsec = bfd_abs_section_ptr;
3966                       break;
3967                     default:
3968                       val = 0;
3969                       break;
3970                     }
3971                 }
3972               else if (hresolve->root.type == bfd_link_hash_defined
3973                        || hresolve->root.type == bfd_link_hash_defweak)
3974                 {
3975                   asection *input_section;
3976                   asection *output_section;
3977
3978                   /* This case usually means a common symbol which was
3979                      turned into a defined symbol.  */
3980                   input_section = hresolve->root.u.def.section;
3981                   output_section = input_section->output_section;
3982                   BFD_ASSERT (bfd_is_abs_section (output_section)
3983                               || output_section->owner == output_bfd);
3984                   val = (hresolve->root.u.def.value
3985                          + bfd_get_section_vma (output_bfd, output_section)
3986                          + input_section->output_offset);
3987
3988                   /* Get the correct type based on the section.  If
3989                      this is a constructed set, force it to be
3990                      globally visible.  */
3991                   if (type == N_SETT
3992                       || type == N_SETD
3993                       || type == N_SETB
3994                       || type == N_SETA)
3995                     type |= N_EXT;
3996
3997                   type &=~ N_TYPE;
3998
3999                   if (output_section == obj_textsec (output_bfd))
4000                     type |= (hresolve->root.type == bfd_link_hash_defined
4001                              ? N_TEXT
4002                              : N_WEAKT);
4003                   else if (output_section == obj_datasec (output_bfd))
4004                     type |= (hresolve->root.type == bfd_link_hash_defined
4005                              ? N_DATA
4006                              : N_WEAKD);
4007                   else if (output_section == obj_bsssec (output_bfd))
4008                     type |= (hresolve->root.type == bfd_link_hash_defined
4009                              ? N_BSS
4010                              : N_WEAKB);
4011                   else
4012                     type |= (hresolve->root.type == bfd_link_hash_defined
4013                              ? N_ABS
4014                              : N_WEAKA);
4015                 }
4016               else if (hresolve->root.type == bfd_link_hash_common)
4017                 val = hresolve->root.u.c.size;
4018               else if (hresolve->root.type == bfd_link_hash_undefweak)
4019                 {
4020                   val = 0;
4021                   type = N_WEAKU;
4022                 }
4023               else
4024                 val = 0;
4025             }
4026           if (symsec != (asection *) NULL)
4027             val = (symsec->output_section->vma
4028                    + symsec->output_offset
4029                    + (GET_WORD (input_bfd, sym->e_value)
4030                       - symsec->vma));
4031
4032           /* If this is a global symbol set the written flag, and if
4033              it is a local symbol see if we should discard it.  */
4034           if (h != (struct aout_link_hash_entry *) NULL)
4035             {
4036               h->written = true;
4037               h->indx = obj_aout_external_sym_count (output_bfd);
4038             }
4039           else if ((type & N_TYPE) != N_SETT
4040                    && (type & N_TYPE) != N_SETD
4041                    && (type & N_TYPE) != N_SETB
4042                    && (type & N_TYPE) != N_SETA)
4043             {
4044               switch (discard)
4045                 {
4046                 case discard_none:
4047                   break;
4048                 case discard_l:
4049                   if (*name == *finfo->info->lprefix
4050                       && (finfo->info->lprefix_len == 1
4051                           || strncmp (name, finfo->info->lprefix,
4052                                       finfo->info->lprefix_len) == 0))
4053                     skip = true;
4054                   break;
4055                 case discard_all:
4056                   skip = true;
4057                   break;
4058                 }
4059               if (skip)
4060                 {
4061                   pass = false;
4062                   continue;
4063                 }
4064             }
4065         }
4066
4067       /* Copy this symbol into the list of symbols we are going to
4068          write out.  */
4069       bfd_h_put_8 (output_bfd, type, outsym->e_type);
4070       bfd_h_put_8 (output_bfd, bfd_h_get_8 (input_bfd, sym->e_other),
4071                    outsym->e_other);
4072       bfd_h_put_16 (output_bfd, bfd_h_get_16 (input_bfd, sym->e_desc),
4073                     outsym->e_desc);
4074       copy = false;
4075       if (! finfo->info->keep_memory)
4076         {
4077           /* name points into a string table which we are going to
4078              free.  If there is a hash table entry, use that string.
4079              Otherwise, copy name into memory.  */
4080           if (h != (struct aout_link_hash_entry *) NULL)
4081             name = h->root.root.string;
4082           else
4083             copy = true;
4084         }
4085       strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4086                                        name, copy);
4087       if (strtab_index == (bfd_size_type) -1)
4088         return false;
4089       PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4090       PUT_WORD (output_bfd, val, outsym->e_value);
4091       *symbol_map = obj_aout_external_sym_count (output_bfd);
4092       ++obj_aout_external_sym_count (output_bfd);
4093       ++outsym;
4094     }
4095
4096   /* Write out the output symbols we have just constructed.  */
4097   if (outsym > finfo->output_syms)
4098     {
4099       bfd_size_type outsym_count;
4100
4101       if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
4102         return false;
4103       outsym_count = outsym - finfo->output_syms;
4104       if (bfd_write ((PTR) finfo->output_syms,
4105                      (bfd_size_type) EXTERNAL_NLIST_SIZE,
4106                      (bfd_size_type) outsym_count, output_bfd)
4107           != outsym_count * EXTERNAL_NLIST_SIZE)
4108         return false;
4109       finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE;
4110     }
4111
4112   return true;
4113 }
4114
4115 /* Write out a symbol that was not associated with an a.out input
4116    object.  */
4117
4118 static boolean
4119 aout_link_write_other_symbol (h, data)
4120      struct aout_link_hash_entry *h;
4121      PTR data;
4122 {
4123   struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
4124   bfd *output_bfd;
4125   int type;
4126   bfd_vma val;
4127   struct external_nlist outsym;
4128   bfd_size_type indx;
4129
4130   output_bfd = finfo->output_bfd;
4131
4132   if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
4133     {
4134       if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
4135              (output_bfd, finfo->info, h)))
4136         {
4137           /* FIXME: No way to handle errors.  */
4138           abort ();
4139         }
4140     }
4141
4142   if (h->written)
4143     return true;
4144
4145   h->written = true;
4146
4147   /* An indx of -2 means the symbol must be written.  */
4148   if (h->indx != -2
4149       && (finfo->info->strip == strip_all
4150           || (finfo->info->strip == strip_some
4151               && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
4152                                   false, false) == NULL)))
4153     return true;
4154
4155   switch (h->root.type)
4156     {
4157     default:
4158       abort ();
4159       /* Avoid variable not initialized warnings.  */
4160       return true;
4161     case bfd_link_hash_new:
4162       /* This can happen for set symbols when sets are not being
4163          built.  */
4164       return true;
4165     case bfd_link_hash_undefined:
4166       type = N_UNDF | N_EXT;
4167       val = 0;
4168       break;
4169     case bfd_link_hash_defined:
4170     case bfd_link_hash_defweak:
4171       {
4172         asection *sec;
4173
4174         sec = h->root.u.def.section->output_section;
4175         BFD_ASSERT (bfd_is_abs_section (sec)
4176                     || sec->owner == output_bfd);
4177         if (sec == obj_textsec (output_bfd))
4178           type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
4179         else if (sec == obj_datasec (output_bfd))
4180           type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
4181         else if (sec == obj_bsssec (output_bfd))
4182           type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
4183         else
4184           type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
4185         type |= N_EXT;
4186         val = (h->root.u.def.value
4187                + sec->vma
4188                + h->root.u.def.section->output_offset);
4189       }
4190       break;
4191     case bfd_link_hash_common:
4192       type = N_UNDF | N_EXT;
4193       val = h->root.u.c.size;
4194       break;
4195     case bfd_link_hash_undefweak:
4196       type = N_WEAKU;
4197       val = 0;
4198     case bfd_link_hash_indirect:
4199     case bfd_link_hash_warning:
4200       /* FIXME: Ignore these for now.  The circumstances under which
4201          they should be written out are not clear to me.  */
4202       return true;
4203     }
4204
4205   bfd_h_put_8 (output_bfd, type, outsym.e_type);
4206   bfd_h_put_8 (output_bfd, 0, outsym.e_other);
4207   bfd_h_put_16 (output_bfd, 0, outsym.e_desc);
4208   indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
4209                            false);
4210   if (indx == (bfd_size_type) -1)
4211     {
4212       /* FIXME: No way to handle errors.  */
4213       abort ();
4214     }
4215   PUT_WORD (output_bfd, indx, outsym.e_strx);
4216   PUT_WORD (output_bfd, val, outsym.e_value);
4217
4218   if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
4219       || bfd_write ((PTR) &outsym, (bfd_size_type) EXTERNAL_NLIST_SIZE,
4220                     (bfd_size_type) 1, output_bfd) != EXTERNAL_NLIST_SIZE)
4221     {
4222       /* FIXME: No way to handle errors.  */
4223       abort ();
4224     }
4225
4226   finfo->symoff += EXTERNAL_NLIST_SIZE;
4227   h->indx = obj_aout_external_sym_count (output_bfd);
4228   ++obj_aout_external_sym_count (output_bfd);
4229
4230   return true;
4231 }
4232
4233 /* Link an a.out section into the output file.  */
4234
4235 static boolean
4236 aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
4237                          rel_size)
4238      struct aout_final_link_info *finfo;
4239      bfd *input_bfd;
4240      asection *input_section;
4241      file_ptr *reloff_ptr;
4242      bfd_size_type rel_size;
4243 {
4244   bfd_size_type input_size;
4245   PTR relocs;
4246
4247   /* Get the section contents.  */
4248   input_size = bfd_section_size (input_bfd, input_section);
4249   if (! bfd_get_section_contents (input_bfd, input_section,
4250                                   (PTR) finfo->contents,
4251                                   (file_ptr) 0, input_size))
4252     return false;
4253
4254   /* Read in the relocs if we haven't already done it.  */
4255   if (aout_section_data (input_section) != NULL
4256       && aout_section_data (input_section)->relocs != NULL)
4257     relocs = aout_section_data (input_section)->relocs;
4258   else
4259     {
4260       relocs = finfo->relocs;
4261       if (rel_size > 0)
4262         {
4263           if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
4264               || bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
4265             return false;
4266         }
4267     }
4268
4269   /* Relocate the section contents.  */
4270   if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
4271     {
4272       if (! aout_link_input_section_std (finfo, input_bfd, input_section,
4273                                          (struct reloc_std_external *) relocs,
4274                                          rel_size, finfo->contents))
4275         return false;
4276     }
4277   else
4278     {
4279       if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
4280                                          (struct reloc_ext_external *) relocs,
4281                                          rel_size, finfo->contents))
4282         return false;
4283     }
4284
4285   /* Write out the section contents.  */
4286   if (! bfd_set_section_contents (finfo->output_bfd,
4287                                   input_section->output_section,
4288                                   (PTR) finfo->contents,
4289                                   input_section->output_offset,
4290                                   input_size))
4291     return false;
4292
4293   /* If we are producing relocateable output, the relocs were
4294      modified, and we now write them out.  */
4295   if (finfo->info->relocateable && rel_size > 0)
4296     {
4297       if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
4298         return false;
4299       if (bfd_write (relocs, (bfd_size_type) 1, rel_size, finfo->output_bfd)
4300           != rel_size)
4301         return false;
4302       *reloff_ptr += rel_size;
4303
4304       /* Assert that the relocs have not run into the symbols, and
4305          that if these are the text relocs they have not run into the
4306          data relocs.  */
4307       BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
4308                   && (reloff_ptr != &finfo->treloff
4309                       || (*reloff_ptr
4310                           <= obj_datasec (finfo->output_bfd)->rel_filepos)));
4311     }
4312
4313   return true;
4314 }
4315
4316 /* Get the section corresponding to a reloc index.  */
4317
4318 static INLINE asection *
4319 aout_reloc_index_to_section (abfd, indx)
4320      bfd *abfd;
4321      int indx;
4322 {
4323   switch (indx & N_TYPE)
4324     {
4325     case N_TEXT:
4326       return obj_textsec (abfd);
4327     case N_DATA:
4328       return obj_datasec (abfd);
4329     case N_BSS:
4330       return obj_bsssec (abfd);
4331     case N_ABS:
4332     case N_UNDF:
4333       return bfd_abs_section_ptr;
4334     default:
4335       abort ();
4336     }
4337 }
4338
4339 /* Relocate an a.out section using standard a.out relocs.  */
4340
4341 static boolean
4342 aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
4343                              rel_size, contents)
4344      struct aout_final_link_info *finfo;
4345      bfd *input_bfd;
4346      asection *input_section;
4347      struct reloc_std_external *relocs;
4348      bfd_size_type rel_size;
4349      bfd_byte *contents;
4350 {
4351   boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
4352                                           bfd *, asection *,
4353                                           struct aout_link_hash_entry *,
4354                                           PTR, bfd_byte *, boolean *,
4355                                           bfd_vma *));
4356   bfd *output_bfd;
4357   boolean relocateable;
4358   struct external_nlist *syms;
4359   char *strings;
4360   struct aout_link_hash_entry **sym_hashes;
4361   int *symbol_map;
4362   bfd_size_type reloc_count;
4363   register struct reloc_std_external *rel;
4364   struct reloc_std_external *rel_end;
4365
4366   output_bfd = finfo->output_bfd;
4367   check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
4368
4369   BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
4370   BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
4371               == output_bfd->xvec->header_byteorder_big_p);
4372
4373   relocateable = finfo->info->relocateable;
4374   syms = obj_aout_external_syms (input_bfd);
4375   strings = obj_aout_external_strings (input_bfd);
4376   sym_hashes = obj_aout_sym_hashes (input_bfd);
4377   symbol_map = finfo->symbol_map;
4378
4379   reloc_count = rel_size / RELOC_STD_SIZE;
4380   rel = relocs;
4381   rel_end = rel + reloc_count;
4382   for (; rel < rel_end; rel++)
4383     {
4384       bfd_vma r_addr;
4385       int r_index;
4386       int r_extern;
4387       int r_pcrel;
4388       int r_baserel = 0;
4389       reloc_howto_type *howto;
4390       struct aout_link_hash_entry *h = NULL;
4391       bfd_vma relocation;
4392       bfd_reloc_status_type r;
4393
4394       r_addr = GET_SWORD (input_bfd, rel->r_address);
4395
4396 #ifdef MY_reloc_howto
4397       howto = MY_reloc_howto(input_bfd, rel, r_index, r_extern, r_pcrel);
4398 #else      
4399       {
4400         int r_jmptable;
4401         int r_relative;
4402         int r_length;
4403         unsigned int howto_idx;
4404
4405         if (input_bfd->xvec->header_byteorder_big_p)
4406           {
4407             r_index   =  ((rel->r_index[0] << 16)
4408                           | (rel->r_index[1] << 8)
4409                           | rel->r_index[2]);
4410             r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
4411             r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
4412             r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
4413             r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
4414             r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
4415             r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
4416                          >> RELOC_STD_BITS_LENGTH_SH_BIG);
4417           }
4418         else
4419           {
4420             r_index   = ((rel->r_index[2] << 16)
4421                          | (rel->r_index[1] << 8)
4422                          | rel->r_index[0]);
4423             r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
4424             r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
4425             r_baserel = (0 != (rel->r_type[0]
4426                                & RELOC_STD_BITS_BASEREL_LITTLE));
4427             r_jmptable= (0 != (rel->r_type[0]
4428                                & RELOC_STD_BITS_JMPTABLE_LITTLE));
4429             r_relative= (0 != (rel->r_type[0]
4430                                & RELOC_STD_BITS_RELATIVE_LITTLE));
4431             r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
4432                          >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
4433           }
4434
4435         howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
4436                      + 16 * r_jmptable + 32 * r_relative);
4437         BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
4438         howto = howto_table_std + howto_idx;
4439       }
4440 #endif
4441
4442       if (relocateable)
4443         {
4444           /* We are generating a relocateable output file, and must
4445              modify the reloc accordingly.  */
4446           if (r_extern)
4447             {
4448               /* If we know the symbol this relocation is against,
4449                  convert it into a relocation against a section.  This
4450                  is what the native linker does.  */
4451               h = sym_hashes[r_index];
4452               if (h != (struct aout_link_hash_entry *) NULL
4453                   && (h->root.type == bfd_link_hash_defined
4454                       || h->root.type == bfd_link_hash_defweak))
4455                 {
4456                   asection *output_section;
4457
4458                   /* Change the r_extern value.  */
4459                   if (output_bfd->xvec->header_byteorder_big_p)
4460                     rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
4461                   else
4462                     rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
4463
4464                   /* Compute a new r_index.  */
4465                   output_section = h->root.u.def.section->output_section;
4466                   if (output_section == obj_textsec (output_bfd))
4467                     r_index = N_TEXT;
4468                   else if (output_section == obj_datasec (output_bfd))
4469                     r_index = N_DATA;
4470                   else if (output_section == obj_bsssec (output_bfd))
4471                     r_index = N_BSS;
4472                   else
4473                     r_index = N_ABS;
4474
4475                   /* Add the symbol value and the section VMA to the
4476                      addend stored in the contents.  */
4477                   relocation = (h->root.u.def.value
4478                                 + output_section->vma
4479                                 + h->root.u.def.section->output_offset);
4480                 }
4481               else
4482                 {
4483                   /* We must change r_index according to the symbol
4484                      map.  */
4485                   r_index = symbol_map[r_index];
4486
4487                   if (r_index == -1)
4488                     {
4489                       if (h != NULL)
4490                         {
4491                           /* We decided to strip this symbol, but it
4492                              turns out that we can't.  Note that we
4493                              lose the other and desc information here.
4494                              I don't think that will ever matter for a
4495                              global symbol.  */
4496                           if (h->indx < 0)
4497                             {
4498                               h->indx = -2;
4499                               h->written = false;
4500                               if (! aout_link_write_other_symbol (h,
4501                                                                   (PTR) finfo))
4502                                 return false;
4503                             }
4504                           r_index = h->indx;
4505                         }
4506                       else
4507                         {
4508                           const char *name;
4509
4510                           name = strings + GET_WORD (input_bfd,
4511                                                      syms[r_index].e_strx);
4512                           if (! ((*finfo->info->callbacks->unattached_reloc)
4513                                  (finfo->info, name, input_bfd, input_section,
4514                                   r_addr)))
4515                             return false;
4516                           r_index = 0;
4517                         }
4518                     }
4519
4520                   relocation = 0;
4521                 }
4522
4523               /* Write out the new r_index value.  */
4524               if (output_bfd->xvec->header_byteorder_big_p)
4525                 {
4526                   rel->r_index[0] = r_index >> 16;
4527                   rel->r_index[1] = r_index >> 8;
4528                   rel->r_index[2] = r_index;
4529                 }
4530               else
4531                 {
4532                   rel->r_index[2] = r_index >> 16;
4533                   rel->r_index[1] = r_index >> 8;
4534                   rel->r_index[0] = r_index;
4535                 }
4536             }
4537           else
4538             {
4539               asection *section;
4540
4541               /* This is a relocation against a section.  We must
4542                  adjust by the amount that the section moved.  */
4543               section = aout_reloc_index_to_section (input_bfd, r_index);
4544               relocation = (section->output_section->vma
4545                             + section->output_offset
4546                             - section->vma);
4547             }
4548
4549           /* Change the address of the relocation.  */
4550           PUT_WORD (output_bfd,
4551                     r_addr + input_section->output_offset,
4552                     rel->r_address);
4553
4554           /* Adjust a PC relative relocation by removing the reference
4555              to the original address in the section and including the
4556              reference to the new address.  */
4557           if (r_pcrel)
4558             relocation -= (input_section->output_section->vma
4559                            + input_section->output_offset
4560                            - input_section->vma);
4561
4562 #ifdef MY_relocatable_reloc
4563           MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
4564 #endif
4565
4566           if (relocation == 0)
4567             r = bfd_reloc_ok;
4568           else
4569             r = _bfd_relocate_contents (howto,
4570                                         input_bfd, relocation,
4571                                         contents + r_addr);
4572         }
4573       else
4574         {
4575           boolean hundef;
4576
4577           /* We are generating an executable, and must do a full
4578              relocation.  */
4579           hundef = false;
4580           if (r_extern)
4581             {
4582               h = sym_hashes[r_index];
4583
4584               if (h != (struct aout_link_hash_entry *) NULL
4585                   && (h->root.type == bfd_link_hash_defined
4586                       || h->root.type == bfd_link_hash_defweak))
4587                 {
4588                   relocation = (h->root.u.def.value
4589                                 + h->root.u.def.section->output_section->vma
4590                                 + h->root.u.def.section->output_offset);
4591                 }
4592               else if (h != (struct aout_link_hash_entry *) NULL
4593                        && h->root.type == bfd_link_hash_undefweak)
4594                 relocation = 0;
4595               else
4596                 {
4597                   hundef = true;
4598                   relocation = 0;
4599                 }
4600             }
4601           else
4602             {
4603               asection *section;
4604
4605               section = aout_reloc_index_to_section (input_bfd, r_index);
4606               relocation = (section->output_section->vma
4607                             + section->output_offset
4608                             - section->vma);
4609               if (r_pcrel)
4610                 relocation += input_section->vma;
4611             }
4612
4613           if (check_dynamic_reloc != NULL)
4614             {
4615               boolean skip;
4616
4617               if (! ((*check_dynamic_reloc)
4618                      (finfo->info, input_bfd, input_section, h,
4619                       (PTR) rel, contents, &skip, &relocation)))
4620                 return false;
4621               if (skip)
4622                 continue;
4623             }
4624
4625           /* Now warn if a global symbol is undefined.  We could not
4626              do this earlier, because check_dynamic_reloc might want
4627              to skip this reloc.  */
4628           if (hundef && ! finfo->info->shared && ! r_baserel)
4629             {
4630               const char *name;
4631
4632               name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
4633               if (! ((*finfo->info->callbacks->undefined_symbol)
4634                      (finfo->info, name, input_bfd, input_section, r_addr)))
4635                 return false;
4636             }
4637
4638           r = _bfd_final_link_relocate (howto,
4639                                         input_bfd, input_section,
4640                                         contents, r_addr, relocation,
4641                                         (bfd_vma) 0);
4642         }
4643
4644       if (r != bfd_reloc_ok)
4645         {
4646           switch (r)
4647             {
4648             default:
4649             case bfd_reloc_outofrange:
4650               abort ();
4651             case bfd_reloc_overflow:
4652               {
4653                 const char *name;
4654
4655                 if (r_extern)
4656                   name = strings + GET_WORD (input_bfd,
4657                                              syms[r_index].e_strx);
4658                 else
4659                   {
4660                     asection *s;
4661
4662                     s = aout_reloc_index_to_section (input_bfd, r_index);
4663                     name = bfd_section_name (input_bfd, s);
4664                   }
4665                 if (! ((*finfo->info->callbacks->reloc_overflow)
4666                        (finfo->info, name, howto->name,
4667                         (bfd_vma) 0, input_bfd, input_section, r_addr)))
4668                   return false;
4669               }
4670               break;
4671             }
4672         }
4673     }
4674
4675   return true;
4676 }
4677
4678 /* Relocate an a.out section using extended a.out relocs.  */
4679
4680 static boolean
4681 aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
4682                              rel_size, contents)
4683      struct aout_final_link_info *finfo;
4684      bfd *input_bfd;
4685      asection *input_section;
4686      struct reloc_ext_external *relocs;
4687      bfd_size_type rel_size;
4688      bfd_byte *contents;
4689 {
4690   boolean (*check_dynamic_reloc) PARAMS ((struct bfd_link_info *,
4691                                           bfd *, asection *,
4692                                           struct aout_link_hash_entry *,
4693                                           PTR, bfd_byte *, boolean *,
4694                                           bfd_vma *));
4695   bfd *output_bfd;
4696   boolean relocateable;
4697   struct external_nlist *syms;
4698   char *strings;
4699   struct aout_link_hash_entry **sym_hashes;
4700   int *symbol_map;
4701   bfd_size_type reloc_count;
4702   register struct reloc_ext_external *rel;
4703   struct reloc_ext_external *rel_end;
4704
4705   output_bfd = finfo->output_bfd;
4706   check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
4707
4708   BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
4709   BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
4710               == output_bfd->xvec->header_byteorder_big_p);
4711
4712   relocateable = finfo->info->relocateable;
4713   syms = obj_aout_external_syms (input_bfd);
4714   strings = obj_aout_external_strings (input_bfd);
4715   sym_hashes = obj_aout_sym_hashes (input_bfd);
4716   symbol_map = finfo->symbol_map;
4717
4718   reloc_count = rel_size / RELOC_EXT_SIZE;
4719   rel = relocs;
4720   rel_end = rel + reloc_count;
4721   for (; rel < rel_end; rel++)
4722     {
4723       bfd_vma r_addr;
4724       int r_index;
4725       int r_extern;
4726       unsigned int r_type;
4727       bfd_vma r_addend;
4728       struct aout_link_hash_entry *h = NULL;
4729       asection *r_section = NULL;
4730       bfd_vma relocation;
4731
4732       r_addr = GET_SWORD (input_bfd, rel->r_address);
4733
4734       if (input_bfd->xvec->header_byteorder_big_p)
4735         {
4736           r_index  = ((rel->r_index[0] << 16)
4737                       | (rel->r_index[1] << 8)
4738                       | rel->r_index[2]);
4739           r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
4740           r_type   = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
4741                       >> RELOC_EXT_BITS_TYPE_SH_BIG);
4742         }
4743       else
4744         {
4745           r_index  = ((rel->r_index[2] << 16)
4746                       | (rel->r_index[1] << 8)
4747                       | rel->r_index[0]);
4748           r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
4749           r_type   = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
4750                       >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
4751         }
4752
4753       r_addend = GET_SWORD (input_bfd, rel->r_addend);
4754
4755       BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext));
4756
4757       if (relocateable)
4758         {
4759           /* We are generating a relocateable output file, and must
4760              modify the reloc accordingly.  */
4761           if (r_extern)
4762             {
4763               /* If we know the symbol this relocation is against,
4764                  convert it into a relocation against a section.  This
4765                  is what the native linker does.  */
4766               h = sym_hashes[r_index];
4767               if (h != (struct aout_link_hash_entry *) NULL
4768                   && (h->root.type == bfd_link_hash_defined
4769                       || h->root.type == bfd_link_hash_defweak))
4770                 {
4771                   asection *output_section;
4772
4773                   /* Change the r_extern value.  */
4774                   if (output_bfd->xvec->header_byteorder_big_p)
4775                     rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
4776                   else
4777                     rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
4778
4779                   /* Compute a new r_index.  */
4780                   output_section = h->root.u.def.section->output_section;
4781                   if (output_section == obj_textsec (output_bfd))
4782                     r_index = N_TEXT;
4783                   else if (output_section == obj_datasec (output_bfd))
4784                     r_index = N_DATA;
4785                   else if (output_section == obj_bsssec (output_bfd))
4786                     r_index = N_BSS;
4787                   else
4788                     r_index = N_ABS;
4789
4790                   /* Add the symbol value and the section VMA to the
4791                      addend.  */
4792                   relocation = (h->root.u.def.value
4793                                 + output_section->vma
4794                                 + h->root.u.def.section->output_offset);
4795
4796                   /* Now RELOCATION is the VMA of the final
4797                      destination.  If this is a PC relative reloc,
4798                      then ADDEND is the negative of the source VMA.
4799                      We want to set ADDEND to the difference between
4800                      the destination VMA and the source VMA, which
4801                      means we must adjust RELOCATION by the change in
4802                      the source VMA.  This is done below.  */
4803                 }
4804               else
4805                 {
4806                   /* We must change r_index according to the symbol
4807                      map.  */
4808                   r_index = symbol_map[r_index];
4809
4810                   if (r_index == -1)
4811                     {
4812                       if (h != NULL)
4813                         {
4814                           /* We decided to strip this symbol, but it
4815                              turns out that we can't.  Note that we
4816                              lose the other and desc information here.
4817                              I don't think that will ever matter for a
4818                              global symbol.  */
4819                           if (h->indx < 0)
4820                             {
4821                               h->indx = -2;
4822                               h->written = false;
4823                               if (! aout_link_write_other_symbol (h,
4824                                                                   (PTR) finfo))
4825                                 return false;
4826                             }
4827                           r_index = h->indx;
4828                         }
4829                       else
4830                         {
4831                           const char *name;
4832
4833                           name = strings + GET_WORD (input_bfd,
4834                                                      syms[r_index].e_strx);
4835                           if (! ((*finfo->info->callbacks->unattached_reloc)
4836                                  (finfo->info, name, input_bfd, input_section,
4837                                   r_addr)))
4838                             return false;
4839                           r_index = 0;
4840                         }
4841                     }
4842
4843                   relocation = 0;
4844
4845                   /* If this is a PC relative reloc, then the addend
4846                      is the negative of the source VMA.  We must
4847                      adjust it by the change in the source VMA.  This
4848                      is done below.  */
4849                 }
4850
4851               /* Write out the new r_index value.  */
4852               if (output_bfd->xvec->header_byteorder_big_p)
4853                 {
4854                   rel->r_index[0] = r_index >> 16;
4855                   rel->r_index[1] = r_index >> 8;
4856                   rel->r_index[2] = r_index;
4857                 }
4858               else
4859                 {
4860                   rel->r_index[2] = r_index >> 16;
4861                   rel->r_index[1] = r_index >> 8;
4862                   rel->r_index[0] = r_index;
4863                 }
4864             }
4865           else
4866             {
4867               /* This is a relocation against a section.  We must
4868                  adjust by the amount that the section moved.  */
4869               r_section = aout_reloc_index_to_section (input_bfd, r_index);
4870               relocation = (r_section->output_section->vma
4871                             + r_section->output_offset
4872                             - r_section->vma);
4873
4874               /* If this is a PC relative reloc, then the addend is
4875                  the difference in VMA between the destination and the
4876                  source.  We have just adjusted for the change in VMA
4877                  of the destination, so we must also adjust by the
4878                  change in VMA of the source.  This is done below.  */
4879             }
4880
4881           /* As described above, we must always adjust a PC relative
4882              reloc by the change in VMA of the source.  */
4883           if (howto_table_ext[r_type].pc_relative)
4884             relocation -= (input_section->output_section->vma
4885                            + input_section->output_offset
4886                            - input_section->vma);
4887
4888           /* Change the addend if necessary.  */
4889           if (relocation != 0)
4890             PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
4891
4892           /* Change the address of the relocation.  */
4893           PUT_WORD (output_bfd,
4894                     r_addr + input_section->output_offset,
4895                     rel->r_address);
4896         }
4897       else
4898         {
4899           boolean hundef;
4900           bfd_reloc_status_type r;
4901
4902           /* We are generating an executable, and must do a full
4903              relocation.  */
4904           hundef = false;
4905           if (r_extern)
4906             {
4907               h = sym_hashes[r_index];
4908
4909               if (h != (struct aout_link_hash_entry *) NULL
4910                   && (h->root.type == bfd_link_hash_defined
4911                       || h->root.type == bfd_link_hash_defweak))
4912                 {
4913                   relocation = (h->root.u.def.value
4914                                 + h->root.u.def.section->output_section->vma
4915                                 + h->root.u.def.section->output_offset);
4916                 }
4917               else if (h != (struct aout_link_hash_entry *) NULL
4918                        && h->root.type == bfd_link_hash_undefweak)
4919                 relocation = 0;
4920               else
4921                 {
4922                   hundef = true;
4923                   relocation = 0;
4924                 }
4925             }
4926           else if (r_type == RELOC_BASE10
4927                    || r_type == RELOC_BASE13
4928                    || r_type == RELOC_BASE22)
4929             {
4930               struct external_nlist *sym;
4931               int type;
4932
4933               /* For base relative relocs, r_index is always an index
4934                  into the symbol table, even if r_extern is 0.  */
4935               sym = syms + r_index;
4936               type = bfd_h_get_8 (input_bfd, sym->e_type);
4937               if ((type & N_TYPE) == N_TEXT
4938                   || type == N_WEAKT)
4939                 r_section = obj_textsec (input_bfd);
4940               else if ((type & N_TYPE) == N_DATA
4941                        || type == N_WEAKD)
4942                 r_section = obj_datasec (input_bfd);
4943               else if ((type & N_TYPE) == N_BSS
4944                        || type == N_WEAKB)
4945                 r_section = obj_bsssec (input_bfd);
4946               else if ((type & N_TYPE) == N_ABS
4947                        || type == N_WEAKA)
4948                 r_section = bfd_abs_section_ptr;
4949               else
4950                 abort ();
4951               relocation = (r_section->output_section->vma
4952                             + r_section->output_offset
4953                             + (GET_WORD (input_bfd, sym->e_value)
4954                                - r_section->vma));
4955             }
4956           else
4957             {
4958               r_section = aout_reloc_index_to_section (input_bfd, r_index);
4959
4960               /* If this is a PC relative reloc, then R_ADDEND is the
4961                  difference between the two vmas, or
4962                    old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
4963                  where
4964                    old_dest_sec == section->vma
4965                  and
4966                    old_src_sec == input_section->vma
4967                  and
4968                    old_src_off == r_addr
4969
4970                  _bfd_final_link_relocate expects RELOCATION +
4971                  R_ADDEND to be the VMA of the destination minus
4972                  r_addr (the minus r_addr is because this relocation
4973                  is not pcrel_offset, which is a bit confusing and
4974                  should, perhaps, be changed), or
4975                    new_dest_sec
4976                  where
4977                    new_dest_sec == output_section->vma + output_offset
4978                  We arrange for this to happen by setting RELOCATION to
4979                    new_dest_sec + old_src_sec - old_dest_sec
4980
4981                  If this is not a PC relative reloc, then R_ADDEND is
4982                  simply the VMA of the destination, so we set
4983                  RELOCATION to the change in the destination VMA, or
4984                    new_dest_sec - old_dest_sec
4985                  */
4986               relocation = (r_section->output_section->vma
4987                             + r_section->output_offset
4988                             - r_section->vma);
4989               if (howto_table_ext[r_type].pc_relative)
4990                 relocation += input_section->vma;
4991             }
4992
4993           if (check_dynamic_reloc != NULL)
4994             {
4995               boolean skip;
4996
4997               if (! ((*check_dynamic_reloc)
4998                      (finfo->info, input_bfd, input_section, h,
4999                       (PTR) rel, contents, &skip, &relocation)))
5000                 return false;
5001               if (skip)
5002                 continue;
5003             }
5004
5005           /* Now warn if a global symbol is undefined.  We could not
5006              do this earlier, because check_dynamic_reloc might want
5007              to skip this reloc.  */
5008           if (hundef
5009               && ! finfo->info->shared
5010               && r_type != RELOC_BASE10
5011               && r_type != RELOC_BASE13
5012               && r_type != RELOC_BASE22)
5013             {
5014               const char *name;
5015
5016               name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
5017               if (! ((*finfo->info->callbacks->undefined_symbol)
5018                      (finfo->info, name, input_bfd, input_section, r_addr)))
5019                 return false;
5020             }
5021
5022           r = _bfd_final_link_relocate (howto_table_ext + r_type,
5023                                         input_bfd, input_section,
5024                                         contents, r_addr, relocation,
5025                                         r_addend);
5026           if (r != bfd_reloc_ok)
5027             {
5028               switch (r)
5029                 {
5030                 default:
5031                 case bfd_reloc_outofrange:
5032                   abort ();
5033                 case bfd_reloc_overflow:
5034                   {
5035                     const char *name;
5036
5037                     if (r_extern
5038                         || r_type == RELOC_BASE10
5039                         || r_type == RELOC_BASE13
5040                         || r_type == RELOC_BASE22)
5041                       name = strings + GET_WORD (input_bfd,
5042                                                  syms[r_index].e_strx);
5043                     else
5044                       {
5045                         asection *s;
5046
5047                         s = aout_reloc_index_to_section (input_bfd, r_index);
5048                         name = bfd_section_name (input_bfd, s);
5049                       }
5050                     if (! ((*finfo->info->callbacks->reloc_overflow)
5051                            (finfo->info, name, howto_table_ext[r_type].name,
5052                             r_addend, input_bfd, input_section, r_addr)))
5053                       return false;
5054                   }
5055                   break;
5056                 }
5057             }
5058         }
5059     }
5060
5061   return true;
5062 }
5063
5064 /* Handle a link order which is supposed to generate a reloc.  */
5065
5066 static boolean
5067 aout_link_reloc_link_order (finfo, o, p)
5068      struct aout_final_link_info *finfo;
5069      asection *o;
5070      struct bfd_link_order *p;
5071 {
5072   struct bfd_link_order_reloc *pr;
5073   int r_index;
5074   int r_extern;
5075   reloc_howto_type *howto;
5076   file_ptr *reloff_ptr;
5077   struct reloc_std_external srel;
5078   struct reloc_ext_external erel;
5079   PTR rel_ptr;
5080
5081   pr = p->u.reloc.p;
5082
5083   if (p->type == bfd_section_reloc_link_order)
5084     {
5085       r_extern = 0;
5086       if (bfd_is_abs_section (pr->u.section))
5087         r_index = N_ABS | N_EXT;
5088       else
5089         {
5090           BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
5091           r_index = pr->u.section->target_index;
5092         }
5093     }
5094   else
5095     {
5096       struct aout_link_hash_entry *h;
5097
5098       BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
5099       r_extern = 1;
5100       h = aout_link_hash_lookup (aout_hash_table (finfo->info),
5101                                  pr->u.name, false, false, true);
5102       if (h != (struct aout_link_hash_entry *) NULL
5103           && h->indx >= 0)
5104         r_index = h->indx;
5105       else if (h != NULL)
5106         {
5107           /* We decided to strip this symbol, but it turns out that we
5108              can't.  Note that we lose the other and desc information
5109              here.  I don't think that will ever matter for a global
5110              symbol.  */
5111           h->indx = -2;
5112           h->written = false;
5113           if (! aout_link_write_other_symbol (h, (PTR) finfo))
5114             return false;
5115           r_index = h->indx;
5116         }
5117       else
5118         {
5119           if (! ((*finfo->info->callbacks->unattached_reloc)
5120                  (finfo->info, pr->u.name, (bfd *) NULL,
5121                   (asection *) NULL, (bfd_vma) 0)))
5122             return false;
5123           r_index = 0;
5124         }
5125     }
5126
5127   howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
5128   if (howto == 0)
5129     {
5130       bfd_set_error (bfd_error_bad_value);
5131       return false;
5132     }
5133
5134   if (o == obj_textsec (finfo->output_bfd))
5135     reloff_ptr = &finfo->treloff;
5136   else if (o == obj_datasec (finfo->output_bfd))
5137     reloff_ptr = &finfo->dreloff;
5138   else
5139     abort ();
5140
5141   if (obj_reloc_entry_size (finfo->output_bfd) == RELOC_STD_SIZE)
5142     {
5143 #ifdef MY_put_reloc
5144       MY_put_reloc(finfo->output_bfd, r_extern, r_index, p->offset, howto,
5145                    &srel);
5146 #else
5147       {
5148         int r_pcrel;
5149         int r_baserel;
5150         int r_jmptable;
5151         int r_relative;
5152         int r_length;
5153
5154         r_pcrel = howto->pc_relative;
5155         r_baserel = (howto->type & 8) != 0;
5156         r_jmptable = (howto->type & 16) != 0;
5157         r_relative = (howto->type & 32) != 0;
5158         r_length = howto->size;
5159
5160         PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
5161         if (finfo->output_bfd->xvec->header_byteorder_big_p)
5162           {
5163             srel.r_index[0] = r_index >> 16;
5164             srel.r_index[1] = r_index >> 8;
5165             srel.r_index[2] = r_index;
5166             srel.r_type[0] =
5167               ((r_extern ?     RELOC_STD_BITS_EXTERN_BIG : 0)
5168                | (r_pcrel ?    RELOC_STD_BITS_PCREL_BIG : 0)
5169                | (r_baserel ?  RELOC_STD_BITS_BASEREL_BIG : 0)
5170                | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
5171                | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
5172                | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG));
5173           }
5174         else
5175           {
5176             srel.r_index[2] = r_index >> 16;
5177             srel.r_index[1] = r_index >> 8;
5178             srel.r_index[0] = r_index;
5179             srel.r_type[0] =
5180               ((r_extern ?     RELOC_STD_BITS_EXTERN_LITTLE : 0)
5181                | (r_pcrel ?    RELOC_STD_BITS_PCREL_LITTLE : 0)
5182                | (r_baserel ?  RELOC_STD_BITS_BASEREL_LITTLE : 0)
5183                | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
5184                | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
5185                | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE));
5186           }
5187       }
5188 #endif
5189       rel_ptr = (PTR) &srel;
5190
5191       /* We have to write the addend into the object file, since
5192          standard a.out relocs are in place.  It would be more
5193          reliable if we had the current contents of the file here,
5194          rather than assuming zeroes, but we can't read the file since
5195          it was opened using bfd_openw.  */
5196       if (pr->addend != 0)
5197         {
5198           bfd_size_type size;
5199           bfd_reloc_status_type r;
5200           bfd_byte *buf;
5201           boolean ok;
5202
5203           size = bfd_get_reloc_size (howto);
5204           buf = (bfd_byte *) bfd_zmalloc (size);
5205           if (buf == (bfd_byte *) NULL)
5206             {
5207               bfd_set_error (bfd_error_no_memory);
5208               return false;
5209             }
5210           r = _bfd_relocate_contents (howto, finfo->output_bfd,
5211                                       pr->addend, buf);
5212           switch (r)
5213             {
5214             case bfd_reloc_ok:
5215               break;
5216             default:
5217             case bfd_reloc_outofrange:
5218               abort ();
5219             case bfd_reloc_overflow:
5220               if (! ((*finfo->info->callbacks->reloc_overflow)
5221                      (finfo->info,
5222                       (p->type == bfd_section_reloc_link_order
5223                        ? bfd_section_name (finfo->output_bfd,
5224                                            pr->u.section)
5225                        : pr->u.name),
5226                       howto->name, pr->addend, (bfd *) NULL,
5227                       (asection *) NULL, (bfd_vma) 0)))
5228                 {
5229                   free (buf);
5230                   return false;
5231                 }
5232               break;
5233             }
5234           ok = bfd_set_section_contents (finfo->output_bfd, o,
5235                                          (PTR) buf,
5236                                          (file_ptr) p->offset,
5237                                          size);
5238           free (buf);
5239           if (! ok)
5240             return false;
5241         }
5242     }
5243   else
5244     {
5245       PUT_WORD (finfo->output_bfd, p->offset, erel.r_address);
5246
5247       if (finfo->output_bfd->xvec->header_byteorder_big_p)
5248         {
5249           erel.r_index[0] = r_index >> 16;
5250           erel.r_index[1] = r_index >> 8;
5251           erel.r_index[2] = r_index;
5252           erel.r_type[0] =
5253             ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
5254              | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG));
5255         }
5256       else
5257         {
5258           erel.r_index[2] = r_index >> 16;
5259           erel.r_index[1] = r_index >> 8;
5260           erel.r_index[0] = r_index;
5261           erel.r_type[0] =
5262             (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
5263               | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
5264         }
5265
5266       PUT_WORD (finfo->output_bfd, pr->addend, erel.r_addend);
5267
5268       rel_ptr = (PTR) &erel;
5269     }
5270
5271   if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
5272       || (bfd_write (rel_ptr, (bfd_size_type) 1,
5273                      obj_reloc_entry_size (finfo->output_bfd),
5274                      finfo->output_bfd)
5275           != obj_reloc_entry_size (finfo->output_bfd)))
5276     return false;
5277
5278   *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd);
5279
5280   /* Assert that the relocs have not run into the symbols, and that n
5281      the text relocs have not run into the data relocs.  */
5282   BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
5283               && (reloff_ptr != &finfo->treloff
5284                   || (*reloff_ptr
5285                       <= obj_datasec (finfo->output_bfd)->rel_filepos)));
5286
5287   return true;
5288 }