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