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