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