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