]> Git Repo - binutils.git/blob - bfd/aoutx.h
* subsegs.c (subseg_get): Accept new argument "force_new". If
[binutils.git] / bfd / aoutx.h
1 /* BFD semi-generic back-end for a.out binaries.
2    Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3    Written by Cygnus Support.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 /*
22 SECTION
23         a.out backends
24
25
26 DESCRIPTION
27
28         BFD supports a number of different flavours of a.out format,
29         though the major differences are only the sizes of the
30         structures on disk, and the shape of the relocation
31         information.
32
33         The support is split into a basic support file @file{aoutx.h}
34         and other files which derive functions from the base. One
35         derivation file is @file{aoutf1.h} (for a.out flavour 1), and
36         adds to the basic a.out functions support for sun3, sun4, 386
37         and 29k a.out files, to create a target jump vector for a
38         specific target.
39
40         This information is further split out into more specific files
41         for each machine, including @file{sunos.c} for sun3 and sun4,
42         @file{newsos3.c} for the Sony NEWS, and @file{demo64.c} for a
43         demonstration of a 64 bit a.out format.
44
45         The base file @file{aoutx.h} defines general mechanisms for
46         reading and writing records to and from disk and various
47         other methods which BFD requires. It is included by
48         @file{aout32.c} and @file{aout64.c} to form the names
49         <<aout_32_swap_exec_header_in>>, <<aout_64_swap_exec_header_in>>, etc.
50
51         As an example, this is what goes on to make the back end for a
52         sun4, from @file{aout32.c}:
53
54 |       #define ARCH_SIZE 32
55 |       #include "aoutx.h"
56
57         Which exports names:
58
59 |       ...
60 |       aout_32_canonicalize_reloc
61 |       aout_32_find_nearest_line
62 |       aout_32_get_lineno
63 |       aout_32_get_reloc_upper_bound
64 |       ...
65
66         from @file{sunos.c}:
67
68 |       #define ARCH 32
69 |       #define TARGET_NAME "a.out-sunos-big"
70 |       #define VECNAME    sunos_big_vec
71 |       #include "aoutf1.h"
72
73         requires all the names from @file{aout32.c}, and produces the jump vector
74
75 |       sunos_big_vec
76
77         The file @file{host-aout.c} is a special case.  It is for a large set
78         of hosts that use ``more or less standard'' a.out files, and
79         for which cross-debugging is not interesting.  It uses the
80         standard 32-bit a.out support routines, but determines the
81         file offsets and addresses of the text, data, and BSS
82         sections, the machine architecture and machine type, and the
83         entry point address, in a host-dependent manner.  Once these
84         values have been determined, generic code is used to handle
85         the  object file.
86
87         When porting it to run on a new system, you must supply:
88
89 |        HOST_PAGE_SIZE
90 |        HOST_SEGMENT_SIZE
91 |        HOST_MACHINE_ARCH       (optional)
92 |        HOST_MACHINE_MACHINE    (optional)
93 |        HOST_TEXT_START_ADDR
94 |        HOST_STACK_END_ADDR
95
96         in the file @file{../include/sys/h-@var{XXX}.h} (for your host).  These
97         values, plus the structures and macros defined in @file{a.out.h} on
98         your host system, will produce a BFD target that will access
99         ordinary a.out files on your host. To configure a new machine
100         to use @file{host-aout.c}, specify:
101
102 |       TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
103 |       TDEPFILES= host-aout.o trad-core.o
104
105         in the @file{config/@var{XXX}.mt} file, and modify @file{configure.in}
106         to use the
107         @file{@var{XXX}.mt} file (by setting "<<bfd_target=XXX>>") when your
108         configuration is selected.
109
110 */
111
112 /* Some assumptions:
113    * Any BFD with D_PAGED set is ZMAGIC, and vice versa.
114      Doesn't matter what the setting of WP_TEXT is on output, but it'll
115      get set on input.
116    * Any BFD with D_PAGED clear and WP_TEXT set is NMAGIC.
117    * Any BFD with both flags clear is OMAGIC.
118    (Just want to make these explicit, so the conditions tested in this
119    file make sense if you're more familiar with a.out than with BFD.)  */
120
121 #define KEEPIT flags
122 #define KEEPITTYPE int
123
124 #include <assert.h>
125 #include <string.h>             /* For strchr and friends */
126 #include "bfd.h"
127 #include <sysdep.h>
128 #include <ansidecl.h>
129 #include "bfdlink.h"
130
131 #include "libaout.h"
132 #include "libbfd.h"
133 #include "aout/aout64.h"
134 #include "aout/stab_gnu.h"
135 #include "aout/ar.h"
136
137 /*
138 SUBSECTION
139         Relocations
140
141 DESCRIPTION
142         The file @file{aoutx.h} provides for both the @emph{standard}
143         and @emph{extended} forms of a.out relocation records.
144
145         The standard records contain only an
146         address, a symbol index, and a type field. The extended records
147         (used on 29ks and sparcs) also have a full integer for an
148         addend.
149
150 */
151 #define CTOR_TABLE_RELOC_IDX 2
152
153 #define howto_table_ext NAME(aout,ext_howto_table)
154 #define howto_table_std NAME(aout,std_howto_table)
155
156 reloc_howto_type howto_table_ext[] =
157 {
158   /* type           rs   size bsz  pcrel bitpos ovrf                  sf name          part_inpl readmask setmask pcdone */
159   HOWTO(RELOC_8,      0,  0,    8,  false, 0, complain_overflow_bitfield,0,"8",        false, 0,0x000000ff, false),
160   HOWTO(RELOC_16,     0,  1,    16, false, 0, complain_overflow_bitfield,0,"16",       false, 0,0x0000ffff, false),
161   HOWTO(RELOC_32,     0,  2,    32, false, 0, complain_overflow_bitfield,0,"32",       false, 0,0xffffffff, false),
162   HOWTO(RELOC_DISP8,  0,  0,    8,  true,  0, complain_overflow_signed,0,"DISP8",       false, 0,0x000000ff, false),
163   HOWTO(RELOC_DISP16, 0,  1,    16, true,  0, complain_overflow_signed,0,"DISP16",      false, 0,0x0000ffff, false),
164   HOWTO(RELOC_DISP32, 0,  2,    32, true,  0, complain_overflow_signed,0,"DISP32",      false, 0,0xffffffff, false),
165   HOWTO(RELOC_WDISP30,2,  2,    30, true,  0, complain_overflow_signed,0,"WDISP30",     false, 0,0x3fffffff, false),
166   HOWTO(RELOC_WDISP22,2,  2,    22, true,  0, complain_overflow_signed,0,"WDISP22",     false, 0,0x003fffff, false),
167   HOWTO(RELOC_HI22,   10, 2,    22, false, 0, complain_overflow_bitfield,0,"HI22",      false, 0,0x003fffff, false),
168   HOWTO(RELOC_22,     0,  2,    22, false, 0, complain_overflow_bitfield,0,"22",       false, 0,0x003fffff, false),
169   HOWTO(RELOC_13,     0,  2,    13, false, 0, complain_overflow_bitfield,0,"13",       false, 0,0x00001fff, false),
170   HOWTO(RELOC_LO10,   0,  2,    10, false, 0, complain_overflow_dont,0,"LO10",     false, 0,0x000003ff, false),
171   HOWTO(RELOC_SFA_BASE,0, 2,    32, false, 0, complain_overflow_bitfield,0,"SFA_BASE", false, 0,0xffffffff, false),
172   HOWTO(RELOC_SFA_OFF13,0,2,    32, false, 0, complain_overflow_bitfield,0,"SFA_OFF13",false, 0,0xffffffff, false),
173   HOWTO(RELOC_BASE10, 0,  2,    16, false, 0, complain_overflow_bitfield,0,"BASE10",   false, 0,0x0000ffff, false),
174   HOWTO(RELOC_BASE13, 0,  2,    13, false, 0, complain_overflow_bitfield,0,"BASE13",   false, 0,0x00001fff, false),
175   HOWTO(RELOC_BASE22, 0,  2,    0,  false, 0, complain_overflow_bitfield,0,"BASE22",   false, 0,0x00000000, false),
176   HOWTO(RELOC_PC10,   0,  2,    10, false, 0, complain_overflow_bitfield,0,"PC10",      false, 0,0x000003ff, false),
177   HOWTO(RELOC_PC22,   0,  2,    22, false, 0, complain_overflow_bitfield,0,"PC22",      false, 0,0x003fffff, false),
178   HOWTO(RELOC_JMP_TBL,0,  2,    32, false, 0, complain_overflow_bitfield,0,"JMP_TBL",   false, 0,0xffffffff, false),
179   HOWTO(RELOC_SEGOFF16,0, 2,    0,  false, 0, complain_overflow_bitfield,0,"SEGOFF16",  false, 0,0x00000000, false),
180   HOWTO(RELOC_GLOB_DAT,0, 2,    0,  false, 0, complain_overflow_bitfield,0,"GLOB_DAT",  false, 0,0x00000000, false),
181   HOWTO(RELOC_JMP_SLOT,0, 2,    0,  false, 0, complain_overflow_bitfield,0,"JMP_SLOT",  false, 0,0x00000000, false),
182   HOWTO(RELOC_RELATIVE,0, 2,    0,  false, 0, complain_overflow_bitfield,0,"RELATIVE",  false, 0,0x00000000, false),
183 };
184
185 /* Convert standard reloc records to "arelent" format (incl byte swap).  */
186
187 reloc_howto_type howto_table_std[] = {
188   /* type              rs size bsz  pcrel bitpos ovrf                     sf name     part_inpl readmask  setmask    pcdone */
189 HOWTO( 0,              0,  0,   8,  false, 0, complain_overflow_bitfield,0,"8",         true, 0x000000ff,0x000000ff, false),
190 HOWTO( 1,              0,  1,   16, false, 0, complain_overflow_bitfield,0,"16",        true, 0x0000ffff,0x0000ffff, false),
191 HOWTO( 2,              0,  2,   32, false, 0, complain_overflow_bitfield,0,"32",        true, 0xffffffff,0xffffffff, false),
192 HOWTO( 3,              0,  4,   64, false, 0, complain_overflow_bitfield,0,"64",        true, 0xdeaddead,0xdeaddead, false),
193 HOWTO( 4,              0,  0,   8,  true,  0, complain_overflow_signed,  0,"DISP8",     true, 0x000000ff,0x000000ff, false),
194 HOWTO( 5,              0,  1,   16, true,  0, complain_overflow_signed,  0,"DISP16",    true, 0x0000ffff,0x0000ffff, false),
195 HOWTO( 6,              0,  2,   32, true,  0, complain_overflow_signed,  0,"DISP32",    true, 0xffffffff,0xffffffff, false),
196 HOWTO( 7,              0,  4,   64, true,  0, complain_overflow_signed,  0,"DISP64",    true, 0xfeedface,0xfeedface, false),
197 { -1 },
198 HOWTO( 9,              0,  1,   16, false, 0, complain_overflow_bitfield,0,"BASE16",    false,0xffffffff,0xffffffff, false),
199 HOWTO(10,              0,  2,   32, false, 0, complain_overflow_bitfield,0,"BASE32",    false,0xffffffff,0xffffffff, false),
200 };
201
202 #define TABLE_SIZE(TABLE)       (sizeof(TABLE)/sizeof(TABLE[0]))
203
204 CONST struct reloc_howto_struct *
205 DEFUN(NAME(aout,reloc_type_lookup),(abfd,code),
206       bfd *abfd AND
207       bfd_reloc_code_real_type code)
208 {
209 #define EXT(i,j)        case i: return &howto_table_ext[j]
210 #define STD(i,j)        case i: return &howto_table_std[j]
211   int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
212   if (code == BFD_RELOC_CTOR)
213     switch (bfd_get_arch_info (abfd)->bits_per_address)
214       {
215       case 32:
216         code = BFD_RELOC_32;
217         break;
218       }
219   if (ext)
220     switch (code)
221       {
222         EXT (BFD_RELOC_32, 2);
223         EXT (BFD_RELOC_HI22, 8);
224         EXT (BFD_RELOC_LO10, 11);
225         EXT (BFD_RELOC_32_PCREL_S2, 6);
226         EXT (BFD_RELOC_SPARC_WDISP22, 7);
227       default: return (CONST struct reloc_howto_struct *) 0;
228       }
229   else
230     /* std relocs */
231     switch (code)
232       {
233         STD (BFD_RELOC_16, 1);
234         STD (BFD_RELOC_32, 2);
235         STD (BFD_RELOC_8_PCREL, 4);
236         STD (BFD_RELOC_16_PCREL, 5);
237         STD (BFD_RELOC_32_PCREL, 6);
238         STD (BFD_RELOC_16_BASEREL, 9);
239         STD (BFD_RELOC_32_BASEREL, 10);
240       default: return (CONST struct reloc_howto_struct *) 0;
241       }
242 }
243
244 /*
245 SUBSECTION
246         Internal entry points
247
248 DESCRIPTION
249         @file{aoutx.h} exports several routines for accessing the
250         contents of an a.out file, which are gathered and exported in
251         turn by various format specific files (eg sunos.c).
252
253 */
254
255 /*
256 FUNCTION
257          aout_@var{size}_swap_exec_header_in
258
259 SYNOPSIS
260         void aout_@var{size}_swap_exec_header_in,
261            (bfd *abfd,
262             struct external_exec *raw_bytes,
263             struct internal_exec *execp);
264
265 DESCRIPTION
266         Swap the information in an executable header @var{raw_bytes} taken
267         from a raw byte stream memory image into the internal exec header
268         structure @var{execp}.
269 */
270
271 #ifndef NAME_swap_exec_header_in
272 void
273 DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
274       bfd *abfd AND
275       struct external_exec *raw_bytes AND
276       struct internal_exec *execp)
277 {
278   struct external_exec *bytes = (struct external_exec *)raw_bytes;
279
280   /* The internal_exec structure has some fields that are unused in this
281      configuration (IE for i960), so ensure that all such uninitialized
282      fields are zero'd out.  There are places where two of these structs
283      are memcmp'd, and thus the contents do matter. */
284   memset (execp, 0, sizeof (struct internal_exec));
285   /* Now fill in fields in the execp, from the bytes in the raw data.  */
286   execp->a_info   = bfd_h_get_32 (abfd, bytes->e_info);
287   execp->a_text   = GET_WORD (abfd, bytes->e_text);
288   execp->a_data   = GET_WORD (abfd, bytes->e_data);
289   execp->a_bss    = GET_WORD (abfd, bytes->e_bss);
290   execp->a_syms   = GET_WORD (abfd, bytes->e_syms);
291   execp->a_entry  = GET_WORD (abfd, bytes->e_entry);
292   execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
293   execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
294 }
295 #define NAME_swap_exec_header_in NAME(aout,swap_exec_header_in)
296 #endif
297
298 /*
299 FUNCTION
300         aout_@var{size}_swap_exec_header_out
301
302 SYNOPSIS
303         void aout_@var{size}_swap_exec_header_out
304           (bfd *abfd,
305            struct internal_exec *execp,
306            struct external_exec *raw_bytes);
307
308 DESCRIPTION
309         Swap the information in an internal exec header structure
310         @var{execp} into the buffer @var{raw_bytes} ready for writing to disk.
311 */
312 void
313 DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
314      bfd *abfd AND
315      struct internal_exec *execp AND
316      struct external_exec *raw_bytes)
317 {
318   struct external_exec *bytes = (struct external_exec *)raw_bytes;
319
320   /* Now fill in fields in the raw data, from the fields in the exec struct. */
321   bfd_h_put_32 (abfd, execp->a_info  , bytes->e_info);
322   PUT_WORD (abfd, execp->a_text  , bytes->e_text);
323   PUT_WORD (abfd, execp->a_data  , bytes->e_data);
324   PUT_WORD (abfd, execp->a_bss   , bytes->e_bss);
325   PUT_WORD (abfd, execp->a_syms  , bytes->e_syms);
326   PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
327   PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
328   PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
329 }
330
331
332
333 /*
334 FUNCTION
335         aout_@var{size}_some_aout_object_p
336
337 SYNOPSIS
338         bfd_target *aout_@var{size}_some_aout_object_p
339          (bfd *abfd,
340           bfd_target *(*callback_to_real_object_p)());
341
342 DESCRIPTION
343         Some a.out variant thinks that the file open in @var{abfd}
344         checking is an a.out file.  Do some more checking, and set up
345         for access if it really is.  Call back to the calling
346         environment's "finish up" function just before returning, to
347         handle any last-minute setup.
348 */
349
350 bfd_target *
351 DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p),
352       bfd *abfd AND
353       struct internal_exec *execp AND
354       bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *)))
355 {
356   struct aout_data_struct *rawptr, *oldrawptr;
357   bfd_target *result;
358
359   rawptr = (struct aout_data_struct  *) bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
360   if (rawptr == NULL) {
361     bfd_error = no_memory;
362     return 0;
363   }
364
365   oldrawptr = abfd->tdata.aout_data;
366   abfd->tdata.aout_data = rawptr;
367
368   /* Copy the contents of the old tdata struct.
369      In particular, we want the subformat, since for hpux it was set in
370      hp300hpux.c:swap_exec_header_in and will be used in
371      hp300hpux.c:callback.  */
372   if (oldrawptr != NULL)
373     *abfd->tdata.aout_data = *oldrawptr;
374
375   abfd->tdata.aout_data->a.hdr = &rawptr->e;
376   *(abfd->tdata.aout_data->a.hdr) = *execp;     /* Copy in the internal_exec struct */
377   execp = abfd->tdata.aout_data->a.hdr;
378
379   /* Set the file flags */
380   abfd->flags = NO_FLAGS;
381   if (execp->a_drsize || execp->a_trsize)
382     abfd->flags |= HAS_RELOC;
383   /* Setting of EXEC_P has been deferred to the bottom of this function */
384   if (execp->a_syms)
385     abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
386   if (N_DYNAMIC(*execp))
387     abfd->flags |= DYNAMIC;
388
389   if (N_MAGIC (*execp) == ZMAGIC)
390     {
391       abfd->flags |= D_PAGED|WP_TEXT;
392       adata(abfd).magic = z_magic;
393     }
394   else if (N_MAGIC (*execp) == NMAGIC)
395     {
396       abfd->flags |= WP_TEXT;
397       adata(abfd).magic = n_magic;
398     }
399   else
400     adata(abfd).magic = o_magic;
401
402   bfd_get_start_address (abfd) = execp->a_entry;
403
404   obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
405   bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
406
407   /* The default relocation entry size is that of traditional V7 Unix.  */
408   obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
409
410   /* The default symbol entry size is that of traditional Unix. */
411   obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
412
413   obj_aout_external_syms (abfd) = NULL;
414   obj_aout_external_strings (abfd) = NULL;
415   obj_aout_sym_hashes (abfd) = NULL;
416
417   /* Create the sections.  This is raunchy, but bfd_close wants to reclaim
418      them.  */
419
420   obj_textsec (abfd) = bfd_make_section_old_way (abfd, ".text");
421   obj_datasec (abfd) = bfd_make_section_old_way (abfd, ".data");
422   obj_bsssec (abfd) = bfd_make_section_old_way (abfd, ".bss");
423
424 #if 0
425   (void)bfd_make_section (abfd, ".text");
426   (void)bfd_make_section (abfd, ".data");
427   (void)bfd_make_section (abfd, ".bss");
428 #endif
429
430   obj_datasec (abfd)->_raw_size = execp->a_data;
431   obj_bsssec (abfd)->_raw_size = execp->a_bss;
432
433   obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
434        (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC) :
435        (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
436   obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
437        (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC) :
438        (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
439   obj_bsssec (abfd)->flags = SEC_ALLOC;
440
441 #ifdef THIS_IS_ONLY_DOCUMENTATION
442   /* The common code can't fill in these things because they depend
443      on either the start address of the text segment, the rounding
444      up of virtual addersses between segments, or the starting file
445      position of the text segment -- all of which varies among different
446      versions of a.out.  */
447
448   /* Call back to the format-dependent code to fill in the rest of the
449      fields and do any further cleanup.  Things that should be filled
450      in by the callback:  */
451
452   struct exec *execp = exec_hdr (abfd);
453
454   obj_textsec (abfd)->size = N_TXTSIZE(*execp);
455   obj_textsec (abfd)->raw_size = N_TXTSIZE(*execp);
456   /* data and bss are already filled in since they're so standard */
457
458   /* The virtual memory addresses of the sections */
459   obj_textsec (abfd)->vma = N_TXTADDR(*execp);
460   obj_datasec (abfd)->vma = N_DATADDR(*execp);
461   obj_bsssec  (abfd)->vma = N_BSSADDR(*execp);
462
463   /* The file offsets of the sections */
464   obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
465   obj_datasec (abfd)->filepos = N_DATOFF(*execp);
466
467   /* The file offsets of the relocation info */
468   obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
469   obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
470
471   /* The file offsets of the string table and symbol table.  */
472   obj_str_filepos (abfd) = N_STROFF (*execp);
473   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
474
475   /* Determine the architecture and machine type of the object file.  */
476   switch (N_MACHTYPE (*exec_hdr (abfd))) {
477   default:
478     abfd->obj_arch = bfd_arch_obscure;
479     break;
480   }
481
482   adata(abfd)->page_size = PAGE_SIZE;
483   adata(abfd)->segment_size = SEGMENT_SIZE;
484   adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
485
486   return abfd->xvec;
487
488   /* The architecture is encoded in various ways in various a.out variants,
489      or is not encoded at all in some of them.  The relocation size depends
490      on the architecture and the a.out variant.  Finally, the return value
491      is the bfd_target vector in use.  If an error occurs, return zero and
492      set bfd_error to the appropriate error code.
493
494      Formats such as b.out, which have additional fields in the a.out
495      header, should cope with them in this callback as well.  */
496 #endif                          /* DOCUMENTATION */
497
498   result = (*callback_to_real_object_p)(abfd);
499
500   /* Now that the segment addresses have been worked out, take a better
501      guess at whether the file is executable.  If the entry point
502      is within the text segment, assume it is.  (This makes files
503      executable even if their entry point address is 0, as long as
504      their text starts at zero.)
505
506      At some point we should probably break down and stat the file and
507      declare it executable if (one of) its 'x' bits are on...  */
508   if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
509       (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
510     abfd->flags |= EXEC_P;
511   if (result)
512     {
513 #if 0 /* These should be set correctly anyways.  */
514       abfd->sections = obj_textsec (abfd);
515       obj_textsec (abfd)->next = obj_datasec (abfd);
516       obj_datasec (abfd)->next = obj_bsssec (abfd);
517 #endif
518     }
519   else
520     {
521       free (rawptr);
522       abfd->tdata.aout_data = oldrawptr;
523     }
524   return result;
525 }
526
527 /*
528 FUNCTION
529         aout_@var{size}_mkobject
530
531 SYNOPSIS
532         boolean aout_@var{size}_mkobject, (bfd *abfd);
533
534 DESCRIPTION
535         Initialize BFD @var{abfd} for use with a.out files.
536 */
537
538 boolean
539 DEFUN(NAME(aout,mkobject),(abfd),
540      bfd *abfd)
541 {
542   struct aout_data_struct  *rawptr;
543
544   bfd_error = system_call_error;
545
546   /* Use an intermediate variable for clarity */
547   rawptr = (struct aout_data_struct *)bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
548
549   if (rawptr == NULL) {
550     bfd_error = no_memory;
551     return false;
552   }
553
554   abfd->tdata.aout_data = rawptr;
555   exec_hdr (abfd) = &(rawptr->e);
556
557   /* For simplicity's sake we just make all the sections right here. */
558
559   obj_textsec (abfd) = (asection *)NULL;
560   obj_datasec (abfd) = (asection *)NULL;
561   obj_bsssec (abfd) = (asection *)NULL;
562   bfd_make_section (abfd, ".text");
563   bfd_make_section (abfd, ".data");
564   bfd_make_section (abfd, ".bss");
565   bfd_make_section (abfd, BFD_ABS_SECTION_NAME);
566   bfd_make_section (abfd, BFD_UND_SECTION_NAME);
567   bfd_make_section (abfd, BFD_COM_SECTION_NAME);
568
569   return true;
570 }
571
572
573 /*
574 FUNCTION
575         aout_@var{size}_machine_type
576
577 SYNOPSIS
578         enum machine_type  aout_@var{size}_machine_type
579          (enum bfd_architecture arch,
580           unsigned long machine));
581
582 DESCRIPTION
583         Keep track of machine architecture and machine type for
584         a.out's. Return the <<machine_type>> for a particular
585         architecture and machine, or <<M_UNKNOWN>> if that exact architecture
586         and machine can't be represented in a.out format.
587
588         If the architecture is understood, machine type 0 (default)
589         is always understood.
590 */
591
592 enum machine_type
593 DEFUN(NAME(aout,machine_type),(arch, machine),
594       enum bfd_architecture arch AND
595       unsigned long machine)
596 {
597   enum machine_type arch_flags;
598
599   arch_flags = M_UNKNOWN;
600
601   switch (arch) {
602   case bfd_arch_sparc:
603     if (machine == 0)   arch_flags = M_SPARC;
604     break;
605
606   case bfd_arch_m68k:
607     switch (machine) {
608     case 0:             arch_flags = M_68010; break;
609     case 68000:         arch_flags = M_UNKNOWN; break;
610     case 68010:         arch_flags = M_68010; break;
611     case 68020:         arch_flags = M_68020; break;
612     default:            arch_flags = M_UNKNOWN; break;
613     }
614     break;
615
616   case bfd_arch_i386:
617     if (machine == 0)   arch_flags = M_386;
618     break;
619
620   case bfd_arch_a29k:
621     if (machine == 0)   arch_flags = M_29K;
622     break;
623
624   case bfd_arch_mips:
625     switch (machine) {
626     case 0:
627     case 2000:
628     case 3000:          arch_flags = M_MIPS1; break;
629     case 4000:
630     case 4400:
631     case 6000:          arch_flags = M_MIPS2; break;
632     default:            arch_flags = M_UNKNOWN; break;
633     }
634     break;
635
636   default:
637     arch_flags = M_UNKNOWN;
638   }
639   return arch_flags;
640 }
641
642
643 /*
644 FUNCTION
645         aout_@var{size}_set_arch_mach
646
647 SYNOPSIS
648         boolean aout_@var{size}_set_arch_mach,
649          (bfd *,
650           enum bfd_architecture arch,
651           unsigned long machine));
652
653 DESCRIPTION
654         Set the architecture and the machine of the BFD @var{abfd} to the
655         values @var{arch} and @var{machine}.  Verify that @var{abfd}'s format
656         can support the architecture required.
657 */
658
659 boolean
660 DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
661       bfd *abfd AND
662       enum bfd_architecture arch AND
663       unsigned long machine)
664 {
665   if (! bfd_default_set_arch_mach (abfd, arch, machine))
666     return false;
667
668   if (arch != bfd_arch_unknown &&
669       NAME(aout,machine_type) (arch, machine) == M_UNKNOWN)
670     return false;               /* We can't represent this type */
671
672   /* Determine the size of a relocation entry */
673   switch (arch) {
674   case bfd_arch_sparc:
675   case bfd_arch_a29k:
676   case bfd_arch_mips:
677     obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
678     break;
679   default:
680     obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
681     break;
682   }
683
684   return (*aout_backend_info(abfd)->set_sizes) (abfd);
685 }
686
687 static void
688 adjust_o_magic (abfd, execp)
689      bfd *abfd;
690      struct internal_exec *execp;
691 {
692   file_ptr pos = adata (abfd).exec_bytes_size;
693   bfd_vma vma = 0;
694   int pad = 0;
695
696   /* Text.  */
697   obj_textsec(abfd)->filepos = pos;
698   pos += obj_textsec(abfd)->_raw_size;
699   vma += obj_textsec(abfd)->_raw_size;
700
701   /* Data.  */
702   if (!obj_datasec(abfd)->user_set_vma)
703     {
704 #if 0       /* ?? Does alignment in the file image really matter? */
705       pad = align_power (vma, obj_datasec(abfd)->alignment_power) - vma;
706 #endif
707       obj_textsec(abfd)->_raw_size += pad;
708       pos += pad;
709       vma += pad;
710       obj_datasec(abfd)->vma = vma;
711     }
712   obj_datasec(abfd)->filepos = pos;
713   pos += obj_datasec(abfd)->_raw_size;
714   vma += obj_datasec(abfd)->_raw_size;
715
716   /* BSS.  */
717   if (!obj_bsssec(abfd)->user_set_vma)
718     {
719 #if 0
720       pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
721 #endif
722       obj_datasec(abfd)->_raw_size += pad;
723       pos += pad;
724       vma += pad;
725       obj_bsssec(abfd)->vma = vma;
726     }
727   obj_bsssec(abfd)->filepos = pos;
728
729   /* Fix up the exec header.  */
730   execp->a_text = obj_textsec(abfd)->_raw_size;
731   execp->a_data = obj_datasec(abfd)->_raw_size;
732   execp->a_bss = obj_bsssec(abfd)->_raw_size;
733   N_SET_MAGIC (*execp, OMAGIC);
734 }
735
736 static void
737 adjust_z_magic (abfd, execp)
738      bfd *abfd;
739      struct internal_exec *execp;
740 {
741   bfd_size_type data_pad, text_pad;
742   file_ptr text_end;
743   CONST struct aout_backend_data *abdp;
744   int ztih;                     /* Nonzero if text includes exec header.  */
745   
746   abdp = aout_backend_info (abfd);
747
748   /* Text.  */
749   ztih = abdp && abdp->text_includes_header;
750   obj_textsec(abfd)->filepos = (ztih
751                                 ? adata(abfd).exec_bytes_size
752                                 : adata(abfd).page_size);
753   if (! obj_textsec(abfd)->user_set_vma)
754     /* ?? Do we really need to check for relocs here?  */
755     obj_textsec(abfd)->vma = ((abfd->flags & HAS_RELOC)
756                               ? 0
757                               : (ztih
758                                  ? (abdp->default_text_vma
759                                     + adata(abfd).exec_bytes_size)
760                                  : abdp->default_text_vma));
761   /* Could take strange alignment of text section into account here?  */
762   
763   /* Find start of data.  */
764   text_end = obj_textsec(abfd)->filepos + obj_textsec(abfd)->_raw_size;
765   text_pad = BFD_ALIGN (text_end, adata(abfd).page_size) - text_end;
766   obj_textsec(abfd)->_raw_size += text_pad;
767   text_end += text_pad;
768
769   /* Data.  */
770   if (!obj_datasec(abfd)->user_set_vma)
771     {
772       bfd_vma vma;
773       vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size;
774       obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
775     }
776   if (abdp && abdp->zmagic_mapped_contiguous)
777     {
778       text_pad = (obj_datasec(abfd)->vma
779                   - obj_textsec(abfd)->vma
780                   - obj_textsec(abfd)->_raw_size);
781       obj_textsec(abfd)->_raw_size += text_pad;
782     }
783   obj_datasec(abfd)->filepos = (obj_textsec(abfd)->filepos
784                                 + obj_textsec(abfd)->_raw_size);
785   
786   /* Fix up exec header while we're at it.  */
787   execp->a_text = obj_textsec(abfd)->_raw_size;
788   if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
789     execp->a_text += adata(abfd).exec_bytes_size;
790   N_SET_MAGIC (*execp, ZMAGIC);
791
792   /* Spec says data section should be rounded up to page boundary.  */
793   obj_datasec(abfd)->_raw_size
794     = align_power (obj_datasec(abfd)->_raw_size,
795                    obj_bsssec(abfd)->alignment_power);
796   execp->a_data = BFD_ALIGN (obj_datasec(abfd)->_raw_size,
797                              adata(abfd).page_size);
798   data_pad = execp->a_data - obj_datasec(abfd)->_raw_size;
799
800   /* BSS.  */
801   if (!obj_bsssec(abfd)->user_set_vma)
802     obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
803                              + obj_datasec(abfd)->_raw_size);
804   /* If the BSS immediately follows the data section and extra space
805      in the page is left after the data section, fudge data
806      in the header so that the bss section looks smaller by that
807      amount.  We'll start the bss section there, and lie to the OS.
808      (Note that a linker script, as well as the above assignment,
809      could have explicitly set the BSS vma to immediately follow
810      the data section.)  */
811   if (align_power (obj_bsssec(abfd)->vma, obj_bsssec(abfd)->alignment_power)
812       == obj_datasec(abfd)->vma + obj_datasec(abfd)->_raw_size)
813     execp->a_bss = (data_pad > obj_bsssec(abfd)->_raw_size) ? 0 :
814       obj_bsssec(abfd)->_raw_size - data_pad;
815   else
816     execp->a_bss = obj_bsssec(abfd)->_raw_size;
817 }
818
819 static void
820 adjust_n_magic (abfd, execp)
821      bfd *abfd;
822      struct internal_exec *execp;
823 {
824   file_ptr pos = adata(abfd).exec_bytes_size;
825   bfd_vma vma = 0;
826   int pad;
827   
828   /* Text.  */
829   obj_textsec(abfd)->filepos = pos;
830   if (!obj_textsec(abfd)->user_set_vma)
831     obj_textsec(abfd)->vma = vma;
832   else
833     vma = obj_textsec(abfd)->vma;
834   pos += obj_textsec(abfd)->_raw_size;
835   vma += obj_textsec(abfd)->_raw_size;
836
837   /* Data.  */
838   obj_datasec(abfd)->filepos = pos;
839   if (!obj_datasec(abfd)->user_set_vma)
840     obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
841   vma = obj_datasec(abfd)->vma;
842   
843   /* Since BSS follows data immediately, see if it needs alignment.  */
844   vma += obj_datasec(abfd)->_raw_size;
845   pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
846   obj_datasec(abfd)->_raw_size += pad;
847   pos += obj_datasec(abfd)->_raw_size;
848
849   /* BSS.  */
850   if (!obj_bsssec(abfd)->user_set_vma)
851     obj_bsssec(abfd)->vma = vma;
852   else
853     vma = obj_bsssec(abfd)->vma;
854
855   /* Fix up exec header.  */
856   execp->a_text = obj_textsec(abfd)->_raw_size;
857   execp->a_data = obj_datasec(abfd)->_raw_size;
858   execp->a_bss = obj_bsssec(abfd)->_raw_size;
859   N_SET_MAGIC (*execp, NMAGIC);
860 }
861
862 boolean
863 DEFUN (NAME(aout,adjust_sizes_and_vmas), (abfd, text_size, text_end),
864        bfd *abfd AND bfd_size_type *text_size AND file_ptr *text_end)
865 {
866   struct internal_exec *execp = exec_hdr (abfd);
867
868   if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL))
869     {
870       bfd_error = invalid_operation;
871       return false;
872     }
873   if (adata(abfd).magic != undecided_magic) return true;
874
875   obj_textsec(abfd)->_raw_size =
876     align_power(obj_textsec(abfd)->_raw_size,
877                 obj_textsec(abfd)->alignment_power);
878
879   *text_size = obj_textsec (abfd)->_raw_size;
880   /* Rule (heuristic) for when to pad to a new page.  Note that there
881      are (at least) two ways demand-paged (ZMAGIC) files have been
882      handled.  Most Berkeley-based systems start the text segment at
883      (PAGE_SIZE).  However, newer versions of SUNOS start the text
884      segment right after the exec header; the latter is counted in the
885      text segment size, and is paged in by the kernel with the rest of
886      the text. */
887
888   /* This perhaps isn't the right way to do this, but made it simpler for me
889      to understand enough to implement it.  Better would probably be to go
890      right from BFD flags to alignment/positioning characteristics.  But the
891      old code was sloppy enough about handling the flags, and had enough
892      other magic, that it was a little hard for me to understand.  I think
893      I understand it better now, but I haven't time to do the cleanup this
894      minute.  */
895
896   if (abfd->flags & D_PAGED)
897     /* Whether or not WP_TEXT is set -- let D_PAGED override.  */
898     /* @@ What about QMAGIC?  */
899     adata(abfd).magic = z_magic;
900   else if (abfd->flags & WP_TEXT)
901     adata(abfd).magic = n_magic;
902   else
903     adata(abfd).magic = o_magic;
904
905 #ifdef BFD_AOUT_DEBUG /* requires gcc2 */
906 #if __GNUC__ >= 2
907   fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
908            ({ char *str;
909               switch (adata(abfd).magic) {
910               case n_magic: str = "NMAGIC"; break;
911               case o_magic: str = "OMAGIC"; break;
912               case z_magic: str = "ZMAGIC"; break;
913               default: abort ();
914               }
915               str;
916             }),
917            obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size,
918                 obj_textsec(abfd)->alignment_power,
919            obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size,
920                 obj_datasec(abfd)->alignment_power,
921            obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size,
922                 obj_bsssec(abfd)->alignment_power);
923 #endif
924 #endif
925
926   switch (adata(abfd).magic)
927     {
928     case o_magic:
929       adjust_o_magic (abfd, execp);
930       break;
931     case z_magic:
932       adjust_z_magic (abfd, execp);
933       break;
934     case n_magic:
935       adjust_n_magic (abfd, execp);
936       break;
937     default:
938       abort ();
939     }
940
941 #ifdef BFD_AOUT_DEBUG
942   fprintf (stderr, "       text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
943            obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size,
944                 obj_textsec(abfd)->filepos,
945            obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size,
946                 obj_datasec(abfd)->filepos,
947            obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size);
948 #endif
949
950   return true;
951 }
952
953 /*
954 FUNCTION
955         aout_@var{size}_new_section_hook
956
957 SYNOPSIS
958         boolean aout_@var{size}_new_section_hook,
959            (bfd *abfd,
960             asection *newsect));
961
962 DESCRIPTION
963         Called by the BFD in response to a @code{bfd_make_section}
964         request.
965 */
966 boolean
967 DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
968         bfd *abfd AND
969         asection *newsect)
970 {
971   /* align to double at least */
972   newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
973
974
975   if (bfd_get_format (abfd) == bfd_object)
976   {
977     if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
978         obj_textsec(abfd)= newsect;
979         newsect->target_index = N_TEXT | N_EXT;
980         return true;
981       }
982
983     if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
984         obj_datasec(abfd) = newsect;
985         newsect->target_index = N_DATA | N_EXT;
986         return true;
987       }
988
989     if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
990         obj_bsssec(abfd) = newsect;
991         newsect->target_index = N_BSS | N_EXT;
992         return true;
993       }
994
995   }
996
997   /* We allow more than three sections internally */
998   return true;
999 }
1000
1001 boolean
1002 DEFUN(NAME(aout,set_section_contents),(abfd, section, location, offset, count),
1003       bfd *abfd AND
1004       sec_ptr section AND
1005       PTR location AND
1006       file_ptr offset AND
1007       bfd_size_type count)
1008 {
1009   file_ptr text_end;
1010   bfd_size_type text_size;
1011
1012   if (abfd->output_has_begun == false)
1013       {
1014         if (NAME(aout,adjust_sizes_and_vmas) (abfd,
1015                                               &text_size,
1016                                               &text_end) == false)
1017           return false;
1018       }
1019
1020   /* regardless, once we know what we're doing, we might as well get going */
1021   if (section != obj_bsssec(abfd))
1022       {
1023         bfd_seek (abfd, section->filepos + offset, SEEK_SET);
1024
1025         if (count) {
1026           return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
1027             true : false;
1028         }
1029         return true;
1030       }
1031   return true;
1032 }
1033 \f
1034 /* Classify stabs symbols */
1035
1036 #define sym_in_text_section(sym) \
1037   (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
1038
1039 #define sym_in_data_section(sym) \
1040   (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
1041
1042 #define sym_in_bss_section(sym) \
1043   (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
1044
1045 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
1046   zero in the "value" field.  Nonzeroes there are fortrancommon
1047   symbols.  */
1048 #define sym_is_undefined(sym) \
1049   ((sym)->type == (N_UNDF | N_EXT) && (sym)->symbol.value == 0)
1050
1051 /* Symbol is a global definition if N_EXT is on and if it has
1052   a nonzero type field.  */
1053 #define sym_is_global_defn(sym) \
1054   (((sym)->type & N_EXT) && (sym)->type & N_TYPE)
1055
1056 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
1057   are on.  */
1058 #define sym_is_debugger_info(sym) \
1059   (((sym)->type & ~(N_EXT | N_TYPE)) || (sym)->type == N_FN)
1060
1061 #define sym_is_fortrancommon(sym)       \
1062   (((sym)->type == (N_EXT)) && (sym)->symbol.value != 0)
1063
1064 /* Symbol is absolute if it has N_ABS set */
1065 #define sym_is_absolute(sym) \
1066   (((sym)->type  & N_TYPE)== N_ABS)
1067
1068
1069 #define sym_is_indirect(sym) \
1070   (((sym)->type & N_ABS)== N_ABS)
1071
1072 /* Only in their own functions for ease of debugging; when sym flags have
1073   stabilised these should be inlined into their (single) caller */
1074
1075 static void
1076 DEFUN (translate_from_native_sym_flags, (sym_pointer, cache_ptr, abfd),
1077        struct external_nlist *sym_pointer AND
1078        aout_symbol_type * cache_ptr AND
1079        bfd * abfd)
1080 {
1081   cache_ptr->symbol.section = 0;
1082   switch (cache_ptr->type & N_TYPE)
1083     {
1084     case N_SETA:
1085     case N_SETT:
1086     case N_SETD:
1087     case N_SETB:
1088       {
1089         char *copy = bfd_alloc (abfd, strlen (cache_ptr->symbol.name) + 1);
1090         asection *section;
1091         asection *into_section;
1092
1093         arelent_chain *reloc = (arelent_chain *) bfd_alloc (abfd, sizeof (arelent_chain));
1094         strcpy (copy, cache_ptr->symbol.name);
1095
1096         /* Make sure that this bfd has a section with the right contructor
1097            name */
1098         section = bfd_get_section_by_name (abfd, copy);
1099         if (!section)
1100           section = bfd_make_section (abfd, copy);
1101
1102         /* Build a relocation entry for the constructor */
1103         switch ((cache_ptr->type & N_TYPE))
1104           {
1105           case N_SETA:
1106             into_section = &bfd_abs_section;
1107             cache_ptr->type = N_ABS;
1108             break;
1109           case N_SETT:
1110             into_section = (asection *) obj_textsec (abfd);
1111             cache_ptr->type = N_TEXT;
1112             break;
1113           case N_SETD:
1114             into_section = (asection *) obj_datasec (abfd);
1115             cache_ptr->type = N_DATA;
1116             break;
1117           case N_SETB:
1118             into_section = (asection *) obj_bsssec (abfd);
1119             cache_ptr->type = N_BSS;
1120             break;
1121           default:
1122             abort ();
1123           }
1124
1125         /* Build a relocation pointing into the constuctor section
1126            pointing at the symbol in the set vector specified */
1127
1128         reloc->relent.addend = cache_ptr->symbol.value;
1129         cache_ptr->symbol.section = into_section->symbol->section;
1130         reloc->relent.sym_ptr_ptr = into_section->symbol_ptr_ptr;
1131
1132
1133         /* We modify the symbol to belong to a section depending upon the
1134            name of the symbol - probably __CTOR__ or __DTOR__ but we don't
1135            really care, and add to the size of the section to contain a
1136            pointer to the symbol. Build a reloc entry to relocate to this
1137            symbol attached to this section.  */
1138
1139         section->flags = SEC_CONSTRUCTOR;
1140
1141
1142         section->reloc_count++;
1143         section->alignment_power = 2;
1144
1145         reloc->next = section->constructor_chain;
1146         section->constructor_chain = reloc;
1147         reloc->relent.address = section->_raw_size;
1148         section->_raw_size += sizeof (int *);
1149
1150         reloc->relent.howto
1151           = (obj_reloc_entry_size(abfd) == RELOC_EXT_SIZE
1152              ? howto_table_ext : howto_table_std)
1153             + CTOR_TABLE_RELOC_IDX;
1154         cache_ptr->symbol.flags |= BSF_CONSTRUCTOR;
1155       }
1156       break;
1157     default:
1158       if (cache_ptr->type == N_WARNING)
1159         {
1160           /* This symbol is the text of a warning message, the next symbol
1161              is the symbol to associate the warning with */
1162           cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
1163
1164           /* @@ Stuffing pointers into integers is a no-no.
1165              We can usually get away with it if the integer is
1166              large enough though.  */
1167           if (sizeof (cache_ptr + 1) > sizeof (bfd_vma))
1168             abort ();
1169           cache_ptr->symbol.value = (bfd_vma) ((cache_ptr + 1));
1170
1171           /* We furgle with the next symbol in place.
1172              We don't want it to be undefined, we'll trample the type */
1173           (sym_pointer + 1)->e_type[0] = 0xff;
1174           break;
1175         }
1176       if ((cache_ptr->type | N_EXT) == (N_INDR | N_EXT))
1177         {
1178           /* Two symbols in a row for an INDR message. The first symbol
1179              contains the name we will match, the second symbol contains
1180              the name the first name is translated into. It is supplied to
1181              us undefined. This is good, since we want to pull in any files
1182              which define it */
1183           cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT;
1184
1185           /* @@ Stuffing pointers into integers is a no-no.
1186              We can usually get away with it if the integer is
1187              large enough though.  */
1188           if (sizeof (cache_ptr + 1) > sizeof (bfd_vma))
1189             abort ();
1190
1191           cache_ptr->symbol.value = (bfd_vma) ((cache_ptr + 1));
1192           cache_ptr->symbol.section = &bfd_ind_section;
1193         }
1194
1195       else if (sym_is_debugger_info (cache_ptr))
1196         {
1197           cache_ptr->symbol.flags = BSF_DEBUGGING;
1198           /* Work out the section correct for this symbol */
1199           switch (cache_ptr->type & N_TYPE)
1200             {
1201             case N_TEXT:
1202             case N_FN:
1203               cache_ptr->symbol.section = obj_textsec (abfd);
1204               cache_ptr->symbol.value -= obj_textsec (abfd)->vma;
1205               break;
1206             case N_DATA:
1207               cache_ptr->symbol.value -= obj_datasec (abfd)->vma;
1208               cache_ptr->symbol.section = obj_datasec (abfd);
1209               break;
1210             case N_BSS:
1211               cache_ptr->symbol.section = obj_bsssec (abfd);
1212               cache_ptr->symbol.value -= obj_bsssec (abfd)->vma;
1213               break;
1214             default:
1215             case N_ABS:
1216               cache_ptr->symbol.section = &bfd_abs_section;
1217               break;
1218             }
1219         }
1220       else
1221         {
1222
1223           if (sym_is_fortrancommon (cache_ptr))
1224             {
1225               cache_ptr->symbol.flags = 0;
1226               cache_ptr->symbol.section = &bfd_com_section;
1227             }
1228           else
1229             {
1230
1231
1232             }
1233
1234           /* In a.out, the value of a symbol is always relative to the
1235            * start of the file, if this is a data symbol we'll subtract
1236            * the size of the text section to get the section relative
1237            * value. If this is a bss symbol (which would be strange)
1238            * we'll subtract the size of the previous two sections
1239            * to find the section relative address.
1240            */
1241
1242           if (sym_in_text_section (cache_ptr))
1243             {
1244               cache_ptr->symbol.value -= obj_textsec (abfd)->vma;
1245               cache_ptr->symbol.section = obj_textsec (abfd);
1246             }
1247           else if (sym_in_data_section (cache_ptr))
1248             {
1249               cache_ptr->symbol.value -= obj_datasec (abfd)->vma;
1250               cache_ptr->symbol.section = obj_datasec (abfd);
1251             }
1252           else if (sym_in_bss_section (cache_ptr))
1253             {
1254               cache_ptr->symbol.section = obj_bsssec (abfd);
1255               cache_ptr->symbol.value -= obj_bsssec (abfd)->vma;
1256             }
1257           else if (sym_is_undefined (cache_ptr))
1258             {
1259               cache_ptr->symbol.flags = 0;
1260               cache_ptr->symbol.section = &bfd_und_section;
1261             }
1262           else if (sym_is_absolute (cache_ptr))
1263             {
1264               cache_ptr->symbol.section = &bfd_abs_section;
1265             }
1266
1267           if (sym_is_global_defn (cache_ptr))
1268             {
1269               cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1270             }
1271           else
1272             {
1273               cache_ptr->symbol.flags = BSF_LOCAL;
1274             }
1275         }
1276     }
1277   if (cache_ptr->symbol.section == 0)
1278     abort ();
1279 }
1280
1281
1282
1283 static boolean
1284 DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
1285      struct external_nlist *sym_pointer AND
1286      asymbol *cache_ptr AND
1287      bfd *abfd)
1288 {
1289   bfd_vma value = cache_ptr->value;
1290
1291   /* mask out any existing type bits in case copying from one section
1292      to another */
1293   sym_pointer->e_type[0] &= ~N_TYPE;
1294
1295   /* We attempt to order these tests by decreasing frequency of success,
1296      according to tcov when linking the linker.  */
1297   if (bfd_get_output_section(cache_ptr) == &bfd_abs_section) {
1298     sym_pointer->e_type[0] |= N_ABS;
1299   }
1300   else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
1301     sym_pointer->e_type[0] |= N_TEXT;
1302   }
1303   else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
1304     sym_pointer->e_type[0] |= N_DATA;
1305   }
1306   else if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
1307     sym_pointer->e_type[0] |= N_BSS;
1308   }
1309   else if (bfd_get_output_section(cache_ptr) == &bfd_und_section) {
1310     sym_pointer->e_type[0] = (N_UNDF | N_EXT);
1311   }
1312   else if (bfd_get_output_section(cache_ptr) == &bfd_ind_section) {
1313     sym_pointer->e_type[0] = N_INDR;
1314   }
1315   else if (bfd_get_output_section(cache_ptr) == NULL) {
1316     /* Protect the bfd_is_com_section call.
1317        This case occurs, e.g., for the *DEBUG* section of a COFF file.  */
1318     bfd_error = bfd_error_nonrepresentable_section;
1319     return false;
1320   }
1321   else if (bfd_is_com_section (bfd_get_output_section (cache_ptr))) {
1322     sym_pointer->e_type[0] = (N_UNDF | N_EXT);
1323   }
1324   else {
1325     bfd_error = bfd_error_nonrepresentable_section;
1326     return false;
1327   }
1328
1329   /* Turn the symbol from section relative to absolute again */
1330
1331   value +=  cache_ptr->section->output_section->vma  + cache_ptr->section->output_offset ;
1332
1333
1334   if (cache_ptr->flags & (BSF_WARNING)) {
1335     (sym_pointer+1)->e_type[0] = 1;
1336   }
1337
1338   if (cache_ptr->flags & BSF_DEBUGGING) {
1339     sym_pointer->e_type[0] = ((aout_symbol_type *)cache_ptr)->type;
1340   }
1341   else if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
1342     sym_pointer->e_type[0] |= N_EXT;
1343   }
1344   if (cache_ptr->flags & BSF_CONSTRUCTOR) {
1345     int type = ((aout_symbol_type *)cache_ptr)->type;
1346     switch (type)
1347       {
1348       case N_ABS:       type = N_SETA; break;
1349       case N_TEXT:      type = N_SETT; break;
1350       case N_DATA:      type = N_SETD; break;
1351       case N_BSS:       type = N_SETB; break;
1352       }
1353     sym_pointer->e_type[0] = type;
1354   }
1355
1356   PUT_WORD(abfd, value, sym_pointer->e_value);
1357
1358   return true;
1359 }
1360 \f
1361 /* Native-level interface to symbols. */
1362
1363 /* We read the symbols into a buffer, which is discarded when this
1364 function exits.  We read the strings into a buffer large enough to
1365 hold them all plus all the cached symbol entries. */
1366
1367 asymbol *
1368 DEFUN(NAME(aout,make_empty_symbol),(abfd),
1369       bfd *abfd)
1370 {
1371   aout_symbol_type  *new =
1372     (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1373   new->symbol.the_bfd = abfd;
1374
1375   return &new->symbol;
1376 }
1377
1378 boolean
1379 DEFUN(NAME(aout,slurp_symbol_table),(abfd),
1380       bfd *abfd)
1381 {
1382   bfd_size_type symbol_size;
1383   bfd_size_type string_size;
1384   unsigned char string_chars[BYTES_IN_WORD];
1385   struct external_nlist *syms;
1386   char *strings;
1387   aout_symbol_type *cached;
1388
1389   /* If there's no work to be done, don't do any */
1390   if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1391   symbol_size = exec_hdr(abfd)->a_syms;
1392   if (symbol_size == 0)
1393     {
1394       bfd_error = no_symbols;
1395       return false;
1396     }
1397
1398   bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1399   if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD)
1400     return false;
1401   string_size = GET_WORD (abfd, string_chars);
1402
1403   strings =(char *) bfd_alloc(abfd, string_size + 1);
1404   cached = (aout_symbol_type *)
1405     bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type)));
1406
1407   /* malloc this, so we can free it if simply. The symbol caching
1408      might want to allocate onto the bfd's obstack  */
1409   syms = (struct external_nlist *) bfd_xmalloc(symbol_size);
1410   bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
1411   if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size)
1412     {
1413     bailout:
1414       if (syms)
1415         free (syms);
1416       if (cached)
1417         bfd_release (abfd, cached);
1418       if (strings)
1419         bfd_release (abfd, strings);
1420       return false;
1421     }
1422
1423   bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1424   if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size)
1425     {
1426       goto bailout;
1427     }
1428   strings[string_size] = 0; /* Just in case. */
1429
1430   /* OK, now walk the new symtable, cacheing symbol properties */
1431   {
1432     register struct external_nlist *sym_pointer;
1433     register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd);
1434     register aout_symbol_type *cache_ptr = cached;
1435
1436     /* Run through table and copy values */
1437     for (sym_pointer = syms, cache_ptr = cached;
1438          sym_pointer < sym_end; sym_pointer ++, cache_ptr++)
1439       {
1440         long x = GET_WORD(abfd, sym_pointer->e_strx);
1441         cache_ptr->symbol.the_bfd = abfd;
1442         if (x == 0)
1443           cache_ptr->symbol.name = "";
1444         else if (x >= 0 && x < string_size)
1445           cache_ptr->symbol.name = x + strings;
1446         else
1447           goto bailout;
1448
1449         cache_ptr->symbol.value = GET_SWORD(abfd,  sym_pointer->e_value);
1450         cache_ptr->desc = bfd_h_get_16(abfd, sym_pointer->e_desc);
1451         cache_ptr->other = bfd_h_get_8(abfd, sym_pointer->e_other);
1452         cache_ptr->type = bfd_h_get_8(abfd,  sym_pointer->e_type);
1453         cache_ptr->symbol.udata = 0;
1454         translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1455       }
1456   }
1457
1458   obj_aout_symbols (abfd) =  cached;
1459   free((PTR)syms);
1460
1461   return true;
1462 }
1463
1464 \f
1465 /* Possible improvements:
1466    + look for strings matching trailing substrings of other strings
1467    + better data structures?  balanced trees?
1468    + smaller per-string or per-symbol data?  re-use some of the symbol's
1469      data fields?
1470    + also look at reducing memory use elsewhere -- maybe if we didn't have to
1471      construct the entire symbol table at once, we could get by with smaller
1472      amounts of VM?  (What effect does that have on the string table
1473      reductions?)
1474    + rip this out of here, put it into its own file in bfd or libiberty, so
1475      coff and elf can use it too.  I'll work on this soon, but have more
1476      pressing tasks right now.
1477
1478    A hash table might(?) be more efficient for handling exactly the cases that
1479    are handled now, but for trailing substring matches, I think we want to
1480    examine the `nearest' values (reverse-)lexically, not merely impose a strict
1481    order, nor look only for exact-match or not-match.  I don't think a hash
1482    table would be very useful for that, and I don't feel like fleshing out two
1483    completely different implementations.  [raeburn:930419.0331EDT] */
1484
1485 struct stringtab_entry {
1486   /* Hash value for this string.  Only useful so long as we aren't doing
1487      substring matches.  */
1488   unsigned int hash;
1489
1490   /* Next node to look at, depending on whether the hash value of the string
1491      being searched for is less than or greater than the hash value of the
1492      current node.  For now, `equal to' is lumped in with `greater than', for
1493      space efficiency.  It's not a common enough case to warrant another field
1494      to be used for all nodes.  */
1495   struct stringtab_entry *less;
1496   struct stringtab_entry *greater;
1497
1498   /* The string itself.  */
1499   CONST char *string;
1500
1501   /* The index allocated for this string.  */
1502   bfd_size_type index;
1503
1504 #ifdef GATHER_STATISTICS
1505   /* How many references have there been to this string?  (Not currently used;
1506      could be dumped out for anaylsis, if anyone's interested.)  */
1507   unsigned long count;
1508 #endif
1509
1510   /* Next node in linked list, in suggested output order.  */
1511   struct stringtab_entry *next_to_output;
1512 };
1513
1514 struct stringtab_data {
1515   /* Tree of string table entries.  */
1516   struct stringtab_entry *strings;
1517
1518   /* Fudge factor used to center top node of tree.  */
1519   int hash_zero;
1520
1521   /* Next index value to issue.  */
1522   bfd_size_type index;
1523
1524   /* Index used for empty strings.  Cached here because checking for them
1525      is really easy, and we can avoid searching the tree.  */
1526   bfd_size_type empty_string_index;
1527
1528   /* These fields indicate the two ends of a singly-linked list that indicates
1529      the order strings should be written out in.  Use this order, and no
1530      seeking will need to be done, so output efficiency should be maximized. */
1531   struct stringtab_entry **end;
1532   struct stringtab_entry *output_order;
1533
1534 #ifdef GATHER_STATISTICS
1535   /* Number of strings which duplicate strings already in the table.  */
1536   unsigned long duplicates;
1537
1538   /* Number of bytes saved by not having to write all the duplicate strings. */
1539   unsigned long bytes_saved;
1540
1541   /* Number of zero-length strings.  Currently, these all turn into
1542      references to the null byte at the end of the first string.  In some
1543      cases (possibly not all?  explore this...), it should be possible to
1544      simply write out a zero index value.  */
1545   unsigned long empty_strings;
1546
1547   /* Number of times the hash values matched but the strings were different.
1548      Note that this includes the number of times the other string(s) occurs, so
1549      there may only be two strings hashing to the same value, even if this
1550      number is very large.  */
1551   unsigned long bad_hash_matches;
1552
1553   /* Null strings aren't counted in this one.
1554      This will probably only be nonzero if we've got an input file
1555      which was produced by `ld -r' (i.e., it's already been processed
1556      through this code).  Under some operating systems, native tools
1557      may make all empty strings have the same index; but the pointer
1558      check won't catch those, because to get to that stage we'd already
1559      have to compute the checksum, which requires reading the string,
1560      so we short-circuit that case with empty_string_index above.  */
1561   unsigned long pointer_matches;
1562
1563   /* Number of comparisons done.  I figure with the algorithms in use below,
1564      the average number of comparisons done (per symbol) should be roughly
1565      log-base-2 of the number of unique strings.  */
1566   unsigned long n_compares;
1567 #endif
1568 };
1569
1570 /* Some utility functions for the string table code.  */
1571
1572 /* For speed, only hash on the first this many bytes of strings.
1573    This number was chosen by profiling ld linking itself, with -g.  */
1574 #define HASHMAXLEN 25
1575
1576 #define HASH_CHAR(c) (sum ^= sum >> 20, sum ^= sum << 7, sum += (c))
1577
1578 static INLINE unsigned int
1579 hash (string, len)
1580      unsigned char *string;
1581      register unsigned int len;
1582 {
1583   register unsigned int sum = 0;
1584
1585   if (len > HASHMAXLEN)
1586     {
1587       HASH_CHAR (len);
1588       len = HASHMAXLEN;
1589     }
1590
1591   while (len--)
1592     {
1593       HASH_CHAR (*string++);
1594     }
1595   return sum;
1596 }
1597
1598 static INLINE void
1599 stringtab_init (tab)
1600      struct stringtab_data *tab;
1601 {
1602   tab->strings = 0;
1603   tab->output_order = 0;
1604   tab->hash_zero = 0;
1605   tab->end = &tab->output_order;
1606
1607   /* Initial string table length includes size of length field.  */
1608   tab->index = BYTES_IN_WORD;
1609   tab->empty_string_index = -1;
1610 #ifdef GATHER_STATISTICS
1611   tab->duplicates = 0;
1612   tab->empty_strings = 0;
1613   tab->bad_hash_matches = 0;
1614   tab->pointer_matches = 0;
1615   tab->bytes_saved = 0;
1616   tab->n_compares = 0;
1617 #endif
1618 }
1619
1620 static INLINE int
1621 compare (entry, str, hash)
1622      struct stringtab_entry *entry;
1623      CONST char *str;
1624      unsigned int hash;
1625 {
1626   return hash - entry->hash;
1627 }
1628
1629 #ifdef GATHER_STATISTICS
1630 /* Don't want to have to link in math library with all bfd applications...  */
1631 static INLINE double
1632 log2 (num)
1633      int num;
1634 {
1635   double d = num;
1636   int n = 0;
1637   while (d >= 2.0)
1638     n++, d /= 2.0;
1639   return ((d > 1.41) ? 0.5 : 0) + n;
1640 }
1641 #endif
1642
1643 /* Main string table routines.  */
1644 /* Returns index in string table.  Whether or not this actually adds an
1645    entry into the string table should be irrelevant -- it just has to
1646    return a valid index.  */
1647 static bfd_size_type
1648 add_to_stringtab (abfd, str, tab)
1649      bfd *abfd;
1650      CONST char *str;
1651      struct stringtab_data *tab;
1652 {
1653   struct stringtab_entry **ep;
1654   register struct stringtab_entry *entry;
1655   unsigned int hashval, len;
1656
1657   if (str[0] == 0)
1658     {
1659       bfd_size_type index;
1660       CONST bfd_size_type minus_one = -1;
1661
1662 #ifdef GATHER_STATISTICS
1663       tab->empty_strings++;
1664 #endif
1665       index = tab->empty_string_index;
1666       if (index != minus_one)
1667         {
1668         got_empty:
1669 #ifdef GATHER_STATISTICS
1670           tab->bytes_saved++;
1671           tab->duplicates++;
1672 #endif
1673           return index;
1674         }
1675
1676       /* Need to find it.  */
1677       entry = tab->strings;
1678       if (entry)
1679         {
1680           index = entry->index + strlen (entry->string);
1681           tab->empty_string_index = index;
1682           goto got_empty;
1683         }
1684       len = 0;
1685     }
1686   else
1687     len = strlen (str);
1688
1689   /* The hash_zero value is chosen such that the first symbol gets a value of
1690      zero.  With a balanced tree, this wouldn't be very useful, but without it,
1691      we might get a more even split at the top level, instead of skewing it
1692      badly should hash("/usr/lib/crt0.o") (or whatever) be far from zero. */
1693   hashval = hash (str, len) ^ tab->hash_zero;
1694   ep = &tab->strings;
1695   if (!*ep)
1696     {
1697       tab->hash_zero = hashval;
1698       hashval = 0;
1699       goto add_it;
1700     }
1701
1702   while (*ep)
1703     {
1704       register int cmp;
1705
1706       entry = *ep;
1707 #ifdef GATHER_STATISTICS
1708       tab->n_compares++;
1709 #endif
1710       cmp = compare (entry, str, hashval);
1711       /* The not-equal cases are more frequent, so check them first.  */
1712       if (cmp > 0)
1713         ep = &entry->greater;
1714       else if (cmp < 0)
1715         ep = &entry->less;
1716       else
1717         {
1718           if (entry->string == str)
1719             {
1720 #ifdef GATHER_STATISTICS
1721               tab->pointer_matches++;
1722 #endif
1723               goto match;
1724             }
1725           /* Compare the first bytes to save a function call if they
1726              don't match.  */
1727           if (entry->string[0] == str[0] && !strcmp (entry->string, str))
1728             {
1729             match:
1730 #ifdef GATHER_STATISTICS
1731               entry->count++;
1732               tab->bytes_saved += len + 1;
1733               tab->duplicates++;
1734 #endif
1735               /* If we're in the linker, and the new string is from a new
1736                  input file which might have already had these reductions
1737                  run over it, we want to keep the new string pointer.  I
1738                  don't think we're likely to see any (or nearly as many,
1739                  at least) cases where a later string is in the same location
1740                  as an earlier one rather than this one.  */
1741               entry->string = str;
1742               return entry->index;
1743             }
1744 #ifdef GATHER_STATISTICS
1745           tab->bad_hash_matches++;
1746 #endif
1747           ep = &entry->greater;
1748         }
1749     }
1750
1751   /* If we get here, nothing that's in the table already matched.
1752      EP points to the `next' field at the end of the chain; stick a
1753      new entry on here.  */
1754  add_it:
1755   entry = (struct stringtab_entry *)
1756     bfd_alloc_by_size_t (abfd, sizeof (struct stringtab_entry));
1757
1758   entry->less = entry->greater = 0;
1759   entry->hash = hashval;
1760   entry->index = tab->index;
1761   entry->string = str;
1762   entry->next_to_output = 0;
1763 #ifdef GATHER_STATISTICS
1764   entry->count = 1;
1765 #endif
1766
1767   assert (*tab->end == 0);
1768   *(tab->end) = entry;
1769   tab->end = &entry->next_to_output;
1770   assert (*tab->end == 0);
1771
1772   {
1773     tab->index += len + 1;
1774     if (len == 0)
1775       tab->empty_string_index = entry->index;
1776   }
1777   assert (*ep == 0);
1778   *ep = entry;
1779   return entry->index;
1780 }
1781
1782 static void
1783 emit_strtab (abfd, tab)
1784      bfd *abfd;
1785      struct stringtab_data *tab;
1786 {
1787   struct stringtab_entry *entry;
1788 #ifdef GATHER_STATISTICS
1789   int count = 0;
1790 #endif
1791
1792   /* Be sure to put string length into correct byte ordering before writing
1793      it out.  */
1794   char buffer[BYTES_IN_WORD];
1795
1796   PUT_WORD (abfd, tab->index, (unsigned char *) buffer);
1797   bfd_write ((PTR) buffer, 1, BYTES_IN_WORD, abfd);
1798
1799   for (entry = tab->output_order; entry; entry = entry->next_to_output)
1800     {
1801       bfd_write ((PTR) entry->string, 1, strlen (entry->string) + 1, abfd);
1802 #ifdef GATHER_STATISTICS
1803       count++;
1804 #endif
1805     }
1806
1807 #ifdef GATHER_STATISTICS
1808   /* Short form only, for now.
1809      To do:  Specify output file.  Conditionalize on environment?  Detailed
1810      analysis if desired.  */
1811   {
1812     int n_syms = bfd_get_symcount (abfd);
1813
1814     fprintf (stderr, "String table data for output file:\n");
1815     fprintf (stderr, "  %8d symbols output\n", n_syms);
1816     fprintf (stderr, "  %8d duplicate strings\n", tab->duplicates);
1817     fprintf (stderr, "  %8d empty strings\n", tab->empty_strings);
1818     fprintf (stderr, "  %8d unique strings output\n", count);
1819     fprintf (stderr, "  %8d pointer matches\n", tab->pointer_matches);
1820     fprintf (stderr, "  %8d bytes saved\n", tab->bytes_saved);
1821     fprintf (stderr, "  %8d bad hash matches\n", tab->bad_hash_matches);
1822     fprintf (stderr, "  %8d hash-val comparisons\n", tab->n_compares);
1823     if (n_syms)
1824       {
1825         double n_compares = tab->n_compares;
1826         double avg_compares = n_compares / n_syms;
1827         /* The second value here should usually be near one.  */
1828         fprintf (stderr,
1829                  "\t    average %f comparisons per symbol (%f * log2 nstrings)\n",
1830                  avg_compares, avg_compares / log2 (count));
1831       }
1832   }
1833 #endif
1834
1835 /* Old code:
1836   unsigned int count;
1837   generic = bfd_get_outsymbols(abfd);
1838   for (count = 0; count < bfd_get_symcount(abfd); count++)
1839     {
1840       asymbol *g = *(generic++);
1841
1842       if (g->name)
1843         {
1844           size_t length = strlen(g->name)+1;
1845           bfd_write((PTR)g->name, 1, length, abfd);
1846         }
1847       g->KEEPIT = (KEEPITTYPE) count;
1848     } */
1849 }
1850
1851 boolean
1852 DEFUN(NAME(aout,write_syms),(abfd),
1853       bfd *abfd)
1854 {
1855   unsigned int count ;
1856   asymbol **generic = bfd_get_outsymbols (abfd);
1857   struct stringtab_data strtab;
1858
1859   stringtab_init (&strtab);
1860
1861   for (count = 0; count < bfd_get_symcount (abfd); count++)
1862     {
1863       asymbol *g = generic[count];
1864       struct external_nlist nsp;
1865
1866       if (g->name)
1867         PUT_WORD (abfd, add_to_stringtab (abfd, g->name, &strtab),
1868                   (unsigned char *) nsp.e_strx);
1869       else
1870         PUT_WORD (abfd, 0, (unsigned char *)nsp.e_strx);
1871
1872       if (bfd_asymbol_flavour(g) == abfd->xvec->flavour)
1873         {
1874           bfd_h_put_16(abfd, aout_symbol(g)->desc,  nsp.e_desc);
1875           bfd_h_put_8(abfd, aout_symbol(g)->other,  nsp.e_other);
1876           bfd_h_put_8(abfd, aout_symbol(g)->type,  nsp.e_type);
1877         }
1878       else
1879         {
1880           bfd_h_put_16(abfd,0, nsp.e_desc);
1881           bfd_h_put_8(abfd, 0, nsp.e_other);
1882           bfd_h_put_8(abfd, 0, nsp.e_type);
1883         }
1884
1885       if (! translate_to_native_sym_flags (&nsp, g, abfd))
1886         return false;
1887
1888       if (bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd)
1889           != EXTERNAL_NLIST_SIZE)
1890         return false;
1891
1892       /* NB: `KEEPIT' currently overlays `flags', so set this only
1893          here, at the end.  */
1894       g->KEEPIT = count;
1895     }
1896
1897   emit_strtab (abfd, &strtab);
1898
1899   return true;
1900 }
1901
1902 \f
1903 unsigned int
1904 DEFUN(NAME(aout,get_symtab),(abfd, location),
1905       bfd *abfd AND
1906       asymbol **location)
1907 {
1908     unsigned int counter = 0;
1909     aout_symbol_type *symbase;
1910
1911     if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1912
1913     for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1914       *(location++) = (asymbol *)( symbase++);
1915     *location++ =0;
1916     return bfd_get_symcount (abfd);
1917 }
1918
1919 \f
1920 /* Standard reloc stuff */
1921 /* Output standard relocation information to a file in target byte order. */
1922
1923 void
1924 DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
1925       bfd *abfd AND
1926       arelent *g AND
1927       struct reloc_std_external *natptr)
1928 {
1929   int r_index;
1930   asymbol *sym = *(g->sym_ptr_ptr);
1931   int r_extern;
1932   unsigned int r_length;
1933   int r_pcrel;
1934   int r_baserel, r_jmptable, r_relative;
1935   asection *output_section = sym->section->output_section;
1936
1937   PUT_WORD(abfd, g->address, natptr->r_address);
1938
1939   r_length = g->howto->size ;   /* Size as a power of two */
1940   r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC? */
1941   /* XXX This relies on relocs coming from a.out files.  */
1942   r_baserel = (g->howto->type & 8) != 0;
1943   /* r_jmptable, r_relative???  FIXME-soon */
1944   r_jmptable = 0;
1945   r_relative = 0;
1946
1947 #if 0
1948   /* For a standard reloc, the addend is in the object file.  */
1949   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
1950 #endif
1951
1952   /* name was clobbered by aout_write_syms to be symbol index */
1953
1954   /* If this relocation is relative to a symbol then set the
1955      r_index to the symbols index, and the r_extern bit.
1956
1957      Absolute symbols can come in in two ways, either as an offset
1958      from the abs section, or as a symbol which has an abs value.
1959      check for that here
1960      */
1961
1962
1963   if (bfd_is_com_section (output_section)
1964       || output_section == &bfd_abs_section
1965       || output_section == &bfd_und_section)
1966     {
1967       if (bfd_abs_section.symbol == sym)
1968       {
1969         /* Whoops, looked like an abs symbol, but is really an offset
1970            from the abs section */
1971         r_index = 0;
1972         r_extern = 0;
1973        }
1974       else
1975       {
1976         /* Fill in symbol */
1977         r_extern = 1;
1978         r_index =  stoi((*(g->sym_ptr_ptr))->KEEPIT);
1979
1980       }
1981     }
1982   else
1983     {
1984       /* Just an ordinary section */
1985       r_extern = 0;
1986       r_index  = output_section->target_index;
1987     }
1988
1989   /* now the fun stuff */
1990   if (abfd->xvec->header_byteorder_big_p != false) {
1991       natptr->r_index[0] = r_index >> 16;
1992       natptr->r_index[1] = r_index >> 8;
1993       natptr->r_index[2] = r_index;
1994       natptr->r_type[0] =
1995        (r_extern?    RELOC_STD_BITS_EXTERN_BIG: 0)
1996         | (r_pcrel?     RELOC_STD_BITS_PCREL_BIG: 0)
1997          | (r_baserel?   RELOC_STD_BITS_BASEREL_BIG: 0)
1998           | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_BIG: 0)
1999            | (r_relative?  RELOC_STD_BITS_RELATIVE_BIG: 0)
2000             | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG);
2001     } else {
2002         natptr->r_index[2] = r_index >> 16;
2003         natptr->r_index[1] = r_index >> 8;
2004         natptr->r_index[0] = r_index;
2005         natptr->r_type[0] =
2006          (r_extern?    RELOC_STD_BITS_EXTERN_LITTLE: 0)
2007           | (r_pcrel?     RELOC_STD_BITS_PCREL_LITTLE: 0)
2008            | (r_baserel?   RELOC_STD_BITS_BASEREL_LITTLE: 0)
2009             | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
2010              | (r_relative?  RELOC_STD_BITS_RELATIVE_LITTLE: 0)
2011               | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE);
2012       }
2013 }
2014
2015
2016 /* Extended stuff */
2017 /* Output extended relocation information to a file in target byte order. */
2018
2019 void
2020 DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
2021       bfd *abfd AND
2022       arelent *g AND
2023       register struct reloc_ext_external *natptr)
2024 {
2025   int r_index;
2026   int r_extern;
2027   unsigned int r_type;
2028   unsigned int r_addend;
2029   asymbol *sym = *(g->sym_ptr_ptr);
2030   asection *output_section = sym->section->output_section;
2031
2032   PUT_WORD (abfd, g->address, natptr->r_address);
2033
2034   r_type = (unsigned int) g->howto->type;
2035
2036   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
2037
2038   /* If this relocation is relative to a symbol then set the
2039      r_index to the symbols index, and the r_extern bit.
2040
2041      Absolute symbols can come in in two ways, either as an offset
2042      from the abs section, or as a symbol which has an abs value.
2043      check for that here.  */
2044
2045   if (bfd_is_com_section (output_section)
2046       || output_section == &bfd_abs_section
2047       || output_section == &bfd_und_section)
2048   {
2049     if (bfd_abs_section.symbol == sym)
2050     {
2051       /* Whoops, looked like an abs symbol, but is really an offset
2052          from the abs section */
2053       r_index = 0;
2054       r_extern = 0;
2055      }
2056     else
2057     {
2058       r_extern = 1;
2059       r_index =  stoi((*(g->sym_ptr_ptr))->KEEPIT);
2060     }
2061   }
2062   else
2063   {
2064     /* Just an ordinary section */
2065     r_extern = 0;
2066     r_index  = output_section->target_index;
2067   }
2068
2069   /* now the fun stuff */
2070   if (abfd->xvec->header_byteorder_big_p != false) {
2071     natptr->r_index[0] = r_index >> 16;
2072     natptr->r_index[1] = r_index >> 8;
2073     natptr->r_index[2] = r_index;
2074     natptr->r_type[0] =
2075       ((r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
2076        | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG));
2077   } else {
2078     natptr->r_index[2] = r_index >> 16;
2079     natptr->r_index[1] = r_index >> 8;
2080     natptr->r_index[0] = r_index;
2081     natptr->r_type[0] =
2082      (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
2083       | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
2084   }
2085
2086   PUT_WORD (abfd, r_addend, natptr->r_addend);
2087 }
2088
2089 /* BFD deals internally with all things based from the section they're
2090    in. so, something in 10 bytes into a text section  with a base of
2091    50 would have a symbol (.text+10) and know .text vma was 50.
2092
2093    Aout keeps all it's symbols based from zero, so the symbol would
2094    contain 60. This macro subs the base of each section from the value
2095    to give the true offset from the section */
2096
2097
2098 #define MOVE_ADDRESS(ad)                                                \
2099   if (r_extern) {                                                       \
2100    /* undefined symbol */                                               \
2101      cache_ptr->sym_ptr_ptr = symbols + r_index;                        \
2102      cache_ptr->addend = ad;                                            \
2103      } else {                                                           \
2104     /* defined, section relative. replace symbol with pointer to        \
2105        symbol which points to section  */                               \
2106     switch (r_index) {                                                  \
2107     case N_TEXT:                                                        \
2108     case N_TEXT | N_EXT:                                                \
2109       cache_ptr->sym_ptr_ptr  = obj_textsec(abfd)->symbol_ptr_ptr;      \
2110       cache_ptr->addend = ad  - su->textsec->vma;                       \
2111       break;                                                            \
2112     case N_DATA:                                                        \
2113     case N_DATA | N_EXT:                                                \
2114       cache_ptr->sym_ptr_ptr  = obj_datasec(abfd)->symbol_ptr_ptr;      \
2115       cache_ptr->addend = ad - su->datasec->vma;                        \
2116       break;                                                            \
2117     case N_BSS:                                                         \
2118     case N_BSS | N_EXT:                                                 \
2119       cache_ptr->sym_ptr_ptr  = obj_bsssec(abfd)->symbol_ptr_ptr;       \
2120       cache_ptr->addend = ad - su->bsssec->vma;                         \
2121       break;                                                            \
2122     default:                                                            \
2123     case N_ABS:                                                         \
2124     case N_ABS | N_EXT:                                                 \
2125      cache_ptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;   \
2126       cache_ptr->addend = ad;                                           \
2127       break;                                                            \
2128     }                                                                   \
2129   }                                                                     \
2130
2131 void
2132 DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
2133       bfd *abfd AND
2134       struct reloc_ext_external *bytes AND
2135       arelent *cache_ptr AND
2136       asymbol **symbols)
2137 {
2138   int r_index;
2139   int r_extern;
2140   unsigned int r_type;
2141   struct aoutdata *su = &(abfd->tdata.aout_data->a);
2142
2143   cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
2144
2145   /* now the fun stuff */
2146   if (abfd->xvec->header_byteorder_big_p != false) {
2147     r_index =  (bytes->r_index[0] << 16)
2148              | (bytes->r_index[1] << 8)
2149              |  bytes->r_index[2];
2150     r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
2151     r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
2152                                       >> RELOC_EXT_BITS_TYPE_SH_BIG;
2153   } else {
2154     r_index =  (bytes->r_index[2] << 16)
2155              | (bytes->r_index[1] << 8)
2156              |  bytes->r_index[0];
2157     r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
2158     r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
2159                                       >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
2160   }
2161
2162   cache_ptr->howto =  howto_table_ext + r_type;
2163   MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend));
2164 }
2165
2166 void
2167 DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
2168   bfd *abfd AND
2169   struct reloc_std_external *bytes AND
2170   arelent *cache_ptr AND
2171   asymbol **symbols)
2172 {
2173   int r_index;
2174   int r_extern;
2175   unsigned int r_length;
2176   int r_pcrel;
2177   int r_baserel, r_jmptable, r_relative;
2178   struct aoutdata  *su = &(abfd->tdata.aout_data->a);
2179   int howto_idx;
2180
2181   cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
2182
2183   /* now the fun stuff */
2184   if (abfd->xvec->header_byteorder_big_p != false) {
2185     r_index =  (bytes->r_index[0] << 16)
2186       | (bytes->r_index[1] << 8)
2187         |  bytes->r_index[2];
2188     r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
2189     r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
2190     r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
2191     r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
2192     r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
2193     r_length  =       (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
2194                         >> RELOC_STD_BITS_LENGTH_SH_BIG;
2195   } else {
2196     r_index =  (bytes->r_index[2] << 16)
2197       | (bytes->r_index[1] << 8)
2198         |  bytes->r_index[0];
2199     r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
2200     r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
2201     r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
2202     r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
2203     r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
2204     r_length  =       (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
2205                         >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
2206   }
2207
2208   howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel;
2209   BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
2210   cache_ptr->howto =  howto_table_std + howto_idx;
2211   BFD_ASSERT (cache_ptr->howto->type != -1);
2212   BFD_ASSERT (r_jmptable == 0);
2213   BFD_ASSERT (r_relative == 0);
2214   /* FIXME-soon:  Roll jmptable, relative bits into howto setting */
2215
2216   MOVE_ADDRESS(0);
2217 }
2218
2219 /* Reloc hackery */
2220
2221 boolean
2222 DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
2223       bfd *abfd AND
2224       sec_ptr asect AND
2225       asymbol **symbols)
2226 {
2227   unsigned int count;
2228   bfd_size_type reloc_size;
2229   PTR relocs;
2230   arelent *reloc_cache;
2231   size_t each_size;
2232
2233   if (asect->relocation) return true;
2234
2235   if (asect->flags & SEC_CONSTRUCTOR) return true;
2236
2237   if (asect == obj_datasec (abfd)) {
2238     reloc_size = exec_hdr(abfd)->a_drsize;
2239   } else if (asect == obj_textsec (abfd)) {
2240     reloc_size = exec_hdr(abfd)->a_trsize;
2241   } else {
2242     bfd_error = invalid_operation;
2243     return false;
2244   }
2245
2246   bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
2247   each_size = obj_reloc_entry_size (abfd);
2248
2249   count = reloc_size / each_size;
2250
2251
2252   reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
2253                                                        (arelent)));
2254   if (!reloc_cache) {
2255 nomem:
2256     bfd_error = no_memory;
2257     return false;
2258   }
2259
2260   relocs = (PTR) bfd_alloc (abfd, reloc_size);
2261   if (!relocs) {
2262     bfd_release (abfd, reloc_cache);
2263     goto nomem;
2264   }
2265
2266   if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
2267     bfd_release (abfd, relocs);
2268     bfd_release (abfd, reloc_cache);
2269     bfd_error = system_call_error;
2270     return false;
2271   }
2272
2273   if (each_size == RELOC_EXT_SIZE) {
2274     register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
2275     unsigned int counter = 0;
2276     arelent *cache_ptr = reloc_cache;
2277
2278     for (; counter < count; counter++, rptr++, cache_ptr++) {
2279       NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
2280     }
2281   } else {
2282     register struct reloc_std_external *rptr = (struct reloc_std_external *) relocs;
2283     unsigned int counter = 0;
2284     arelent *cache_ptr = reloc_cache;
2285
2286     for (; counter < count; counter++, rptr++, cache_ptr++) {
2287       NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
2288     }
2289
2290   }
2291
2292   bfd_release (abfd,relocs);
2293   asect->relocation = reloc_cache;
2294   asect->reloc_count = count;
2295   return true;
2296 }
2297
2298
2299
2300 /* Write out a relocation section into an object file.  */
2301
2302 boolean
2303 DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
2304       bfd *abfd AND
2305       asection *section)
2306 {
2307   arelent **generic;
2308   unsigned char *native, *natptr;
2309   size_t each_size;
2310
2311   unsigned int count = section->reloc_count;
2312   size_t natsize;
2313
2314   if (count == 0) return true;
2315
2316   each_size = obj_reloc_entry_size (abfd);
2317   natsize = each_size * count;
2318   native = (unsigned char *) bfd_zalloc (abfd, natsize);
2319   if (!native) {
2320     bfd_error = no_memory;
2321     return false;
2322   }
2323
2324   generic = section->orelocation;
2325
2326   if (each_size == RELOC_EXT_SIZE)
2327     {
2328       for (natptr = native;
2329            count != 0;
2330            --count, natptr += each_size, ++generic)
2331         NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
2332     }
2333   else
2334     {
2335       for (natptr = native;
2336            count != 0;
2337            --count, natptr += each_size, ++generic)
2338         NAME(aout,swap_std_reloc_out)(abfd, *generic, (struct reloc_std_external *)natptr);
2339     }
2340
2341   if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
2342     bfd_release(abfd, native);
2343     return false;
2344   }
2345   bfd_release (abfd, native);
2346
2347   return true;
2348 }
2349
2350 /* This is stupid.  This function should be a boolean predicate */
2351 unsigned int
2352 DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
2353       bfd *abfd AND
2354       sec_ptr section AND
2355       arelent **relptr AND
2356       asymbol **symbols)
2357 {
2358   arelent *tblptr = section->relocation;
2359   unsigned int count;
2360
2361   if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
2362     return 0;
2363
2364   if (section->flags & SEC_CONSTRUCTOR) {
2365     arelent_chain *chain = section->constructor_chain;
2366     for (count = 0; count < section->reloc_count; count ++) {
2367       *relptr ++ = &chain->relent;
2368       chain = chain->next;
2369     }
2370   }
2371   else {
2372     tblptr = section->relocation;
2373     if (!tblptr) return 0;
2374
2375     for (count = 0; count++ < section->reloc_count;)
2376       {
2377         *relptr++ = tblptr++;
2378       }
2379   }
2380   *relptr = 0;
2381
2382   return section->reloc_count;
2383 }
2384
2385 unsigned int
2386 DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
2387      bfd *abfd AND
2388      sec_ptr asect)
2389 {
2390   if (bfd_get_format (abfd) != bfd_object) {
2391     bfd_error = invalid_operation;
2392     return 0;
2393   }
2394   if (asect->flags & SEC_CONSTRUCTOR) {
2395     return (sizeof (arelent *) * (asect->reloc_count+1));
2396   }
2397
2398
2399   if (asect == obj_datasec (abfd))
2400     return (sizeof (arelent *) *
2401             ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
2402              +1));
2403
2404   if (asect == obj_textsec (abfd))
2405     return (sizeof (arelent *) *
2406             ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
2407              +1));
2408
2409   bfd_error = invalid_operation;
2410   return 0;
2411 }
2412
2413 \f
2414  unsigned int
2415 DEFUN(NAME(aout,get_symtab_upper_bound),(abfd),
2416      bfd *abfd)
2417 {
2418   if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
2419
2420   return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
2421 }
2422
2423 /*ARGSUSED*/
2424  alent *
2425 DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
2426       bfd *ignore_abfd AND
2427       asymbol *ignore_symbol)
2428 {
2429 return (alent *)NULL;
2430 }
2431
2432 /*ARGSUSED*/
2433 void
2434 DEFUN(NAME(aout,get_symbol_info),(ignore_abfd, symbol, ret),
2435       bfd *ignore_abfd AND
2436       asymbol *symbol AND
2437       symbol_info *ret)
2438 {
2439   bfd_symbol_info (symbol, ret);
2440
2441   if (ret->type == '?')
2442     {
2443       int type_code = aout_symbol(symbol)->type & 0xff;
2444       CONST char *stab_name = aout_stab_name(type_code);
2445       static char buf[10];
2446
2447       if (stab_name == NULL)
2448         {
2449           sprintf(buf, "(%d)", type_code);
2450           stab_name = buf;
2451         }
2452       ret->type = '-';
2453       ret->stab_other = (unsigned)(aout_symbol(symbol)->other & 0xff);
2454       ret->stab_desc = (unsigned)(aout_symbol(symbol)->desc & 0xffff);
2455       ret->stab_name = stab_name;
2456     }
2457 }
2458
2459 /*ARGSUSED*/
2460 void
2461 DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
2462       bfd *ignore_abfd AND
2463       PTR afile AND
2464       asymbol *symbol AND
2465       bfd_print_symbol_type how)
2466 {
2467   FILE *file = (FILE *)afile;
2468
2469   switch (how) {
2470   case bfd_print_symbol_name:
2471     if (symbol->name)
2472       fprintf(file,"%s", symbol->name);
2473     break;
2474   case bfd_print_symbol_more:
2475     fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
2476             (unsigned)(aout_symbol(symbol)->other & 0xff),
2477             (unsigned)(aout_symbol(symbol)->type));
2478     break;
2479   case bfd_print_symbol_all:
2480     {
2481    CONST char *section_name = symbol->section->name;
2482
2483
2484       bfd_print_symbol_vandf((PTR)file,symbol);
2485
2486       fprintf(file," %-5s %04x %02x %02x",
2487               section_name,
2488               (unsigned)(aout_symbol(symbol)->desc & 0xffff),
2489               (unsigned)(aout_symbol(symbol)->other & 0xff),
2490               (unsigned)(aout_symbol(symbol)->type  & 0xff));
2491       if (symbol->name)
2492         fprintf(file," %s", symbol->name);
2493     }
2494     break;
2495   }
2496 }
2497
2498 /*
2499  provided a BFD, a section and an offset into the section, calculate
2500  and return the name of the source file and the line nearest to the
2501  wanted location.
2502 */
2503
2504 boolean
2505 DEFUN(NAME(aout,find_nearest_line),(abfd,
2506                                      section,
2507                                      symbols,
2508                                      offset,
2509                                      filename_ptr,
2510                                      functionname_ptr,
2511                                      line_ptr),
2512       bfd *abfd AND
2513       asection *section AND
2514       asymbol **symbols AND
2515       bfd_vma offset AND
2516       CONST char **filename_ptr AND
2517       CONST char **functionname_ptr AND
2518       unsigned int *line_ptr)
2519 {
2520   /* Run down the file looking for the filename, function and linenumber */
2521   asymbol **p;
2522   static  char buffer[100];
2523   static  char filename_buffer[200];
2524   CONST char *directory_name = NULL;
2525   CONST char *main_file_name = NULL;
2526   CONST char *current_file_name = NULL;
2527   CONST char *line_file_name = NULL; /* Value of current_file_name at line number. */
2528   bfd_vma high_line_vma = ~0;
2529   bfd_vma low_func_vma = 0;
2530   asymbol *func = 0;
2531   *filename_ptr = abfd->filename;
2532   *functionname_ptr = 0;
2533   *line_ptr = 0;
2534   if (symbols != (asymbol **)NULL) {
2535     for (p = symbols; *p; p++) {
2536       aout_symbol_type  *q = (aout_symbol_type *)(*p);
2537     next:
2538       switch (q->type){
2539       case N_SO:
2540         main_file_name = current_file_name = q->symbol.name;
2541         /* Look ahead to next symbol to check if that too is an N_SO. */
2542         p++;
2543         if (*p == NULL)
2544           break;
2545         q = (aout_symbol_type *)(*p);
2546         if (q->type != (int)N_SO)
2547           goto next;
2548
2549         /* Found a second N_SO  First is directory; second is filename. */
2550         directory_name = current_file_name;
2551         main_file_name = current_file_name = q->symbol.name;
2552         if (obj_textsec(abfd) != section)
2553           goto done;
2554         break;
2555       case N_SOL:
2556         current_file_name = q->symbol.name;
2557         break;
2558
2559       case N_SLINE:
2560
2561       case N_DSLINE:
2562       case N_BSLINE:
2563         /* We'll keep this if it resolves nearer than the one we have already */
2564         if (q->symbol.value >= offset &&
2565             q->symbol.value < high_line_vma) {
2566           *line_ptr = q->desc;
2567           high_line_vma = q->symbol.value;
2568           line_file_name = current_file_name;
2569         }
2570         break;
2571       case N_FUN:
2572         {
2573           /* We'll keep this if it is nearer than the one we have already */
2574           if (q->symbol.value >= low_func_vma &&
2575               q->symbol.value <= offset) {
2576             low_func_vma = q->symbol.value;
2577             func = (asymbol *)q;
2578           }
2579           if (*line_ptr && func) {
2580             CONST char *function = func->name;
2581             char *p;
2582             strncpy(buffer, function, sizeof(buffer)-1);
2583             buffer[sizeof(buffer)-1] = 0;
2584             /* Have to remove : stuff */
2585             p = strchr(buffer,':');
2586             if (p != NULL) { *p = '\0'; }
2587             *functionname_ptr = buffer;
2588             goto done;
2589
2590           }
2591         }
2592         break;
2593       }
2594     }
2595   }
2596
2597  done:
2598   if (*line_ptr)
2599     main_file_name = line_file_name;
2600   if (main_file_name) {
2601       if (main_file_name[0] == '/' || directory_name == NULL)
2602           *filename_ptr = main_file_name;
2603       else {
2604           sprintf(filename_buffer, "%.140s%.50s",
2605                   directory_name, main_file_name);
2606           *filename_ptr = filename_buffer;
2607       }
2608   }
2609   return true;
2610
2611 }
2612
2613 /*ARGSUSED*/
2614 int
2615 DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
2616       bfd *abfd AND
2617       boolean execable)
2618 {
2619   return adata(abfd).exec_bytes_size;
2620 }
2621 \f
2622 /* a.out link code.  */
2623
2624 /* a.out linker hash table entries.  */
2625
2626 struct aout_link_hash_entry
2627 {
2628   struct bfd_link_hash_entry root;
2629   /* Symbol index in output file.  */
2630   int indx;
2631 };
2632
2633 /* a.out linker hash table.  */
2634
2635 struct aout_link_hash_table
2636 {
2637   struct bfd_link_hash_table root;
2638 };
2639
2640 static struct bfd_hash_entry *aout_link_hash_newfunc
2641   PARAMS ((struct bfd_hash_entry *entry,
2642            struct bfd_hash_table *table,
2643            const char *string));
2644 static boolean aout_link_add_object_symbols
2645   PARAMS ((bfd *, struct bfd_link_info *));
2646 static boolean aout_link_check_archive_element
2647   PARAMS ((bfd *, struct bfd_link_info *, boolean *));
2648 static boolean aout_link_get_symbols PARAMS ((bfd *));
2649 static boolean aout_link_free_symbols PARAMS ((bfd *));
2650 static boolean aout_link_check_ar_symbols
2651   PARAMS ((bfd *, struct bfd_link_info *, boolean *pneeded));
2652 static boolean aout_link_add_symbols
2653   PARAMS ((bfd *, struct bfd_link_info *));
2654
2655 /* Routine to create an entry in an a.out link hash table.  */
2656
2657 static struct bfd_hash_entry *
2658 aout_link_hash_newfunc (entry, table, string)
2659      struct bfd_hash_entry *entry;
2660      struct bfd_hash_table *table;
2661      const char *string;
2662 {
2663   struct aout_link_hash_entry *ret = (struct aout_link_hash_entry *) entry;
2664
2665   /* Allocate the structure if it has not already been allocated by a
2666      subclass.  */
2667   if (ret == (struct aout_link_hash_entry *) NULL)
2668     ret = ((struct aout_link_hash_entry *)
2669            bfd_hash_allocate (table, sizeof (struct aout_link_hash_entry)));
2670
2671   /* Call the allocation method of the superclass.  */
2672   ret = ((struct aout_link_hash_entry *)
2673          _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
2674                                  table, string));
2675
2676   /* Set local fields.  */
2677   ret->indx = -1;
2678
2679   return (struct bfd_hash_entry *) ret;
2680 }
2681
2682 /* Create an a.out link hash table.  */
2683
2684 struct bfd_link_hash_table *
2685 NAME(aout,link_hash_table_create) (abfd)
2686      bfd *abfd;
2687 {
2688   struct aout_link_hash_table *ret;
2689
2690   ret = ((struct aout_link_hash_table *)
2691          bfd_xmalloc (sizeof (struct aout_link_hash_table)));
2692   if (! _bfd_link_hash_table_init (&ret->root, abfd,
2693                                    aout_link_hash_newfunc))
2694     {
2695       free (ret);
2696       return (struct bfd_link_hash_table *) NULL;
2697     }
2698   return &ret->root;
2699 }
2700
2701 /* Look up an entry in an a.out link hash table.  */
2702
2703 #define aout_link_hash_lookup(table, string, create, copy, follow) \
2704   ((struct aout_link_hash_entry *) \
2705    bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow)))
2706
2707 /* Traverse an a.out link hash table.  */
2708
2709 #define aout_link_hash_traverse(table, func, info)                      \
2710   (bfd_link_hash_traverse                                               \
2711    (&(table)->root,                                                     \
2712     (boolean (*) PARAMS ((struct bfd_link_hash_entry *, PTR))) (func),  \
2713     (info)))
2714
2715 /* Get the a.out link hash table from the info structure.  This is
2716    just a cast.  */
2717
2718 #define aout_hash_table(p) ((struct aout_link_hash_table *) ((p)->hash))
2719
2720 /* Given an a.out BFD, add symbols to the global hash table as
2721    appropriate.  */
2722
2723 boolean
2724 NAME(aout,link_add_symbols) (abfd, info)
2725      bfd *abfd;
2726      struct bfd_link_info *info;
2727 {
2728   switch (bfd_get_format (abfd))
2729     {
2730     case bfd_object:
2731       return aout_link_add_object_symbols (abfd, info);
2732     case bfd_archive:
2733       return _bfd_generic_link_add_archive_symbols
2734         (abfd, info, aout_link_check_archive_element);
2735     default:
2736       bfd_error = wrong_format;
2737       return false;
2738     }
2739 }
2740
2741 /* Add symbols from an a.out object file.  */
2742
2743 static boolean
2744 aout_link_add_object_symbols (abfd, info)
2745      bfd *abfd;
2746      struct bfd_link_info *info;
2747 {
2748   if (! aout_link_get_symbols (abfd))
2749     return false;
2750   if (! aout_link_add_symbols (abfd, info))
2751     return false;
2752   if (! info->keep_memory)
2753     {
2754       if (! aout_link_free_symbols (abfd))
2755         return false;
2756     }
2757   return true;
2758 }
2759
2760 /* Check a single archive element to see if we need to include it in
2761    the link.  *PNEEDED is set according to whether this element is
2762    needed in the link or not.  This is called from
2763    _bfd_generic_link_add_archive_symbols.  */
2764
2765 static boolean
2766 aout_link_check_archive_element (abfd, info, pneeded)
2767      bfd *abfd;
2768      struct bfd_link_info *info;
2769      boolean *pneeded;
2770 {
2771   if (! aout_link_get_symbols (abfd))
2772     return false;
2773
2774   if (! aout_link_check_ar_symbols (abfd, info, pneeded))
2775     return false;
2776
2777   if (*pneeded)
2778     {
2779       if (! aout_link_add_symbols (abfd, info))
2780         return false;
2781     }
2782
2783   /* We keep around the symbols even if we aren't going to use this
2784      object file, because we may want to reread it.  This doesn't
2785      waste too much memory, because it isn't all that common to read
2786      an archive element but not need it.  */
2787   if (! info->keep_memory)
2788     {
2789       if (! aout_link_free_symbols (abfd))
2790         return false;
2791     }
2792
2793   return true;
2794 }
2795
2796 /* Read the internal symbols from an a.out file.  */
2797
2798 static boolean
2799 aout_link_get_symbols (abfd)
2800      bfd *abfd;
2801 {
2802   bfd_size_type count;
2803   struct external_nlist *syms;
2804   unsigned char string_chars[BYTES_IN_WORD];
2805   bfd_size_type stringsize;
2806   char *strings;
2807
2808   if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
2809     {
2810       /* We already have them.  */
2811       return true;
2812     }
2813
2814   count = exec_hdr (abfd)->a_syms / EXTERNAL_NLIST_SIZE;
2815
2816   /* We allocate using bfd_xmalloc to make the values easy to free
2817      later on.  If we put them on the obstack it might not be possible
2818      to free them.  */
2819   syms = ((struct external_nlist *)
2820           bfd_xmalloc ((size_t) count * EXTERNAL_NLIST_SIZE));
2821
2822   if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
2823       || (bfd_read ((PTR) syms, 1, exec_hdr (abfd)->a_syms, abfd)
2824           != exec_hdr (abfd)->a_syms))
2825     return false;
2826
2827   /* Get the size of the strings.  */
2828   if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0
2829       || (bfd_read ((PTR) string_chars, BYTES_IN_WORD, 1, abfd)
2830           != BYTES_IN_WORD))
2831     return false;
2832   stringsize = GET_WORD (abfd, string_chars);
2833   strings = (char *) bfd_xmalloc ((size_t) stringsize);
2834
2835   /* Skip space for the string count in the buffer for convenience
2836      when using indexes.  */
2837   if (bfd_read (strings + BYTES_IN_WORD, 1, stringsize - BYTES_IN_WORD, abfd)
2838       != stringsize - BYTES_IN_WORD)
2839     return false;
2840
2841   /* Save the data.  */
2842   obj_aout_external_syms (abfd) = syms;
2843   obj_aout_external_sym_count (abfd) = count;
2844   obj_aout_external_strings (abfd) = strings;
2845
2846   return true;
2847 }
2848
2849 /* Free up the internal symbols read from an a.out file.  */
2850
2851 static boolean
2852 aout_link_free_symbols (abfd)
2853      bfd *abfd;
2854 {
2855   if (obj_aout_external_syms (abfd) != (struct external_nlist *) NULL)
2856     {
2857       free ((PTR) obj_aout_external_syms (abfd));
2858       obj_aout_external_syms (abfd) = (struct external_nlist *) NULL;
2859     }
2860   if (obj_aout_external_strings (abfd) != (char *) NULL)
2861     {
2862       free ((PTR) obj_aout_external_strings (abfd));
2863       obj_aout_external_strings (abfd) = (char *) NULL;
2864     }
2865   return true;
2866 }
2867
2868 /* Look through the internal symbols to see if this object file should
2869    be included in the link.  We should include this object file if it
2870    defines any symbols which are currently undefined.  If this object
2871    file defines a common symbol, then we may adjust the size of the
2872    known symbol but we do not include the object file in the link
2873    (unless there is some other reason to include it).  */
2874
2875 static boolean
2876 aout_link_check_ar_symbols (abfd, info, pneeded)
2877      bfd *abfd;
2878      struct bfd_link_info *info;
2879      boolean *pneeded;
2880 {
2881   register struct external_nlist *p;
2882   struct external_nlist *pend;
2883   char *strings;
2884
2885   *pneeded = false;
2886
2887   /* Look through all the symbols.  */
2888   p = obj_aout_external_syms (abfd);
2889   pend = p + obj_aout_external_sym_count (abfd);
2890   strings = obj_aout_external_strings (abfd);
2891   for (; p < pend; p++)
2892     {
2893       int type = bfd_h_get_8 (abfd, p->e_type);
2894       const char *name;
2895       struct bfd_link_hash_entry *h;
2896
2897       /* Ignore symbols that are not externally visible.  */
2898       if ((type & N_EXT) == 0)
2899         continue;
2900
2901       name = strings + GET_WORD (abfd, p->e_strx);
2902       h = bfd_link_hash_lookup (info->hash, name, false, false, true);
2903
2904       /* We are only interested in symbols that are currently
2905          undefined or common.  */
2906       if (h == (struct bfd_link_hash_entry *) NULL
2907           || (h->type != bfd_link_hash_undefined
2908               && h->type != bfd_link_hash_common))
2909         continue;
2910
2911       if ((type & (N_TEXT | N_DATA | N_BSS)) != 0)
2912         {
2913           /* This object file defines this symbol.  We must link it
2914              in.  This is true regardless of whether the current
2915              definition of the symbol is undefined or common.  If the
2916              current definition is common, we have a case in which we
2917              have already seen an object file including
2918                  int a;
2919              and this object file from the archive includes
2920                  int a = 5;
2921              In such a case we must include this object file.  */
2922           if (! (*info->callbacks->add_archive_element) (info, abfd, name))
2923             return false;
2924           *pneeded = true;
2925           return true;
2926         }
2927
2928       if (type == (N_EXT | N_UNDF))
2929         {
2930           bfd_vma value;
2931
2932           value = GET_WORD (abfd, p->e_value);
2933           if (value != 0)
2934             {
2935               /* This symbol is common in the object from the archive
2936                  file.  */
2937               if (h->type == bfd_link_hash_undefined)
2938                 {
2939                   bfd *symbfd;
2940
2941                   symbfd = h->u.undef.abfd;
2942                   if (symbfd == (bfd *) NULL)
2943                     {
2944                       /* This symbol was created as undefined from
2945                          outside BFD.  We assume that we should link
2946                          in the object file.  This is done for the -u
2947                          option in the linker.  */
2948                       if (! (*info->callbacks->add_archive_element) (info,
2949                                                                      abfd,
2950                                                                      name))
2951                         return false;
2952                       *pneeded = true;
2953                       return true;
2954                     }
2955                   /* Turn the current link symbol into a common
2956                      symbol.  It is already on the undefs list.  */
2957                   h->type = bfd_link_hash_common;
2958                   h->u.c.size = value;
2959                   h->u.c.section = bfd_make_section_old_way (symbfd,
2960                                                              "COMMON");
2961                 }
2962               else
2963                 {
2964                   /* Adjust the size of the common symbol if
2965                      necessary.  */
2966                   if (value > h->u.c.size)
2967                     h->u.c.size = value;
2968                 }
2969             }
2970         }
2971     }
2972
2973   /* We do not need this object file.  */
2974   return true;
2975 }
2976
2977 /* Add all symbols from an object file to the hash table.  */
2978
2979 static boolean
2980 aout_link_add_symbols (abfd, info)
2981      bfd *abfd;
2982      struct bfd_link_info *info;
2983 {
2984   bfd_size_type sym_count;
2985   char *strings;
2986   boolean copy;
2987   struct aout_link_hash_entry **sym_hash;
2988   register struct external_nlist *p;
2989   struct external_nlist *pend;
2990
2991   sym_count = obj_aout_external_sym_count (abfd);
2992   strings = obj_aout_external_strings (abfd);
2993   if (info->keep_memory)
2994     copy = false;
2995   else
2996     copy = true;
2997
2998   /* We keep a list of the linker hash table entries that correspond
2999      to particular symbols.  We could just look them up in the hash
3000      table, but keeping the list is more efficient.  Perhaps this
3001      should be conditional on info->keep_memory.  */
3002   sym_hash = ((struct aout_link_hash_entry **)
3003               bfd_alloc (abfd,
3004                          ((size_t) sym_count
3005                           * sizeof (struct aout_link_hash_entry *))));
3006   obj_aout_sym_hashes (abfd) = sym_hash;
3007
3008   p = obj_aout_external_syms (abfd);
3009   pend = p + sym_count;
3010   for (; p < pend; p++, sym_hash++)
3011     {
3012       int type;
3013       const char *name;
3014       bfd_vma value;
3015       asection *section;
3016       flagword flags;
3017       const char *string;
3018
3019       *sym_hash = NULL;
3020
3021       type = bfd_h_get_8 (abfd, p->e_type);
3022
3023       /* Ignore debugging symbols.  */
3024       if ((type & N_STAB) != 0)
3025         continue;
3026
3027       /* Ignore symbols that are not external.  */
3028       if ((type & N_EXT) == 0
3029           && type != N_WARNING
3030           && type != N_SETA
3031           && type != N_SETT
3032           && type != N_SETD
3033           && type != N_SETB)
3034         {
3035           /* If this is an N_INDR symbol we must skip the next entry,
3036              which is the symbol to indirect to (actually, an N_INDR
3037              symbol without N_EXT set is pretty useless).  */
3038           if (type == N_INDR)
3039             ++p;
3040           continue;
3041         }
3042
3043       /* Ignore N_FN symbols (these appear to have N_EXT set).  */
3044       if (type == N_FN)
3045         continue;
3046
3047       name = strings + GET_WORD (abfd, p->e_strx);
3048       value = GET_WORD (abfd, p->e_value);
3049       flags = BSF_GLOBAL;
3050       string = NULL;
3051       switch (type)
3052         {
3053         default:
3054           abort ();
3055         case N_UNDF | N_EXT:
3056           if (value != 0)
3057             section = &bfd_com_section;
3058           else
3059             section = &bfd_und_section;
3060           break;
3061         case N_ABS | N_EXT:
3062           section = &bfd_abs_section;
3063           break;
3064         case N_TEXT | N_EXT:
3065           section = obj_textsec (abfd);
3066           value -= bfd_get_section_vma (abfd, section);
3067           break;
3068         case N_DATA | N_EXT:
3069           section = obj_datasec (abfd);
3070           value -= bfd_get_section_vma (abfd, section);
3071           break;
3072         case N_BSS | N_EXT:
3073           section = obj_bsssec (abfd);
3074           value -= bfd_get_section_vma (abfd, section);
3075           break;
3076         case N_INDR | N_EXT:
3077           /* An indirect symbol.  The next symbol is the symbol
3078              which this one really is.  */
3079           BFD_ASSERT (p + 1 < pend);
3080           ++p;
3081           string = strings + GET_WORD (abfd, p->e_strx);
3082           section = &bfd_ind_section;
3083           flags |= BSF_INDIRECT;
3084           break;
3085         case N_COMM | N_EXT:
3086           section = &bfd_com_section;
3087           break;
3088         case N_SETA:
3089           section = &bfd_abs_section;
3090           flags |= BSF_CONSTRUCTOR;
3091           break;
3092         case N_SETT:
3093           section = obj_textsec (abfd);
3094           flags |= BSF_CONSTRUCTOR;
3095           value -= bfd_get_section_vma (abfd, section);
3096           break;
3097         case N_SETD:
3098           section = obj_datasec (abfd);
3099           flags |= BSF_CONSTRUCTOR;
3100           value -= bfd_get_section_vma (abfd, section);
3101           break;
3102         case N_SETB:
3103           section = obj_bsssec (abfd);
3104           flags |= BSF_CONSTRUCTOR;
3105           value -= bfd_get_section_vma (abfd, section);
3106           break;
3107         case N_WARNING:
3108           /* A warning symbol.  The next symbol is the one to warn
3109              about.  */
3110           BFD_ASSERT (p + 1 < pend);
3111           ++p;
3112           string = name;
3113           name = strings + GET_WORD (abfd, p->e_strx);
3114           section = &bfd_und_section;
3115           flags |= BSF_WARNING;
3116           break;
3117         }
3118
3119       if (! (_bfd_generic_link_add_one_symbol
3120              (info, abfd, name, flags, section, value, string, copy, false,
3121               ARCH_SIZE, (struct bfd_link_hash_entry **) sym_hash)))
3122         return false;
3123     }
3124
3125   return true;
3126 }
3127
3128 /* During the final link step we need to pass around a bunch of
3129    information, so we do it in an instance of this structure.  */
3130
3131 struct aout_final_link_info
3132 {
3133   /* General link information.  */
3134   struct bfd_link_info *info;
3135   /* Output bfd.  */
3136   bfd *output_bfd;
3137   /* Reloc file positions.  */
3138   file_ptr treloff, dreloff;
3139   /* File position of symbols.  */
3140   file_ptr symoff;
3141   /* String table.  */
3142   struct stringtab_data strtab;
3143 };
3144
3145 static boolean aout_link_input_bfd
3146   PARAMS ((struct aout_final_link_info *, bfd *input_bfd));
3147 static boolean aout_link_write_symbols
3148   PARAMS ((struct aout_final_link_info *, bfd *input_bfd, int *symbol_map));
3149 static boolean aout_link_write_other_symbol
3150   PARAMS ((struct aout_link_hash_entry *, PTR));
3151 static boolean aout_link_input_section
3152   PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3153            asection *input_section, file_ptr *reloff_ptr,
3154            bfd_size_type rel_size, int *symbol_map));
3155 static boolean aout_link_input_section_std
3156   PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3157            asection *input_section, struct reloc_std_external *,
3158            bfd_size_type rel_size, bfd_byte *contents, int *symbol_map));
3159 static boolean aout_link_input_section_ext
3160   PARAMS ((struct aout_final_link_info *, bfd *input_bfd,
3161            asection *input_section, struct reloc_ext_external *,
3162            bfd_size_type rel_size, bfd_byte *contents, int *symbol_map));
3163 static INLINE asection *aout_reloc_index_to_section
3164   PARAMS ((bfd *, int));
3165
3166 /* Do the final link step.  This is called on the output BFD.  The
3167    INFO structure should point to a list of BFDs linked through the
3168    link_next field which can be used to find each BFD which takes part
3169    in the output.  Also, each section in ABFD should point to a list
3170    of bfd_link_order structures which list all the input sections for
3171    the output section.  */
3172
3173 boolean
3174 NAME(aout,final_link) (abfd, info, callback)
3175      bfd *abfd;
3176      struct bfd_link_info *info;
3177      void (*callback) PARAMS ((bfd *, file_ptr *, file_ptr *, file_ptr *));
3178 {
3179   struct aout_final_link_info aout_info;
3180   register bfd *sub;
3181   bfd_size_type text_size;
3182   file_ptr text_end;
3183   register struct bfd_link_order *p;
3184   asection *o;
3185
3186   aout_info.info = info;
3187   aout_info.output_bfd = abfd;
3188
3189   if (! info->relocateable)
3190     {
3191       exec_hdr (abfd)->a_trsize = 0;
3192       exec_hdr (abfd)->a_drsize = 0;
3193     }
3194   else
3195     {
3196       bfd_size_type trsize, drsize;
3197
3198       /* Count up the relocation sizes.  */
3199       trsize = 0;
3200       drsize = 0;
3201       for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
3202         {
3203           if (bfd_get_flavour (abfd) == bfd_target_aout_flavour)
3204             {
3205               trsize += exec_hdr (sub)->a_trsize;
3206               drsize += exec_hdr (sub)->a_drsize;
3207             }
3208           else
3209             {
3210               /* FIXME: We need to identify the .text and .data sections
3211                  and call get_reloc_upper_bound and canonicalize_reloc to
3212                  work out the number of relocs needed, and then multiply
3213                  by the reloc size.  */
3214               abort ();
3215             }
3216         }
3217       exec_hdr (abfd)->a_trsize = trsize;
3218       exec_hdr (abfd)->a_drsize = drsize;
3219     }
3220
3221   /* Adjust the section sizes and vmas according to the magic number.
3222      This sets a_text, a_data and a_bss in the exec_hdr and sets the
3223      filepos for each section.  */
3224   if (! NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end))
3225     return false;
3226
3227   /* The relocation and symbol file positions differ among a.out
3228      targets.  We are passed a callback routine from the backend
3229      specific code to handle this.
3230      FIXME: At this point we do not know how much space the symbol
3231      table will require.  This will not work for any (nonstandard)
3232      a.out target that needs to know the symbol table size before it
3233      can compute the relocation file positions.  This may or may not
3234      be the case for the hp300hpux target, for example.  */
3235   (*callback) (abfd, &aout_info.treloff, &aout_info.dreloff,
3236                &aout_info.symoff);
3237   obj_textsec (abfd)->rel_filepos = aout_info.treloff;
3238   obj_datasec (abfd)->rel_filepos = aout_info.dreloff;
3239   obj_sym_filepos (abfd) = aout_info.symoff;
3240
3241   /* We keep a count of the symbols as we output them.  */
3242   obj_aout_external_sym_count (abfd) = 0;
3243
3244   /* We accumulate the string table as we write out the symbols.  */
3245   stringtab_init (&aout_info.strtab);
3246
3247   /* The most time efficient way to do the link would be to read all
3248      the input object files into memory and then sort out the
3249      information into the output file.  Unfortunately, that will
3250      probably use too much memory.  Another method would be to step
3251      through everything that composes the text section and write it
3252      out, and then everything that composes the data section and write
3253      it out, and then write out the relocs, and then write out the
3254      symbols.  Unfortunately, that requires reading stuff from each
3255      input file several times, and we will not be able to keep all the
3256      input files open simultaneously, and reopening them will be slow.
3257
3258      What we do is basically process one input file at a time.  We do
3259      everything we need to do with an input file once--copy over the
3260      section contents, handle the relocation information, and write
3261      out the symbols--and then we throw away the information we read
3262      from it.  This approach requires a lot of lseeks of the output
3263      file, which is unfortunate but still faster than reopening a lot
3264      of files.
3265
3266      We use the output_has_begun field of the input BFDs to see
3267      whether we have already handled it.  */
3268   for (sub = info->input_bfds; sub != (bfd *) NULL; sub = sub->link_next)
3269     sub->output_has_begun = false;
3270
3271   for (o = abfd->sections; o != (asection *) NULL; o = o->next)
3272     {
3273       for (p = o->link_order_head;
3274            p != (struct bfd_link_order *) NULL;
3275            p = p->next)
3276         {
3277           /* If we might be using the C based alloca function, we need
3278              to dump the memory allocated by aout_link_input_bfd.  */
3279 #ifndef __GNUC__
3280 #ifndef alloca
3281           (void) alloca (0);
3282 #endif
3283 #endif
3284           if (p->type == bfd_indirect_link_order
3285               && (bfd_get_flavour (p->u.indirect.section->owner)
3286                   == bfd_target_aout_flavour))
3287             {
3288               bfd *input_bfd;
3289
3290               input_bfd = p->u.indirect.section->owner;
3291               if (! input_bfd->output_has_begun)
3292                 {
3293                   if (! aout_link_input_bfd (&aout_info, input_bfd))
3294                     return false;
3295                   input_bfd->output_has_begun = true;
3296                 }
3297             }
3298           else
3299             {
3300               if (! _bfd_default_link_order (abfd, info, o, p))
3301                 return false;
3302             }
3303         }
3304     }
3305
3306   /* Write out any symbols that we have not already written out.  */
3307   aout_link_hash_traverse (aout_hash_table (info),
3308                            aout_link_write_other_symbol,
3309                            (PTR) &aout_info);
3310
3311   /* Update the header information.  */
3312   abfd->symcount = obj_aout_external_sym_count (abfd);
3313   exec_hdr (abfd)->a_syms = abfd->symcount * EXTERNAL_NLIST_SIZE;
3314   obj_str_filepos (abfd) = obj_sym_filepos (abfd) + exec_hdr (abfd)->a_syms;
3315   obj_textsec (abfd)->reloc_count =
3316     exec_hdr (abfd)->a_trsize / obj_reloc_entry_size (abfd);
3317   obj_datasec (abfd)->reloc_count =
3318     exec_hdr (abfd)->a_drsize / obj_reloc_entry_size (abfd);
3319
3320   /* Write out the string table.  */
3321   if (bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET) != 0)
3322     return false;
3323   emit_strtab (abfd, &aout_info.strtab);
3324
3325   return true;
3326 }
3327
3328 /* Link an a.out input BFD into the output file.  */
3329
3330 static boolean
3331 aout_link_input_bfd (finfo, input_bfd)
3332      struct aout_final_link_info *finfo;
3333      bfd *input_bfd;
3334 {
3335   bfd_size_type sym_count;
3336   int *symbol_map;
3337
3338   BFD_ASSERT (bfd_get_format (input_bfd) == bfd_object);
3339
3340   /* Get the symbols.  We probably have them already, unless
3341      finfo->info->keep_memory is false.  */
3342   if (! aout_link_get_symbols (input_bfd))
3343     return false;
3344
3345   sym_count = obj_aout_external_sym_count (input_bfd);
3346   symbol_map = (int *) alloca ((size_t) sym_count * sizeof (int));
3347
3348   /* Write out the symbols and get a map of the new indices.  */
3349   if (! aout_link_write_symbols (finfo, input_bfd, symbol_map))
3350     return false;
3351
3352   /* Relocate and write out the sections.  */
3353   if (! aout_link_input_section (finfo, input_bfd,
3354                                  obj_textsec (input_bfd),
3355                                  &finfo->treloff,
3356                                  exec_hdr (input_bfd)->a_trsize,
3357                                  symbol_map)
3358       || ! aout_link_input_section (finfo, input_bfd,
3359                                     obj_datasec (input_bfd),
3360                                     &finfo->dreloff,
3361                                     exec_hdr (input_bfd)->a_drsize,
3362                                     symbol_map))
3363     return false;
3364
3365   /* If we are not keeping memory, we don't need the symbols any
3366      longer.  We still need them if we are keeping memory, because the
3367      strings in the hash table point into them.  */
3368   if (! finfo->info->keep_memory)
3369     {
3370       if (! aout_link_free_symbols (input_bfd))
3371         return false;
3372     }
3373
3374   return true;
3375 }
3376
3377 /* Adjust and write out the symbols for an a.out file.  Set the new
3378    symbol indices into a symbol_map.  */
3379
3380 static boolean
3381 aout_link_write_symbols (finfo, input_bfd, symbol_map)
3382      struct aout_final_link_info *finfo;
3383      bfd *input_bfd;
3384      int *symbol_map;
3385 {
3386   bfd *output_bfd;
3387   bfd_size_type sym_count;
3388   char *strings;
3389   enum bfd_link_strip strip;
3390   enum bfd_link_discard discard;
3391   struct external_nlist *output_syms;
3392   struct external_nlist *outsym;
3393   register struct external_nlist *sym;
3394   struct external_nlist *sym_end;
3395   struct aout_link_hash_entry **sym_hash;
3396   boolean pass;
3397
3398   output_bfd = finfo->output_bfd;
3399   sym_count = obj_aout_external_sym_count (input_bfd);
3400   strings = obj_aout_external_strings (input_bfd);
3401   strip = finfo->info->strip;
3402   discard = finfo->info->discard;
3403   output_syms = ((struct external_nlist *)
3404                  alloca ((size_t) (sym_count + 1) * EXTERNAL_NLIST_SIZE));
3405   outsym = output_syms;
3406
3407   /* First write out a symbol for this object file, unless we are
3408      discarding such symbols.  */
3409   if (strip != strip_all
3410       && (strip != strip_some
3411           || bfd_hash_lookup (finfo->info->keep_hash, input_bfd->filename,
3412                               false, false) != NULL)
3413       && discard != discard_all)
3414     {
3415       bfd_h_put_8 (output_bfd, N_TEXT, outsym->e_type);
3416       bfd_h_put_8 (output_bfd, 0, outsym->e_other);
3417       bfd_h_put_16 (output_bfd, (bfd_vma) 0, outsym->e_desc);
3418       PUT_WORD (output_bfd,
3419                 add_to_stringtab (output_bfd, input_bfd->filename,
3420                                   &finfo->strtab),
3421                 outsym->e_strx);
3422       PUT_WORD (output_bfd,
3423                 bfd_get_section_vma (input_bfd, obj_textsec (input_bfd)),
3424                 outsym->e_value);
3425       ++obj_aout_external_sym_count (output_bfd);
3426       ++outsym;
3427     }
3428
3429   pass = false;
3430   sym = obj_aout_external_syms (input_bfd);
3431   sym_end = sym + sym_count;
3432   sym_hash = obj_aout_sym_hashes (input_bfd);
3433   for (; sym < sym_end; sym++, sym_hash++, symbol_map++)
3434     {
3435       const char *name;
3436       int type;
3437       boolean skip;
3438       asection *symsec;
3439       bfd_vma val = 0;
3440
3441       *symbol_map = -1;
3442
3443       type = bfd_h_get_8 (input_bfd, sym->e_type);
3444       name = strings + GET_WORD (input_bfd, sym->e_strx);
3445
3446       if (pass)
3447         {
3448           /* Pass this symbol through.  */
3449           val = GET_WORD (input_bfd, sym->e_value);
3450           pass = false;
3451         }
3452       else
3453         {
3454           struct aout_link_hash_entry *h;
3455
3456           /* We have saved the hash table entry for this symbol, if
3457              there is one.  Note that we could just look it up again
3458              in the hash table, provided we first check that it is an
3459              external symbol. */
3460           h = *sym_hash;
3461
3462           /* If the symbol has already been written out, skip it.  */
3463           if (h != (struct aout_link_hash_entry *) NULL
3464               && h->root.written)
3465             {
3466               *symbol_map = h->indx;
3467               continue;
3468             }
3469
3470           /* See if we are stripping this symbol.  */
3471           skip = false;
3472           switch (strip)
3473             {
3474             case strip_none:
3475               break;
3476             case strip_debugger:
3477               if ((type & N_STAB) != 0)
3478                 skip = true;
3479               break;
3480             case strip_some:
3481               if (bfd_hash_lookup (finfo->info->keep_hash, name, false, false)
3482                   == NULL)
3483                 skip = true;
3484               break;
3485             case strip_all:
3486               skip = true;
3487               break;
3488             }
3489           if (skip)
3490             {
3491               if (h != (struct aout_link_hash_entry *) NULL)
3492                 h->root.written = true;
3493               continue;
3494             }
3495
3496           /* Get the value of the symbol.  */
3497           if ((type & N_TYPE) == N_TEXT)
3498             symsec = obj_textsec (input_bfd);
3499           else if ((type & N_TYPE) == N_DATA)
3500             symsec = obj_datasec (input_bfd);
3501           else if ((type & N_TYPE) == N_BSS)
3502             symsec = obj_bsssec (input_bfd);
3503           else if ((type & N_TYPE) == N_ABS)
3504             symsec = &bfd_abs_section;
3505           else if ((type & N_TYPE) == N_INDR
3506                    || type == N_WARNING)
3507             {
3508               /* Pass the next symbol through unchanged.  */
3509               pass = true;
3510               val = GET_WORD (input_bfd, sym->e_value);
3511               symsec = NULL;
3512             }
3513           else if ((type & N_STAB) != 0)
3514             {
3515               val = GET_WORD (input_bfd, sym->e_value);
3516               symsec = NULL;
3517             }
3518           else
3519             {
3520               if (h == (struct aout_link_hash_entry *) NULL)
3521                 val = 0;
3522               else if (h->root.type == bfd_link_hash_defined)
3523                 {
3524                   asection *output_section;
3525
3526                   /* This case means a common symbol which was turned
3527                      into a defined symbol.  */
3528                   output_section = h->root.u.def.section->output_section;
3529                   BFD_ASSERT (output_section == &bfd_abs_section
3530                               || output_section->owner == output_bfd);
3531                   val = (h->root.u.def.value
3532                          + bfd_get_section_vma (output_bfd, output_section)
3533                          + h->root.u.def.section->output_offset);
3534
3535                   /* Get the correct type based on the section.  If
3536                      this is a constructed set, force it to be
3537                      globally visible.  */
3538                   if (type == N_SETT
3539                       || type == N_SETD
3540                       || type == N_SETB
3541                       || type == N_SETA)
3542                     type |= N_EXT;
3543
3544                   type &=~ N_TYPE;
3545
3546                   if (output_section == obj_textsec (output_bfd))
3547                     type |= N_TEXT;
3548                   else if (output_section == obj_datasec (output_bfd))
3549                     type |= N_DATA;
3550                   else if (output_section == obj_bsssec (output_bfd))
3551                     type |= N_BSS;
3552                   else
3553                     type |= N_ABS;
3554                 }
3555               else if (h->root.type == bfd_link_hash_common)
3556                 val = h->root.u.c.size;
3557               else
3558                 val = 0;
3559
3560               symsec = NULL;
3561             }
3562           if (symsec != (asection *) NULL)
3563             val = (symsec->output_section->vma
3564                    + symsec->output_offset
3565                    + (GET_WORD (input_bfd, sym->e_value)
3566                       - symsec->vma));
3567
3568           /* If this is a global symbol set the written flag, and if
3569              it is a local symbol see if we should discard it.  */
3570           if (h != (struct aout_link_hash_entry *) NULL)
3571             {
3572               h->root.written = true;
3573               h->indx = obj_aout_external_sym_count (output_bfd);
3574             }
3575           else
3576             {
3577               switch (discard)
3578                 {
3579                 case discard_none:
3580                   break;
3581                 case discard_l:
3582                   if (*name == *finfo->info->lprefix
3583                       && (finfo->info->lprefix_len == 1
3584                           || strncmp (name, finfo->info->lprefix,
3585                                       finfo->info->lprefix_len) == 0))
3586                     skip = true;
3587                   break;
3588                 case discard_all:
3589                   skip = true;
3590                   break;
3591                 }
3592               if (skip)
3593                 {
3594                   pass = false;
3595                   continue;
3596                 }
3597             }
3598         }
3599
3600       /* Copy this symbol into the list of symbols we are going to
3601          write out.  */
3602       bfd_h_put_8 (output_bfd, type, outsym->e_type);
3603       bfd_h_put_8 (output_bfd, bfd_h_get_8 (input_bfd, sym->e_other),
3604                    outsym->e_other);
3605       bfd_h_put_16 (output_bfd, bfd_h_get_16 (input_bfd, sym->e_desc),
3606                     outsym->e_desc);
3607       PUT_WORD (output_bfd,
3608                 add_to_stringtab (output_bfd, name, &finfo->strtab),
3609                 outsym->e_strx);
3610       PUT_WORD (output_bfd, val, outsym->e_value);
3611       *symbol_map = obj_aout_external_sym_count (output_bfd);
3612       ++obj_aout_external_sym_count (output_bfd);
3613       ++outsym;
3614     }
3615
3616   /* Write out the output symbols we have just constructed.  */
3617   if (outsym > output_syms)
3618     {
3619       bfd_size_type outsym_count;
3620
3621       if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0)
3622         return false;
3623       outsym_count = outsym - output_syms;
3624       if (bfd_write ((PTR) output_syms, (bfd_size_type) EXTERNAL_NLIST_SIZE,
3625                      (bfd_size_type) outsym_count, output_bfd)
3626           != outsym_count * EXTERNAL_NLIST_SIZE)
3627         return false;
3628       finfo->symoff += outsym_count * EXTERNAL_NLIST_SIZE;
3629     }
3630
3631   return true;
3632 }
3633
3634 /* Write out a symbol that was not associated with an a.out input
3635    object.  */
3636
3637 static boolean
3638 aout_link_write_other_symbol (h, data)
3639      struct aout_link_hash_entry *h;
3640      PTR data;
3641 {
3642   struct aout_final_link_info *finfo = (struct aout_final_link_info *) data;
3643   bfd *output_bfd;
3644   int type;
3645   bfd_vma val;
3646   struct external_nlist outsym;
3647
3648   if (h->root.written)
3649     return true;
3650
3651   output_bfd = finfo->output_bfd;
3652
3653   switch (h->root.type)
3654     {
3655     default:
3656     case bfd_link_hash_new:
3657       abort ();
3658       /* Avoid variable not initialized warnings.  */
3659       return true;
3660     case bfd_link_hash_undefined:
3661       type = N_UNDF | N_EXT;
3662       val = 0;
3663       break;
3664     case bfd_link_hash_defined:
3665       {
3666         asection *sec;
3667
3668         sec = h->root.u.def.section;
3669         BFD_ASSERT (sec == &bfd_abs_section
3670                     || sec->owner == output_bfd);
3671         if (sec == obj_textsec (output_bfd))
3672           type = N_TEXT | N_EXT;
3673         else if (sec == obj_datasec (output_bfd))
3674           type = N_DATA | N_EXT;
3675         else if (sec == obj_bsssec (output_bfd))
3676           type = N_BSS | N_EXT;
3677         else
3678           type = N_ABS | N_EXT;
3679         val = (h->root.u.def.value
3680                + sec->output_section->vma
3681                + sec->output_offset);
3682       }
3683       break;
3684     case bfd_link_hash_common:
3685       type = N_UNDF | N_EXT;
3686       val = h->root.u.c.size;
3687       break;
3688     case bfd_link_hash_indirect:
3689     case bfd_link_hash_warning:
3690       /* FIXME: Ignore these for now.  The circumstances under which
3691          they should be written out are not clear to me.  */
3692       return true;
3693     }
3694
3695   bfd_h_put_8 (output_bfd, type, outsym.e_type);
3696   bfd_h_put_8 (output_bfd, 0, outsym.e_other);
3697   bfd_h_put_16 (output_bfd, 0, outsym.e_desc);
3698   PUT_WORD (output_bfd,
3699             add_to_stringtab (output_bfd, h->root.root.string, &finfo->strtab),
3700             outsym.e_strx);
3701   PUT_WORD (output_bfd, val, outsym.e_value);
3702
3703   if (bfd_seek (output_bfd, finfo->symoff, SEEK_SET) != 0
3704       || bfd_write ((PTR) &outsym, (bfd_size_type) EXTERNAL_NLIST_SIZE,
3705                     (bfd_size_type) 1, output_bfd) != EXTERNAL_NLIST_SIZE)
3706     {
3707       /* FIXME: No way to handle errors.  */
3708       abort ();
3709     }
3710
3711   finfo->symoff += EXTERNAL_NLIST_SIZE;
3712   h->indx = obj_aout_external_sym_count (output_bfd);
3713   ++obj_aout_external_sym_count (output_bfd);
3714
3715   return true;
3716 }
3717
3718 /* Link an a.out section into the output file.  */
3719
3720 static boolean
3721 aout_link_input_section (finfo, input_bfd, input_section, reloff_ptr,
3722                          rel_size, symbol_map)
3723      struct aout_final_link_info *finfo;
3724      bfd *input_bfd;
3725      asection *input_section;
3726      file_ptr *reloff_ptr;
3727      bfd_size_type rel_size;
3728      int *symbol_map;
3729 {
3730   bfd_size_type input_size;
3731   bfd_byte *contents;
3732   PTR relocs;
3733
3734   /* Get the section contents.  */
3735   input_size = bfd_section_size (input_bfd, input_section);
3736   contents = (bfd_byte *) alloca (input_size);
3737   if (! bfd_get_section_contents (input_bfd, input_section, (PTR) contents,
3738                                   (file_ptr) 0, input_size))
3739     return false;
3740
3741   /* Read in the relocs.  */
3742   relocs = (PTR) alloca (rel_size);
3743   if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
3744       || bfd_read (relocs, 1, rel_size, input_bfd) != rel_size)
3745     return false;
3746
3747   /* Relocate the section contents.  */
3748   if (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE)
3749     {
3750       if (! aout_link_input_section_std (finfo, input_bfd, input_section,
3751                                          (struct reloc_std_external *) relocs,
3752                                          rel_size, contents, symbol_map))
3753         return false;
3754     }
3755   else
3756     {
3757       if (! aout_link_input_section_ext (finfo, input_bfd, input_section,
3758                                          (struct reloc_ext_external *) relocs,
3759                                          rel_size, contents, symbol_map))
3760         return false;
3761     }
3762
3763   /* Write out the section contents.  */
3764   if (! bfd_set_section_contents (finfo->output_bfd,
3765                                   input_section->output_section,
3766                                   (PTR) contents,
3767                                   input_section->output_offset,
3768                                   input_size))
3769     return false;
3770
3771   /* If we are producing relocateable output, the relocs were
3772      modified, and we now write them out.  */
3773   if (finfo->info->relocateable)
3774     {
3775       if (bfd_seek (finfo->output_bfd, *reloff_ptr, SEEK_SET) != 0)
3776         return false;
3777       if (bfd_write (relocs, (bfd_size_type) 1, rel_size, finfo->output_bfd)
3778           != rel_size)
3779         return false;
3780       *reloff_ptr += rel_size;
3781
3782       /* Assert that the relocs have not run into the symbols, and
3783          that if these are the text relocs they have not run into the
3784          data relocs.  */
3785       BFD_ASSERT (*reloff_ptr <= obj_sym_filepos (finfo->output_bfd)
3786                   && (reloff_ptr != &finfo->treloff
3787                       || (*reloff_ptr
3788                           <= obj_datasec (finfo->output_bfd)->rel_filepos)));
3789     }
3790
3791   return true;
3792 }
3793
3794 /* Get the section corresponding to a reloc index.  */
3795
3796 static INLINE asection *
3797 aout_reloc_index_to_section (abfd, indx)
3798      bfd *abfd;
3799      int indx;
3800 {
3801   switch (indx & N_TYPE)
3802     {
3803     case N_TEXT:
3804       return obj_textsec (abfd);
3805     case N_DATA:
3806       return obj_datasec (abfd);
3807     case N_BSS:
3808       return obj_bsssec (abfd);
3809     case N_ABS:
3810       return &bfd_abs_section;
3811     default:
3812       abort ();
3813     }
3814 }
3815
3816 /* Relocate an a.out section using standard a.out relocs.  */
3817
3818 static boolean
3819 aout_link_input_section_std (finfo, input_bfd, input_section, relocs,
3820                              rel_size, contents, symbol_map)
3821      struct aout_final_link_info *finfo;
3822      bfd *input_bfd;
3823      asection *input_section;
3824      struct reloc_std_external *relocs;
3825      bfd_size_type rel_size;
3826      bfd_byte *contents;
3827      int *symbol_map;
3828 {
3829   bfd *output_bfd;
3830   boolean relocateable;
3831   struct external_nlist *syms;
3832   char *strings;
3833   struct aout_link_hash_entry **sym_hashes;
3834   bfd_size_type reloc_count;
3835   register struct reloc_std_external *rel;
3836   struct reloc_std_external *rel_end;
3837
3838   output_bfd = finfo->output_bfd;
3839
3840   BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_STD_SIZE);
3841   BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
3842               == output_bfd->xvec->header_byteorder_big_p);
3843
3844   relocateable = finfo->info->relocateable;
3845   syms = obj_aout_external_syms (input_bfd);
3846   strings = obj_aout_external_strings (input_bfd);
3847   sym_hashes = obj_aout_sym_hashes (input_bfd);
3848
3849   reloc_count = rel_size / RELOC_STD_SIZE;
3850   rel = relocs;
3851   rel_end = rel + reloc_count;
3852   for (; rel < rel_end; rel++)
3853     {
3854       bfd_vma r_addr;
3855       int r_index;
3856       int r_extern;
3857       int r_pcrel;
3858       int r_baserel;
3859       int r_jmptable;
3860       int r_relative;
3861       int r_length;
3862       int howto_idx;
3863       bfd_vma relocation;
3864       bfd_reloc_status_type r;
3865
3866       r_addr = GET_SWORD (input_bfd, rel->r_address);
3867
3868       if (input_bfd->xvec->header_byteorder_big_p)
3869         {
3870           r_index   =  ((rel->r_index[0] << 16)
3871                         | (rel->r_index[1] << 8)
3872                         | rel->r_index[2]);
3873           r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
3874           r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
3875           r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
3876           r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
3877           r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
3878           r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_BIG)
3879                        >> RELOC_STD_BITS_LENGTH_SH_BIG);
3880         }
3881       else
3882         {
3883           r_index   = ((rel->r_index[2] << 16)
3884                        | (rel->r_index[1] << 8)
3885                        | rel->r_index[0]);
3886           r_extern  = (0 != (rel->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
3887           r_pcrel   = (0 != (rel->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
3888           r_baserel = (0 != (rel->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
3889           r_jmptable= (0 != (rel->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
3890           r_relative= (0 != (rel->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
3891           r_length  = ((rel->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE)
3892                        >> RELOC_STD_BITS_LENGTH_SH_LITTLE);
3893         }
3894
3895       howto_idx = r_length + 4 * r_pcrel + 8 * r_baserel;
3896       BFD_ASSERT (howto_idx < TABLE_SIZE (howto_table_std));
3897       BFD_ASSERT (r_jmptable == 0);
3898       BFD_ASSERT (r_relative == 0);
3899
3900       if (relocateable)
3901         {
3902           /* We are generating a relocateable output file, and must
3903              modify the reloc accordingly.  */
3904           if (r_extern)
3905             {
3906               struct aout_link_hash_entry *h;
3907
3908               /* If we know the symbol this relocation is against,
3909                  convert it into a relocation against a section.  This
3910                  is what the native linker does.  */
3911               h = sym_hashes[r_index];
3912               if (h != (struct aout_link_hash_entry *) NULL
3913                   && h->root.type == bfd_link_hash_defined)
3914                 {
3915                   asection *output_section;
3916
3917                   /* Change the r_extern value.  */
3918                   if (output_bfd->xvec->header_byteorder_big_p)
3919                     rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_BIG;
3920                   else
3921                     rel->r_type[0] &=~ RELOC_STD_BITS_EXTERN_LITTLE;
3922
3923                   /* Compute a new r_index.  */
3924                   output_section = h->root.u.def.section->output_section;
3925                   if (output_section == obj_textsec (output_bfd))
3926                     r_index = N_TEXT;
3927                   else if (output_section == obj_datasec (output_bfd))
3928                     r_index = N_DATA;
3929                   else if (output_section == obj_bsssec (output_bfd))
3930                     r_index = N_BSS;
3931                   else
3932                     r_index = N_ABS;
3933
3934                   /* Add the symbol value and the section VMA to the
3935                      addend stored in the contents.  */
3936                   relocation = (h->root.u.def.value
3937                                 + output_section->vma
3938                                 + h->root.u.def.section->output_offset);
3939                 }
3940               else
3941                 {
3942                   /* We must change r_index according to the symbol
3943                      map.  */
3944                   r_index = symbol_map[r_index];
3945
3946                   if (r_index == -1)
3947                     {
3948                       const char *name;
3949
3950                       name = strings + GET_WORD (input_bfd,
3951                                                  syms[r_index].e_strx);
3952                       if (! ((*finfo->info->callbacks->unattached_reloc)
3953                              (finfo->info, name, input_bfd, input_section,
3954                               r_addr)))
3955                         return false;
3956                       r_index = 0;
3957                     }
3958
3959                   relocation = 0;
3960                 }
3961
3962               /* Write out the new r_index value.  */
3963               if (output_bfd->xvec->header_byteorder_big_p)
3964                 {
3965                   rel->r_index[0] = r_index >> 16;
3966                   rel->r_index[1] = r_index >> 8;
3967                   rel->r_index[2] = r_index;
3968                 }
3969               else
3970                 {
3971                   rel->r_index[2] = r_index >> 16;
3972                   rel->r_index[1] = r_index >> 8;
3973                   rel->r_index[0] = r_index;
3974                 }
3975             }
3976           else
3977             {
3978               asection *section;
3979
3980               /* This is a relocation against a section.  We must
3981                  adjust by the amount that the section moved.  */
3982               section = aout_reloc_index_to_section (input_bfd, r_index);
3983               relocation = (section->output_section->vma
3984                             + section->output_offset
3985                             - section->vma);
3986             }
3987
3988           /* Change the address of the relocation.  */
3989           PUT_WORD (output_bfd,
3990                     r_addr + input_section->output_offset,
3991                     rel->r_address);
3992
3993           /* Adjust a PC relative relocation by removing the reference
3994              to the original address in the section and including the
3995              reference to the new address.  */
3996           if (r_pcrel)
3997             relocation -= (input_section->output_section->vma
3998                            + input_section->output_offset
3999                            - input_section->vma);
4000
4001           if (relocation == 0)
4002             r = bfd_reloc_ok;
4003           else
4004             r = _bfd_relocate_contents (howto_table_std + howto_idx,
4005                                         input_bfd, relocation,
4006                                         contents + r_addr);
4007         }
4008       else
4009         {
4010           /* We are generating an executable, and must do a full
4011              relocation.  */
4012           if (r_extern)
4013             {
4014               struct aout_link_hash_entry *h;
4015
4016               h = sym_hashes[r_index];
4017               if (h != (struct aout_link_hash_entry *) NULL
4018                   && h->root.type == bfd_link_hash_defined)
4019                 {
4020                   relocation = (h->root.u.def.value
4021                                 + h->root.u.def.section->output_section->vma
4022                                 + h->root.u.def.section->output_offset);
4023                 }
4024               else
4025                 {
4026                   const char *name;
4027
4028                   name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
4029                   if (! ((*finfo->info->callbacks->undefined_symbol)
4030                          (finfo->info, name, input_bfd, input_section,
4031                           r_addr)))
4032                     return false;
4033                   relocation = 0;
4034                 }
4035             }
4036           else
4037             {
4038               asection *section;
4039
4040               section = aout_reloc_index_to_section (input_bfd, r_index);
4041               relocation = (section->output_section->vma
4042                             + section->output_offset
4043                             - section->vma);
4044               if (r_pcrel)
4045                 relocation += input_section->vma;
4046             }
4047
4048           r = _bfd_final_link_relocate (howto_table_std + howto_idx,
4049                                         input_bfd, input_section,
4050                                         contents, r_addr, relocation,
4051                                         (bfd_vma) 0);
4052         }
4053
4054       if (r != bfd_reloc_ok)
4055         {
4056           switch (r)
4057             {
4058             default:
4059             case bfd_reloc_outofrange:
4060               abort ();
4061             case bfd_reloc_overflow:
4062               if (! ((*finfo->info->callbacks->reloc_overflow)
4063                      (finfo->info, input_bfd, input_section, r_addr)))
4064                 return false;
4065               break;
4066             }
4067         }
4068     }
4069
4070   return true;
4071 }
4072
4073 /* Relocate an a.out section using extended a.out relocs.  */
4074
4075 static boolean
4076 aout_link_input_section_ext (finfo, input_bfd, input_section, relocs,
4077                              rel_size, contents, symbol_map)
4078      struct aout_final_link_info *finfo;
4079      bfd *input_bfd;
4080      asection *input_section;
4081      struct reloc_ext_external *relocs;
4082      bfd_size_type rel_size;
4083      bfd_byte *contents;
4084      int *symbol_map;
4085 {
4086   bfd *output_bfd;
4087   boolean relocateable;
4088   struct external_nlist *syms;
4089   char *strings;
4090   struct aout_link_hash_entry **sym_hashes;
4091   bfd_size_type reloc_count;
4092   register struct reloc_ext_external *rel;
4093   struct reloc_ext_external *rel_end;
4094
4095   output_bfd = finfo->output_bfd;
4096
4097   BFD_ASSERT (obj_reloc_entry_size (input_bfd) == RELOC_EXT_SIZE);
4098   BFD_ASSERT (input_bfd->xvec->header_byteorder_big_p
4099               == output_bfd->xvec->header_byteorder_big_p);
4100
4101   relocateable = finfo->info->relocateable;
4102   syms = obj_aout_external_syms (input_bfd);
4103   strings = obj_aout_external_strings (input_bfd);
4104   sym_hashes = obj_aout_sym_hashes (input_bfd);
4105
4106   reloc_count = rel_size / RELOC_EXT_SIZE;
4107   rel = relocs;
4108   rel_end = rel + reloc_count;
4109   for (; rel < rel_end; rel++)
4110     {
4111       bfd_vma r_addr;
4112       int r_index;
4113       int r_extern;
4114       int r_type;
4115       bfd_vma r_addend;
4116       bfd_vma relocation;
4117
4118       r_addr = GET_SWORD (input_bfd, rel->r_address);
4119
4120       if (input_bfd->xvec->header_byteorder_big_p)
4121         {
4122           r_index  = ((rel->r_index[0] << 16)
4123                       | (rel->r_index[1] << 8)
4124                       | rel->r_index[2]);
4125           r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
4126           r_type   = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
4127                       >> RELOC_EXT_BITS_TYPE_SH_BIG);
4128         }
4129       else
4130         {
4131           r_index  = ((rel->r_index[2] << 16)
4132                       | (rel->r_index[1] << 8)
4133                       | rel->r_index[0]);
4134           r_extern = (0 != (rel->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
4135           r_type   = ((rel->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
4136                       >> RELOC_EXT_BITS_TYPE_SH_LITTLE);
4137         }
4138
4139       r_addend = GET_SWORD (input_bfd, rel->r_addend);
4140
4141       BFD_ASSERT (r_type >= 0
4142                   && r_type < TABLE_SIZE (howto_table_ext));
4143
4144       if (relocateable)
4145         {
4146           /* We are generating a relocateable output file, and must
4147              modify the reloc accordingly.  */
4148           if (r_extern)
4149             {
4150               struct aout_link_hash_entry *h;
4151
4152               /* If we know the symbol this relocation is against,
4153                  convert it into a relocation against a section.  This
4154                  is what the native linker does.  */
4155               h = sym_hashes[r_index];
4156               if (h != (struct aout_link_hash_entry *) NULL
4157                   && h->root.type == bfd_link_hash_defined)
4158                 {
4159                   asection *output_section;
4160
4161                   /* Change the r_extern value.  */
4162                   if (output_bfd->xvec->header_byteorder_big_p)
4163                     rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_BIG;
4164                   else
4165                     rel->r_type[0] &=~ RELOC_EXT_BITS_EXTERN_LITTLE;
4166
4167                   /* Compute a new r_index.  */
4168                   output_section = h->root.u.def.section->output_section;
4169                   if (output_section == obj_textsec (output_bfd))
4170                     r_index = N_TEXT;
4171                   else if (output_section == obj_datasec (output_bfd))
4172                     r_index = N_DATA;
4173                   else if (output_section == obj_bsssec (output_bfd))
4174                     r_index = N_BSS;
4175                   else
4176                     r_index = N_ABS;
4177
4178                   /* Add the symbol value and the section VMA to the
4179                      addend.  */
4180                   relocation = (h->root.u.def.value
4181                                 + output_section->vma
4182                                 + h->root.u.def.section->output_offset);
4183
4184                   /* Now RELOCATION is the VMA of the final
4185                      destination.  If this is a PC relative reloc,
4186                      then ADDEND is the negative of the source VMA.
4187                      We want to set ADDEND to the difference between
4188                      the destination VMA and the source VMA, which
4189                      means we must adjust RELOCATION by the change in
4190                      the source VMA.  This is done below.  */
4191                 }
4192               else
4193                 {
4194                   /* We must change r_index according to the symbol
4195                      map.  */
4196                   r_index = symbol_map[r_index];
4197
4198                   if (r_index == -1)
4199                     {
4200                       const char *name;
4201
4202                       name = (strings
4203                               + GET_WORD (input_bfd, syms[r_index].e_strx));
4204                       if (! ((*finfo->info->callbacks->unattached_reloc)
4205                              (finfo->info, name, input_bfd, input_section,
4206                               r_addr)))
4207                         return false;
4208                       r_index = 0;
4209                     }
4210
4211                   relocation = 0;
4212
4213                   /* If this is a PC relative reloc, then the addend
4214                      is the negative of the source VMA.  We must
4215                      adjust it by the change in the source VMA.  This
4216                      is done below.  */
4217                 }
4218
4219               /* Write out the new r_index value.  */
4220               if (output_bfd->xvec->header_byteorder_big_p)
4221                 {
4222                   rel->r_index[0] = r_index >> 16;
4223                   rel->r_index[1] = r_index >> 8;
4224                   rel->r_index[2] = r_index;
4225                 }
4226               else
4227                 {
4228                   rel->r_index[2] = r_index >> 16;
4229                   rel->r_index[1] = r_index >> 8;
4230                   rel->r_index[0] = r_index;
4231                 }
4232             }
4233           else
4234             {
4235               asection *section;
4236
4237               /* This is a relocation against a section.  We must
4238                  adjust by the amount that the section moved.  */
4239               section = aout_reloc_index_to_section (input_bfd, r_index);
4240               relocation = (section->output_section->vma
4241                             + section->output_offset
4242                             - section->vma);
4243
4244               /* If this is a PC relative reloc, then the addend is
4245                  the difference in VMA between the destination and the
4246                  source.  We have just adjusted for the change in VMA
4247                  of the destination, so we must also adjust by the
4248                  change in VMA of the source.  This is done below.  */
4249             }
4250
4251           /* As described above, we must always adjust a PC relative
4252              reloc by the change in VMA of the source.  */
4253           if (howto_table_ext[r_type].pc_relative)
4254             relocation -= (input_section->output_section->vma
4255                            + input_section->output_offset
4256                            - input_section->vma);
4257
4258           /* Change the addend if necessary.  */
4259           if (relocation != 0)
4260             PUT_WORD (output_bfd, r_addend + relocation, rel->r_addend);
4261
4262           /* Change the address of the relocation.  */
4263           PUT_WORD (output_bfd,
4264                     r_addr + input_section->output_offset,
4265                     rel->r_address);
4266         }
4267       else
4268         {
4269           bfd_reloc_status_type r;
4270
4271           /* We are generating an executable, and must do a full
4272              relocation.  */
4273           if (r_extern)
4274             {
4275               struct aout_link_hash_entry *h;
4276
4277               h = sym_hashes[r_index];
4278               if (h != (struct aout_link_hash_entry *) NULL
4279                   && h->root.type == bfd_link_hash_defined)
4280                 {
4281                   relocation = (h->root.u.def.value
4282                                 + h->root.u.def.section->output_section->vma
4283                                 + h->root.u.def.section->output_offset);
4284                 }
4285               else
4286                 {
4287                   const char *name;
4288
4289                   name = strings + GET_WORD (input_bfd, syms[r_index].e_strx);
4290                   if (! ((*finfo->info->callbacks->undefined_symbol)
4291                          (finfo->info, name, input_bfd, input_section,
4292                           r_addr)))
4293                     return false;
4294                   relocation = 0;
4295                 }
4296             }
4297           else
4298             {
4299               asection *section;
4300
4301               section = aout_reloc_index_to_section (input_bfd, r_index);
4302
4303               /* If this is a PC relative reloc, then R_ADDEND is the
4304                  difference between the two vmas, or
4305                    old_dest_sec + old_dest_off - (old_src_sec + old_src_off)
4306                  where
4307                    old_dest_sec == section->vma
4308                  and
4309                    old_src_sec == input_section->vma
4310                  and
4311                    old_src_off == r_addr
4312
4313                  _bfd_final_link_relocate expects RELOCATION +
4314                  R_ADDEND to be the VMA of the destination minus
4315                  r_addr (the minus r_addr is because this relocation
4316                  is not pcrel_offset, which is a bit confusing and
4317                  should, perhaps, be changed), or
4318                    new_dest_sec
4319                  where
4320                    new_dest_sec == output_section->vma + output_offset
4321                  We arrange for this to happen by setting RELOCATION to
4322                    new_dest_sec + old_src_sec - old_dest_sec
4323
4324                  If this is not a PC relative reloc, then R_ADDEND is
4325                  simply the VMA of the destination, so we set
4326                  RELOCATION to the change in the destination VMA, or
4327                    new_dest_sec - old_dest_sec
4328                  */
4329               relocation = (section->output_section->vma
4330                             + section->output_offset
4331                             - section->vma);
4332               if (howto_table_ext[r_type].pc_relative)
4333                 relocation += input_section->vma;
4334             }
4335
4336           r = _bfd_final_link_relocate (howto_table_ext + r_type,
4337                                         input_bfd, input_section,
4338                                         contents, r_addr, relocation,
4339                                         r_addend);
4340           if (r != bfd_reloc_ok)
4341             {
4342               switch (r)
4343                 {
4344                 default:
4345                 case bfd_reloc_outofrange:
4346                   abort ();
4347                 case bfd_reloc_overflow:
4348                   if (! ((*finfo->info->callbacks->reloc_overflow)
4349                          (finfo->info, input_bfd, input_section, r_addr)))
4350                     return false;
4351                   break;
4352                 }
4353             }
4354         }
4355     }
4356
4357   return true;
4358 }
This page took 0.265148 seconds and 4 git commands to generate.