OSDN Git Service

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