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