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