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