OSDN Git Service

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