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