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