OSDN Git Service

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