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