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