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