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