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