* aoutx.h (translate_from_native_sym_flags): Removed statep
[external/binutils.git] / bfd / aoutx.h
1 /* BFD semi-generic back-end for a.out binaries.
2    Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
3    Written by Cygnus Support.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 /*
22 SECTION
23         a.out backends
24
25
26 DESCRIPTION
27
28         BFD supports a number of different flavours of a.out format,
29         though the major differences are only the sizes of the
30         structures on disk, and the shape of the relocation
31         information. 
32
33         The support is split into a basic support file @code{aoutx.h}
34         and other files which derive functions from the base. One
35         derivation file is @code{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 @code{sunos.c} for sun3 and sun4,
42         @code{newsos3.c} for the Sony NEWS, and @code{demo64.c} for a
43         demonstration of a 64 bit a.out format.
44
45         The base file @code{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         @code{aout32.c} and @code{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 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 sunos.c
67
68 |       #define ARCH 32
69 |       #define TARGET_NAME "a.out-sunos-big"
70 |       #define VECNAME    sunos_big_vec
71 |       #include "aoutf1.h"
72
73         requires all the names from aout32.c, and produces the jump vector
74
75 |       sunos_big_vec
76
77         The file host-aout.c is a special case.  It is for a large set
78         of hosts that use ``more or less standard'' a.out files, and
79         for which cross-debugging is not interesting.  It uses the
80         standard 32-bit a.out support routines, but determines the
81         file offsets and addresses of the text, data, and BSS
82         sections, the machine architecture and machine type, and the
83         entry point address, in a host-dependent manner.  Once these
84         values have been determined, generic code is used to handle
85         the  object file. 
86
87         When porting it to run on a new system, you must supply:
88
89 |        HOST_PAGE_SIZE
90 |        HOST_SEGMENT_SIZE
91 |        HOST_MACHINE_ARCH       (optional)
92 |        HOST_MACHINE_MACHINE    (optional)
93 |        HOST_TEXT_START_ADDR
94 |        HOST_STACK_END_ADDR
95
96         in the file <<../include/sys/h-XXX.h>> (for your host).  These
97         values, plus the structures and macros defined in <<a.out.h>> on
98         your host system, will produce a BFD target that will access
99         ordinary a.out files on your host. To configure a new machine
100         to use <<host-aout.c>., specify: 
101
102 |       TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec
103 |       TDEPFILES= host-aout.o trad-core.o
104
105         in the <<config/mt-XXX>> file, and modify configure.in to use the
106         <<mt-XXX>> 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 <assert.h>
124 #include <string.h>             /* For strchr and friends */
125 #include "bfd.h"
126 #include <sysdep.h>
127 #include <ansidecl.h>
128
129 struct external_exec;
130 #include "libaout.h"
131 #include "libbfd.h"
132 #include "aout/aout64.h"
133 #include "aout/stab_gnu.h"
134 #include "aout/ar.h"
135
136 extern void (*bfd_error_trap)();
137
138 /*
139 SUBSECTION
140         relocations
141
142 DESCRIPTION
143         The file @code{aoutx.h} caters for both the @emph{standard}
144         and @emph{extended} forms of a.out relocation records.
145
146         The standard records are characterised by containing only an
147         address, a symbol index and a type field. The extended records
148         (used on 29ks and sparcs) also have a full integer for an
149         addend. 
150
151 */
152 #define CTOR_TABLE_RELOC_IDX 2
153
154 #define howto_table_ext NAME(aout,ext_howto_table)
155 #define howto_table_std NAME(aout,std_howto_table)
156
157 reloc_howto_type howto_table_ext[] = 
158 {
159 /*      type rightshift size bitsize pc_  bit absol compl  spec  name partial_ src_ dst_    pcrel_
160                                      rela pos ute   ain_on ial_       inplace  mask mask    offset
161                                      tive           _overf fn                                       */
162   HOWTO(RELOC_8,      0,  0,    8,  false, 0, true,  true,0,"8",        false, 0,0x000000ff, false),
163   HOWTO(RELOC_16,     0,  1,    16, false, 0, true,  true,0,"16",       false, 0,0x0000ffff, false),
164   HOWTO(RELOC_32,     0,  2,    32, false, 0, true,  true,0,"32",       false, 0,0xffffffff, false),
165   HOWTO(RELOC_DISP8,  0,  0,    8,  true,  0, false, true,0,"DISP8",    false, 0,0x000000ff, false),
166   HOWTO(RELOC_DISP16, 0,  1,    16, true,  0, false, true,0,"DISP16",   false, 0,0x0000ffff, false),
167   HOWTO(RELOC_DISP32, 0,  2,    32, true,  0, false, true,0,"DISP32",   false, 0,0xffffffff, false),
168   HOWTO(RELOC_WDISP30,2,  2,    30, true,  0, false, true,0,"WDISP30",  false, 0,0x3fffffff, false),
169   HOWTO(RELOC_WDISP22,2,  2,    22, true,  0, false, true,0,"WDISP22",  false, 0,0x003fffff, false),
170   HOWTO(RELOC_HI22,   10, 2,    22, false, 0, false, true,0,"HI22",     false, 0,0x003fffff, false),
171   HOWTO(RELOC_22,     0,  2,    22, false, 0, false, true,0,"22",       false, 0,0x003fffff, false),
172   HOWTO(RELOC_13,     0,  2,    13, false, 0, false, true,0,"13",       false, 0,0x00001fff, false),
173   HOWTO(RELOC_LO10,   0,  2,    10, false, 0, false, true,0,"LO10",     false, 0,0x000003ff, false),
174   HOWTO(RELOC_SFA_BASE,0, 2,    32, false, 0, false, true,0,"SFA_BASE", false, 0,0xffffffff, false),
175   HOWTO(RELOC_SFA_OFF13,0,2,    32, false, 0, false, true,0,"SFA_OFF13",false, 0,0xffffffff, false),
176   HOWTO(RELOC_BASE10, 0,  2,    16, false, 0, false, true,0,"BASE10",   false, 0,0x0000ffff, false),
177   HOWTO(RELOC_BASE13, 0,  2,    13, false, 0, false, true,0,"BASE13",   false, 0,0x00001fff, false),
178   HOWTO(RELOC_BASE22, 0,  2,    0,  false, 0, false, true,0,"BASE22",   false, 0,0x00000000, false),
179   HOWTO(RELOC_PC10,   0,  2,    10, false, 0, false, true,0,"PC10",     false, 0,0x000003ff, false),
180   HOWTO(RELOC_PC22,   0,  2,    22, false, 0, false, true,0,"PC22",     false, 0,0x003fffff, false),
181   HOWTO(RELOC_JMP_TBL,0,  2,    32, false, 0, false, true,0,"JMP_TBL",  false, 0,0xffffffff, false),
182   HOWTO(RELOC_SEGOFF16,0, 2,    0,  false, 0, false, true,0,"SEGOFF16", false, 0,0x00000000, false),
183   HOWTO(RELOC_GLOB_DAT,0, 2,    0,  false, 0, false, true,0,"GLOB_DAT", false, 0,0x00000000, false),
184   HOWTO(RELOC_JMP_SLOT,0, 2,    0,  false, 0, false, true,0,"JMP_SLOT", false, 0,0x00000000, false),
185   HOWTO(RELOC_RELATIVE,0, 2,    0,  false, 0, false, true,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  abs ovrf sf name    part_inpl   readmask  setmask  pcdone */
192 HOWTO( 0,              0,  0,   8,  false, 0, true,  true,0,"8",        true, 0x000000ff,0x000000ff, false),
193 HOWTO( 1,              0,  1,   16, false, 0, true,  true,0,"16",       true, 0x0000ffff,0x0000ffff, false),
194 HOWTO( 2,              0,  2,   32, false, 0, true,  true,0,"32",       true, 0xffffffff,0xffffffff, false),
195 HOWTO( 3,              0,  3,   64, false, 0, true,  true,0,"64",       true, 0xdeaddead,0xdeaddead, false),
196 HOWTO( 4,              0,  0,   8,  true,  0, false, true,0,"DISP8",    true, 0x000000ff,0x000000ff, false),
197 HOWTO( 5,              0,  1,   16, true,  0, false, true,0,"DISP16",   true, 0x0000ffff,0x0000ffff, false),
198 HOWTO( 6,              0,  2,   32, true,  0, false, true,0,"DISP32",   true, 0xffffffff,0xffffffff, false),
199 HOWTO( 7,              0,  3,   64, true,  0, false, true,0,"DISP64",   true, 0xfeedface,0xfeedface, false),
200 };
201
202 CONST struct reloc_howto_struct *
203 DEFUN(NAME(aout,reloc_type_lookup),(abfd,code),
204       bfd *abfd AND
205       bfd_reloc_code_real_type code)
206 {
207 #define EXT(i,j)        case i: return &howto_table_ext[j]
208 #define STD(i,j)        case i: return &howto_table_std[j]
209   int ext = obj_reloc_entry_size (abfd) == RELOC_EXT_SIZE;
210   if (code == BFD_RELOC_CTOR)
211     switch (bfd_get_arch_info (abfd)->bits_per_address)
212       {
213       case 32:
214         code = BFD_RELOC_32;
215         break;
216       }
217   if (ext)
218     switch (code)
219       {
220         EXT (BFD_RELOC_32, 2);
221         EXT (BFD_RELOC_HI22, 8);
222         EXT (BFD_RELOC_LO10, 11);
223         EXT (BFD_RELOC_32_PCREL_S2, 6);
224       default: return (CONST struct reloc_howto_struct *) 0;
225       }
226   else
227     /* std relocs */
228     switch (code)
229       {
230         STD (BFD_RELOC_16, 1);
231         STD (BFD_RELOC_32, 2);
232         STD (BFD_RELOC_8_PCREL, 4);
233         STD (BFD_RELOC_16_PCREL, 5);
234         STD (BFD_RELOC_32_PCREL, 6);
235       default: return (CONST struct reloc_howto_struct *) 0;
236       }
237 }
238
239 extern bfd_error_vector_type bfd_error_vector;
240
241 /*
242 SUBSECTION
243         Internal Entry Points
244
245 DESCRIPTION
246         @code{aoutx.h} exports several routines for accessing the
247         contents of an a.out file, which are gathered and exported in
248         turn by various format specific files (eg sunos.c).
249
250 */
251
252 /*
253 FUNCTION
254          aout_<size>_swap_exec_header_in
255
256 DESCRIPTION
257         Swaps the information in an executable header taken from a raw
258         byte stream memory image, into the internal exec_header
259         structure.
260
261 SYNOPSIS
262         void aout_<size>_swap_exec_header_in,
263            (bfd *abfd,
264             struct external_exec *raw_bytes,
265             struct internal_exec *execp);
266 */
267          
268 #ifndef NAME_swap_exec_header_in
269 void
270 DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
271       bfd *abfd AND
272       struct external_exec *raw_bytes AND
273       struct internal_exec *execp)
274 {
275   struct external_exec *bytes = (struct external_exec *)raw_bytes;
276
277   /* The internal_exec structure has some fields that are unused in this
278      configuration (IE for i960), so ensure that all such uninitialized
279      fields are zero'd out.  There are places where two of these structs
280      are memcmp'd, and thus the contents do matter. */
281   memset (execp, 0, sizeof (struct internal_exec));
282   /* Now fill in fields in the execp, from the bytes in the raw data.  */
283   execp->a_info   = bfd_h_get_32 (abfd, bytes->e_info);
284   execp->a_text   = GET_WORD (abfd, bytes->e_text);
285   execp->a_data   = GET_WORD (abfd, bytes->e_data);
286   execp->a_bss    = GET_WORD (abfd, bytes->e_bss);
287   execp->a_syms   = GET_WORD (abfd, bytes->e_syms);
288   execp->a_entry  = GET_WORD (abfd, bytes->e_entry);
289   execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
290   execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
291 }
292 #define NAME_swap_exec_header_in NAME(aout,swap_exec_header_in)
293 #endif
294
295 /*
296 FUNCTION
297         aout_<size>_swap_exec_header_out
298
299 DESCRIPTION
300         Swaps the information in an internal exec header structure
301         into the supplied buffer ready for writing to disk.
302
303 SYNOPSIS
304         void aout_<size>_swap_exec_header_out
305           (bfd *abfd,
306            struct internal_exec *execp,
307            struct external_exec *raw_bytes);
308 */
309 void
310 DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
311      bfd *abfd AND
312      struct internal_exec *execp AND 
313      struct external_exec *raw_bytes)
314 {
315   struct external_exec *bytes = (struct external_exec *)raw_bytes;
316
317   /* Now fill in fields in the raw data, from the fields in the exec struct. */
318   bfd_h_put_32 (abfd, execp->a_info  , bytes->e_info);
319   PUT_WORD (abfd, execp->a_text  , bytes->e_text);
320   PUT_WORD (abfd, execp->a_data  , bytes->e_data);
321   PUT_WORD (abfd, execp->a_bss   , bytes->e_bss);
322   PUT_WORD (abfd, execp->a_syms  , bytes->e_syms);
323   PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
324   PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
325   PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
326 }
327
328
329
330 /*
331 FUNCTION
332         aout_<size>_some_aout_object_p
333
334 DESCRIPTION
335         Some A.OUT variant thinks that the file whose format we're
336         checking is an a.out file.  Do some more checking, and set up
337         for access if it really is.  Call back to the calling
338         environments "finish up" function just before returning, to
339         handle any last-minute setup.  
340
341 SYNOPSIS
342         bfd_target *aout_<size>_some_aout_object_p
343          (bfd *abfd,
344           bfd_target *(*callback_to_real_object_p)());
345 */
346  
347 bfd_target *
348 DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p),
349       bfd *abfd AND
350       struct internal_exec *execp AND
351       bfd_target *(*callback_to_real_object_p) PARAMS ((bfd *)))
352 {
353   struct aout_data_struct *rawptr, *oldrawptr;
354   bfd_target *result;
355
356   rawptr = (struct aout_data_struct  *) bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
357   if (rawptr == NULL) {
358     bfd_error = no_memory;
359     return 0;
360   }
361
362   oldrawptr = abfd->tdata.aout_data;
363   abfd->tdata.aout_data = rawptr;
364
365   /* Copy the contents of the old tdata struct.
366      In particular, we want the subformat, since for hpux it was set in
367      hp300hpux.c:swap_exec_header_in and will be used in
368      hp300hpux.c:callback.  */
369   if (oldrawptr != NULL)
370     *abfd->tdata.aout_data = *oldrawptr;
371
372   abfd->tdata.aout_data->a.hdr = &rawptr->e;
373   *(abfd->tdata.aout_data->a.hdr) = *execp;     /* Copy in the internal_exec struct */
374   execp = abfd->tdata.aout_data->a.hdr;
375
376   /* Set the file flags */
377   abfd->flags = NO_FLAGS;
378   if (execp->a_drsize || execp->a_trsize)
379     abfd->flags |= HAS_RELOC;
380   /* Setting of EXEC_P has been deferred to the bottom of this function */
381   if (execp->a_syms) 
382     abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
383
384   if (N_MAGIC (*execp) == ZMAGIC)
385     {
386       abfd->flags |= D_PAGED|WP_TEXT;
387       adata(abfd).magic = z_magic;
388     }
389   else if (N_MAGIC (*execp) == NMAGIC)
390     {
391       abfd->flags |= WP_TEXT;
392       adata(abfd).magic = n_magic;
393     }
394   else
395     adata(abfd).magic = o_magic;
396
397   bfd_get_start_address (abfd) = execp->a_entry;
398
399   obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
400   bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
401
402   /* The default relocation entry size is that of traditional V7 Unix.  */
403   obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
404
405   /* The default symbol entry size is that of traditional Unix. */
406   obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
407
408   /* create the sections.  This is raunchy, but bfd_close wants to reclaim
409      them */
410
411   obj_textsec (abfd) = bfd_make_section_old_way (abfd, ".text");
412   obj_datasec (abfd) = bfd_make_section_old_way (abfd, ".data");
413   obj_bsssec (abfd) = bfd_make_section_old_way (abfd, ".bss");
414
415 #if 0
416   (void)bfd_make_section (abfd, ".text");
417   (void)bfd_make_section (abfd, ".data");
418   (void)bfd_make_section (abfd, ".bss");
419 #endif
420
421   obj_datasec (abfd)->_raw_size = execp->a_data;
422   obj_bsssec (abfd)->_raw_size = execp->a_bss;
423
424   obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
425        (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_RELOC) :
426        (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS));
427   obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
428        (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS | SEC_RELOC) :
429        (SEC_ALLOC | SEC_LOAD | SEC_DATA | SEC_HAS_CONTENTS));
430   obj_bsssec (abfd)->flags = SEC_ALLOC;
431
432 #ifdef THIS_IS_ONLY_DOCUMENTATION
433   /* The common code can't fill in these things because they depend
434      on either the start address of the text segment, the rounding
435      up of virtual addersses between segments, or the starting file 
436      position of the text segment -- all of which varies among different
437      versions of a.out.  */
438
439   /* Call back to the format-dependent code to fill in the rest of the 
440      fields and do any further cleanup.  Things that should be filled
441      in by the callback:  */
442
443   struct exec *execp = exec_hdr (abfd);
444
445   obj_textsec (abfd)->size = N_TXTSIZE(*execp);
446   obj_textsec (abfd)->raw_size = N_TXTSIZE(*execp);
447   /* data and bss are already filled in since they're so standard */
448
449   /* The virtual memory addresses of the sections */
450   obj_textsec (abfd)->vma = N_TXTADDR(*execp);
451   obj_datasec (abfd)->vma = N_DATADDR(*execp);
452   obj_bsssec  (abfd)->vma = N_BSSADDR(*execp);
453
454   /* The file offsets of the sections */
455   obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
456   obj_datasec (abfd)->filepos = N_DATOFF(*execp);
457
458   /* The file offsets of the relocation info */
459   obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
460   obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
461
462   /* The file offsets of the string table and symbol table.  */
463   obj_str_filepos (abfd) = N_STROFF (*execp);
464   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
465
466   /* Determine the architecture and machine type of the object file.  */
467   switch (N_MACHTYPE (*exec_hdr (abfd))) {
468   default:
469     abfd->obj_arch = bfd_arch_obscure;
470     break;
471   }
472
473   adata(abfd)->page_size = PAGE_SIZE;
474   adata(abfd)->segment_size = SEGMENT_SIZE;
475   adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
476
477   return abfd->xvec;
478
479   /* The architecture is encoded in various ways in various a.out variants,
480      or is not encoded at all in some of them.  The relocation size depends
481      on the architecture and the a.out variant.  Finally, the return value
482      is the bfd_target vector in use.  If an error occurs, return zero and
483      set bfd_error to the appropriate error code.
484      
485      Formats such as b.out, which have additional fields in the a.out
486      header, should cope with them in this callback as well.  */
487 #endif                          /* DOCUMENTATION */
488
489   result = (*callback_to_real_object_p)(abfd);
490
491   /* Now that the segment addresses have been worked out, take a better
492      guess at whether the file is executable.  If the entry point
493      is within the text segment, assume it is.  (This makes files
494      executable even if their entry point address is 0, as long as
495      their text starts at zero.)  
496
497      At some point we should probably break down and stat the file and
498      declare it executable if (one of) its 'x' bits are on...  */
499   if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
500       (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
501     abfd->flags |= EXEC_P;
502   if (result)
503     {
504 #if 0 /* These should be set correctly anyways.  */
505       abfd->sections = obj_textsec (abfd);
506       obj_textsec (abfd)->next = obj_datasec (abfd);
507       obj_datasec (abfd)->next = obj_bsssec (abfd);
508 #endif
509     }
510   else
511     {
512       free (rawptr);
513       abfd->tdata.aout_data = oldrawptr;
514     }
515   return result;
516 }
517
518 /*
519 FUNCTION
520         aout_<size>_mkobject
521
522 DESCRIPTION
523         This routine initializes a BFD for use with a.out files.
524
525 SYNOPSIS
526         boolean aout_<size>_mkobject, (bfd *);
527 */
528
529 boolean
530 DEFUN(NAME(aout,mkobject),(abfd),
531      bfd *abfd)
532 {
533   struct aout_data_struct  *rawptr;
534
535   bfd_error = system_call_error;
536
537   /* Use an intermediate variable for clarity */
538   rawptr = (struct aout_data_struct  *)bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
539   
540   if (rawptr == NULL) {
541     bfd_error = no_memory;
542     return false;
543   }
544   
545   abfd->tdata.aout_data = rawptr;
546   exec_hdr (abfd) = &(rawptr->e);
547   
548   /* For simplicity's sake we just make all the sections right here. */
549   
550   obj_textsec (abfd) = (asection *)NULL;
551   obj_datasec (abfd) = (asection *)NULL;
552   obj_bsssec (abfd) = (asection *)NULL;
553   bfd_make_section (abfd, ".text");
554   bfd_make_section (abfd, ".data");
555   bfd_make_section (abfd, ".bss");
556   bfd_make_section (abfd, BFD_ABS_SECTION_NAME);
557   bfd_make_section (abfd, BFD_UND_SECTION_NAME);
558   bfd_make_section (abfd, BFD_COM_SECTION_NAME);
559   
560   return true;
561 }
562
563
564 /*
565 FUNCTION
566         aout_<size>_machine_type
567
568 DESCRIPTION
569         Keep track of machine architecture and machine type for
570         a.out's. Return the machine_type for a particular
571         arch&machine, or M_UNKNOWN if that exact arch&machine can't be
572         represented in a.out format. 
573
574         If the architecture is understood, machine type 0 (default)
575         should always be understood.  
576
577 SYNOPSIS
578         enum machine_type  aout_<size>_machine_type
579          (enum bfd_architecture arch,
580           unsigned long machine));
581 */
582
583 enum machine_type
584 DEFUN(NAME(aout,machine_type),(arch, machine),
585       enum bfd_architecture arch AND
586       unsigned long machine)
587 {
588   enum machine_type arch_flags;
589     
590   arch_flags = M_UNKNOWN;
591     
592   switch (arch) {
593   case bfd_arch_sparc:
594     if (machine == 0)   arch_flags = M_SPARC;
595     break;
596       
597   case bfd_arch_m68k:
598     switch (machine) {
599     case 0:             arch_flags = M_68010; break;
600     case 68000:         arch_flags = M_UNKNOWN; break;
601     case 68010:         arch_flags = M_68010; break;
602     case 68020:         arch_flags = M_68020; break;
603     default:            arch_flags = M_UNKNOWN; break;
604     }
605     break;
606       
607   case bfd_arch_i386:
608     if (machine == 0)   arch_flags = M_386;
609     break;
610       
611   case bfd_arch_a29k:
612     if (machine == 0)   arch_flags = M_29K;
613     break;
614       
615   case bfd_arch_mips:
616     switch (machine) {
617     case 0:
618     case 2000:
619     case 3000:          arch_flags = M_MIPS1; break;
620     case 4000:
621     case 4400:
622     case 6000:          arch_flags = M_MIPS2; break;
623     default:            arch_flags = M_UNKNOWN; break;
624     }
625     break;
626
627   default:
628     arch_flags = M_UNKNOWN;
629   }
630   return arch_flags;
631 }
632
633
634 /*
635 FUNCTION
636         aout_<size>_set_arch_mach
637
638 DESCRIPTION
639         Sets the architecture and the machine of the BFD to those
640         values supplied. Verifies that the format can support the
641         architecture required.
642
643 SYNOPSIS
644         boolean aout_<size>_set_arch_mach,
645          (bfd *,
646           enum bfd_architecture,
647           unsigned long machine));
648 */
649
650 boolean
651 DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
652       bfd *abfd AND
653       enum bfd_architecture arch AND
654       unsigned long machine)
655 {
656   bfd_default_set_arch_mach(abfd, arch, machine);
657   if (arch != bfd_arch_unknown &&
658       NAME(aout,machine_type) (arch, machine) == M_UNKNOWN)
659     return false;               /* We can't represent this type */
660
661   /* Determine the size of a relocation entry */
662   switch (arch) {
663   case bfd_arch_sparc:
664   case bfd_arch_a29k:
665   case bfd_arch_mips:
666     obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
667     break;
668   default:
669     obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
670     break;
671   }
672
673   return (*aout_backend_info(abfd)->set_sizes) (abfd);
674 }
675
676 boolean
677 DEFUN (NAME (aout,adjust_sizes_and_vmas), (abfd, text_size, text_end),
678        bfd *abfd AND bfd_size_type *text_size AND file_ptr *text_end)
679 {
680   struct internal_exec *execp = exec_hdr (abfd);
681   if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL)) 
682     {
683       bfd_error = invalid_operation;
684       return false;
685     }
686   if (adata(abfd).magic != undecided_magic) return true;
687   obj_textsec(abfd)->_raw_size =              
688     align_power(obj_textsec(abfd)->_raw_size,
689                 obj_textsec(abfd)->alignment_power);
690
691   *text_size = obj_textsec (abfd)->_raw_size;
692   /* Rule (heuristic) for when to pad to a new page.  Note that there
693    * are (at least) two ways demand-paged (ZMAGIC) files have been
694    * handled.  Most Berkeley-based systems start the text segment at
695    * (PAGE_SIZE).  However, newer versions of SUNOS start the text
696    * segment right after the exec header; the latter is counted in the
697    * text segment size, and is paged in by the kernel with the rest of
698    * the text. */
699
700   /* This perhaps isn't the right way to do this, but made it simpler for me
701      to understand enough to implement it.  Better would probably be to go
702      right from BFD flags to alignment/positioning characteristics.  But the
703      old code was sloppy enough about handling the flags, and had enough
704      other magic, that it was a little hard for me to understand.  I think
705      I understand it better now, but I haven't time to do the cleanup this
706      minute.  */
707   if (adata(abfd).magic == undecided_magic)
708     {
709       if (abfd->flags & D_PAGED)
710         /* whether or not WP_TEXT is set */
711         adata(abfd).magic = z_magic;
712       else if (abfd->flags & WP_TEXT)
713         adata(abfd).magic = n_magic;
714       else
715         adata(abfd).magic = o_magic;
716     }
717
718 #ifdef BFD_AOUT_DEBUG /* requires gcc2 */
719 #if __GNUC__ >= 2
720   fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
721            ({ char *str;
722               switch (adata(abfd).magic) {
723               case n_magic: str = "NMAGIC"; break;
724               case o_magic: str = "OMAGIC"; break;
725               case z_magic: str = "ZMAGIC"; break;
726               default: abort ();
727               }
728               str;
729             }),
730            obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size, obj_textsec(abfd)->alignment_power,
731            obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size, obj_datasec(abfd)->alignment_power,
732            obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size, obj_bsssec(abfd)->alignment_power);
733 #endif
734 #endif
735
736   switch (adata(abfd).magic)
737     {
738     case o_magic:
739       {
740         file_ptr pos = adata (abfd).exec_bytes_size;
741         bfd_vma vma = 0;
742         int pad = 0;
743
744         obj_textsec(abfd)->filepos = pos;
745         pos += obj_textsec(abfd)->_raw_size;
746         vma += obj_textsec(abfd)->_raw_size;
747         if (!obj_datasec(abfd)->user_set_vma)
748           {
749 #if 0       /* ?? Does alignment in the file image really matter? */
750             pad = align_power (vma, obj_datasec(abfd)->alignment_power) - vma;
751 #endif
752             obj_textsec(abfd)->_raw_size += pad;
753             pos += pad;
754             vma += pad;
755             obj_datasec(abfd)->vma = vma;
756           }
757         obj_datasec(abfd)->filepos = pos;
758         pos += obj_datasec(abfd)->_raw_size;
759         vma += obj_datasec(abfd)->_raw_size;
760         if (!obj_bsssec(abfd)->user_set_vma)
761           {
762 #if 0
763             pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
764 #endif
765             obj_datasec(abfd)->_raw_size += pad;
766             pos += pad;
767             vma += pad;
768             obj_bsssec(abfd)->vma = vma;
769           }
770         obj_bsssec(abfd)->filepos = pos;
771         execp->a_text = obj_textsec(abfd)->_raw_size;
772         execp->a_data = obj_datasec(abfd)->_raw_size;
773         execp->a_bss = obj_bsssec(abfd)->_raw_size;
774         N_SET_MAGIC (*execp, OMAGIC);
775       }
776       break;
777     case z_magic:
778       {
779         bfd_size_type data_pad, text_pad;
780         file_ptr text_end;
781         CONST struct aout_backend_data *abdp;
782         int ztih;
783         bfd_vma data_vma;
784
785         abdp = aout_backend_info (abfd);
786         ztih = abdp && abdp->text_includes_header;
787         obj_textsec(abfd)->filepos = (ztih
788                                       ? adata(abfd).exec_bytes_size
789                                       : adata(abfd).page_size);
790         if (! obj_textsec(abfd)->user_set_vma)
791           /* ?? Do we really need to check for relocs here?  */
792           obj_textsec(abfd)->vma = ((abfd->flags & HAS_RELOC)
793                                     ? 0
794                                     : (ztih
795                                        ? (abdp->default_text_vma
796                                           + adata(abfd).exec_bytes_size)
797                                        : abdp->default_text_vma));
798         /* Could take strange alignment of text section into account here?  */
799
800         /* Find start of data.  */
801         text_end = obj_textsec(abfd)->filepos + obj_textsec(abfd)->_raw_size;
802         text_pad = BFD_ALIGN (text_end, adata(abfd).page_size) - text_end;
803         obj_textsec(abfd)->_raw_size += text_pad;
804         text_end += text_pad;
805
806         if (!obj_datasec(abfd)->user_set_vma)
807           {
808             bfd_vma vma;
809             vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size;
810             obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
811           }
812         data_vma = obj_datasec(abfd)->vma;
813         if (abdp && abdp->zmagic_mapped_contiguous)
814           {
815             text_pad = (obj_datasec(abfd)->vma
816                         - obj_textsec(abfd)->vma
817                         - obj_textsec(abfd)->_raw_size);
818             obj_textsec(abfd)->_raw_size += text_pad;
819           }
820         obj_datasec(abfd)->filepos = (obj_textsec(abfd)->filepos
821                                       + obj_textsec(abfd)->_raw_size);
822
823         /* Fix up exec header while we're at it.  */
824         execp->a_text = obj_textsec(abfd)->_raw_size;
825         if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
826           execp->a_text += adata(abfd).exec_bytes_size;
827         N_SET_MAGIC (*execp, ZMAGIC);
828         /* Spec says data section should be rounded up to page boundary.  */
829         /* If extra space in page is left after data section, fudge data
830            in the header so that the bss section looks smaller by that
831            amount.  We'll start the bss section there, and lie to the OS.  */
832         obj_datasec(abfd)->_raw_size
833           = align_power (obj_datasec(abfd)->_raw_size,
834                          obj_bsssec(abfd)->alignment_power);
835         execp->a_data = BFD_ALIGN (obj_datasec(abfd)->_raw_size,
836                                    adata(abfd).page_size);
837         data_pad = execp->a_data - obj_datasec(abfd)->_raw_size;
838
839         if (!obj_bsssec(abfd)->user_set_vma)
840           obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
841                                    + obj_datasec(abfd)->_raw_size);
842         if (data_pad > obj_bsssec(abfd)->_raw_size)
843           execp->a_bss = 0;
844         else
845           execp->a_bss = obj_bsssec(abfd)->_raw_size - data_pad;
846       }
847       break;
848     case n_magic:
849       {
850         file_ptr pos = adata(abfd).exec_bytes_size;
851         bfd_vma vma = 0;
852         int pad;
853
854         obj_textsec(abfd)->filepos = pos;
855         if (!obj_textsec(abfd)->user_set_vma)
856           obj_textsec(abfd)->vma = vma;
857         else
858           vma = obj_textsec(abfd)->vma;
859         pos += obj_textsec(abfd)->_raw_size;
860         vma += obj_textsec(abfd)->_raw_size;
861         obj_datasec(abfd)->filepos = pos;
862         if (!obj_datasec(abfd)->user_set_vma)
863           obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
864         vma = obj_datasec(abfd)->vma;
865
866         /* Since BSS follows data immediately, see if it needs alignment.  */
867         vma += obj_datasec(abfd)->_raw_size;
868         pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
869         obj_datasec(abfd)->_raw_size += pad;
870         pos += obj_datasec(abfd)->_raw_size;
871
872         if (!obj_bsssec(abfd)->user_set_vma)
873           obj_bsssec(abfd)->vma = vma;
874         else
875           vma = obj_bsssec(abfd)->vma;
876       }
877       execp->a_text = obj_textsec(abfd)->_raw_size;
878       execp->a_data = obj_datasec(abfd)->_raw_size;
879       execp->a_bss = obj_bsssec(abfd)->_raw_size;
880       N_SET_MAGIC (*execp, NMAGIC);
881       break;
882     default:
883       abort ();
884     }
885 #ifdef BFD_AOUT_DEBUG
886   fprintf (stderr, "       text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
887            obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size, obj_textsec(abfd)->filepos,
888            obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size, obj_datasec(abfd)->filepos,
889            obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size);
890 #endif
891   return true;
892 }
893
894 /*
895 FUNCTION
896         aout_<size>_new_section_hook
897   
898 DESCRIPTION
899         Called by the BFD in response to a @code{bfd_make_section}
900         request.
901
902 SYNOPSIS
903         boolean aout_<size>_new_section_hook,
904            (bfd *abfd,
905             asection *newsect));
906 */
907 boolean
908 DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
909         bfd *abfd AND
910         asection *newsect)
911 {
912   /* align to double at least */
913   newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
914
915     
916   if (bfd_get_format (abfd) == bfd_object) 
917   {
918     if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
919         obj_textsec(abfd)= newsect;
920         newsect->target_index = N_TEXT | N_EXT;
921         return true;
922       }
923       
924     if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
925         obj_datasec(abfd) = newsect;
926         newsect->target_index = N_DATA | N_EXT;
927         return true;
928       }
929       
930     if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
931         obj_bsssec(abfd) = newsect;
932         newsect->target_index = N_BSS | N_EXT;
933         return true;
934       }
935
936   }
937     
938   /* We allow more than three sections internally */
939   return true;
940 }
941
942 boolean
943   DEFUN(NAME(aout,set_section_contents),(abfd, section, location, offset, count),
944         bfd *abfd AND
945         sec_ptr section AND
946         PTR location AND
947         file_ptr offset AND
948         bfd_size_type count)
949 {
950   file_ptr text_end;
951   bfd_size_type text_size;
952
953   if (abfd->output_has_begun == false)
954       {
955         if (NAME(aout,adjust_sizes_and_vmas) (abfd,
956                                               &text_size,
957                                               &text_end) == false)
958           return false;
959       }
960
961   /* regardless, once we know what we're doing, we might as well get going */
962   if (section != obj_bsssec(abfd)) 
963       {
964         bfd_seek (abfd, section->filepos + offset, SEEK_SET);
965     
966         if (count) {
967           return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
968             true : false;
969         }
970         return true;
971       }
972   return true;
973 }
974 \f
975 /* Classify stabs symbols */
976
977 #define sym_in_text_section(sym) \
978   (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
979
980 #define sym_in_data_section(sym) \
981   (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
982
983 #define sym_in_bss_section(sym) \
984   (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
985
986 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
987   zero in the "value" field.  Nonzeroes there are fortrancommon
988   symbols.  */
989 #define sym_is_undefined(sym) \
990   ((sym)->type == (N_UNDF | N_EXT) && (sym)->symbol.value == 0)
991
992 /* Symbol is a global definition if N_EXT is on and if it has
993   a nonzero type field.  */
994 #define sym_is_global_defn(sym) \
995   (((sym)->type & N_EXT) && (sym)->type & N_TYPE)
996
997 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
998   are on.  */
999 #define sym_is_debugger_info(sym) \
1000   ((sym)->type & ~(N_EXT | N_TYPE))
1001
1002 #define sym_is_fortrancommon(sym)       \
1003   (((sym)->type == (N_EXT)) && (sym)->symbol.value != 0)
1004
1005 /* Symbol is absolute if it has N_ABS set */
1006 #define sym_is_absolute(sym) \
1007   (((sym)->type  & N_TYPE)== N_ABS)
1008
1009
1010 #define sym_is_indirect(sym) \
1011   (((sym)->type & N_ABS)== N_ABS)
1012
1013 /* Only in their own functions for ease of debugging; when sym flags have
1014   stabilised these should be inlined into their (single) caller */
1015   
1016 static void
1017 DEFUN (translate_from_native_sym_flags, (sym_pointer, cache_ptr, abfd),
1018        struct external_nlist *sym_pointer AND
1019        aout_symbol_type * cache_ptr AND
1020        bfd * abfd)
1021 {
1022   cache_ptr->symbol.section = 0;
1023   switch (cache_ptr->type & N_TYPE)
1024     {
1025     case N_SETA:
1026     case N_SETT:
1027     case N_SETD:
1028     case N_SETB:
1029       {
1030         char *copy = bfd_alloc (abfd, strlen (cache_ptr->symbol.name) + 1);
1031         asection *section;
1032         asection *into_section;
1033
1034         arelent_chain *reloc = (arelent_chain *) bfd_alloc (abfd, sizeof (arelent_chain));
1035         strcpy (copy, cache_ptr->symbol.name);
1036
1037         /* Make sure that this bfd has a section with the right contructor
1038            name */
1039         section = bfd_get_section_by_name (abfd, copy);
1040         if (!section)
1041           section = bfd_make_section (abfd, copy);
1042
1043         /* Build a relocation entry for the constructor */
1044         switch ((cache_ptr->type & N_TYPE))
1045           {
1046           case N_SETA:
1047             into_section = &bfd_abs_section;
1048             cache_ptr->type = N_ABS;
1049             break;
1050           case N_SETT:
1051             into_section = (asection *) obj_textsec (abfd);
1052             cache_ptr->type = N_TEXT;
1053             break;
1054           case N_SETD:
1055             into_section = (asection *) obj_datasec (abfd);
1056             cache_ptr->type = N_DATA;
1057             break;
1058           case N_SETB:
1059             into_section = (asection *) obj_bsssec (abfd);
1060             cache_ptr->type = N_BSS;
1061             break;
1062           default:
1063             abort ();
1064           }
1065
1066         /* Build a relocation pointing into the constuctor section
1067            pointing at the symbol in the set vector specified */
1068
1069         reloc->relent.addend = cache_ptr->symbol.value;
1070         cache_ptr->symbol.section = into_section->symbol->section;
1071         reloc->relent.sym_ptr_ptr = into_section->symbol_ptr_ptr;
1072
1073
1074         /* We modify the symbol to belong to a section depending upon the
1075            name of the symbol - probably __CTOR__ or __DTOR__ but we don't
1076            really care, and add to the size of the section to contain a
1077            pointer to the symbol. Build a reloc entry to relocate to this
1078            symbol attached to this section.  */
1079
1080         section->flags = SEC_CONSTRUCTOR;
1081
1082
1083         section->reloc_count++;
1084         section->alignment_power = 2;
1085
1086         reloc->next = section->constructor_chain;
1087         section->constructor_chain = reloc;
1088         reloc->relent.address = section->_raw_size;
1089         section->_raw_size += sizeof (int *);
1090
1091         reloc->relent.howto
1092           = (obj_reloc_entry_size(abfd) == RELOC_EXT_SIZE
1093              ? howto_table_ext : howto_table_std)
1094             + CTOR_TABLE_RELOC_IDX;
1095         cache_ptr->symbol.flags |= BSF_CONSTRUCTOR;
1096       }
1097       break;
1098     default:
1099       if (cache_ptr->type == N_WARNING)
1100         {
1101           /* This symbol is the text of a warning message, the next symbol
1102              is the symbol to associate the warning with */
1103           cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
1104
1105           /* @@ Stuffing pointers into integers is a no-no.
1106              We can usually get away with it if the integer is
1107              large enough though.  */
1108           if (sizeof (cache_ptr + 1) > sizeof (bfd_vma))
1109             abort ();
1110           cache_ptr->symbol.value = (bfd_vma) ((cache_ptr + 1));
1111
1112           /* We furgle with the next symbol in place.
1113              We don't want it to be undefined, we'll trample the type */
1114           (sym_pointer + 1)->e_type[0] = 0xff;
1115           break;
1116         }
1117       if ((cache_ptr->type | N_EXT) == (N_INDR | N_EXT))
1118         {
1119           /* Two symbols in a row for an INDR message. The first symbol
1120              contains the name we will match, the second symbol contains
1121              the name the first name is translated into. It is supplied to
1122              us undefined. This is good, since we want to pull in any files
1123              which define it */
1124           cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT;
1125
1126           /* @@ Stuffing pointers into integers is a no-no.
1127              We can usually get away with it if the integer is
1128              large enough though.  */
1129           if (sizeof (cache_ptr + 1) > sizeof (bfd_vma))
1130             abort ();
1131
1132           cache_ptr->symbol.value = (bfd_vma) ((cache_ptr + 1));
1133           cache_ptr->symbol.section = &bfd_ind_section;
1134         }
1135
1136       else if (sym_is_debugger_info (cache_ptr))
1137         {
1138           cache_ptr->symbol.flags = BSF_DEBUGGING;
1139           /* Work out the section correct for this symbol */
1140           switch (cache_ptr->type & N_TYPE)
1141             {
1142             case N_TEXT:
1143             case N_FN:
1144               cache_ptr->symbol.section = obj_textsec (abfd);
1145               cache_ptr->symbol.value -= obj_textsec (abfd)->vma;
1146               break;
1147             case N_DATA:
1148               cache_ptr->symbol.value -= obj_datasec (abfd)->vma;
1149               cache_ptr->symbol.section = obj_datasec (abfd);
1150               break;
1151             case N_BSS:
1152               cache_ptr->symbol.section = obj_bsssec (abfd);
1153               cache_ptr->symbol.value -= obj_bsssec (abfd)->vma;
1154               break;
1155             default:
1156             case N_ABS:
1157
1158               cache_ptr->symbol.section = &bfd_abs_section;
1159               break;
1160             }
1161         }
1162       else
1163         {
1164
1165           if (sym_is_fortrancommon (cache_ptr))
1166             {
1167               cache_ptr->symbol.flags = 0;
1168               cache_ptr->symbol.section = &bfd_com_section;
1169             }
1170           else
1171             {
1172
1173
1174             }
1175
1176           /* In a.out, the value of a symbol is always relative to the
1177            * start of the file, if this is a data symbol we'll subtract
1178            * the size of the text section to get the section relative
1179            * value. If this is a bss symbol (which would be strange)
1180            * we'll subtract the size of the previous two sections
1181            * to find the section relative address.
1182            */
1183
1184           if (sym_in_text_section (cache_ptr))
1185             {
1186               cache_ptr->symbol.value -= obj_textsec (abfd)->vma;
1187               cache_ptr->symbol.section = obj_textsec (abfd);
1188             }
1189           else if (sym_in_data_section (cache_ptr))
1190             {
1191               cache_ptr->symbol.value -= obj_datasec (abfd)->vma;
1192               cache_ptr->symbol.section = obj_datasec (abfd);
1193             }
1194           else if (sym_in_bss_section (cache_ptr))
1195             {
1196               cache_ptr->symbol.section = obj_bsssec (abfd);
1197               cache_ptr->symbol.value -= obj_bsssec (abfd)->vma;
1198             }
1199           else if (sym_is_undefined (cache_ptr))
1200             {
1201               cache_ptr->symbol.flags = 0;
1202               cache_ptr->symbol.section = &bfd_und_section;
1203             }
1204           else if (sym_is_absolute (cache_ptr))
1205             {
1206               cache_ptr->symbol.section = &bfd_abs_section;
1207             }
1208
1209           if (sym_is_global_defn (cache_ptr))
1210             {
1211               cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1212             }
1213           else
1214             {
1215               cache_ptr->symbol.flags = BSF_LOCAL;
1216             }
1217         }
1218     }
1219   if (cache_ptr->symbol.section == 0)
1220     abort ();
1221 }
1222
1223
1224
1225 static void
1226 DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
1227      struct external_nlist *sym_pointer AND
1228      asymbol *cache_ptr AND
1229      bfd *abfd)
1230 {
1231   bfd_vma value = cache_ptr->value;
1232
1233   /* mask out any existing type bits in case copying from one section
1234      to another */
1235   sym_pointer->e_type[0] &= ~N_TYPE;
1236
1237   
1238   /* We attempt to order these tests by decreasing frequency of success,
1239      according to tcov when linking the linker.  */
1240   if (bfd_get_output_section(cache_ptr) == &bfd_abs_section) {
1241     sym_pointer->e_type[0] |= N_ABS;
1242   }
1243   else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
1244     sym_pointer->e_type[0] |= N_TEXT;
1245   }
1246   else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
1247     sym_pointer->e_type[0] |= N_DATA;
1248   }
1249   else if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
1250     sym_pointer->e_type[0] |= N_BSS;
1251   }
1252   else if (bfd_get_output_section(cache_ptr) == &bfd_und_section) 
1253     {
1254       sym_pointer->e_type[0] = (N_UNDF | N_EXT);
1255     }
1256   else if (bfd_get_output_section(cache_ptr) == &bfd_ind_section) 
1257     {
1258       sym_pointer->e_type[0] = N_INDR;
1259     }
1260   else if (bfd_is_com_section (bfd_get_output_section (cache_ptr))) {
1261     sym_pointer->e_type[0] = (N_UNDF | N_EXT);
1262   }    
1263   else {    
1264     if (cache_ptr->section->output_section) 
1265       {
1266         
1267         bfd_error_vector.nonrepresentable_section(abfd,
1268                                                   bfd_get_output_section(cache_ptr)->name);
1269       }
1270     else 
1271       {
1272         bfd_error_vector.nonrepresentable_section(abfd,
1273                                                   cache_ptr->section->name);
1274         
1275       }
1276       
1277   }
1278   /* Turn the symbol from section relative to absolute again */
1279     
1280   value +=  cache_ptr->section->output_section->vma  + cache_ptr->section->output_offset ;
1281
1282
1283   if (cache_ptr->flags & (BSF_WARNING)) {
1284     (sym_pointer+1)->e_type[0] = 1;
1285   }  
1286     
1287   if (cache_ptr->flags & BSF_DEBUGGING) {
1288     sym_pointer->e_type[0] = ((aout_symbol_type *)cache_ptr)->type;
1289   }
1290   else if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
1291     sym_pointer->e_type[0] |= N_EXT;
1292   }
1293   if (cache_ptr->flags & BSF_CONSTRUCTOR) {
1294     int type = ((aout_symbol_type *)cache_ptr)->type;
1295     switch (type)
1296       {
1297       case N_ABS:       type = N_SETA; break;
1298       case N_TEXT:      type = N_SETT; break;
1299       case N_DATA:      type = N_SETD; break;
1300       case N_BSS:       type = N_SETB; break;
1301       }
1302     sym_pointer->e_type[0] = type;
1303   }
1304
1305   PUT_WORD(abfd, value, sym_pointer->e_value);
1306 }
1307 \f
1308 /* Native-level interface to symbols. */
1309
1310 /* We read the symbols into a buffer, which is discarded when this
1311 function exits.  We read the strings into a buffer large enough to
1312 hold them all plus all the cached symbol entries. */
1313
1314 asymbol *
1315 DEFUN(NAME(aout,make_empty_symbol),(abfd),
1316       bfd *abfd)
1317 {
1318   aout_symbol_type  *new =
1319     (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1320   new->symbol.the_bfd = abfd;
1321
1322   return &new->symbol;
1323 }
1324
1325 boolean
1326 DEFUN(NAME(aout,slurp_symbol_table),(abfd),
1327       bfd *abfd)
1328 {
1329   bfd_size_type symbol_size;
1330   bfd_size_type string_size;
1331   unsigned char string_chars[BYTES_IN_WORD];
1332   struct external_nlist *syms;
1333   char *strings;
1334   aout_symbol_type *cached;
1335
1336   /* If there's no work to be done, don't do any */
1337   if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1338   symbol_size = exec_hdr(abfd)->a_syms;
1339   if (symbol_size == 0)
1340     {
1341       bfd_error = no_symbols;
1342       return false;
1343     }
1344
1345   bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1346   if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD)
1347     return false;
1348   string_size = GET_WORD (abfd, string_chars);
1349
1350   strings =(char *) bfd_alloc(abfd, string_size + 1);
1351   cached = (aout_symbol_type *)
1352     bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type)));
1353
1354   /* malloc this, so we can free it if simply. The symbol caching
1355      might want to allocate onto the bfd's obstack  */
1356   syms = (struct external_nlist *) bfd_xmalloc(symbol_size);
1357   bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
1358   if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size)
1359     {
1360     bailout:
1361       if (syms)
1362         free (syms);
1363       if (cached)
1364         bfd_release (abfd, cached);
1365       if (strings)
1366         bfd_release (abfd, strings);
1367       return false;
1368     }
1369
1370   bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1371   if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size)
1372     {
1373       goto bailout;
1374     }
1375   strings[string_size] = 0; /* Just in case. */
1376
1377   /* OK, now walk the new symtable, cacheing symbol properties */
1378   {
1379     register struct external_nlist *sym_pointer;
1380     register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd);
1381     register aout_symbol_type *cache_ptr = cached;
1382
1383     /* Run through table and copy values */
1384     for (sym_pointer = syms, cache_ptr = cached;
1385          sym_pointer < sym_end; sym_pointer ++, cache_ptr++) 
1386       {
1387         long x = GET_WORD(abfd, sym_pointer->e_strx);
1388         cache_ptr->symbol.the_bfd = abfd;
1389         if (x == 0)
1390           cache_ptr->symbol.name = "";
1391         else if (x >= 0 && x < string_size)
1392           cache_ptr->symbol.name = x + strings;
1393         else
1394           goto bailout;
1395
1396         cache_ptr->symbol.value = GET_SWORD(abfd,  sym_pointer->e_value);
1397         cache_ptr->desc = bfd_h_get_16(abfd, sym_pointer->e_desc);
1398         cache_ptr->other = bfd_h_get_8(abfd, sym_pointer->e_other);
1399         cache_ptr->type = bfd_h_get_8(abfd,  sym_pointer->e_type);
1400         cache_ptr->symbol.udata = 0;
1401         translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1402       }
1403   }
1404
1405   obj_aout_symbols (abfd) =  cached;
1406   free((PTR)syms);
1407
1408   return true;
1409 }
1410
1411 \f
1412 /* Possible improvements:
1413    + look for strings matching trailing substrings of other strings
1414    + better data structures?  balanced trees?
1415    + smaller per-string or per-symbol data?  re-use some of the symbol's
1416      data fields?
1417    + also look at reducing memory use elsewhere -- maybe if we didn't have to
1418      construct the entire symbol table at once, we could get by with smaller
1419      amounts of VM?  (What effect does that have on the string table
1420      reductions?)
1421    + rip this out of here, put it into its own file in bfd or libiberty, so
1422      coff and elf can use it too.  I'll work on this soon, but have more
1423      pressing tasks right now.
1424
1425    A hash table might(?) be more efficient for handling exactly the cases that
1426    are handled now, but for trailing substring matches, I think we want to
1427    examine the `nearest' values (reverse-)lexically, not merely impose a strict
1428    order, nor look only for exact-match or not-match.  I don't think a hash
1429    table would be very useful for that, and I don't feel like fleshing out two
1430    completely different implementations.  [raeburn:930419.0331EDT] */
1431
1432 #if __GNUC__ >= 2
1433 #define INLINE __inline__
1434 #else
1435 #define INLINE
1436 #endif
1437
1438 struct stringtab_entry {
1439   /* Hash value for this string.  Only useful so long as we aren't doing
1440      substring matches.  */
1441   unsigned int hash;
1442
1443   /* Next node to look at, depending on whether the hash value of the string
1444      being searched for is less than or greater than the hash value of the
1445      current node.  For now, `equal to' is lumped in with `greater than', for
1446      space efficiency.  It's not a common enough case to warrant another field
1447      to be used for all nodes.  */
1448   struct stringtab_entry *less;
1449   struct stringtab_entry *greater;
1450
1451   /* The string itself.  */
1452   CONST char *string;
1453
1454   /* The index allocated for this string.  */
1455   bfd_size_type index;
1456
1457 #ifdef GATHER_STATISTICS
1458   /* How many references have there been to this string?  (Not currently used;
1459      could be dumped out for anaylsis, if anyone's interested.)  */
1460   unsigned long count;
1461 #endif
1462
1463   /* Next node in linked list, in suggested output order.  */
1464   struct stringtab_entry *next_to_output;
1465 };
1466
1467 struct stringtab_data {
1468   /* Tree of string table entries.  */
1469   struct stringtab_entry *strings;
1470
1471   /* Fudge factor used to center top node of tree.  */
1472   int hash_zero;
1473
1474   /* Next index value to issue.  */
1475   bfd_size_type index;
1476
1477   /* Index used for empty strings.  Cached here because checking for them
1478      is really easy, and we can avoid searching the tree.  */
1479   bfd_size_type empty_string_index;
1480
1481   /* These fields indicate the two ends of a singly-linked list that indicates
1482      the order strings should be written out in.  Use this order, and no
1483      seeking will need to be done, so output efficiency should be maximized. */
1484   struct stringtab_entry **end;
1485   struct stringtab_entry *output_order;
1486
1487 #ifdef GATHER_STATISTICS
1488   /* Number of strings which duplicate strings already in the table.  */
1489   unsigned long duplicates;
1490
1491   /* Number of bytes saved by not having to write all the duplicate strings. */
1492   unsigned long bytes_saved;
1493
1494   /* Number of zero-length strings.  Currently, these all turn into
1495      references to the null byte at the end of the first string.  In some
1496      cases (possibly not all?  explore this...), it should be possible to
1497      simply write out a zero index value.  */
1498   unsigned long empty_strings;
1499
1500   /* Number of times the hash values matched but the strings were different.
1501      Note that this includes the number of times the other string(s) occurs, so
1502      there may only be two strings hashing to the same value, even if this
1503      number is very large.  */
1504   unsigned long bad_hash_matches;
1505
1506   /* Null strings aren't counted in this one.
1507      This will probably only be nonzero if we've got an input file
1508      which was produced by `ld -r' (i.e., it's already been processed
1509      through this code).  Under some operating systems, native tools
1510      may make all empty strings have the same index; but the pointer
1511      check won't catch those, because to get to that stage we'd already
1512      have to compute the checksum, which requires reading the string,
1513      so we short-circuit that case with empty_string_index above.  */
1514   unsigned long pointer_matches;
1515
1516   /* Number of comparisons done.  I figure with the algorithms in use below,
1517      the average number of comparisons done (per symbol) should be roughly
1518      log-base-2 of the number of unique strings.  */
1519   unsigned long n_compares;
1520 #endif
1521 };
1522
1523 /* Some utility functions for the string table code.  */
1524
1525 /* For speed, only hash on the first this many bytes of strings.
1526    This number was chosen by profiling ld linking itself, with -g.  */
1527 #define HASHMAXLEN 25
1528
1529 #define HASH_CHAR(c) (sum ^= sum >> 20, sum ^= sum << 7, sum += (c))
1530
1531 static INLINE unsigned int
1532 hash (string, len)
1533      unsigned char *string;
1534      register unsigned int len;
1535 {
1536   register unsigned int sum = 0;
1537
1538   if (len > HASHMAXLEN)
1539     {
1540       HASH_CHAR (len);
1541       len = HASHMAXLEN;
1542     }
1543
1544   while (len--)
1545     {
1546       HASH_CHAR (*string++);
1547     }
1548   return sum;
1549 }
1550
1551 static INLINE void
1552 stringtab_init (tab)
1553      struct stringtab_data *tab;
1554 {
1555   tab->strings = 0;
1556   tab->output_order = 0;
1557   tab->end = &tab->output_order;
1558
1559   /* Initial string table length includes size of length field.  */
1560   tab->index = BYTES_IN_WORD;
1561   tab->empty_string_index = -1;
1562 #ifdef GATHER_STATISTICS
1563   tab->duplicates = 0;
1564   tab->empty_strings = 0;
1565   tab->bad_hash_matches = 0;
1566   tab->pointer_matches = 0;
1567   tab->bytes_saved = 0;
1568   tab->n_compares = 0;
1569 #endif
1570 }
1571
1572 static INLINE int
1573 compare (entry, str, hash)
1574      struct stringtab_entry *entry;
1575      CONST char *str;
1576      unsigned int hash;
1577 {
1578   return hash - entry->hash;
1579 }
1580
1581 #ifdef GATHER_STATISTICS
1582 /* Don't want to have to link in math library with all bfd applications...  */
1583 static INLINE double
1584 log2 (num)
1585      int num;
1586 {
1587   double d = num;
1588 #if defined (__i386__) && __GNUC__ >= 2
1589   asm ("fyl2x" : "=t" (d) : "0" (d), "u" (1.0));
1590   return d;
1591 #else
1592   int n = 0;
1593   while (d >= 2.0)
1594     n++, d /= 2.0;
1595   return ((d > 1.41) ? 0.5 : 0) + n;
1596 #endif
1597 }
1598 #endif
1599
1600 /* Main string table routines.  */
1601 /* Returns index in string table.  Whether or not this actually adds an
1602    entry into the string table should be irrelevant -- it just has to
1603    return a valid index.  */
1604 static bfd_size_type
1605 add_to_stringtab (abfd, str, tab, check)
1606      bfd *abfd;
1607      CONST char *str;
1608      struct stringtab_data *tab;
1609      int check;
1610 {
1611   struct stringtab_entry **ep;
1612   register struct stringtab_entry *entry;
1613   unsigned int hashval, len;
1614
1615   if (str[0] == 0)
1616     {
1617       bfd_size_type index;
1618       CONST bfd_size_type minus_one = -1;
1619
1620 #ifdef GATHER_STATISTICS
1621       tab->empty_strings++;
1622 #endif
1623       index = tab->empty_string_index;
1624       if (index != minus_one)
1625         {
1626         got_empty:
1627 #ifdef GATHER_STATISTICS
1628           tab->bytes_saved++;
1629           tab->duplicates++;
1630 #endif
1631           return index;
1632         }
1633
1634       /* Need to find it.  */
1635       entry = tab->strings;
1636       if (entry)
1637         {
1638           index = entry->index + strlen (entry->string);
1639           tab->empty_string_index = index;
1640           goto got_empty;
1641         }
1642       len = 0;
1643     }
1644   else
1645     len = strlen (str);
1646
1647   /* The hash_zero value is chosen such that the first symbol gets a value of
1648      zero.  With a balanced tree, this wouldn't be very useful, but without it,
1649      we might get a more even split at the top level, instead of skewing it
1650      badly should hash("/usr/lib/crt0.o") (or whatever) be far from zero. */
1651   hashval = hash (str, len) ^ tab->hash_zero;
1652   ep = &tab->strings;
1653   if (!*ep)
1654     {
1655       tab->hash_zero = hashval;
1656       hashval = 0;
1657       goto add_it;
1658     }
1659
1660   while (*ep)
1661     {
1662       register int cmp;
1663
1664       entry = *ep;
1665 #ifdef GATHER_STATISTICS
1666       tab->n_compares++;
1667 #endif
1668       cmp = compare (entry, str, hashval);
1669       /* The not-equal cases are more frequent, so check them first.  */
1670       if (cmp > 0)
1671         ep = &entry->greater;
1672       else if (cmp < 0)
1673         ep = &entry->less;
1674       else
1675         {
1676           if (entry->string == str)
1677             {
1678 #ifdef GATHER_STATISTICS
1679               tab->pointer_matches++;
1680 #endif
1681               goto match;
1682             }
1683           /* Compare the first bytes to save a function call if they
1684              don't match.  */
1685           if (entry->string[0] == str[0] && !strcmp (entry->string, str))
1686             {
1687             match:
1688 #ifdef GATHER_STATISTICS
1689               entry->count++;
1690               tab->bytes_saved += len + 1;
1691               tab->duplicates++;
1692 #endif
1693               /* If we're in the linker, and the new string is from a new
1694                  input file which might have already had these reductions
1695                  run over it, we want to keep the new string pointer.  I
1696                  don't think we're likely to see any (or nearly as many,
1697                  at least) cases where a later string is in the same location
1698                  as an earlier one rather than this one.  */
1699               entry->string = str;
1700               return entry->index;
1701             }
1702 #ifdef GATHER_STATISTICS
1703           tab->bad_hash_matches++;
1704 #endif
1705           ep = &entry->greater;
1706         }
1707     }
1708
1709   /* If we get here, nothing that's in the table already matched.
1710      EP points to the `next' field at the end of the chain; stick a
1711      new entry on here.  */
1712  add_it:
1713   entry = (struct stringtab_entry *)
1714     bfd_alloc_by_size_t (abfd, sizeof (struct stringtab_entry));
1715
1716   entry->less = entry->greater = 0;
1717   entry->hash = hashval;
1718   entry->index = tab->index;
1719   entry->string = str;
1720   entry->next_to_output = 0;
1721 #ifdef GATHER_STATISTICS
1722   entry->count = 1;
1723 #endif
1724
1725   assert (*tab->end == 0);
1726   *(tab->end) = entry;
1727   tab->end = &entry->next_to_output;
1728   assert (*tab->end == 0);
1729
1730   {
1731     tab->index += len + 1;
1732     if (len == 0)
1733       tab->empty_string_index = entry->index;
1734   }
1735   assert (*ep == 0);
1736   *ep = entry;
1737   return entry->index;
1738 }
1739
1740 static void
1741 emit_strtab (abfd, tab)
1742      bfd *abfd;
1743      struct stringtab_data *tab;
1744 {
1745   struct stringtab_entry *entry;
1746 #ifdef GATHER_STATISTICS
1747   int count = 0;
1748 #endif
1749
1750   /* Be sure to put string length into correct byte ordering before writing
1751      it out.  */
1752   char buffer[BYTES_IN_WORD];
1753
1754   PUT_WORD (abfd, tab->index, (unsigned char *) buffer);
1755   bfd_write ((PTR) buffer, 1, BYTES_IN_WORD, abfd);
1756
1757   for (entry = tab->output_order; entry; entry = entry->next_to_output)
1758     {
1759       bfd_write ((PTR) entry->string, 1, strlen (entry->string) + 1, abfd);
1760 #ifdef GATHER_STATISTICS
1761       count++;
1762 #endif
1763     }
1764
1765 #ifdef GATHER_STATISTICS
1766   /* Short form only, for now.
1767      To do:  Specify output file.  Conditionalize on environment?  Detailed
1768      analysis if desired.  */
1769   {
1770     int n_syms = bfd_get_symcount (abfd);
1771
1772     fprintf (stderr, "String table data for output file:\n");
1773     fprintf (stderr, "  %8d symbols output\n", n_syms);
1774     fprintf (stderr, "  %8d duplicate strings\n", tab->duplicates);
1775     fprintf (stderr, "  %8d empty strings\n", tab->empty_strings);
1776     fprintf (stderr, "  %8d unique strings output\n", count);
1777     fprintf (stderr, "  %8d pointer matches\n", tab->pointer_matches);
1778     fprintf (stderr, "  %8d bytes saved\n", tab->bytes_saved);
1779     fprintf (stderr, "  %8d bad hash matches\n", tab->bad_hash_matches);
1780     fprintf (stderr, "  %8d hash-val comparisons\n", tab->n_compares);
1781     if (n_syms)
1782       {
1783         double n_compares = tab->n_compares;
1784         double avg_compares = n_compares / n_syms;
1785         /* The second value here should usually be near one.  */
1786         fprintf (stderr,
1787                  "\t    average %f comparisons per symbol (%f * log2 nstrings)\n",
1788                  avg_compares, avg_compares / log2 (count));
1789       }
1790   }
1791 #endif
1792
1793 /* Old code:
1794   unsigned int count;
1795   generic = bfd_get_outsymbols(abfd);
1796   for (count = 0; count < bfd_get_symcount(abfd); count++)
1797     {
1798       asymbol *g = *(generic++);
1799
1800       if (g->name)
1801         {
1802           size_t length = strlen(g->name)+1;
1803           bfd_write((PTR)g->name, 1, length, abfd);
1804         }
1805       g->KEEPIT = (KEEPITTYPE) count;
1806     } */
1807 }
1808
1809 void
1810 DEFUN(NAME(aout,write_syms),(abfd),
1811       bfd *abfd)
1812 {
1813   unsigned int count ;
1814   asymbol **generic = bfd_get_outsymbols (abfd);
1815   struct stringtab_data strtab;
1816
1817   stringtab_init (&strtab);
1818
1819   for (count = 0; count < bfd_get_symcount (abfd); count++)
1820     {
1821       asymbol *g = generic[count];
1822       struct external_nlist nsp;
1823
1824       if (g->name)
1825         PUT_WORD (abfd, add_to_stringtab (abfd, g->name, &strtab),
1826                   (unsigned char *) nsp.e_strx);
1827       else
1828         PUT_WORD (abfd, 0, (unsigned char *)nsp.e_strx);
1829
1830       if (bfd_asymbol_flavour(g) == abfd->xvec->flavour)
1831         {
1832           bfd_h_put_16(abfd, aout_symbol(g)->desc,  nsp.e_desc);
1833           bfd_h_put_8(abfd, aout_symbol(g)->other,  nsp.e_other);
1834           bfd_h_put_8(abfd, aout_symbol(g)->type,  nsp.e_type);
1835         }
1836       else
1837         {
1838           bfd_h_put_16(abfd,0, nsp.e_desc);
1839           bfd_h_put_8(abfd, 0, nsp.e_other);
1840           bfd_h_put_8(abfd, 0, nsp.e_type);
1841         }
1842
1843       translate_to_native_sym_flags (&nsp, g, abfd);
1844
1845       bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd);
1846
1847       /* NB: `KEEPIT' currently overlays `flags', so set this only
1848          here, at the end.  */
1849       g->KEEPIT = count;
1850     }
1851
1852   emit_strtab (abfd, &strtab);
1853 }
1854
1855 \f
1856 unsigned int
1857 DEFUN(NAME(aout,get_symtab),(abfd, location),
1858       bfd *abfd AND
1859       asymbol **location)
1860 {
1861     unsigned int counter = 0;
1862     aout_symbol_type *symbase;
1863
1864     if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1865
1866     for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1867       *(location++) = (asymbol *)( symbase++);
1868     *location++ =0;
1869     return bfd_get_symcount (abfd);
1870 }
1871
1872 \f
1873 /* Standard reloc stuff */
1874 /* Output standard relocation information to a file in target byte order. */
1875
1876 void
1877 DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
1878       bfd *abfd AND
1879       arelent *g AND
1880       struct reloc_std_external *natptr)
1881 {
1882   int r_index;
1883   asymbol *sym = *(g->sym_ptr_ptr);
1884   int r_extern;
1885   unsigned int r_length;
1886   int r_pcrel;
1887   int r_baserel, r_jmptable, r_relative;
1888   unsigned int r_addend;
1889   asection *output_section = sym->section->output_section;
1890
1891   PUT_WORD(abfd, g->address, natptr->r_address);
1892
1893   r_length = g->howto->size ;   /* Size as a power of two */
1894   r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC? */
1895   /* r_baserel, r_jmptable, r_relative???  FIXME-soon */
1896   r_baserel = 0;
1897   r_jmptable = 0;
1898   r_relative = 0;
1899     
1900   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
1901     
1902   /* name was clobbered by aout_write_syms to be symbol index */
1903
1904   /* If this relocation is relative to a symbol then set the 
1905      r_index to the symbols index, and the r_extern bit.
1906
1907      Absolute symbols can come in in two ways, either as an offset
1908      from the abs section, or as a symbol which has an abs value.
1909      check for that here
1910      */
1911      
1912
1913   if (bfd_is_com_section (output_section)
1914       || output_section == &bfd_abs_section
1915       || output_section == &bfd_und_section) 
1916     {
1917       if (bfd_abs_section.symbol == sym)
1918       {
1919         /* Whoops, looked like an abs symbol, but is really an offset
1920            from the abs section */
1921         r_index = 0;
1922         r_extern = 0;
1923        }
1924       else 
1925       {
1926         /* Fill in symbol */
1927         r_extern = 1;
1928         r_index =  stoi((*(g->sym_ptr_ptr))->KEEPIT);
1929      
1930       }
1931     }
1932   else 
1933     {
1934       /* Just an ordinary section */
1935       r_extern = 0;
1936       r_index  = output_section->target_index;      
1937     }
1938
1939   /* now the fun stuff */
1940   if (abfd->xvec->header_byteorder_big_p != false) {
1941       natptr->r_index[0] = r_index >> 16;
1942       natptr->r_index[1] = r_index >> 8;
1943       natptr->r_index[2] = r_index;
1944       natptr->r_type[0] =
1945        (r_extern?    RELOC_STD_BITS_EXTERN_BIG: 0)
1946         | (r_pcrel?     RELOC_STD_BITS_PCREL_BIG: 0)
1947          | (r_baserel?   RELOC_STD_BITS_BASEREL_BIG: 0)
1948           | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_BIG: 0)
1949            | (r_relative?  RELOC_STD_BITS_RELATIVE_BIG: 0)
1950             | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG);
1951     } else {
1952         natptr->r_index[2] = r_index >> 16;
1953         natptr->r_index[1] = r_index >> 8;
1954         natptr->r_index[0] = r_index;
1955         natptr->r_type[0] =
1956          (r_extern?    RELOC_STD_BITS_EXTERN_LITTLE: 0)
1957           | (r_pcrel?     RELOC_STD_BITS_PCREL_LITTLE: 0)
1958            | (r_baserel?   RELOC_STD_BITS_BASEREL_LITTLE: 0)
1959             | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1960              | (r_relative?  RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1961               | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE);
1962       }
1963 }
1964
1965
1966 /* Extended stuff */
1967 /* Output extended relocation information to a file in target byte order. */
1968
1969 void
1970 DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
1971       bfd *abfd AND
1972       arelent *g AND
1973       register struct reloc_ext_external *natptr)
1974 {
1975   int r_index;
1976   int r_extern;
1977   unsigned int r_type;
1978   unsigned int r_addend;
1979   asymbol *sym = *(g->sym_ptr_ptr);    
1980   asection *output_section = sym->section->output_section;
1981   
1982   PUT_WORD (abfd, g->address, natptr->r_address);
1983     
1984   r_type = (unsigned int) g->howto->type;
1985     
1986   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
1987
1988
1989   /* If this relocation is relative to a symbol then set the 
1990      r_index to the symbols index, and the r_extern bit.
1991
1992      Absolute symbols can come in in two ways, either as an offset
1993      from the abs section, or as a symbol which has an abs value.
1994      check for that here
1995      */
1996      
1997   if (bfd_is_com_section (output_section)
1998       || output_section == &bfd_abs_section
1999       || output_section == &bfd_und_section)
2000   {
2001     if (bfd_abs_section.symbol == sym)
2002     {
2003       /* Whoops, looked like an abs symbol, but is really an offset
2004          from the abs section */
2005       r_index = 0;
2006       r_extern = 0;
2007      }
2008     else 
2009     {
2010       r_extern = 1;
2011       r_index =  stoi((*(g->sym_ptr_ptr))->KEEPIT);
2012     }
2013   }
2014   else 
2015   {
2016     /* Just an ordinary section */
2017     r_extern = 0;
2018     r_index  = output_section->target_index;      
2019   }
2020          
2021          
2022   /* now the fun stuff */
2023   if (abfd->xvec->header_byteorder_big_p != false) {
2024     natptr->r_index[0] = r_index >> 16;
2025     natptr->r_index[1] = r_index >> 8;
2026     natptr->r_index[2] = r_index;
2027     natptr->r_type[0] =
2028      (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
2029       | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
2030   } else {
2031     natptr->r_index[2] = r_index >> 16;
2032     natptr->r_index[1] = r_index >> 8;
2033     natptr->r_index[0] = r_index;
2034     natptr->r_type[0] =
2035      (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
2036       | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
2037   }
2038
2039   PUT_WORD (abfd, r_addend, natptr->r_addend);
2040 }
2041
2042 /* BFD deals internally with all things based from the section they're
2043    in. so, something in 10 bytes into a text section  with a base of
2044    50 would have a symbol (.text+10) and know .text vma was 50. 
2045
2046    Aout keeps all it's symbols based from zero, so the symbol would
2047    contain 60. This macro subs the base of each section from the value
2048    to give the true offset from the section */
2049
2050
2051 #define MOVE_ADDRESS(ad)                                                \
2052   if (r_extern) {                                                       \
2053    /* undefined symbol */                                               \
2054      cache_ptr->sym_ptr_ptr = symbols + r_index;                        \
2055      cache_ptr->addend = ad;                                            \
2056      } else {                                                           \
2057     /* defined, section relative. replace symbol with pointer to        \
2058        symbol which points to section  */                               \
2059     switch (r_index) {                                                  \
2060     case N_TEXT:                                                        \
2061     case N_TEXT | N_EXT:                                                \
2062       cache_ptr->sym_ptr_ptr  = obj_textsec(abfd)->symbol_ptr_ptr;      \
2063       cache_ptr->addend = ad  - su->textsec->vma;                       \
2064       break;                                                            \
2065     case N_DATA:                                                        \
2066     case N_DATA | N_EXT:                                                \
2067       cache_ptr->sym_ptr_ptr  = obj_datasec(abfd)->symbol_ptr_ptr;      \
2068       cache_ptr->addend = ad - su->datasec->vma;                        \
2069       break;                                                            \
2070     case N_BSS:                                                         \
2071     case N_BSS | N_EXT:                                                 \
2072       cache_ptr->sym_ptr_ptr  = obj_bsssec(abfd)->symbol_ptr_ptr;       \
2073       cache_ptr->addend = ad - su->bsssec->vma;                         \
2074       break;                                                            \
2075     default:                                                            \
2076     case N_ABS:                                                         \
2077     case N_ABS | N_EXT:                                                 \
2078      cache_ptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;   \
2079       cache_ptr->addend = ad;                                           \
2080       break;                                                            \
2081     }                                                                   \
2082   }                                                                     \
2083
2084 void
2085 DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
2086       bfd *abfd AND
2087       struct reloc_ext_external *bytes AND
2088       arelent *cache_ptr AND
2089       asymbol **symbols)
2090 {
2091   int r_index;
2092   int r_extern;
2093   unsigned int r_type;
2094   struct aoutdata *su = &(abfd->tdata.aout_data->a);
2095
2096   cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
2097
2098   /* now the fun stuff */
2099   if (abfd->xvec->header_byteorder_big_p != false) {
2100     r_index =  (bytes->r_index[0] << 16)
2101              | (bytes->r_index[1] << 8)
2102              |  bytes->r_index[2];
2103     r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
2104     r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
2105                                       >> RELOC_EXT_BITS_TYPE_SH_BIG;
2106   } else {
2107     r_index =  (bytes->r_index[2] << 16)
2108              | (bytes->r_index[1] << 8)
2109              |  bytes->r_index[0];
2110     r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
2111     r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
2112                                       >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
2113   }
2114
2115   cache_ptr->howto =  howto_table_ext + r_type;
2116   MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend));
2117 }
2118
2119 void
2120 DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
2121   bfd *abfd AND
2122   struct reloc_std_external *bytes AND
2123   arelent *cache_ptr AND
2124   asymbol **symbols)
2125 {
2126   int r_index;
2127   int r_extern;
2128   unsigned int r_length;
2129   int r_pcrel;
2130   int r_baserel, r_jmptable, r_relative;
2131   struct aoutdata  *su = &(abfd->tdata.aout_data->a);
2132
2133   cache_ptr->address = bfd_h_get_32 (abfd, bytes->r_address);
2134
2135   /* now the fun stuff */
2136   if (abfd->xvec->header_byteorder_big_p != false) {
2137     r_index =  (bytes->r_index[0] << 16)
2138       | (bytes->r_index[1] << 8)
2139         |  bytes->r_index[2];
2140     r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
2141     r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
2142     r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
2143     r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
2144     r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
2145     r_length  =       (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) 
2146                         >> RELOC_STD_BITS_LENGTH_SH_BIG;
2147   } else {
2148     r_index =  (bytes->r_index[2] << 16)
2149       | (bytes->r_index[1] << 8)
2150         |  bytes->r_index[0];
2151     r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
2152     r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
2153     r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
2154     r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
2155     r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
2156     r_length  =       (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) 
2157                         >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
2158   }
2159
2160   cache_ptr->howto =  howto_table_std + r_length + 4 * r_pcrel;
2161   /* FIXME-soon:  Roll baserel, jmptable, relative bits into howto setting */
2162
2163   MOVE_ADDRESS(0);
2164 }
2165
2166 /* Reloc hackery */
2167
2168 boolean
2169 DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
2170       bfd *abfd AND
2171       sec_ptr asect AND
2172       asymbol **symbols)
2173 {
2174   unsigned int count;
2175   bfd_size_type reloc_size;
2176   PTR relocs;
2177   arelent *reloc_cache;
2178   size_t each_size;
2179
2180   if (asect->relocation) return true;
2181
2182   if (asect->flags & SEC_CONSTRUCTOR) return true;
2183
2184   if (asect == obj_datasec (abfd)) {
2185     reloc_size = exec_hdr(abfd)->a_drsize;
2186     goto doit;
2187   }
2188
2189   if (asect == obj_textsec (abfd)) {
2190     reloc_size = exec_hdr(abfd)->a_trsize;
2191     goto doit;
2192   }
2193
2194   bfd_error = invalid_operation;
2195   return false;
2196
2197  doit:
2198   bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
2199   each_size = obj_reloc_entry_size (abfd);
2200
2201   count = reloc_size / each_size;
2202
2203
2204   reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
2205                                                        (arelent)));
2206   if (!reloc_cache) {
2207 nomem:
2208     bfd_error = no_memory;
2209     return false;
2210   }
2211
2212   relocs = (PTR) bfd_alloc (abfd, reloc_size);
2213   if (!relocs) {
2214     bfd_release (abfd, reloc_cache);
2215     goto nomem;
2216   }
2217
2218   if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
2219     bfd_release (abfd, relocs);
2220     bfd_release (abfd, reloc_cache);
2221     bfd_error = system_call_error;
2222     return false;
2223   }
2224
2225   if (each_size == RELOC_EXT_SIZE) {
2226     register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
2227     unsigned int counter = 0;
2228     arelent *cache_ptr = reloc_cache;
2229
2230     for (; counter < count; counter++, rptr++, cache_ptr++) {
2231       NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
2232     }
2233   } else {
2234     register struct reloc_std_external *rptr = (struct reloc_std_external*) relocs;
2235     unsigned int counter = 0;
2236     arelent *cache_ptr = reloc_cache;
2237
2238     for (; counter < count; counter++, rptr++, cache_ptr++) {
2239         NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
2240     }
2241
2242   }
2243
2244   bfd_release (abfd,relocs);
2245   asect->relocation = reloc_cache;
2246   asect->reloc_count = count;
2247   return true;
2248 }
2249
2250
2251
2252 /* Write out a relocation section into an object file.  */
2253
2254 boolean
2255 DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
2256       bfd *abfd AND
2257       asection *section)
2258 {
2259   arelent **generic;
2260   unsigned char *native, *natptr;
2261   size_t each_size;
2262
2263   unsigned int count = section->reloc_count;
2264   size_t natsize;
2265
2266   if (count == 0) return true;
2267
2268   each_size = obj_reloc_entry_size (abfd);
2269   natsize = each_size * count;
2270   native = (unsigned char *) bfd_zalloc (abfd, natsize);
2271   if (!native) {
2272     bfd_error = no_memory;
2273     return false;
2274   }
2275
2276   generic = section->orelocation;
2277
2278   if (each_size == RELOC_EXT_SIZE) 
2279     {
2280       for (natptr = native;
2281            count != 0;
2282            --count, natptr += each_size, ++generic)
2283         NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
2284     }
2285   else 
2286     {
2287       for (natptr = native;
2288            count != 0;
2289            --count, natptr += each_size, ++generic)
2290         NAME(aout,swap_std_reloc_out)(abfd, *generic, (struct reloc_std_external *)natptr);
2291     }
2292
2293   if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
2294     bfd_release(abfd, native);
2295     return false;
2296   }
2297   bfd_release (abfd, native);
2298
2299   return true;
2300 }
2301
2302 /* This is stupid.  This function should be a boolean predicate */
2303 unsigned int
2304 DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
2305       bfd *abfd AND
2306       sec_ptr section AND
2307       arelent **relptr AND
2308       asymbol **symbols)
2309 {
2310   arelent *tblptr = section->relocation;
2311   unsigned int count;
2312
2313   if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
2314     return 0;
2315
2316   if (section->flags & SEC_CONSTRUCTOR) {
2317     arelent_chain *chain = section->constructor_chain;
2318     for (count = 0; count < section->reloc_count; count ++) {
2319       *relptr ++ = &chain->relent;
2320       chain = chain->next;
2321     }
2322   }
2323   else {
2324     tblptr = section->relocation;
2325     if (!tblptr) return 0;
2326
2327     for (count = 0; count++ < section->reloc_count;) 
2328       {
2329         *relptr++ = tblptr++;
2330       }
2331   }
2332   *relptr = 0;
2333
2334   return section->reloc_count;
2335 }
2336
2337 unsigned int
2338 DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
2339      bfd *abfd AND
2340      sec_ptr asect)
2341 {
2342   if (bfd_get_format (abfd) != bfd_object) {
2343     bfd_error = invalid_operation;
2344     return 0;
2345   }
2346   if (asect->flags & SEC_CONSTRUCTOR) {
2347     return (sizeof (arelent *) * (asect->reloc_count+1));
2348   }
2349
2350
2351   if (asect == obj_datasec (abfd))
2352     return (sizeof (arelent *) *
2353             ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
2354              +1));
2355
2356   if (asect == obj_textsec (abfd))
2357     return (sizeof (arelent *) *
2358             ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
2359              +1));
2360
2361   bfd_error = invalid_operation;
2362   return 0;
2363 }
2364
2365 \f
2366  unsigned int
2367 DEFUN(NAME(aout,get_symtab_upper_bound),(abfd),
2368      bfd *abfd)
2369 {
2370   if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
2371
2372   return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
2373 }
2374  alent *
2375 DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
2376       bfd *ignore_abfd AND
2377       asymbol *ignore_symbol)
2378 {
2379 return (alent *)NULL;
2380 }
2381
2382 void 
2383 DEFUN(NAME(aout,get_symbol_info),(ignore_abfd, symbol, ret),
2384       bfd *ignore_abfd AND
2385       asymbol *symbol AND
2386       symbol_info *ret)
2387 {
2388   bfd_symbol_info (symbol, ret);
2389
2390   if (ret->type == '?')
2391     {
2392       int type_code = aout_symbol(symbol)->type & 0xff;
2393       CONST char *stab_name = aout_stab_name(type_code);
2394       static char buf[10];
2395
2396       if (stab_name == NULL)
2397         {
2398           sprintf(buf, "(%d)", type_code);
2399           stab_name = buf;
2400         }
2401       ret->type = '-';
2402       ret->stab_other = (unsigned)(aout_symbol(symbol)->other & 0xff);
2403       ret->stab_desc = (unsigned)(aout_symbol(symbol)->desc & 0xffff);
2404       ret->stab_name = stab_name;
2405     }
2406 }
2407
2408 void 
2409 DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
2410       bfd *ignore_abfd AND
2411       PTR afile AND
2412       asymbol *symbol AND
2413       bfd_print_symbol_type how)
2414 {
2415   FILE *file = (FILE *)afile;
2416
2417   switch (how) {
2418   case bfd_print_symbol_name:
2419     if (symbol->name)
2420       fprintf(file,"%s", symbol->name);
2421     break;
2422   case bfd_print_symbol_more:
2423     fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
2424             (unsigned)(aout_symbol(symbol)->other & 0xff),
2425             (unsigned)(aout_symbol(symbol)->type));
2426     break;
2427   case bfd_print_symbol_all:
2428     {
2429    CONST char *section_name = symbol->section->name;
2430
2431
2432       bfd_print_symbol_vandf((PTR)file,symbol);
2433
2434       fprintf(file," %-5s %04x %02x %02x",
2435               section_name,
2436               (unsigned)(aout_symbol(symbol)->desc & 0xffff),
2437               (unsigned)(aout_symbol(symbol)->other & 0xff),
2438               (unsigned)(aout_symbol(symbol)->type  & 0xff));
2439       if (symbol->name)
2440         fprintf(file," %s", symbol->name);
2441     }
2442     break;
2443   }
2444 }
2445
2446 /* 
2447  provided a BFD, a section and an offset into the section, calculate
2448  and return the name of the source file and the line nearest to the
2449  wanted location.
2450 */
2451  
2452 boolean
2453 DEFUN(NAME(aout,find_nearest_line),(abfd,
2454                                      section,
2455                                      symbols,
2456                                      offset,
2457                                      filename_ptr,
2458                                      functionname_ptr,
2459                                      line_ptr),
2460       bfd *abfd AND
2461       asection *section AND
2462       asymbol **symbols AND
2463       bfd_vma offset AND
2464       CONST char **filename_ptr AND
2465       CONST char **functionname_ptr AND
2466       unsigned int *line_ptr)
2467 {
2468   /* Run down the file looking for the filename, function and linenumber */
2469   asymbol **p;
2470   static  char buffer[100];
2471   static  char filename_buffer[200];
2472   CONST char *directory_name = NULL;
2473   CONST char *main_file_name = NULL;
2474   CONST char *current_file_name = NULL;
2475   CONST char *line_file_name = NULL; /* Value of current_file_name at line number. */
2476   bfd_vma high_line_vma = ~0;
2477   bfd_vma low_func_vma = 0;
2478   asymbol *func = 0;
2479   *filename_ptr = abfd->filename;
2480   *functionname_ptr = 0;
2481   *line_ptr = 0;
2482   if (symbols != (asymbol **)NULL) {
2483     for (p = symbols; *p; p++) {
2484       aout_symbol_type  *q = (aout_symbol_type *)(*p);
2485     next:
2486       switch (q->type){
2487       case N_SO:
2488         main_file_name = current_file_name = q->symbol.name;
2489         /* Look ahead to next symbol to check if that too is an N_SO. */
2490         p++;
2491         if (*p == NULL)
2492           break;
2493         q = (aout_symbol_type *)(*p);
2494         if (q->type != (int)N_SO)
2495           goto next;
2496
2497         /* Found a second N_SO  First is directory; second is filename. */
2498         directory_name = current_file_name;
2499         main_file_name = current_file_name = q->symbol.name;
2500         if (obj_textsec(abfd) != section)
2501           goto done;
2502         break;
2503       case N_SOL:
2504         current_file_name = q->symbol.name;
2505         break;
2506
2507       case N_SLINE:
2508
2509       case N_DSLINE:
2510       case N_BSLINE:
2511         /* We'll keep this if it resolves nearer than the one we have already */
2512         if (q->symbol.value >= offset &&
2513             q->symbol.value < high_line_vma) {
2514           *line_ptr = q->desc;
2515           high_line_vma = q->symbol.value;
2516           line_file_name = current_file_name;
2517         }
2518         break;
2519       case N_FUN:
2520         {
2521           /* We'll keep this if it is nearer than the one we have already */
2522           if (q->symbol.value >= low_func_vma &&
2523               q->symbol.value <= offset) {
2524             low_func_vma = q->symbol.value;
2525             func = (asymbol *)q;
2526           }
2527           if (*line_ptr && func) {
2528             CONST char *function = func->name;
2529             char *p;
2530             strncpy(buffer, function, sizeof(buffer)-1);
2531             buffer[sizeof(buffer)-1] = 0;
2532             /* Have to remove : stuff */
2533             p = strchr(buffer,':');
2534             if (p != NULL) { *p = '\0'; }
2535             *functionname_ptr = buffer;
2536             goto done;
2537
2538           }
2539         }
2540         break;
2541       }
2542     }
2543   }
2544
2545  done:
2546   if (*line_ptr)
2547     main_file_name = line_file_name;
2548   if (main_file_name) {
2549       if (main_file_name[0] == '/' || directory_name == NULL)
2550           *filename_ptr = main_file_name;
2551       else {
2552           sprintf(filename_buffer, "%.140s%.50s",
2553                   directory_name, main_file_name);
2554           *filename_ptr = filename_buffer;
2555       }
2556   }
2557   return true;
2558
2559 }
2560
2561 int 
2562 DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
2563       bfd *abfd AND
2564       boolean execable)
2565 {
2566   return adata(abfd).exec_bytes_size;
2567 }