OSDN Git Service

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