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