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