OSDN Git Service

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