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