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