OSDN Git Service

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