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