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