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, bfd_boolean execable ATTRIBUTE_UNUSED)
2784 {
2785   return adata (abfd).exec_bytes_size;
2786 }
2787
2788 /* Free all information we have cached for this BFD.  We can always
2789    read it again later if we need it.  */
2790
2791 bfd_boolean
2792 NAME (aout, bfd_free_cached_info) (bfd *abfd)
2793 {
2794   asection *o;
2795
2796   if (bfd_get_format (abfd) != bfd_object
2797       || abfd->tdata.aout_data == NULL)
2798     return TRUE;
2799
2800 #define BFCI_FREE(x) if (x != NULL) { free (x); x = NULL; }
2801   BFCI_FREE (obj_aout_symbols (abfd));
2802 #ifdef USE_MMAP
2803   obj_aout_external_syms (abfd) = 0;
2804   bfd_free_window (&obj_aout_sym_window (abfd));
2805   bfd_free_window (&obj_aout_string_window (abfd));
2806   obj_aout_external_strings (abfd) = 0;
2807 #else
2808   BFCI_FREE (obj_aout_external_syms (abfd));
2809   BFCI_FREE (obj_aout_external_strings (abfd));
2810 #endif
2811   for (o = abfd->sections; o != NULL; o = o->next)
2812     BFCI_FREE (o->relocation);
2813 #undef BFCI_FREE
2814
2815   return TRUE;
2816 }
2817 \f
2818 /* a.out link code.  */
2819
2820 /* Routine to create an entry in an a.out link hash table.  */
2821
2822 struct bfd_hash_entry *
2823 NAME (aout, link_hash_newfunc) (struct bfd_hash_entry *entry,
2824                                 struct bfd_hash_table *table,
2825                                 const char *string)
2826 {
2827   struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
2828
2829   /* Allocate the structure if it has not already been allocated by a
2830      subclass.  */
2831   if (ret == NULL)
2832     ret = bfd_hash_allocate (table, sizeof (* ret));
2833   if (ret == NULL)
2834     return NULL;
2835
2836   /* Call the allocation method of the superclass.  */
2837   ret = ((struct aout_link_hash_entry *)
2838          _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
2839                                  table, string));
2840   if (ret)
2841     {
2842       /* Set local fields.  */
2843       ret->written = FALSE;
2844       ret->indx = -1;
2845     }
2846
2847   return (struct bfd_hash_entry *) ret;
2848 }
2849
2850 /* Initialize an a.out link hash table.  */
2851
2852 bfd_boolean
2853 NAME (aout, link_hash_table_init) (struct aout_link_hash_table *table,
2854                                    bfd *abfd,
2855                                    struct bfd_hash_entry *(*newfunc)
2856                                    (struct bfd_hash_entry *, struct bfd_hash_table *,
2857                                     const char *),
2858                                    unsigned int entsize)
2859 {
2860   return _bfd_link_hash_table_init (&table->root, abfd, newfunc, entsize);
2861 }
2862
2863 /* Create an a.out link hash table.  */
2864
2865 struct bfd_link_hash_table *
2866 NAME (aout, link_hash_table_create) (bfd *abfd)
2867 {
2868   struct aout_link_hash_table *ret;
2869   bfd_size_type amt = sizeof (* ret);
2870
2871   ret = bfd_malloc (amt);
2872   if (ret == NULL)
2873     return NULL;
2874
2875   if (!NAME (aout, link_hash_table_init) (ret, abfd,
2876                                           NAME (aout, link_hash_newfunc),
2877                                           sizeof (struct aout_link_hash_entry)))
2878     {
2879       free (ret);
2880       return NULL;
2881     }
2882   return &ret->root;
2883 }
2884
2885 /* Add all symbols from an object file to the hash table.  */
2886
2887 static bfd_boolean
2888 aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
2889 {
2890   bfd_boolean (*add_one_symbol)
2891     (struct bfd_link_info *, bfd *, const char *, flagword, asection *,
2892              bfd_vma, const char *, bfd_boolean, bfd_boolean,
2893              struct bfd_link_hash_entry **);
2894   struct external_nlist *syms;
2895   bfd_size_type sym_count;
2896   char *strings;
2897   bfd_boolean copy;
2898   struct aout_link_hash_entry **sym_hash;
2899   struct external_nlist *p;
2900   struct external_nlist *pend;
2901   bfd_size_type amt;
2902
2903   syms = obj_aout_external_syms (abfd);
2904   sym_count = obj_aout_external_sym_count (abfd);
2905   strings = obj_aout_external_strings (abfd);
2906   if (info->keep_memory)
2907     copy = FALSE;
2908   else
2909     copy = TRUE;
2910
2911   if (aout_backend_info (abfd)->add_dynamic_symbols != NULL)
2912     {
2913       if (! ((*aout_backend_info (abfd)->add_dynamic_symbols)
2914              (abfd, info, &syms, &sym_count, &strings)))
2915         return FALSE;
2916     }
2917
2918   /* We keep a list of the linker hash table entries that correspond
2919      to particular symbols.  We could just look them up in the hash
2920      table, but keeping the list is more efficient.  Perhaps this
2921      should be conditional on info->keep_memory.  */
2922   amt = sym_count * sizeof (struct aout_link_hash_entry *);
2923   sym_hash = bfd_alloc (abfd, amt);
2924   if (sym_hash == NULL && sym_count != 0)
2925     return FALSE;
2926   obj_aout_sym_hashes (abfd) = sym_hash;
2927
2928   add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
2929   if (add_one_symbol == NULL)
2930     add_one_symbol = _bfd_generic_link_add_one_symbol;
2931
2932   p = syms;
2933   pend = p + sym_count;
2934   for (; p < pend; p++, sym_hash++)
2935     {
2936       int type;
2937       const char *name;
2938       bfd_vma value;
2939       asection *section;
2940       flagword flags;
2941       const char *string;
2942
2943       *sym_hash = NULL;
2944
2945       type = H_GET_8 (abfd, p->e_type);
2946
2947       /* Ignore debugging symbols.  */
2948       if ((type & N_STAB) != 0)
2949         continue;
2950
2951       name = strings + GET_WORD (abfd, p->e_strx);
2952       value = GET_WORD (abfd, p->e_value);
2953       flags = BSF_GLOBAL;
2954       string = NULL;
2955       switch (type)
2956         {
2957         default:
2958           abort ();
2959
2960         case N_UNDF:
2961         case N_ABS:
2962         case N_TEXT:
2963         case N_DATA:
2964         case N_BSS:
2965         case N_FN_SEQ:
2966         case N_COMM:
2967         case N_SETV:
2968         case N_FN:
2969           /* Ignore symbols that are not externally visible.  */
2970           continue;
2971         case N_INDR:
2972           /* Ignore local indirect symbol.  */
2973           ++p;
2974           ++sym_hash;
2975           continue;
2976
2977         case N_UNDF | N_EXT:
2978           if (value == 0)
2979             {
2980               section = bfd_und_section_ptr;
2981               flags = 0;
2982             }
2983           else
2984             section = bfd_com_section_ptr;
2985           break;
2986         case N_ABS | N_EXT:
2987           section = bfd_abs_section_ptr;
2988           break;
2989         case N_TEXT | N_EXT:
2990           section = obj_textsec (abfd);
2991           value -= bfd_get_section_vma (abfd, section);
2992           break;
2993         case N_DATA | N_EXT:
2994         case N_SETV | N_EXT:
2995           /* Treat N_SETV symbols as N_DATA symbol; see comment in
2996              translate_from_native_sym_flags.  */
2997           section = obj_datasec (abfd);
2998           value -= bfd_get_section_vma (abfd, section);
2999           break;
3000         case N_BSS | N_EXT:
3001           section = obj_bsssec (abfd);
3002           value -= bfd_get_section_vma (abfd, section);
3003           break;
3004         case N_INDR | N_EXT:
3005           /* An indirect symbol.  The next symbol is the symbol
3006              which this one really is.  */
3007           BFD_ASSERT (p + 1 < pend);
3008           ++p;
3009           string = strings + GET_WORD (abfd, p->e_strx);
3010           section = bfd_ind_section_ptr;
3011           flags |= BSF_INDIRECT;
3012           break;
3013         case N_COMM | N_EXT:
3014           section = bfd_com_section_ptr;
3015           break;
3016         case N_SETA: case N_SETA | N_EXT:
3017           section = bfd_abs_section_ptr;
3018           flags |= BSF_CONSTRUCTOR;
3019           break;
3020         case N_SETT: case N_SETT | N_EXT:
3021           section = obj_textsec (abfd);
3022           flags |= BSF_CONSTRUCTOR;
3023           value -= bfd_get_section_vma (abfd, section);
3024           break;
3025         case N_SETD: case N_SETD | N_EXT:
3026           section = obj_datasec (abfd);
3027           flags |= BSF_CONSTRUCTOR;
3028           value -= bfd_get_section_vma (abfd, section);
3029           break;
3030         case N_SETB: case N_SETB | N_EXT:
3031           section = obj_bsssec (abfd);
3032           flags |= BSF_CONSTRUCTOR;
3033           value -= bfd_get_section_vma (abfd, section);
3034           break;
3035         case N_WARNING:
3036           /* A warning symbol.  The next symbol is the one to warn
3037              about.  If there is no next symbol, just look away.  */
3038           if (p + 1 >= pend)
3039             return TRUE;
3040           ++p;
3041           string = name;
3042           name = strings + GET_WORD (abfd, p->e_strx);
3043           section = bfd_und_section_ptr;
3044           flags |= BSF_WARNING;
3045           break;
3046         case N_WEAKU:
3047           section = bfd_und_section_ptr;
3048           flags = BSF_WEAK;
3049           break;
3050         case N_WEAKA:
3051           section = bfd_abs_section_ptr;
3052           flags = BSF_WEAK;
3053           break;
3054         case N_WEAKT:
3055           section = obj_textsec (abfd);
3056           value -= bfd_get_section_vma (abfd, section);
3057           flags = BSF_WEAK;
3058           break;
3059         case N_WEAKD:
3060           section = obj_datasec (abfd);
3061           value -= bfd_get_section_vma (abfd, section);
3062           flags = BSF_WEAK;
3063           break;
3064         case N_WEAKB:
3065           section = obj_bsssec (abfd);
3066           value -= bfd_get_section_vma (abfd, section);
3067           flags = BSF_WEAK;
3068           break;
3069         }
3070
3071       if (! ((*add_one_symbol)
3072              (info, abfd, name, flags, section, value, string, copy, FALSE,
3073               (struct bfd_link_hash_entry **) sym_hash)))
3074         return FALSE;
3075
3076       /* Restrict the maximum alignment of a common symbol based on
3077          the architecture, since a.out has no way to represent
3078          alignment requirements of a section in a .o file.  FIXME:
3079          This isn't quite right: it should use the architecture of the
3080          output file, not the input files.  */
3081       if ((*sym_hash)->root.type == bfd_link_hash_common
3082           && ((*sym_hash)->root.u.c.p->alignment_power >
3083               bfd_get_arch_info (abfd)->section_align_power))
3084         (*sym_hash)->root.u.c.p->alignment_power =
3085           bfd_get_arch_info (abfd)->section_align_power;
3086
3087       /* If this is a set symbol, and we are not building sets, then
3088          it is possible for the hash entry to not have been set.  In
3089          such a case, treat the symbol as not globally defined.  */
3090       if ((*sym_hash)->root.type == bfd_link_hash_new)
3091         {
3092           BFD_ASSERT ((flags & BSF_CONSTRUCTOR) != 0);
3093           *sym_hash = NULL;
3094         }
3095
3096       if (type == (N_INDR | N_EXT) || type == N_WARNING)
3097         ++sym_hash;
3098     }
3099
3100   return TRUE;
3101 }
3102
3103 /* Free up the internal symbols read from an a.out file.  */
3104
3105 static bfd_boolean
3106 aout_link_free_symbols (bfd *abfd)
3107 {
3108   if (obj_aout_external_syms (abfd) != NULL)
3109     {
3110 #ifdef USE_MMAP
3111       bfd_free_window (&obj_aout_sym_window (abfd));
3112 #else
3113       free ((void *) obj_aout_external_syms (abfd));
3114 #endif
3115       obj_aout_external_syms (abfd) = NULL;
3116     }
3117   if (obj_aout_external_strings (abfd) != NULL)
3118     {
3119 #ifdef USE_MMAP
3120       bfd_free_window (&obj_aout_string_window (abfd));
3121 #else
3122       free ((void *) obj_aout_external_strings (abfd));
3123 #endif
3124       obj_aout_external_strings (abfd) = NULL;
3125     }
3126   return TRUE;
3127 }
3128
3129 /* Add symbols from an a.out object file.  */
3130
3131 static bfd_boolean
3132 aout_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
3133 {
3134   if (! aout_get_external_symbols (abfd))
3135     return FALSE;
3136   if (! aout_link_add_symbols (abfd, info))
3137     return FALSE;
3138   if (! info->keep_memory)
3139     {
3140       if (! aout_link_free_symbols (abfd))
3141         return FALSE;
3142     }
3143   return TRUE;
3144 }
3145
3146 /* Look through the internal symbols to see if this object file should
3147    be included in the link.  We should include this object file if it
3148    defines any symbols which are currently undefined.  If this object
3149    file defines a common symbol, then we may adjust the size of the
3150    known symbol but we do not include the object file in the link
3151    (unless there is some other reason to include it).  */
3152
3153 static bfd_boolean
3154 aout_link_check_ar_symbols (bfd *abfd,
3155                             struct bfd_link_info *info,
3156                             bfd_boolean *pneeded)
3157 {
3158   struct external_nlist *p;
3159   struct external_nlist *pend;
3160   char *strings;
3161
3162   *pneeded = FALSE;
3163
3164   /* Look through all the symbols.  */
3165   p = obj_aout_external_syms (abfd);
3166   pend = p + obj_aout_external_sym_count (abfd);
3167   strings = obj_aout_external_strings (abfd);
3168   for (; p < pend; p++)
3169     {
3170       int type = H_GET_8 (abfd, p->e_type);
3171       const char *name;
3172       struct bfd_link_hash_entry *h;
3173
3174       /* Ignore symbols that are not externally visible.  This is an
3175          optimization only, as we check the type more thoroughly
3176          below.  */
3177       if (((type & N_EXT) == 0
3178            || (type & N_STAB) != 0
3179            || type == N_FN)
3180           && type != N_WEAKA
3181           && type != N_WEAKT
3182           && type != N_WEAKD
3183           && type != N_WEAKB)
3184         {
3185           if (type == N_WARNING
3186               || type == N_INDR)
3187             ++p;
3188           continue;
3189         }
3190
3191       name = strings + GET_WORD (abfd, p->e_strx);
3192       h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
3193
3194       /* We are only interested in symbols that are currently
3195          undefined or common.  */
3196       if (h == NULL
3197           || (h->type != bfd_link_hash_undefined
3198               && h->type != bfd_link_hash_common))
3199         {
3200           if (type == (N_INDR | N_EXT))
3201             ++p;
3202           continue;
3203         }
3204
3205       if (type == (N_TEXT | N_EXT)
3206           || type == (N_DATA | N_EXT)
3207           || type == (N_BSS | N_EXT)
3208           || type == (N_ABS | N_EXT)
3209           || type == (N_INDR | N_EXT))
3210         {
3211           /* This object file defines this symbol.  We must link it
3212              in.  This is true regardless of whether the current
3213              definition of the symbol is undefined or common.
3214
3215              If the current definition is common, we have a case in
3216              which we have already seen an object file including:
3217                  int a;
3218              and this object file from the archive includes:
3219                  int a = 5;
3220              In such a case, whether to include this object is target
3221              dependant for backward compatibility.
3222
3223              FIXME: The SunOS 4.1.3 linker will pull in the archive
3224              element if the symbol is defined in the .data section,
3225              but not if it is defined in the .text section.  That
3226              seems a bit crazy to me, and it has not been implemented
3227              yet.  However, it might be correct.  */
3228           if (h->type == bfd_link_hash_common)
3229             {
3230               int skip = 0;
3231
3232               switch (info->common_skip_ar_aymbols)
3233                 {
3234                 case bfd_link_common_skip_text:
3235                   skip = (type == (N_TEXT | N_EXT));
3236                   break;
3237                 case bfd_link_common_skip_data:
3238                   skip = (type == (N_DATA | N_EXT));
3239                   break;
3240                 default:
3241                 case bfd_link_common_skip_all:
3242                   skip = 1;
3243                   break;
3244                 }
3245
3246               if (skip)
3247                 continue;
3248             }
3249
3250           if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3251             return FALSE;
3252           *pneeded = TRUE;
3253           return TRUE;
3254         }
3255
3256       if (type == (N_UNDF | N_EXT))
3257         {
3258           bfd_vma value;
3259
3260           value = GET_WORD (abfd, p->e_value);
3261           if (value != 0)
3262             {
3263               /* This symbol is common in the object from the archive
3264                  file.  */
3265               if (h->type == bfd_link_hash_undefined)
3266                 {
3267                   bfd *symbfd;
3268                   unsigned int power;
3269
3270                   symbfd = h->u.undef.abfd;
3271                   if (symbfd == NULL)
3272                     {
3273                       /* This symbol was created as undefined from
3274                          outside BFD.  We assume that we should link
3275                          in the object file.  This is done for the -u
3276                          option in the linker.  */
3277                       if (! (*info->callbacks->add_archive_element) (info,
3278                                                                      abfd,
3279                                                                      name))
3280                         return FALSE;
3281                       *pneeded = TRUE;
3282                       return TRUE;
3283                     }
3284                   /* Turn the current link symbol into a common
3285                      symbol.  It is already on the undefs list.  */
3286                   h->type = bfd_link_hash_common;
3287                   h->u.c.p = bfd_hash_allocate (&info->hash->table,
3288                                                 sizeof (struct bfd_link_hash_common_entry));
3289                   if (h->u.c.p == NULL)
3290                     return FALSE;
3291
3292                   h->u.c.size = value;
3293
3294                   /* FIXME: This isn't quite right.  The maximum
3295                      alignment of a common symbol should be set by the
3296                      architecture of the output file, not of the input
3297                      file.  */
3298                   power = bfd_log2 (value);
3299                   if (power > bfd_get_arch_info (abfd)->section_align_power)
3300                     power = bfd_get_arch_info (abfd)->section_align_power;
3301                   h->u.c.p->alignment_power = power;
3302
3303                   h->u.c.p->section = bfd_make_section_old_way (symbfd,
3304                                                                 "COMMON");
3305                 }
3306               else
3307                 {
3308                   /* Adjust the size of the common symbol if
3309                      necessary.  */
3310                   if (value > h->u.c.size)
3311                     h->u.c.size = value;
3312                 }
3313             }
3314         }
3315
3316       if (type == N_WEAKA
3317           || type == N_WEAKT
3318           || type == N_WEAKD
3319           || type == N_WEAKB)
3320         {
3321           /* This symbol is weak but defined.  We must pull it in if
3322              the current link symbol is undefined, but we don't want
3323              it if the current link symbol is common.  */
3324           if (h->type == bfd_link_hash_undefined)
3325             {
3326               if (! (*info->callbacks->add_archive_element) (info, abfd, name))
3327                 return FALSE;
3328               *pneeded = TRUE;
3329               return TRUE;
3330             }
3331         }
3332     }
3333
3334   /* We do not need this object file.  */
3335   return TRUE;
3336 }
3337 /* Check a single archive element to see if we need to include it in
3338    the link.  *PNEEDED is set according to whether this element is
3339    needed in the link or not.  This is called from
3340    _bfd_generic_link_add_archive_symbols.  */
3341
3342 static bfd_boolean
3343 aout_link_check_archive_element (bfd *abfd,
3344                                  struct bfd_link_info *info,
3345                                  bfd_boolean *pneeded)
3346 {
3347   if (! aout_get_external_symbols (abfd))
3348     return FALSE;
3349
3350   if (! aout_link_check_ar_symbols (abfd, info, pneeded))
3351     return FALSE;
3352
3353   if (*pneeded)
3354     {
3355       if (! aout_link_add_symbols (abfd, info))
3356         return FALSE;
3357     }
3358
3359   if (! info->keep_memory || ! *pneeded)
3360     {
3361       if (! aout_link_free_symbols (abfd))
3362         return FALSE;
3363     }
3364
3365   return TRUE;
3366 }
3367
3368 /* Given an a.out BFD, add symbols to the global hash table as
3369    appropriate.  */
3370
3371 bfd_boolean
3372 NAME (aout, link_add_symbols) (bfd *abfd, struct bfd_link_info *info)
3373 {
3374   switch (bfd_get_format (abfd))
3375     {
3376     case bfd_object:
3377       return aout_link_add_object_symbols (abfd, info);
3378     case bfd_archive:
3379       return _bfd_generic_link_add_archive_symbols
3380         (abfd, info, aout_link_check_archive_element);
3381     default:
3382       bfd_set_error (bfd_error_wrong_format);
3383       return FALSE;
3384     }
3385 }
3386 \f
3387 /* A hash table used for header files with N_BINCL entries.  */
3388
3389 struct aout_link_includes_table
3390 {
3391   struct bfd_hash_table root;
3392 };
3393
3394 /* A linked list of totals that we have found for a particular header
3395    file.  */
3396
3397 struct aout_link_includes_totals
3398 {
3399   struct aout_link_includes_totals *next;
3400   bfd_vma total;
3401 };
3402
3403 /* An entry in the header file hash table.  */
3404
3405 struct aout_link_includes_entry
3406 {
3407   struct bfd_hash_entry root;
3408   /* List of totals we have found for this file.  */
3409   struct aout_link_includes_totals *totals;
3410 };
3411
3412 /* Look up an entry in an the header file hash table.  */
3413
3414 #define aout_link_includes_lookup(table, string, create, copy)          \
3415   ((struct aout_link_includes_entry *)                                  \
3416    bfd_hash_lookup (&(table)->root, (string), (create), (copy)))
3417
3418 /* During the final link step we need to pass around a bunch of
3419    information, so we do it in an instance of this structure.  */
3420
3421 struct aout_final_link_info
3422 {
3423   /* General link information.  */
3424   struct bfd_link_info *info;
3425   /* Output bfd.  */
3426   bfd *output_bfd;
3427   /* Reloc file positions.  */
3428   file_ptr treloff, dreloff;
3429   /* File position of symbols.  */
3430   file_ptr symoff;
3431   /* String table.  */
3432   struct bfd_strtab_hash *strtab;
3433   /* Header file hash table.  */
3434   struct aout_link_includes_table includes;
3435   /* A buffer large enough to hold the contents of any section.  */
3436   bfd_byte *contents;
3437   /* A buffer large enough to hold the relocs of any section.  */
3438   void * relocs;
3439   /* A buffer large enough to hold the symbol map of any input BFD.  */
3440   int *symbol_map;
3441   /* A buffer large enough to hold output symbols of any input BFD.  */
3442   struct external_nlist *output_syms;
3443 };
3444
3445 /* The function to create a new entry in the header file hash table.  */
3446
3447 static struct bfd_hash_entry *
3448 aout_link_includes_newfunc (struct bfd_hash_entry *entry,
3449                             struct bfd_hash_table *table,
3450                             const char *string)
3451 {
3452   struct aout_link_includes_entry *ret =
3453     (struct aout_link_includes_entry *) entry;
3454
3455   /* Allocate the structure if it has not already been allocated by a
3456      subclass.  */
3457   if (ret == NULL)
3458     ret = bfd_hash_allocate (table, sizeof (* ret));
3459   if (ret == NULL)
3460     return NULL;
3461
3462   /* Call the allocation method of the superclass.  */
3463   ret = ((struct aout_link_includes_entry *)
3464          bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
3465   if (ret)
3466     {
3467       /* Set local fields.  */
3468       ret->totals = NULL;
3469     }
3470
3471   return (struct bfd_hash_entry *) ret;
3472 }
3473
3474 /* Write out a symbol that was not associated with an a.out input
3475    object.  */
3476
3477 static bfd_boolean
3478 aout_link_write_other_symbol (struct aout_link_hash_entry *h, void * data)
3479 {
3480   struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
3481   bfd *output_bfd;
3482   int type;
3483   bfd_vma val;
3484   struct external_nlist outsym;
3485   bfd_size_type indx;
3486   bfd_size_type amt;
3487
3488   if (h->root.type == bfd_link_hash_warning)
3489     {
3490       h = (struct aout_link_hash_entry *) h->root.u.i.link;
3491       if (h->root.type == bfd_link_hash_new)
3492         return TRUE;
3493     }
3494
3495   output_bfd = finfo->output_bfd;
3496
3497   if (aout_backend_info (output_bfd)->write_dynamic_symbol != NULL)
3498     {
3499       if (! ((*aout_backend_info (output_bfd)->write_dynamic_symbol)
3500              (output_bfd, finfo->info, h)))
3501         {
3502           /* FIXME: No way to handle errors.  */
3503           abort ();
3504         }
3505     }
3506
3507   if (h->written)
3508     return TRUE;
3509
3510   h->written = TRUE;
3511
3512   /* An indx of -2 means the symbol must be written.  */
3513   if (h->indx != -2
3514       && (finfo->info->strip == strip_all
3515           || (finfo->info->strip == strip_some
3516               && bfd_hash_lookup (finfo->info->keep_hash, h->root.root.string,
3517                                   FALSE, FALSE) == NULL)))
3518     return TRUE;
3519
3520   switch (h->root.type)
3521     {
3522     default:
3523     case bfd_link_hash_warning:
3524       abort ();
3525       /* Avoid variable not initialized warnings.  */
3526       return TRUE;
3527     case bfd_link_hash_new:
3528       /* This can happen for set symbols when sets are not being
3529          built.  */
3530       return TRUE;
3531     case bfd_link_hash_undefined:
3532       type = N_UNDF | N_EXT;
3533       val = 0;
3534       break;
3535     case bfd_link_hash_defined:
3536     case bfd_link_hash_defweak:
3537       {
3538         asection *sec;
3539
3540         sec = h->root.u.def.section->output_section;
3541         BFD_ASSERT (bfd_is_abs_section (sec)
3542                     || sec->owner == output_bfd);
3543         if (sec == obj_textsec (output_bfd))
3544           type = h->root.type == bfd_link_hash_defined ? N_TEXT : N_WEAKT;
3545         else if (sec == obj_datasec (output_bfd))
3546           type = h->root.type == bfd_link_hash_defined ? N_DATA : N_WEAKD;
3547         else if (sec == obj_bsssec (output_bfd))
3548           type = h->root.type == bfd_link_hash_defined ? N_BSS : N_WEAKB;
3549         else
3550           type = h->root.type == bfd_link_hash_defined ? N_ABS : N_WEAKA;
3551         type |= N_EXT;
3552         val = (h->root.u.def.value
3553                + sec->vma
3554                + h->root.u.def.section->output_offset);
3555       }
3556       break;
3557     case bfd_link_hash_common:
3558       type = N_UNDF | N_EXT;
3559       val = h->root.u.c.size;
3560       break;
3561     case bfd_link_hash_undefweak:
3562       type = N_WEAKU;
3563       val = 0;
3564     case bfd_link_hash_indirect:
3565       /* We ignore these symbols, since the indirected symbol is
3566          already in the hash table.  */
3567       return TRUE;
3568     }
3569
3570   H_PUT_8 (output_bfd, type, outsym.e_type);
3571   H_PUT_8 (output_bfd, 0, outsym.e_other);
3572   H_PUT_16 (output_bfd, 0, outsym.e_desc);
3573   indx = add_to_stringtab (output_bfd, finfo->strtab, h->root.root.string,
3574                            FALSE);
3575   if (indx == - (bfd_size_type) 1)
3576     /* FIXME: No way to handle errors.  */
3577     abort ();
3578
3579   PUT_WORD (output_bfd, indx, outsym.e_strx);
3580   PUT_WORD (output_bfd, val, outsym.e_value);
3581
3582   amt = EXTERNAL_NLIST_SIZE;
3583   if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
3584       || bfd_bwrite ((void *) &outsym, amt, output_bfd) != amt)
3585     /* FIXME: No way to handle errors.  */
3586     abort ();
3587
3588   finfo->symoff += EXTERNAL_NLIST_SIZE;
3589   h->indx = obj_aout_external_sym_count (output_bfd);
3590   ++obj_aout_external_sym_count (output_bfd);
3591
3592   return TRUE;
3593 }
3594
3595 /* Handle a link order which is supposed to generate a reloc.  */
3596
3597 static bfd_boolean
3598 aout_link_reloc_link_order (struct aout_final_link_info *finfo,
3599                             asection *o,
3600                             struct bfd_link_order *p)
3601 {
3602   struct bfd_link_order_reloc *pr;
3603   int r_index;
3604   int r_extern;
3605   reloc_howto_type *howto;
3606   file_ptr *reloff_ptr = NULL;
3607   struct reloc_std_external srel;
3608   struct reloc_ext_external erel;
3609   void * rel_ptr;
3610   bfd_size_type amt;
3611
3612   pr = p->u.reloc.p;
3613
3614   if (p->type == bfd_section_reloc_link_order)
3615     {
3616       r_extern = 0;
3617       if (bfd_is_abs_section (pr->u.section))
3618         r_index = N_ABS | N_EXT;
3619       else
3620         {
3621           BFD_ASSERT (pr->u.section->owner == finfo->output_bfd);
3622           r_index = pr->u.section->target_index;
3623         }
3624     }
3625   else
3626     {
3627       struct aout_link_hash_entry *h;
3628
3629       BFD_ASSERT (p->type == bfd_symbol_reloc_link_order);
3630       r_extern = 1;
3631       h = ((struct aout_link_hash_entry *)
3632            bfd_wrapped_link_hash_lookup (finfo->output_bfd, finfo->info,
3633                                          pr->u.name, FALSE, FALSE, TRUE));
3634       if (h != NULL
3635           && h->indx >= 0)
3636         r_index = h->indx;
3637       else if (h != NULL)
3638         {
3639           /* We decided to strip this symbol, but it turns out that we
3640              can't.  Note that we lose the other and desc information
3641              here.  I don't think that will ever matter for a global
3642              symbol.  */
3643           h->indx = -2;
3644           h->written = FALSE;
3645           if (! aout_link_write_other_symbol (h, (void *) finfo))
3646             return FALSE;
3647           r_index = h->indx;
3648         }
3649       else
3650         {
3651           if (! ((*finfo->info->callbacks->unattached_reloc)
3652                  (finfo->info, pr->u.name, NULL, NULL, (bfd_vma) 0)))
3653             return FALSE;
3654           r_index = 0;
3655         }
3656     }
3657
3658   howto = bfd_reloc_type_lookup (finfo->output_bfd, pr->reloc);
3659   if (howto == 0)
3660     {
3661       bfd_set_error (bfd_error_bad_value);
3662       return FALSE;
3663     }
3664
3665   if (o == obj_textsec (finfo->output_bfd))
3666     reloff_ptr = &finfo->treloff;
3667   else if (o == obj_datasec (finfo->output_bfd))
3668     reloff_ptr = &finfo->dreloff;
3669   else
3670     abort ();
3671
3672   if (obj_reloc_entry_size (finfo->output_bfd) == RELOC_STD_SIZE)
3673     {
3674 #ifdef MY_put_reloc
3675       MY_put_reloc (finfo->output_bfd, r_extern, r_index, p->offset, howto,
3676                     &srel);
3677 #else
3678       {
3679         int r_pcrel;
3680         int r_baserel;
3681         int r_jmptable;
3682         int r_relative;
3683         int r_length;
3684
3685         r_pcrel = (int) howto->pc_relative;
3686         r_baserel = (howto->type & 8) != 0;
3687         r_jmptable = (howto->type & 16) != 0;
3688         r_relative = (howto->type & 32) != 0;
3689         r_length = howto->size;
3690
3691         PUT_WORD (finfo->output_bfd, p->offset, srel.r_address);
3692         if (bfd_header_big_endian (finfo->output_bfd))
3693           {
3694             srel.r_index[0] = r_index >> 16;
3695             srel.r_index[1] = r_index >> 8;
3696             srel.r_index[2] = r_index;
3697             srel.r_type[0] =
3698               ((r_extern ?     RELOC_STD_BITS_EXTERN_BIG : 0)
3699                | (r_pcrel ?    RELOC_STD_BITS_PCREL_BIG : 0)
3700                | (r_baserel ?  RELOC_STD_BITS_BASEREL_BIG : 0)
3701                | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_BIG : 0)
3702                | (r_relative ? RELOC_STD_BITS_RELATIVE_BIG : 0)
3703                | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG));
3704           }
3705         else
3706           {
3707             srel.r_index[2] = r_index >> 16;
3708             srel.r_index[1] = r_index >> 8;
3709             srel.r_index[0] = r_index;
3710             srel.r_type[0] =
3711               ((r_extern ?     RELOC_STD_BITS_EXTERN_LITTLE : 0)
3712                | (r_pcrel ?    RELOC_STD_BITS_PCREL_LITTLE : 0)
3713                | (r_baserel ?  RELOC_STD_BITS_BASEREL_LITTLE : 0)
3714                | (r_jmptable ? RELOC_STD_BITS_JMPTABLE_LITTLE : 0)
3715                | (r_relative ? RELOC_STD_BITS_RELATIVE_LITTLE : 0)
3716                | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE));
3717           }
3718       }
3719 #endif
3720       rel_ptr = (void *) &srel;
3721
3722       /* We have to write the addend into the object file, since
3723          standard a.out relocs are in place.  It would be more
3724          reliable if we had the current contents of the file here,
3725          rather than assuming zeroes, but we can't read the file since
3726          it was opened using bfd_openw.  */
3727       if (pr->addend != 0)
3728         {
3729           bfd_size_type size;
3730           bfd_reloc_status_type r;
3731           bfd_byte *buf;
3732           bfd_boolean ok;
3733
3734           size = bfd_get_reloc_size (howto);
3735           buf = bfd_zmalloc (size);
3736           if (buf == NULL)
3737             return FALSE;
3738           r = MY_relocate_contents (howto, finfo->output_bfd,
3739                                     (bfd_vma) pr->addend, buf);
3740           switch (r)
3741             {
3742             case bfd_reloc_ok:
3743               break;
3744             default:
3745             case bfd_reloc_outofrange:
3746               abort ();
3747             case bfd_reloc_overflow:
3748               if (! ((*finfo->info->callbacks->reloc_overflow)
3749                      (finfo->info, NULL,
3750                       (p->type == bfd_section_reloc_link_order
3751                        ? bfd_section_name (finfo->output_bfd,
3752                                            pr->u.section)
3753                        : pr->u.name),
3754                       howto->name, pr->addend, NULL, NULL, (bfd_vma) 0)))
3755                 {
3756                   free (buf);
3757                   return FALSE;
3758                 }
3759               break;
3760             }
3761           ok = bfd_set_section_contents (finfo->output_bfd, o, (void *) buf,
3762                                          (file_ptr) p->offset, size);
3763           free (buf);
3764           if (! ok)
3765             return FALSE;
3766         }
3767     }
3768   else
3769     {
3770 #ifdef MY_put_ext_reloc
3771       MY_put_ext_reloc (finfo->output_bfd, r_extern, r_index, p->offset,
3772                         howto, &erel, pr->addend);
3773 #else
3774       PUT_WORD (finfo->output_bfd, p->offset, erel.r_address);
3775
3776       if (bfd_header_big_endian (finfo->output_bfd))
3777         {
3778           erel.r_index[0] = r_index >> 16;
3779           erel.r_index[1] = r_index >> 8;
3780           erel.r_index[2] = r_index;
3781           erel.r_type[0] =
3782             ((r_extern ? RELOC_EXT_BITS_EXTERN_BIG : 0)
3783              | (howto->type << RELOC_EXT_BITS_TYPE_SH_BIG));
3784         }
3785       else
3786         {
3787           erel.r_index[2] = r_index >> 16;
3788           erel.r_index[1] = r_index >> 8;
3789           erel.r_index[0] = r_index;
3790           erel.r_type[0] =
3791             (r_extern ? RELOC_EXT_BITS_EXTERN_LITTLE : 0)
3792               | (howto->type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
3793         }
3794
3795       PUT_WORD (finfo->output_bfd, (bfd_vma) pr->addend, erel.r_addend);
3796 #endif /* MY_put_ext_reloc */
3797
3798       rel_ptr = (void *) &erel;
3799     }
3800
3801   amt = obj_reloc_entry_size (finfo->output_bfd);
3802   if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0
3803       || bfd_bwrite (rel_ptr, amt, finfo->output_bfd) != amt)
3804     return FALSE;
3805
3806   *reloff_ptr += obj_reloc_entry_size (finfo->output_bfd);
3807
3808   /* Assert that the relocs have not run into the symbols, and that n
3809      the text relocs have not run into the data relocs.  */
3810   BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
3811               && (reloff_ptr != &finfo->treloff
3812                   || (*reloff_ptr
3813                       <= obj_datasec (finfo->output_bfd)->rel_filepos)));
3814
3815   return TRUE;
3816 }
3817
3818 /* Get the section corresponding to a reloc index.  */
3819
3820 static INLINE asection *
3821 aout_reloc_index_to_section (bfd *abfd, int indx)
3822 {
3823   switch (indx & N_TYPE)
3824     {
3825     case N_TEXT:   return obj_textsec (abfd);
3826     case N_DATA:   return obj_datasec (abfd);
3827     case N_BSS:    return obj_bsssec (abfd);
3828     case N_ABS:
3829     case N_UNDF:   return bfd_abs_section_ptr;
3830     default:       abort ();
3831     }
3832   return NULL;
3833 }
3834
3835 /* Relocate an a.out section using standard a.out relocs.  */
3836
3837 static bfd_boolean
3838 aout_link_input_section_std (struct aout_final_link_info *finfo,
3839                              bfd *input_bfd,
3840                              asection *input_section,
3841                              struct reloc_std_external *relocs,
3842                              bfd_size_type rel_size,
3843                              bfd_byte *contents)
3844 {
3845   bfd_boolean (*check_dynamic_reloc)
3846     (struct bfd_link_info *, bfd *, asection *,
3847              struct aout_link_hash_entry *, void *, bfd_byte *, bfd_boolean *,
3848              bfd_vma *);
3849   bfd *output_bfd;
3850   bfd_boolean relocatable;
3851   struct external_nlist *syms;
3852   char *strings;
3853   struct aout_link_hash_entry **sym_hashes;
3854   int *symbol_map;
3855   bfd_size_type reloc_count;
3856   struct reloc_std_external *rel;
3857   struct reloc_std_external *rel_end;
3858
3859   output_bfd = finfo->output_bfd;
3860   check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
3861
3862   BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
3863   BFD_ASSERT (input_bfd->xvec->header_byteorder
3864               == output_bfd->xvec->header_byteorder);
3865
3866   relocatable = finfo->info->relocatable;
3867   syms = obj_aout_external_syms (input_bfd);
3868   strings = obj_aout_external_strings (input_bfd);
3869   sym_hashes = obj_aout_sym_hashes (input_bfd);
3870   symbol_map = finfo->symbol_map;
3871
3872   reloc_count = rel_size / RELOC_STD_SIZE;
3873   rel = relocs;
3874   rel_end = rel + reloc_count;
3875   for (; rel < rel_end; rel++)
3876     {
3877       bfd_vma r_addr;
3878       int r_index;
3879       int r_extern;
3880       int r_pcrel;
3881       int r_baserel = 0;
3882       reloc_howto_type *howto;
3883       struct aout_link_hash_entry *h = NULL;
3884       bfd_vma relocation;
3885       bfd_reloc_status_type r;
3886
3887       r_addr = GET_SWORD (input_bfd, rel->r_address);
3888
3889 #ifdef MY_reloc_howto
3890       howto = MY_reloc_howto (input_bfd, rel, r_index, r_extern, r_pcrel);
3891 #else
3892       {
3893         int r_jmptable;
3894         int r_relative;
3895         int r_length;
3896         unsigned int howto_idx;
3897
3898         if (bfd_header_big_endian (input_bfd))
3899           {
3900             r_index   =  (((unsigned int) rel->r_index[0] << 16)
3901                           | ((unsigned int) rel->r_index[1] << 8)
3902                           | rel->r_index[2]);
3903             r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
3904             r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
3905             r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
3906             r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
3907             r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
3908             r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
3909                          >> RELOC_STD_BITS_LENGTH_SH_BIG);
3910           }
3911         else
3912           {
3913             r_index   = (((unsigned int) rel->r_index[2] << 16)
3914                          | ((unsigned int) rel->r_index[1] << 8)
3915                          | rel->r_index[0]);
3916             r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
3917             r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
3918             r_baserel = (0 != (rel->r_type[0]
3919                                & RELOC_STD_BITS_BASEREL_LITTLE));
3920             r_jmptable= (0 != (rel->r_type[0]
3921                                & RELOC_STD_BITS_JMPTABLE_LITTLE));
3922             r_relative= (0 != (rel->r_type[0]
3923                                & RELOC_STD_BITS_RELATIVE_LITTLE));
3924             r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
3925                          >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
3926           }
3927
3928         howto_idx = (r_length + 4 * r_pcrel + 8 * r_baserel
3929                      + 16 * r_jmptable + 32 * r_relative);
3930         BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
3931         howto = howto_table_std + howto_idx;
3932       }
3933 #endif
3934
3935       if (relocatable)
3936         {
3937           /* We are generating a relocatable output file, and must
3938              modify the reloc accordingly.  */
3939           if (r_extern)
3940             {
3941               /* If we know the symbol this relocation is against,
3942                  convert it into a relocation against a section.  This
3943                  is what the native linker does.  */
3944               h = sym_hashes[r_index];
3945               if (h != NULL
3946                   && (h->root.type == bfd_link_hash_defined
3947                       || h->root.type == bfd_link_hash_defweak))
3948                 {
3949                   asection *output_section;
3950
3951                   /* Change the r_extern value.  */
3952                   if (bfd_header_big_endian (output_bfd))
3953                     rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
3954                   else
3955                     rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
3956
3957                   /* Compute a new r_index.  */
3958                   output_section = h->root.u.def.section->output_section;
3959                   if (output_section == obj_textsec (output_bfd))
3960                     r_index = N_TEXT;
3961                   else if (output_section == obj_datasec (output_bfd))
3962                     r_index = N_DATA;
3963                   else if (output_section == obj_bsssec (output_bfd))
3964                     r_index = N_BSS;
3965                   else
3966                     r_index = N_ABS;
3967
3968                   /* Add the symbol value and the section VMA to the
3969                      addend stored in the contents.  */
3970                   relocation = (h->root.u.def.value
3971                                 + output_section->vma
3972                                 + h->root.u.def.section->output_offset);
3973                 }
3974               else
3975                 {
3976                   /* We must change r_index according to the symbol
3977                      map.  */
3978                   r_index = symbol_map[r_index];
3979
3980                   if (r_index == -1)
3981                     {
3982                       if (h != NULL)
3983                         {
3984                           /* We decided to strip this symbol, but it
3985                              turns out that we can't.  Note that we
3986                              lose the other and desc information here.
3987                              I don't think that will ever matter for a
3988                              global symbol.  */
3989                           if (h->indx < 0)
3990                             {
3991                               h->indx = -2;
3992                               h->written = FALSE;
3993                               if (! aout_link_write_other_symbol (h,
3994                                                                   (void *) finfo))
3995                                 return FALSE;
3996                             }
3997                           r_index = h->indx;
3998                         }
3999                       else
4000                         {
4001                           const char *name;
4002
4003                           name = strings + GET_WORD (input_bfd,
4004                                                      syms[r_index].e_strx);
4005                           if (! ((*finfo->info->callbacks->unattached_reloc)
4006                                  (finfo->info, name, input_bfd, input_section,
4007                                   r_addr)))
4008                             return FALSE;
4009                           r_index = 0;
4010                         }
4011                     }
4012
4013                   relocation = 0;
4014                 }
4015
4016               /* Write out the new r_index value.  */
4017               if (bfd_header_big_endian (output_bfd))
4018                 {
4019                   rel->r_index[0] = r_index >> 16;
4020                   rel->r_index[1] = r_index >> 8;
4021                   rel->r_index[2] = r_index;
4022                 }
4023               else
4024                 {
4025                   rel->r_index[2] = r_index >> 16;
4026                   rel->r_index[1] = r_index >> 8;
4027                   rel->r_index[0] = r_index;
4028                 }
4029             }
4030           else
4031             {
4032               asection *section;
4033
4034               /* This is a relocation against a section.  We must
4035                  adjust by the amount that the section moved.  */
4036               section = aout_reloc_index_to_section (input_bfd, r_index);
4037               relocation = (section->output_section->vma
4038                             + section->output_offset
4039                             - section->vma);
4040             }
4041
4042           /* Change the address of the relocation.  */
4043           PUT_WORD (output_bfd,
4044                     r_addr + input_section->output_offset,
4045                     rel->r_address);
4046
4047           /* Adjust a PC relative relocation by removing the reference
4048              to the original address in the section and including the
4049              reference to the new address.  */
4050           if (r_pcrel)
4051             relocation -= (input_section->output_section->vma
4052                            + input_section->output_offset
4053                            - input_section->vma);
4054
4055 #ifdef MY_relocatable_reloc
4056           MY_relocatable_reloc (howto, output_bfd, rel, relocation, r_addr);
4057 #endif
4058
4059           if (relocation == 0)
4060             r = bfd_reloc_ok;
4061           else
4062             r = MY_relocate_contents (howto,
4063                                         input_bfd, relocation,
4064                                         contents + r_addr);
4065         }
4066       else
4067         {
4068           bfd_boolean hundef;
4069
4070           /* We are generating an executable, and must do a full
4071              relocation.  */
4072           hundef = FALSE;
4073
4074           if (r_extern)
4075             {
4076               h = sym_hashes[r_index];
4077
4078               if (h != NULL
4079                   && (h->root.type == bfd_link_hash_defined
4080                       || h->root.type == bfd_link_hash_defweak))
4081                 {
4082                   relocation = (h->root.u.def.value
4083                                 + h->root.u.def.section->output_section->vma
4084                                 + h->root.u.def.section->output_offset);
4085                 }
4086               else if (h != NULL
4087                        && h->root.type == bfd_link_hash_undefweak)
4088                 relocation = 0;
4089               else
4090                 {
4091                   hundef = TRUE;
4092                   relocation = 0;
4093                 }
4094             }
4095           else
4096             {
4097               asection *section;
4098
4099               section = aout_reloc_index_to_section (input_bfd, r_index);
4100               relocation = (section->output_section->vma
4101                             + section->output_offset
4102                             - section->vma);
4103               if (r_pcrel)
4104                 relocation += input_section->vma;
4105             }
4106
4107           if (check_dynamic_reloc != NULL)
4108             {
4109               bfd_boolean skip;
4110
4111               if (! ((*check_dynamic_reloc)
4112                      (finfo->info, input_bfd, input_section, h,
4113                       (void *) rel, contents, &skip, &relocation)))
4114                 return FALSE;
4115               if (skip)
4116                 continue;
4117             }
4118
4119           /* Now warn if a global symbol is undefined.  We could not
4120              do this earlier, because check_dynamic_reloc might want
4121              to skip this reloc.  */
4122           if (hundef && ! finfo->info->shared && ! r_baserel)
4123             {
4124               const char *name;
4125
4126               if (h != NULL)
4127                 name = h->root.root.string;
4128               else
4129                 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
4130               if (! ((*finfo->info->callbacks->undefined_symbol)
4131                      (finfo->info, name, input_bfd, input_section,
4132                      r_addr, TRUE)))
4133                 return FALSE;
4134             }
4135
4136           r = MY_final_link_relocate (howto,
4137                                       input_bfd, input_section,
4138                                       contents, r_addr, relocation,
4139                                       (bfd_vma) 0);
4140         }
4141
4142       if (r != bfd_reloc_ok)
4143         {
4144           switch (r)
4145             {
4146             default:
4147             case bfd_reloc_outofrange:
4148               abort ();
4149             case bfd_reloc_overflow:
4150               {
4151                 const char *name;
4152
4153                 if (h != NULL)
4154                   name = NULL;
4155                 else if (r_extern)
4156                   name = strings + GET_WORD (input_bfd,
4157                                              syms[r_index].e_strx);
4158                 else
4159                   {
4160                     asection *s;
4161
4162                     s = aout_reloc_index_to_section (input_bfd, r_index);
4163                     name = bfd_section_name (input_bfd, s);
4164                   }
4165                 if (! ((*finfo->info->callbacks->reloc_overflow)
4166                        (finfo->info, (h ? &h->root : NULL), name,
4167                         howto->name, (bfd_vma) 0, input_bfd,
4168                         input_section, r_addr)))
4169                   return FALSE;
4170               }
4171               break;
4172             }
4173         }
4174     }
4175
4176   return TRUE;
4177 }
4178
4179 /* Relocate an a.out section using extended a.out relocs.  */
4180
4181 static bfd_boolean
4182 aout_link_input_section_ext (struct aout_final_link_info *finfo,
4183                              bfd *input_bfd,
4184                              asection *input_section,
4185                              struct reloc_ext_external *relocs,
4186                              bfd_size_type rel_size,
4187                              bfd_byte *contents)
4188 {
4189   bfd_boolean (*check_dynamic_reloc)
4190     (struct bfd_link_info *, bfd *, asection *,
4191              struct aout_link_hash_entry *, void *, bfd_byte *, bfd_boolean *,
4192              bfd_vma *);
4193   bfd *output_bfd;
4194   bfd_boolean relocatable;
4195   struct external_nlist *syms;
4196   char *strings;
4197   struct aout_link_hash_entry **sym_hashes;
4198   int *symbol_map;
4199   bfd_size_type reloc_count;
4200   struct reloc_ext_external *rel;
4201   struct reloc_ext_external *rel_end;
4202
4203   output_bfd = finfo->output_bfd;
4204   check_dynamic_reloc = aout_backend_info (output_bfd)->check_dynamic_reloc;
4205
4206   BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
4207   BFD_ASSERT (input_bfd->xvec->header_byteorder
4208               == output_bfd->xvec->header_byteorder);
4209
4210   relocatable = finfo->info->relocatable;
4211   syms = obj_aout_external_syms (input_bfd);
4212   strings = obj_aout_external_strings (input_bfd);
4213   sym_hashes = obj_aout_sym_hashes (input_bfd);
4214   symbol_map = finfo->symbol_map;
4215
4216   reloc_count = rel_size / RELOC_EXT_SIZE;
4217   rel = relocs;
4218   rel_end = rel + reloc_count;
4219   for (; rel < rel_end; rel++)
4220     {
4221       bfd_vma r_addr;
4222       int r_index;
4223       int r_extern;
4224       unsigned int r_type;
4225       bfd_vma r_addend;
4226       struct aout_link_hash_entry *h = NULL;
4227       asection *r_section = NULL;
4228       bfd_vma relocation;
4229
4230       r_addr = GET_SWORD (input_bfd, rel->r_address);
4231
4232       if (bfd_header_big_endian (input_bfd))
4233         {
4234           r_index  = (((unsigned int) rel->r_index[0] << 16)
4235                       | ((unsigned int) rel->r_index[1] << 8)
4236                       | rel->r_index[2]);
4237           r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
4238           r_type   = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
4239                       >> RELOC_EXT_BITS_TYPE_SH_BIG);
4240         }
4241       else
4242         {
4243           r_index  = (((unsigned int) rel->r_index[2] << 16)
4244                       | ((unsigned int) rel->r_index[1] << 8)
4245                       | rel->r_index[0]);
4246           r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
4247           r_type   = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
4248                       >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
4249         }
4250
4251       r_addend = GET_SWORD (input_bfd, rel->r_addend);
4252
4253       BFD_ASSERT (r_type < TABLE_SIZE (howto_table_ext));
4254
4255       if (relocatable)
4256         {
4257           /* We are generating a relocatable output file, and must
4258              modify the reloc accordingly.  */
4259           if (r_extern
4260               || r_type == (unsigned int) RELOC_BASE10
4261               || r_type == (unsigned int) RELOC_BASE13
4262               || r_type == (unsigned int) RELOC_BASE22)
4263             {
4264               /* If we know the symbol this relocation is against,
4265                  convert it into a relocation against a section.  This
4266                  is what the native linker does.  */
4267               if (r_type == (unsigned int) RELOC_BASE10
4268                   || r_type == (unsigned int) RELOC_BASE13
4269                   || r_type == (unsigned int) RELOC_BASE22)
4270                 h = NULL;
4271               else
4272                 h = sym_hashes[r_index];
4273               if (h != NULL
4274                   && (h->root.type == bfd_link_hash_defined
4275                       || h->root.type == bfd_link_hash_defweak))
4276                 {
4277                   asection *output_section;
4278
4279                   /* Change the r_extern value.  */
4280                   if (bfd_header_big_endian (output_bfd))
4281                     rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
4282                   else
4283                     rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
4284
4285                   /* Compute a new r_index.  */
4286                   output_section = h->root.u.def.section->output_section;
4287                   if (output_section == obj_textsec (output_bfd))
4288                     r_index = N_TEXT;
4289                   else if (output_section == obj_datasec (output_bfd))
4290                     r_index = N_DATA;
4291                   else if (output_section == obj_bsssec (output_bfd))
4292                     r_index = N_BSS;
4293                   else
4294                     r_index = N_ABS;
4295
4296                   /* Add the symbol value and the section VMA to the
4297                      addend.  */
4298                   relocation = (h->root.u.def.value
4299                                 + output_section->vma
4300                                 + h->root.u.def.section->output_offset);
4301
4302                   /* Now RELOCATION is the VMA of the final
4303                      destination.  If this is a PC relative reloc,
4304                      then ADDEND is the negative of the source VMA.
4305                      We want to set ADDEND to the difference between
4306                      the destination VMA and the source VMA, which
4307                      means we must adjust RELOCATION by the change in
4308                      the source VMA.  This is done below.  */
4309                 }
4310               else
4311                 {
4312                   /* We must change r_index according to the symbol
4313                      map.  */
4314                   r_index = symbol_map[r_index];
4315
4316                   if (r_index == -1)
4317                     {
4318                       if (h != NULL)
4319                         {
4320                           /* We decided to strip this symbol, but it
4321                              turns out that we can't.  Note that we
4322                              lose the other and desc information here.
4323                              I don't think that will ever matter for a
4324                              global symbol.  */
4325                           if (h->indx < 0)
4326                             {
4327                               h->indx = -2;
4328                               h->written = FALSE;
4329                               if (! aout_link_write_other_symbol (h,
4330                                                                   (void *) finfo))
4331                                 return FALSE;
4332                             }
4333                           r_index = h->indx;
4334                         }
4335                       else
4336                         {
4337                           const char *name;
4338
4339                           name = strings + GET_WORD (input_bfd,
4340                                                      syms[r_index].e_strx);
4341                           if (! ((*finfo->info->callbacks->unattached_reloc)
4342                                  (finfo->info, name, input_bfd, input_section,
4343                                   r_addr)))
4344                             return FALSE;
4345                           r_index = 0;
4346                         }
4347                     }
4348
4349                   relocation = 0;
4350
4351                   /* If this is a PC relative reloc, then the addend
4352                      is the negative of the source VMA.  We must
4353                      adjust it by the change in the source VMA.  This
4354                      is done below.  */
4355                 }
4356
4357               /* Write out the new r_index value.  */
4358               if (bfd_header_big_endian (output_bfd))
4359                 {
4360                   rel->r_index[0] = r_index >> 16;
4361                   rel->r_index[1] = r_index >> 8;
4362                   rel->r_index[2] = r_index;
4363                 }
4364               else
4365                 {
4366                   rel->r_index[2] = r_index >> 16;
4367                   rel->r_index[1] = r_index >> 8;
4368                   rel->r_index[0] = r_index;
4369                 }
4370             }
4371           else
4372             {
4373               /* This is a relocation against a section.  We must
4374                  adjust by the amount that the section moved.  */
4375               r_section = aout_reloc_index_to_section (input_bfd, r_index);
4376               relocation = (r_section->output_section->vma
4377                             + r_section->output_offset
4378                             - r_section->vma);
4379
4380               /* If this is a PC relative reloc, then the addend is
4381                  the difference in VMA between the destination and the
4382                  source.  We have just adjusted for the change in VMA
4383                  of the destination, so we must also adjust by the
4384                  change in VMA of the source.  This is done below.  */
4385             }
4386
4387           /* As described above, we must always adjust a PC relative
4388              reloc by the change in VMA of the source.  However, if
4389              pcrel_offset is set, then the addend does not include the
4390              location within the section, in which case we don't need
4391              to adjust anything.  */
4392           if (howto_table_ext[r_type].pc_relative
4393               && ! howto_table_ext[r_type].pcrel_offset)
4394             relocation -= (input_section->output_section->vma
4395                            + input_section->output_offset
4396                            - input_section->vma);
4397
4398           /* Change the addend if necessary.  */
4399           if (relocation != 0)
4400             PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
4401
4402           /* Change the address of the relocation.  */
4403           PUT_WORD (output_bfd,
4404                     r_addr + input_section->output_offset,
4405                     rel->r_address);
4406         }
4407       else
4408         {
4409           bfd_boolean hundef;
4410           bfd_reloc_status_type r;
4411
4412           /* We are generating an executable, and must do a full
4413              relocation.  */
4414           hundef = FALSE;
4415
4416           if (r_extern)
4417             {
4418               h = sym_hashes[r_index];
4419
4420               if (h != NULL
4421                   && (h->root.type == bfd_link_hash_defined
4422                       || h->root.type == bfd_link_hash_defweak))
4423                 {
4424                   relocation = (h->root.u.def.value
4425                                 + h->root.u.def.section->output_section->vma
4426                                 + h->root.u.def.section->output_offset);
4427                 }
4428               else if (h != NULL
4429                        && h->root.type == bfd_link_hash_undefweak)
4430                 relocation = 0;
4431               else
4432                 {
4433                   hundef = TRUE;
4434                   relocation = 0;
4435                 }
4436             }
4437           else if (r_type == (unsigned int) RELOC_BASE10
4438                    || r_type == (unsigned int) RELOC_BASE13
4439                    || r_type == (unsigned int) RELOC_BASE22)
4440             {
4441               struct external_nlist *sym;
4442               int type;
4443
4444               /* For base relative relocs, r_index is always an index
4445                  into the symbol table, even if r_extern is 0.  */
4446               sym = syms + r_index;
4447               type = H_GET_8 (input_bfd, sym->e_type);
4448               if ((type & N_TYPE) == N_TEXT
4449                   || type == N_WEAKT)
4450                 r_section = obj_textsec (input_bfd);
4451               else if ((type & N_TYPE) == N_DATA
4452                        || type == N_WEAKD)
4453                 r_section = obj_datasec (input_bfd);
4454               else if ((type & N_TYPE) == N_BSS
4455                        || type == N_WEAKB)
4456                 r_section = obj_bsssec (input_bfd);
4457               else if ((type & N_TYPE) == N_ABS
4458                        || type == N_WEAKA)
4459                 r_section = bfd_abs_section_ptr;
4460               else
4461                 abort ();
4462               relocation = (r_section->output_section->vma
4463                             + r_section->output_offset
4464                             + (GET_WORD (input_bfd, sym->e_value)
4465                                - r_section->vma));
4466             }
4467           else
4468             {
4469               r_section = aout_reloc_index_to_section (input_bfd, r_index);
4470
4471               /* If this is a PC relative reloc, then R_ADDEND is the
4472                  difference between the two vmas, or
4473                    old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
4474                  where
4475                    old_dest_sec == section->vma
4476                  and
4477                    old_src_sec == input_section->vma
4478                  and
4479                    old_src_off == r_addr
4480
4481                  _bfd_final_link_relocate expects RELOCATION +
4482                  R_ADDEND to be the VMA of the destination minus
4483                  r_addr (the minus r_addr is because this relocation
4484                  is not pcrel_offset, which is a bit confusing and
4485                  should, perhaps, be changed), or
4486                    new_dest_sec
4487                  where
4488                    new_dest_sec == output_section->vma + output_offset
4489                  We arrange for this to happen by setting RELOCATION to
4490                    new_dest_sec + old_src_sec - old_dest_sec
4491
4492                  If this is not a PC relative reloc, then R_ADDEND is
4493                  simply the VMA of the destination, so we set
4494                  RELOCATION to the change in the destination VMA, or
4495                    new_dest_sec - old_dest_sec
4496                  */
4497               relocation = (r_section->output_section->vma
4498                             + r_section->output_offset
4499                             - r_section->vma);
4500               if (howto_table_ext[r_type].pc_relative)
4501                 relocation += input_section->vma;
4502             }
4503
4504           if (check_dynamic_reloc != NULL)
4505             {
4506               bfd_boolean skip;
4507
4508               if (! ((*check_dynamic_reloc)
4509                      (finfo->info, input_bfd, input_section, h,
4510                       (void *) rel, contents, &skip, &relocation)))
4511                 return FALSE;
4512               if (skip)
4513                 continue;
4514             }
4515
4516           /* Now warn if a global symbol is undefined.  We could not
4517              do this earlier, because check_dynamic_reloc might want
4518              to skip this reloc.  */
4519           if (hundef
4520               && ! finfo->info->shared
4521               && r_type != (unsigned int) RELOC_BASE10
4522               && r_type != (unsigned int) RELOC_BASE13
4523               && r_type != (unsigned int) RELOC_BASE22)
4524             {
4525               const char *name;
4526
4527               if (h != NULL)
4528                 name = h->root.root.string;
4529               else
4530                 name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
4531               if (! ((*finfo->info->callbacks->undefined_symbol)
4532                      (finfo->info, name, input_bfd, input_section,
4533                      r_addr, TRUE)))
4534                 return FALSE;
4535             }
4536
4537           if (r_type != (unsigned int) RELOC_SPARC_REV32)
4538             r = MY_final_link_relocate (howto_table_ext + r_type,
4539                                         input_bfd, input_section,
4540                                         contents, r_addr, relocation,
4541                                         r_addend);
4542           else
4543             {
4544               bfd_vma x;
4545
4546               x = bfd_get_32 (input_bfd, contents + r_addr);
4547               x = x + relocation + r_addend;
4548               bfd_putl32 (/*input_bfd,*/ x, contents + r_addr);
4549               r = bfd_reloc_ok;
4550             }
4551
4552           if (r != bfd_reloc_ok)
4553             {
4554               switch (r)
4555                 {
4556                 default:
4557                 case bfd_reloc_outofrange:
4558                   abort ();
4559                 case bfd_reloc_overflow:
4560                   {
4561                     const char *name;
4562
4563                     if (h != NULL)
4564                       name = NULL;
4565                     else if (r_extern
4566                              || r_type == (unsigned int) RELOC_BASE10
4567                              || r_type == (unsigned int) RELOC_BASE13
4568                              || r_type == (unsigned int) RELOC_BASE22)
4569                       name = strings + GET_WORD (input_bfd,
4570                                                  syms[r_index].e_strx);
4571                     else
4572                       {
4573                         asection *s;
4574
4575                         s = aout_reloc_index_to_section (input_bfd, r_index);
4576                         name = bfd_section_name (input_bfd, s);
4577                       }
4578                     if (! ((*finfo->info->callbacks->reloc_overflow)
4579                            (finfo->info, (h ? &h->root : NULL), name,
4580                             howto_table_ext[r_type].name,
4581                             r_addend, input_bfd, input_section, r_addr)))
4582                       return FALSE;
4583                   }
4584                   break;
4585                 }
4586             }
4587         }
4588     }
4589
4590   return TRUE;
4591 }
4592
4593 /* Link an a.out section into the output file.  */
4594
4595 static bfd_boolean
4596 aout_link_input_section (struct aout_final_link_info *finfo,
4597                          bfd *input_bfd,
4598                          asection *input_section,
4599                          file_ptr *reloff_ptr,
4600                          bfd_size_type rel_size)
4601 {
4602   bfd_size_type input_size;
4603   void * relocs;
4604
4605   /* Get the section contents.  */
4606   input_size = input_section->size;
4607   if (! bfd_get_section_contents (input_bfd, input_section,
4608                                   (void *) finfo->contents,
4609                                   (file_ptr) 0, input_size))
4610     return FALSE;
4611
4612   /* Read in the relocs if we haven't already done it.  */
4613   if (aout_section_data (input_section) != NULL
4614       && aout_section_data (input_section)->relocs != NULL)
4615     relocs = aout_section_data (input_section)->relocs;
4616   else
4617     {
4618       relocs = finfo->relocs;
4619       if (rel_size > 0)
4620         {
4621           if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
4622               || bfd_bread (relocs, rel_size, input_bfd) != rel_size)
4623             return FALSE;
4624         }
4625     }
4626
4627   /* Relocate the section contents.  */
4628   if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
4629     {
4630       if (! aout_link_input_section_std (finfo, input_bfd, input_section,
4631                                          (struct reloc_std_external *) relocs,
4632                                          rel_size, finfo->contents))
4633         return FALSE;
4634     }
4635   else
4636     {
4637       if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
4638                                          (struct reloc_ext_external *) relocs,
4639                                          rel_size, finfo->contents))
4640         return FALSE;
4641     }
4642
4643   /* Write out the section contents.  */
4644   if (! bfd_set_section_contents (finfo->output_bfd,
4645                                   input_section->output_section,
4646                                   (void *) finfo->contents,
4647                                   (file_ptr) input_section->output_offset,
4648                                   input_size))
4649     return FALSE;
4650
4651   /* If we are producing relocatable output, the relocs were
4652      modified, and we now write them out.  */
4653   if (finfo->info->relocatable && rel_size > 0)
4654     {
4655       if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
4656         return FALSE;
4657       if (bfd_bwrite (relocs, rel_size, finfo->output_bfd) != rel_size)
4658         return FALSE;
4659       *reloff_ptr += rel_size;
4660
4661       /* Assert that the relocs have not run into the symbols, and
4662          that if these are the text relocs they have not run into the
4663          data relocs.  */
4664       BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
4665                   && (reloff_ptr != &finfo->treloff
4666                       || (*reloff_ptr
4667                           <= obj_datasec (finfo->output_bfd)->rel_filepos)));
4668     }
4669
4670   return TRUE;
4671 }
4672
4673 /* Adjust and write out the symbols for an a.out file.  Set the new
4674    symbol indices into a symbol_map.  */
4675
4676 static bfd_boolean
4677 aout_link_write_symbols (struct aout_final_link_info *finfo, bfd *input_bfd)
4678 {
4679   bfd *output_bfd;
4680   bfd_size_type sym_count;
4681   char *strings;
4682   enum bfd_link_strip strip;
4683   enum bfd_link_discard discard;
4684   struct external_nlist *outsym;
4685   bfd_size_type strtab_index;
4686   struct external_nlist *sym;
4687   struct external_nlist *sym_end;
4688   struct aout_link_hash_entry **sym_hash;
4689   int *symbol_map;
4690   bfd_boolean pass;
4691   bfd_boolean skip_next;
4692
4693   output_bfd = finfo->output_bfd;
4694   sym_count = obj_aout_external_sym_count (input_bfd);
4695   strings = obj_aout_external_strings (input_bfd);
4696   strip = finfo->info->strip;
4697   discard = finfo->info->discard;
4698   outsym = finfo->output_syms;
4699
4700   /* First write out a symbol for this object file, unless we are
4701      discarding such symbols.  */
4702   if (strip != strip_all
4703       && (strip != strip_some
4704           || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
4705                               FALSE, FALSE) != NULL)
4706       && discard != discard_all)
4707     {
4708       H_PUT_8 (output_bfd, N_TEXT, outsym->e_type);
4709       H_PUT_8 (output_bfd, 0, outsym->e_other);
4710       H_PUT_16 (output_bfd, 0, outsym->e_desc);
4711       strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
4712                                        input_bfd->filename, FALSE);
4713       if (strtab_index == (bfd_size_type) -1)
4714         return FALSE;
4715       PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
4716       PUT_WORD (output_bfd,
4717                 (bfd_get_section_vma (output_bfd,
4718                                       obj_textsec (input_bfd)->output_section)
4719                  + obj_textsec (input_bfd)->output_offset),
4720                 outsym->e_value);
4721       ++obj_aout_external_sym_count (output_bfd);
4722       ++outsym;
4723     }
4724
4725   pass = FALSE;
4726   skip_next = FALSE;
4727   sym = obj_aout_external_syms (input_bfd);
4728   sym_end = sym + sym_count;
4729   sym_hash = obj_aout_sym_hashes (input_bfd);
4730   symbol_map = finfo->symbol_map;
4731   memset (symbol_map, 0, (size_t) sym_count * sizeof *symbol_map);
4732   for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
4733     {
4734       const char *name;
4735       int type;
4736       struct aout_link_hash_entry *h;
4737       bfd_boolean skip;
4738       asection *symsec;
4739       bfd_vma val = 0;
4740       bfd_boolean copy;
4741
4742       /* We set *symbol_map to 0 above for all symbols.  If it has
4743          already been set to -1 for this symbol, it means that we are
4744          discarding it because it appears in a duplicate header file.
4745          See the N_BINCL code below.  */
4746       if (*symbol_map == -1)
4747         continue;
4748
4749       /* Initialize *symbol_map to -1, which means that the symbol was
4750          not copied into the output file.  We will change it later if
4751          we do copy the symbol over.  */
4752       *symbol_map = -1;
4753
4754       type = H_GET_8 (input_bfd, sym->e_type);
4755       name = strings + GET_WORD (input_bfd, sym->e_strx);
4756
4757       h = NULL;
4758
4759       if (pass)
4760         {
4761           /* Pass this symbol through.  It is the target of an
4762              indirect or warning symbol.  */
4763           val = GET_WORD (input_bfd, sym->e_value);
4764           pass = FALSE;
4765         }
4766       else if (skip_next)
4767         {
4768           /* Skip this symbol, which is the target of an indirect
4769              symbol that we have changed to no longer be an indirect
4770              symbol.  */
4771           skip_next = FALSE;
4772           continue;
4773         }
4774       else
4775         {
4776           struct aout_link_hash_entry *hresolve;
4777
4778           /* We have saved the hash table entry for this symbol, if
4779              there is one.  Note that we could just look it up again
4780              in the hash table, provided we first check that it is an
4781              external symbol.  */
4782           h = *sym_hash;
4783
4784           /* Use the name from the hash table, in case the symbol was
4785              wrapped.  */
4786           if (h != NULL
4787               && h->root.type != bfd_link_hash_warning)
4788             name = h->root.root.string;
4789
4790           /* If this is an indirect or warning symbol, then change
4791              hresolve to the base symbol.  We also change *sym_hash so
4792              that the relocation routines relocate against the real
4793              symbol.  */
4794           hresolve = h;
4795           if (h != (struct aout_link_hash_entry *) NULL
4796               && (h->root.type == bfd_link_hash_indirect
4797                   || h->root.type == bfd_link_hash_warning))
4798             {
4799               hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
4800               while (hresolve->root.type == bfd_link_hash_indirect
4801                      || hresolve->root.type == bfd_link_hash_warning)
4802                 hresolve = ((struct aout_link_hash_entry *)
4803                             hresolve->root.u.i.link);
4804               *sym_hash = hresolve;
4805             }
4806
4807           /* If the symbol has already been written out, skip it.  */
4808           if (h != NULL
4809               && h->written)
4810             {
4811               if ((type & N_TYPE) == N_INDR
4812                   || type == N_WARNING)
4813                 skip_next = TRUE;
4814               *symbol_map = h->indx;
4815               continue;
4816             }
4817
4818           /* See if we are stripping this symbol.  */
4819           skip = FALSE;
4820           switch (strip)
4821             {
4822             case strip_none:
4823               break;
4824             case strip_debugger:
4825               if ((type & N_STAB) != 0)
4826                 skip = TRUE;
4827               break;
4828             case strip_some:
4829               if (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE)
4830                   == NULL)
4831                 skip = TRUE;
4832               break;
4833             case strip_all:
4834               skip = TRUE;
4835               break;
4836             }
4837           if (skip)
4838             {
4839               if (h != NULL)
4840                 h->written = TRUE;
4841               continue;
4842             }
4843
4844           /* Get the value of the symbol.  */
4845           if ((type & N_TYPE) == N_TEXT
4846               || type == N_WEAKT)
4847             symsec = obj_textsec (input_bfd);
4848           else if ((type & N_TYPE) == N_DATA
4849                    || type == N_WEAKD)
4850             symsec = obj_datasec (input_bfd);
4851           else if ((type & N_TYPE) == N_BSS
4852                    || type == N_WEAKB)
4853             symsec = obj_bsssec (input_bfd);
4854           else if ((type & N_TYPE) == N_ABS
4855                    || type == N_WEAKA)
4856             symsec = bfd_abs_section_ptr;
4857           else if (((type & N_TYPE) == N_INDR
4858                     && (hresolve == NULL
4859                         || (hresolve->root.type != bfd_link_hash_defined
4860                             && hresolve->root.type != bfd_link_hash_defweak
4861                             && hresolve->root.type != bfd_link_hash_common)))
4862                    || type == N_WARNING)
4863             {
4864               /* Pass the next symbol through unchanged.  The
4865                  condition above for indirect symbols is so that if
4866                  the indirect symbol was defined, we output it with
4867                  the correct definition so the debugger will
4868                  understand it.  */
4869               pass = TRUE;
4870               val = GET_WORD (input_bfd, sym->e_value);
4871               symsec = NULL;
4872             }
4873           else if ((type & N_STAB) != 0)
4874             {
4875               val = GET_WORD (input_bfd, sym->e_value);
4876               symsec = NULL;
4877             }
4878           else
4879             {
4880               /* If we get here with an indirect symbol, it means that
4881                  we are outputting it with a real definition.  In such
4882                  a case we do not want to output the next symbol,
4883                  which is the target of the indirection.  */
4884               if ((type & N_TYPE) == N_INDR)
4885                 skip_next = TRUE;
4886
4887               symsec = NULL;
4888
4889               /* We need to get the value from the hash table.  We use
4890                  hresolve so that if we have defined an indirect
4891                  symbol we output the final definition.  */
4892               if (h == NULL)
4893                 {
4894                   switch (type & N_TYPE)
4895                     {
4896                     case N_SETT:
4897                       symsec = obj_textsec (input_bfd);
4898                       break;
4899                     case N_SETD:
4900                       symsec = obj_datasec (input_bfd);
4901                       break;
4902                     case N_SETB:
4903                       symsec = obj_bsssec (input_bfd);
4904                       break;
4905                     case N_SETA:
4906                       symsec = bfd_abs_section_ptr;
4907                       break;
4908                     default:
4909                       val = 0;
4910                       break;
4911                     }
4912                 }
4913               else if (hresolve->root.type == bfd_link_hash_defined
4914                        || hresolve->root.type == bfd_link_hash_defweak)
4915                 {
4916                   asection *input_section;
4917                   asection *output_section;
4918
4919                   /* This case usually means a common symbol which was
4920                      turned into a defined symbol.  */
4921                   input_section = hresolve->root.u.def.section;
4922                   output_section = input_section->output_section;
4923                   BFD_ASSERT (bfd_is_abs_section (output_section)
4924                               || output_section->owner == output_bfd);
4925                   val = (hresolve->root.u.def.value
4926                          + bfd_get_section_vma (output_bfd, output_section)
4927                          + input_section->output_offset);
4928
4929                   /* Get the correct type based on the section.  If
4930                      this is a constructed set, force it to be
4931                      globally visible.  */
4932                   if (type == N_SETT
4933                       || type == N_SETD
4934                       || type == N_SETB
4935                       || type == N_SETA)
4936                     type |= N_EXT;
4937
4938                   type &=~ N_TYPE;
4939
4940                   if (output_section == obj_textsec (output_bfd))
4941                     type |= (hresolve->root.type == bfd_link_hash_defined
4942                              ? N_TEXT
4943                              : N_WEAKT);
4944                   else if (output_section == obj_datasec (output_bfd))
4945                     type |= (hresolve->root.type == bfd_link_hash_defined
4946                              ? N_DATA
4947                              : N_WEAKD);
4948                   else if (output_section == obj_bsssec (output_bfd))
4949                     type |= (hresolve->root.type == bfd_link_hash_defined
4950                              ? N_BSS
4951                              : N_WEAKB);
4952                   else
4953                     type |= (hresolve->root.type == bfd_link_hash_defined
4954                              ? N_ABS
4955                              : N_WEAKA);
4956                 }
4957               else if (hresolve->root.type == bfd_link_hash_common)
4958                 val = hresolve->root.u.c.size;
4959               else if (hresolve->root.type == bfd_link_hash_undefweak)
4960                 {
4961                   val = 0;
4962                   type = N_WEAKU;
4963                 }
4964               else
4965                 val = 0;
4966             }
4967           if (symsec != NULL)
4968             val = (symsec->output_section->vma
4969                    + symsec->output_offset
4970                    + (GET_WORD (input_bfd, sym->e_value)
4971                       - symsec->vma));
4972
4973           /* If this is a global symbol set the written flag, and if
4974              it is a local symbol see if we should discard it.  */
4975           if (h != NULL)
4976             {
4977               h->written = TRUE;
4978               h->indx = obj_aout_external_sym_count (output_bfd);
4979             }
4980           else if ((type & N_TYPE) != N_SETT
4981                    && (type & N_TYPE) != N_SETD
4982                    && (type & N_TYPE) != N_SETB
4983                    && (type & N_TYPE) != N_SETA)
4984             {
4985               switch (discard)
4986                 {
4987                 case discard_none:
4988                 case discard_sec_merge:
4989                   break;
4990                 case discard_l:
4991                   if ((type & N_STAB) == 0
4992                       && bfd_is_local_label_name (input_bfd, name))
4993                     skip = TRUE;
4994                   break;
4995                 case discard_all:
4996                   skip = TRUE;
4997                   break;
4998                 }
4999               if (skip)
5000                 {
5001                   pass = FALSE;
5002                   continue;
5003                 }
5004             }
5005
5006           /* An N_BINCL symbol indicates the start of the stabs
5007              entries for a header file.  We need to scan ahead to the
5008              next N_EINCL symbol, ignoring nesting, adding up all the
5009              characters in the symbol names, not including the file
5010              numbers in types (the first number after an open
5011              parenthesis).  */
5012           if (type == (int) N_BINCL)
5013             {
5014               struct external_nlist *incl_sym;
5015               int nest;
5016               struct aout_link_includes_entry *incl_entry;
5017               struct aout_link_includes_totals *t;
5018
5019               val = 0;
5020               nest = 0;
5021               for (incl_sym = sym + 1; incl_sym < sym_end; incl_sym++)
5022                 {
5023                   int incl_type;
5024
5025                   incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
5026                   if (incl_type == (int) N_EINCL)
5027                     {
5028                       if (nest == 0)
5029                         break;
5030                       --nest;
5031                     }
5032                   else if (incl_type == (int) N_BINCL)
5033                     ++nest;
5034                   else if (nest == 0)
5035                     {
5036                       const char *s;
5037
5038                       s = strings + GET_WORD (input_bfd, incl_sym->e_strx);
5039                       for (; *s != '\0'; s++)
5040                         {
5041                           val += *s;
5042                           if (*s == '(')
5043                             {
5044                               /* Skip the file number.  */
5045                               ++s;
5046                               while (ISDIGIT (*s))
5047                                 ++s;
5048                               --s;
5049                             }
5050                         }
5051                     }
5052                 }
5053
5054               /* If we have already included a header file with the
5055                  same value, then replace this one with an N_EXCL
5056                  symbol.  */
5057               copy = (bfd_boolean) (! finfo->info->keep_memory);
5058               incl_entry = aout_link_includes_lookup (&finfo->includes,
5059                                                       name, TRUE, copy);
5060               if (incl_entry == NULL)
5061                 return FALSE;
5062               for (t = incl_entry->totals; t != NULL; t = t->next)
5063                 if (t->total == val)
5064                   break;
5065               if (t == NULL)
5066                 {
5067                   /* This is the first time we have seen this header
5068                      file with this set of stabs strings.  */
5069                   t = bfd_hash_allocate (&finfo->includes.root,
5070                                          sizeof *t);
5071                   if (t == NULL)
5072                     return FALSE;
5073                   t->total = val;
5074                   t->next = incl_entry->totals;
5075                   incl_entry->totals = t;
5076                 }
5077               else
5078                 {
5079                   int *incl_map;
5080
5081                   /* This is a duplicate header file.  We must change
5082                      it to be an N_EXCL entry, and mark all the
5083                      included symbols to prevent outputting them.  */
5084                   type = (int) N_EXCL;
5085
5086                   nest = 0;
5087                   for (incl_sym = sym + 1, incl_map = symbol_map + 1;
5088                        incl_sym < sym_end;
5089                        incl_sym++, incl_map++)
5090                     {
5091                       int incl_type;
5092
5093                       incl_type = H_GET_8 (input_bfd, incl_sym->e_type);
5094                       if (incl_type == (int) N_EINCL)
5095                         {
5096                           if (nest == 0)
5097                             {
5098                               *incl_map = -1;
5099                               break;
5100                             }
5101                           --nest;
5102                         }
5103                       else if (incl_type == (int) N_BINCL)
5104                         ++nest;
5105                       else if (nest == 0)
5106                         *incl_map = -1;
5107                     }
5108                 }
5109             }
5110         }
5111
5112       /* Copy this symbol into the list of symbols we are going to
5113          write out.  */
5114       H_PUT_8 (output_bfd, type, outsym->e_type);
5115       H_PUT_8 (output_bfd, H_GET_8 (input_bfd, sym->e_other), outsym->e_other);
5116       H_PUT_16 (output_bfd, H_GET_16 (input_bfd, sym->e_desc), outsym->e_desc);
5117       copy = FALSE;
5118       if (! finfo->info->keep_memory)
5119         {
5120           /* name points into a string table which we are going to
5121              free.  If there is a hash table entry, use that string.
5122              Otherwise, copy name into memory.  */
5123           if (h != NULL)
5124             name = h->root.root.string;
5125           else
5126             copy = TRUE;
5127         }
5128       strtab_index = add_to_stringtab (output_bfd, finfo->strtab,
5129                                        name, copy);
5130       if (strtab_index == (bfd_size_type) -1)
5131         return FALSE;
5132       PUT_WORD (output_bfd, strtab_index, outsym->e_strx);
5133       PUT_WORD (output_bfd, val, outsym->e_value);
5134       *symbol_map = obj_aout_external_sym_count (output_bfd);
5135       ++obj_aout_external_sym_count (output_bfd);
5136       ++outsym;
5137     }
5138
5139   /* Write out the output symbols we have just constructed.  */
5140   if (outsym > finfo->output_syms)
5141     {
5142       bfd_size_type outsym_size;
5143
5144       if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
5145         return FALSE;
5146       outsym_size = outsym - finfo->output_syms;
5147       outsym_size *= EXTERNAL_NLIST_SIZE;
5148       if (bfd_bwrite ((void *) finfo->output_syms, outsym_size, output_bfd)
5149           != outsym_size)
5150         return FALSE;
5151       finfo->symoff += outsym_size;
5152     }
5153
5154   return TRUE;
5155 }
5156
5157 /* Link an a.out input BFD into the output file.  */
5158
5159 static bfd_boolean
5160 aout_link_input_bfd (struct aout_final_link_info *finfo, bfd *input_bfd)
5161 {
5162   bfd_size_type sym_count;
5163
5164   BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
5165
5166   /* If this is a dynamic object, it may need special handling.  */
5167   if ((input_bfd->flags & DYNAMIC) != 0
5168       && aout_backend_info (input_bfd)->link_dynamic_object != NULL)
5169     return ((*aout_backend_info (input_bfd)->link_dynamic_object)
5170             (finfo->info, input_bfd));
5171
5172   /* Get the symbols.  We probably have them already, unless
5173      finfo->info->keep_memory is FALSE.  */
5174   if (! aout_get_external_symbols (input_bfd))
5175     return FALSE;
5176
5177   sym_count = obj_aout_external_sym_count (input_bfd);
5178
5179   /* Write out the symbols and get a map of the new indices.  The map
5180      is placed into finfo->symbol_map.  */
5181   if (! aout_link_write_symbols (finfo, input_bfd))
5182     return FALSE;
5183
5184   /* Relocate and write out the sections.  These functions use the
5185      symbol map created by aout_link_write_symbols.  The linker_mark
5186      field will be set if these sections are to be included in the
5187      link, which will normally be the case.  */
5188   if (obj_textsec (input_bfd)->linker_mark)
5189     {
5190       if (! aout_link_input_section (finfo, input_bfd,
5191                                      obj_textsec (input_bfd),
5192                                      &finfo->treloff,
5193                                      exec_hdr (input_bfd)->a_trsize))
5194         return FALSE;
5195     }
5196   if (obj_datasec (input_bfd)->linker_mark)
5197     {
5198       if (! aout_link_input_section (finfo, input_bfd,
5199                                      obj_datasec (input_bfd),
5200                                      &finfo->dreloff,
5201                                      exec_hdr (input_bfd)->a_drsize))
5202         return FALSE;
5203     }
5204
5205   /* If we are not keeping memory, we don't need the symbols any
5206      longer.  We still need them if we are keeping memory, because the
5207      strings in the hash table point into them.  */
5208   if (! finfo->info->keep_memory)
5209     {
5210       if (! aout_link_free_symbols (input_bfd))
5211         return FALSE;
5212     }
5213
5214   return TRUE;
5215 }
5216
5217 /* Do the final link step.  This is called on the output BFD.  The
5218    INFO structure should point to a list of BFDs linked through the
5219    link_next field which can be used to find each BFD which takes part
5220    in the output.  Also, each section in ABFD should point to a list
5221    of bfd_link_order structures which list all the input sections for
5222    the output section.  */
5223
5224 bfd_boolean
5225 NAME (aout, final_link) (bfd *abfd,
5226                          struct bfd_link_info *info,
5227                          void (*callback) (bfd *, file_ptr *, file_ptr *, file_ptr *))
5228 {
5229   struct aout_final_link_info aout_info;
5230   bfd_boolean includes_hash_initialized = FALSE;
5231   bfd *sub;
5232   bfd_size_type trsize, drsize;
5233   bfd_size_type max_contents_size;
5234   bfd_size_type max_relocs_size;
5235   bfd_size_type max_sym_count;
5236   bfd_size_type text_size;
5237   file_ptr text_end;
5238   struct bfd_link_order *p;
5239   asection *o;
5240   bfd_boolean have_link_order_relocs;
5241
5242   if (info->shared)
5243     abfd->flags |= DYNAMIC;
5244
5245   aout_info.info = info;
5246   aout_info.output_bfd = abfd;
5247   aout_info.contents = NULL;
5248   aout_info.relocs = NULL;
5249   aout_info.symbol_map = NULL;
5250   aout_info.output_syms = NULL;
5251
5252   if (!bfd_hash_table_init_n (&aout_info.includes.root,
5253                               aout_link_includes_newfunc,
5254                               sizeof (struct aout_link_includes_entry),
5255                               251))
5256     goto error_return;
5257   includes_hash_initialized = TRUE;
5258
5259   /* Figure out the largest section size.  Also, if generating
5260      relocatable output, count the relocs.  */
5261   trsize = 0;
5262   drsize = 0;
5263   max_contents_size = 0;
5264   max_relocs_size = 0;
5265   max_sym_count = 0;
5266   for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
5267     {
5268       bfd_size_type sz;
5269
5270       if (info->relocatable)
5271         {
5272           if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
5273             {
5274               trsize += exec_hdr (sub)->a_trsize;
5275               drsize += exec_hdr (sub)->a_drsize;
5276             }
5277           else
5278             {
5279               /* FIXME: We need to identify the .text and .data sections
5280                  and call get_reloc_upper_bound and canonicalize_reloc to
5281                  work out the number of relocs needed, and then multiply
5282                  by the reloc size.  */
5283               (*_bfd_error_handler)
5284                 (_("%s: relocatable link from %s to %s not supported"),
5285                  bfd_get_filename (abfd),
5286                  sub->xvec->name, abfd->xvec->name);
5287               bfd_set_error (bfd_error_invalid_operation);
5288               goto error_return;
5289             }
5290         }
5291
5292       if (bfd_get_flavour (sub) == bfd_target_aout_flavour)
5293         {
5294           sz = obj_textsec (sub)->size;
5295           if (sz > max_contents_size)
5296             max_contents_size = sz;
5297           sz = obj_datasec (sub)->size;
5298           if (sz > max_contents_size)
5299             max_contents_size = sz;
5300
5301           sz = exec_hdr (sub)->a_trsize;
5302           if (sz > max_relocs_size)
5303             max_relocs_size = sz;
5304           sz = exec_hdr (sub)->a_drsize;
5305           if (sz > max_relocs_size)
5306             max_relocs_size = sz;
5307
5308           sz = obj_aout_external_sym_count (sub);
5309           if (sz > max_sym_count)
5310             max_sym_count = sz;
5311         }
5312     }
5313
5314   if (info->relocatable)
5315     {
5316       if (obj_textsec (abfd) != NULL)
5317         trsize += (_bfd_count_link_order_relocs (obj_textsec (abfd)
5318                                                  ->map_head.link_order)
5319                    * obj_reloc_entry_size (abfd));
5320       if (obj_datasec (abfd) != NULL)
5321         drsize += (_bfd_count_link_order_relocs (obj_datasec (abfd)
5322                                                  ->map_head.link_order)
5323                    * obj_reloc_entry_size (abfd));
5324     }
5325
5326   exec_hdr (abfd)->a_trsize = trsize;
5327   exec_hdr (abfd)->a_drsize = drsize;
5328
5329   exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
5330
5331   /* Adjust the section sizes and vmas according to the magic number.
5332      This sets a_text, a_data and a_bss in the exec_hdr and sets the
5333      filepos for each section.  */
5334   if (! NAME (aout, adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
5335     goto error_return;
5336
5337   /* The relocation and symbol file positions differ among a.out
5338      targets.  We are passed a callback routine from the backend
5339      specific code to handle this.
5340      FIXME: At this point we do not know how much space the symbol
5341      table will require.  This will not work for any (nonstandard)
5342      a.out target that needs to know the symbol table size before it
5343      can compute the relocation file positions.  This may or may not
5344      be the case for the hp300hpux target, for example.  */
5345   (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
5346                &aout_info.symoff);
5347   obj_textsec (abfd)->rel_filepos = aout_info.treloff;
5348   obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
5349   obj_sym_filepos (abfd) = aout_info.symoff;
5350
5351   /* We keep a count of the symbols as we output them.  */
5352   obj_aout_external_sym_count (abfd) = 0;
5353
5354   /* We accumulate the string table as we write out the symbols.  */
5355   aout_info.strtab = _bfd_stringtab_init ();
5356   if (aout_info.strtab == NULL)
5357     goto error_return;
5358
5359   /* Allocate buffers to hold section contents and relocs.  */
5360   aout_info.contents = bfd_malloc (max_contents_size);
5361   aout_info.relocs = bfd_malloc (max_relocs_size);
5362   aout_info.symbol_map = bfd_malloc (max_sym_count * sizeof (int *));
5363   aout_info.output_syms = bfd_malloc ((max_sym_count + 1)
5364                                       * sizeof (struct external_nlist));
5365   if ((aout_info.contents == NULL && max_contents_size != 0)
5366       || (aout_info.relocs == NULL && max_relocs_size != 0)
5367       || (aout_info.symbol_map == NULL && max_sym_count != 0)
5368       || aout_info.output_syms == NULL)
5369     goto error_return;
5370
5371   /* If we have a symbol named __DYNAMIC, force it out now.  This is
5372      required by SunOS.  Doing this here rather than in sunos.c is a
5373      hack, but it's easier than exporting everything which would be
5374      needed.  */
5375   {
5376     struct aout_link_hash_entry *h;
5377
5378     h = aout_link_hash_lookup (aout_hash_table (info), "__DYNAMIC",
5379                                FALSE, FALSE, FALSE);
5380     if (h != NULL)
5381       aout_link_write_other_symbol (h, &aout_info);
5382   }
5383
5384   /* The most time efficient way to do the link would be to read all
5385      the input object files into memory and then sort out the
5386      information into the output file.  Unfortunately, that will
5387      probably use too much memory.  Another method would be to step
5388      through everything that composes the text section and write it
5389      out, and then everything that composes the data section and write
5390      it out, and then write out the relocs, and then write out the
5391      symbols.  Unfortunately, that requires reading stuff from each
5392      input file several times, and we will not be able to keep all the
5393      input files open simultaneously, and reopening them will be slow.
5394
5395      What we do is basically process one input file at a time.  We do
5396      everything we need to do with an input file once--copy over the
5397      section contents, handle the relocation information, and write
5398      out the symbols--and then we throw away the information we read
5399      from it.  This approach requires a lot of lseeks of the output
5400      file, which is unfortunate but still faster than reopening a lot
5401      of files.
5402
5403      We use the output_has_begun field of the input BFDs to see
5404      whether we have already handled it.  */
5405   for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
5406     sub->output_has_begun = FALSE;
5407
5408   /* Mark all sections which are to be included in the link.  This
5409      will normally be every section.  We need to do this so that we
5410      can identify any sections which the linker has decided to not
5411      include.  */
5412   for (o = abfd->sections; o != NULL; o = o->next)
5413     {
5414       for (p = o->map_head.link_order; p != NULL; p = p->next)
5415         if (p->type == bfd_indirect_link_order)
5416           p->u.indirect.section->linker_mark = TRUE;
5417     }
5418
5419   have_link_order_relocs = FALSE;
5420   for (o = abfd->sections; o != NULL; o = o->next)
5421     {
5422       for (p = o->map_head.link_order;
5423            p != NULL;
5424            p = p->next)
5425         {
5426           if (p->type == bfd_indirect_link_order
5427               && (bfd_get_flavour (p->u.indirect.section->owner)
5428                   == bfd_target_aout_flavour))
5429             {
5430               bfd *input_bfd;
5431
5432               input_bfd = p->u.indirect.section->owner;
5433               if (! input_bfd->output_has_begun)
5434                 {
5435                   if (! aout_link_input_bfd (&aout_info, input_bfd))
5436                     goto error_return;
5437                   input_bfd->output_has_begun = TRUE;
5438                 }
5439             }
5440           else if (p->type == bfd_section_reloc_link_order
5441                    || p->type == bfd_symbol_reloc_link_order)
5442             {
5443               /* These are handled below.  */
5444               have_link_order_relocs = TRUE;
5445             }
5446           else
5447             {
5448               if (! _bfd_default_link_order (abfd, info, o, p))
5449                 goto error_return;
5450             }
5451         }
5452     }
5453
5454   /* Write out any symbols that we have not already written out.  */
5455   aout_link_hash_traverse (aout_hash_table (info),
5456                            aout_link_write_other_symbol,
5457                            (void *) &aout_info);
5458
5459   /* Now handle any relocs we were asked to create by the linker.
5460      These did not come from any input file.  We must do these after
5461      we have written out all the symbols, so that we know the symbol
5462      indices to use.  */
5463   if (have_link_order_relocs)
5464     {
5465       for (o = abfd->sections; o != NULL; o = o->next)
5466         {
5467           for (p = o->map_head.link_order;
5468                p != NULL;
5469                p = p->next)
5470             {
5471               if (p->type == bfd_section_reloc_link_order
5472                   || p->type == bfd_symbol_reloc_link_order)
5473                 {
5474                   if (! aout_link_reloc_link_order (&aout_info, o, p))
5475                     goto error_return;
5476                 }
5477             }
5478         }
5479     }
5480
5481   if (aout_info.contents != NULL)
5482     {
5483       free (aout_info.contents);
5484       aout_info.contents = NULL;
5485     }
5486   if (aout_info.relocs != NULL)
5487     {
5488       free (aout_info.relocs);
5489       aout_info.relocs = NULL;
5490     }
5491   if (aout_info.symbol_map != NULL)
5492     {
5493       free (aout_info.symbol_map);
5494       aout_info.symbol_map = NULL;
5495     }
5496   if (aout_info.output_syms != NULL)
5497     {
5498       free (aout_info.output_syms);
5499       aout_info.output_syms = NULL;
5500     }
5501   if (includes_hash_initialized)
5502     {
5503       bfd_hash_table_free (&aout_info.includes.root);
5504       includes_hash_initialized = FALSE;
5505     }
5506
5507   /* Finish up any dynamic linking we may be doing.  */
5508   if (aout_backend_info (abfd)->finish_dynamic_link != NULL)
5509     {
5510       if (! (*aout_backend_info (abfd)->finish_dynamic_link) (abfd, info))
5511         goto error_return;
5512     }
5513
5514   /* Update the header information.  */
5515   abfd->symcount = obj_aout_external_sym_count (abfd);
5516   exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
5517   obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
5518   obj_textsec (abfd)->reloc_count =
5519     exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
5520   obj_datasec (abfd)->reloc_count =
5521     exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
5522
5523   /* Write out the string table, unless there are no symbols.  */
5524   if (abfd->symcount > 0)
5525     {
5526       if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
5527           || ! emit_stringtab (abfd, aout_info.strtab))
5528         goto error_return;
5529     }
5530   else if (obj_textsec (abfd)->reloc_count == 0
5531            && obj_datasec (abfd)->reloc_count == 0)
5532     {
5533       bfd_byte b;
5534       file_ptr pos;
5535
5536       b = 0;
5537       pos = obj_datasec (abfd)->filepos + exec_hdr (abfd)->a_data - 1;
5538       if (bfd_seek (abfd, pos, SEEK_SET) != 0
5539           || bfd_bwrite (&b, (bfd_size_type) 1, abfd) != 1)
5540         goto error_return;
5541     }
5542
5543   return TRUE;
5544
5545  error_return:
5546   if (aout_info.contents != NULL)
5547     free (aout_info.contents);
5548   if (aout_info.relocs != NULL)
5549     free (aout_info.relocs);
5550   if (aout_info.symbol_map != NULL)
5551     free (aout_info.symbol_map);
5552   if (aout_info.output_syms != NULL)
5553     free (aout_info.output_syms);
5554   if (includes_hash_initialized)
5555     bfd_hash_table_free (&aout_info.includes.root);
5556   return FALSE;
5557 }