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