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