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