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