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