* aoutx.h (translate_from_native_sym_flags): when creating an alias symbol, fill...
[external/binutils.git] / bfd / aoutx.h
1 /* BFD semi-generic back-end for a.out binaries
2    Copyright (C) 1990-1991 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 #define KEEPIT flags
112 #define KEEPITTYPE int
113
114 #include "bfd.h"
115 #include <sysdep.h>
116 #include <ansidecl.h>
117
118 struct external_exec;
119 #include "libaout.h"
120 #include "libbfd.h"
121 #include "aout/aout64.h"
122 #include "aout/stab_gnu.h"
123 #include "aout/ar.h"
124
125 void (*bfd_error_trap)();
126
127 /*
128 SUBSECTION
129         relocations
130
131 DESCRIPTION
132         The file @code{aoutx.h} caters for both the @emph{standard}
133         and @emph{extended} forms of a.out relocation records.
134
135         The standard records are characterised by containing only an
136         address, a symbol index and a type field. The extended records
137         (used on 29ks and sparcs) also have a full integer for an
138         addend. 
139
140 */
141 #define CTOR_TABLE_RELOC_IDX 2
142
143
144 static  reloc_howto_type howto_table_ext[] = 
145 {
146   HOWTO(RELOC_8,      0,  0,    8,  false, 0, true,  true,0,"8",      false, 0,0x000000ff, false),
147   HOWTO(RELOC_16,     0,  1,    16, false, 0, true,  true,0,"16",      false, 0,0x0000ffff, false),
148   HOWTO(RELOC_32,     0,  2,    32, false, 0, true,  true,0,"32",      false, 0,0xffffffff, false),
149   HOWTO(RELOC_DISP8,  0,  0,    8,  true,  0, false, true,0,"DISP8",    false, 0,0x000000ff, false),
150   HOWTO(RELOC_DISP16, 0,  1,    16, true,  0, false, true,0,"DISP16",   false, 0,0x0000ffff, false),
151   HOWTO(RELOC_DISP32, 0,  2,    32, true,  0, false, true,0,"DISP32",   false, 0,0xffffffff, false),
152   HOWTO(RELOC_WDISP30,2,  2,    30, true,  0, false, true,0,"WDISP30",  false, 0,0x3fffffff, false),
153   HOWTO(RELOC_WDISP22,2,  2,    22, true,  0, false, true,0,"WDISP22",  false, 0,0x003fffff, false),
154   HOWTO(RELOC_HI22,   10, 2,    22, false, 0, false, true,0,"HI22",     false, 0,0x003fffff, false),
155   HOWTO(RELOC_22,      0, 2,    22, false, 0, false, true,0,"22",       false, 0,0x003fffff, false),
156   HOWTO(RELOC_13,       0, 2,   13, false, 0, false, true,0,"13",       false, 0,0x00001fff, false),
157   HOWTO(RELOC_LO10,     0, 2,   10, false, 0, false, true,0,"LO10",     false, 0,0x000003ff, false),
158   HOWTO(RELOC_SFA_BASE,0, 2,    32, false, 0, false, true,0,"SFA_BASE", false, 0,0xffffffff, false),
159   HOWTO(RELOC_SFA_OFF13,0,2,    32, false, 0, false, true,0,"SFA_OFF13",false, 0,0xffffffff, false),
160   HOWTO(RELOC_BASE10, 0,  2,    16, false, 0, false, true,0,"BASE10",   false, 0,0x0000ffff, false),
161   HOWTO(RELOC_BASE13, 0,  2,    13, false, 0, false, true,0,"BASE13",   false, 0,0x00001fff, false),
162   HOWTO(RELOC_BASE22, 0,  2,    0,  false, 0, false, true,0,"BASE22",   false, 0,0x00000000, false),
163   HOWTO(RELOC_PC10,   0,  2,    10, false, 0, false, true,0,"PC10",     false, 0,0x000003ff, false),
164   HOWTO(RELOC_PC22,   0,  2,    22, false, 0, false, true,0,"PC22",     false, 0,0x003fffff, false),
165   HOWTO(RELOC_JMP_TBL,0,  2,    32, false, 0, false, true,0,"JMP_TBL",  false, 0,0xffffffff, false),
166   HOWTO(RELOC_SEGOFF16,0, 2,    0,  false, 0, false, true,0,"SEGOFF16", false, 0,0x00000000, false),
167   HOWTO(RELOC_GLOB_DAT,0, 2,    0,  false, 0, false, true,0,"GLOB_DAT", false, 0,0x00000000, false),
168   HOWTO(RELOC_JMP_SLOT,0, 2,    0,  false, 0, false, true,0,"JMP_SLOT", false, 0,0x00000000, false),
169   HOWTO(RELOC_RELATIVE,0, 2,    0,  false, 0, false,    true,0,"RELATIVE",      false, 0,0x00000000, false),
170
171 };
172
173 /* Convert standard reloc records to "arelent" format (incl byte swap).  */
174
175 static  reloc_howto_type howto_table_std[] = {
176   /* type           rs   size bsz  pcrel bitpos  abs ovrf sf name    part_inpl   readmask  setmask  pcdone */
177 HOWTO( 0,              0,  0,   8,  false, 0, true,  true,0,"8",        true, 0x000000ff,0x000000ff, false),
178 HOWTO( 1,              0,  1,   16, false, 0, true,  true,0,"16",       true, 0x0000ffff,0x0000ffff, false),
179 HOWTO( 2,              0,  2,   32, false, 0, true,  true,0,"32",       true, 0xffffffff,0xffffffff, false),
180 HOWTO( 3,              0,  3,   64, false, 0, true,  true,0,"64",       true, 0xdeaddead,0xdeaddead, false),
181 HOWTO( 4,              0,  0,   8,  true,  0, false, true,0,"DISP8",    true, 0x000000ff,0x000000ff, false),
182 HOWTO( 5,              0,  1,   16, true,  0, false, true,0,"DISP16",   true, 0x0000ffff,0x0000ffff, false),
183 HOWTO( 6,              0,  2,   32, true,  0, false, true,0,"DISP32",   true, 0xffffffff,0xffffffff, false),
184 HOWTO( 7,              0,  3,   64, true,  0, false, true,0,"DISP64",   true, 0xfeedface,0xfeedface, false),
185 };
186
187
188 bfd_error_vector_type bfd_error_vector;
189
190 /*
191 SUBSECTION
192         Internal Entry Points
193
194 DESCRIPTION
195         @code{aoutx.h} exports several routines for accessing the
196         contents of an a.out file, which are gathered and exported in
197         turn by various format specific files (eg sunos.c).
198
199 */
200
201 /*
202 FUNCTION
203          aout_<size>_swap_exec_header_in
204
205 DESCRIPTION
206         Swaps the information in an executable header taken from a raw
207         byte stream memory image, into the internal exec_header
208         structure.
209
210 EXAMPLE
211         void aout_<size>_swap_exec_header_in,
212            (bfd *abfd,
213             struct external_exec *raw_bytes,
214             struct internal_exec *execp);
215 */
216          
217 void
218 DEFUN(NAME(aout,swap_exec_header_in),(abfd, raw_bytes, execp),
219       bfd *abfd AND
220       struct external_exec *raw_bytes AND
221       struct internal_exec *execp)
222 {
223   struct external_exec *bytes = (struct external_exec *)raw_bytes;
224
225   /* Now fill in fields in the execp, from the bytes in the raw data.  */
226   execp->a_info   = bfd_h_get_32 (abfd, bytes->e_info);
227   execp->a_text   = GET_WORD (abfd, bytes->e_text);
228   execp->a_data   = GET_WORD (abfd, bytes->e_data);
229   execp->a_bss    = GET_WORD (abfd, bytes->e_bss);
230   execp->a_syms   = GET_WORD (abfd, bytes->e_syms);
231   execp->a_entry  = GET_WORD (abfd, bytes->e_entry);
232   execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
233   execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
234 }
235
236 /*
237 FUNCTION
238         aout_<size>_swap_exec_header_out
239
240 DESCRIPTION
241         Swaps the information in an internal exec header structure
242         into the supplied buffer ready for writing to disk.
243
244 EXAMPLE
245         void aout_<size>_swap_exec_header_out
246           (bfd *abfd,
247            struct internal_exec *execp,
248            struct external_exec *raw_bytes);
249 */
250 void
251 DEFUN(NAME(aout,swap_exec_header_out),(abfd, execp, raw_bytes),
252      bfd *abfd AND
253      struct internal_exec *execp AND 
254      struct external_exec *raw_bytes)
255 {
256   struct external_exec *bytes = (struct external_exec *)raw_bytes;
257
258   /* Now fill in fields in the raw data, from the fields in the exec struct. */
259   bfd_h_put_32 (abfd, execp->a_info  , bytes->e_info);
260   PUT_WORD (abfd, execp->a_text  , bytes->e_text);
261   PUT_WORD (abfd, execp->a_data  , bytes->e_data);
262   PUT_WORD (abfd, execp->a_bss   , bytes->e_bss);
263   PUT_WORD (abfd, execp->a_syms  , bytes->e_syms);
264   PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
265   PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
266   PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
267 }
268
269
270
271 /*
272 FUNCTION
273         aout_<size>_some_aout_object_p
274
275 DESCRIPTION
276         Some A.OUT variant thinks that the file whose format we're
277         checking is an a.out file.  Do some more checking, and set up
278         for access if it really is.  Call back to the calling
279         environments "finish up" function just before returning, to
280         handle any last-minute setup.  
281
282 EXAMPLE
283         bfd_target *aout_<size>_some_aout_object_p
284          (bfd *abfd,
285           bfd_target *(*callback_to_real_object_p)());
286 */
287  
288 bfd_target *
289 DEFUN(NAME(aout,some_aout_object_p),(abfd, execp, callback_to_real_object_p),
290       bfd *abfd AND
291       struct internal_exec *execp AND
292       bfd_target *(*callback_to_real_object_p) ())
293 {
294   struct aout_data_struct  *rawptr;
295   bfd_target *result;
296
297   rawptr = (struct aout_data_struct  *) bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
298   if (rawptr == NULL) {
299     bfd_error = no_memory;
300     return 0;
301   }
302
303   abfd->tdata.aout_data = rawptr;
304   abfd->tdata.aout_data->a.hdr = &rawptr->e;
305   *(abfd->tdata.aout_data->a.hdr) = *execp;     /* Copy in the internal_exec struct */
306   execp = abfd->tdata.aout_data->a.hdr;
307
308   /* Set the file flags */
309   abfd->flags = NO_FLAGS;
310   if (execp->a_drsize || execp->a_trsize)
311     abfd->flags |= HAS_RELOC;
312   /* Setting of EXEC_P has been deferred to the bottom of this function */
313   if (execp->a_syms) 
314     abfd->flags |= HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS;
315
316   if (N_MAGIC (*execp) == ZMAGIC) abfd->flags |= D_PAGED;
317   if (N_MAGIC (*execp) == NMAGIC) abfd->flags |= WP_TEXT;
318
319   bfd_get_start_address (abfd) = execp->a_entry;
320
321   obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
322   bfd_get_symcount (abfd) = execp->a_syms / sizeof (struct external_nlist);
323
324   /* The default relocation entry size is that of traditional V7 Unix.  */
325   obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
326
327   /* The default symbol entry size is that of traditional Unix. */
328   obj_symbol_entry_size (abfd) = EXTERNAL_NLIST_SIZE;
329
330   /* create the sections.  This is raunchy, but bfd_close wants to reclaim
331      them */
332
333   obj_textsec (abfd) = (asection *)NULL;
334   obj_datasec (abfd) = (asection *)NULL;
335   obj_bsssec (abfd) = (asection *)NULL;
336   
337   (void)bfd_make_section(abfd, ".text");
338   (void)bfd_make_section(abfd, ".data");
339   (void)bfd_make_section(abfd, ".bss");
340 /*  (void)bfd_make_section(abfd, BFD_ABS_SECTION_NAME);
341   (void)bfd_make_section (abfd, BFD_UND_SECTION_NAME);
342   (void)bfd_make_section (abfd, BFD_COM_SECTION_NAME);*/
343   abfd->sections = obj_textsec (abfd);
344   obj_textsec (abfd)->next = obj_datasec (abfd);
345   obj_datasec (abfd)->next = obj_bsssec (abfd);
346
347   obj_datasec (abfd)->_raw_size = execp->a_data;
348   obj_bsssec (abfd)->_raw_size = execp->a_bss;
349
350   obj_textsec (abfd)->flags = (execp->a_trsize != 0 ?
351                        (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
352                        (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
353   obj_datasec (abfd)->flags = (execp->a_drsize != 0 ?
354                        (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_HAS_CONTENTS) :
355                        (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS));
356   obj_bsssec (abfd)->flags = SEC_ALLOC;
357
358 #ifdef THIS_IS_ONLY_DOCUMENTATION
359   /* The common code can't fill in these things because they depend
360      on either the start address of the text segment, the rounding
361      up of virtual addersses between segments, or the starting file 
362      position of the text segment -- all of which varies among different
363      versions of a.out.  */
364
365   /* Call back to the format-dependent code to fill in the rest of the 
366      fields and do any further cleanup.  Things that should be filled
367      in by the callback:  */
368
369   struct exec *execp = exec_hdr (abfd);
370
371   obj_textsec (abfd)->size = N_TXTSIZE(*execp);
372   obj_textsec (abfd)->raw_size = N_TXTSIZE(*execp);
373   /* data and bss are already filled in since they're so standard */
374
375   /* The virtual memory addresses of the sections */
376   obj_textsec (abfd)->vma = N_TXTADDR(*execp);
377   obj_datasec (abfd)->vma = N_DATADDR(*execp);
378   obj_bsssec  (abfd)->vma = N_BSSADDR(*execp);
379
380   /* The file offsets of the sections */
381   obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
382   obj_datasec (abfd)->filepos = N_DATOFF(*execp);
383
384   /* The file offsets of the relocation info */
385   obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp);
386   obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp);
387
388   /* The file offsets of the string table and symbol table.  */
389   obj_str_filepos (abfd) = N_STROFF (*execp);
390   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
391
392   /* Determine the architecture and machine type of the object file.  */
393   switch (N_MACHTYPE (*exec_hdr (abfd))) {
394   default:
395     abfd->obj_arch = bfd_arch_obscure;
396     break;
397   }
398
399   /* Determine the size of a relocation entry */
400   switch (abfd->obj_arch) {
401   case bfd_arch_sparc:
402   case bfd_arch_a29k:
403     obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
404   default:
405     obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
406   }
407
408   adata(abfd)->page_size = PAGE_SIZE;
409   adata(abfd)->segment_size = SEGMENT_SIZE;
410   adata(abfd)->exec_bytes_size = EXEC_BYTES_SIZE;
411
412   return abfd->xvec;
413
414   /* The architecture is encoded in various ways in various a.out variants,
415      or is not encoded at all in some of them.  The relocation size depends
416      on the architecture and the a.out variant.  Finally, the return value
417      is the bfd_target vector in use.  If an error occurs, return zero and
418      set bfd_error to the appropriate error code.
419      
420      Formats such as b.out, which have additional fields in the a.out
421      header, should cope with them in this callback as well.  */
422 #endif                          /* DOCUMENTATION */
423
424   result = (*callback_to_real_object_p)(abfd);
425
426   /* Now that the segment addresses have been worked out, take a better
427      guess at whether the file is executable.  If the entry point
428      is within the text segment, assume it is.  (This makes files
429      executable even if their entry point address is 0, as long as
430      their text starts at zero.)  
431
432      At some point we should probably break down and stat the file and
433      declare it executable if (one of) its 'x' bits are on...  */
434   if ((execp->a_entry >= obj_textsec(abfd)->vma) &&
435       (execp->a_entry < obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size))
436     abfd->flags |= EXEC_P;
437   return result;
438 }
439
440 /*
441 FUNCTION
442         aout_<size>_mkobject
443
444 DESCRIPTION
445         This routine initializes a BFD for use with a.out files.
446
447 EXAMPLE
448         boolean aout_<size>_mkobject, (bfd *);
449 */
450
451 boolean
452 DEFUN(NAME(aout,mkobject),(abfd),
453      bfd *abfd)
454 {
455   struct aout_data_struct  *rawptr;
456
457   bfd_error = system_call_error;
458
459   /* Use an intermediate variable for clarity */
460   rawptr = (struct aout_data_struct  *)bfd_zalloc (abfd, sizeof (struct aout_data_struct ));
461   
462   if (rawptr == NULL) {
463     bfd_error = no_memory;
464     return false;
465   }
466   
467   abfd->tdata.aout_data = rawptr;
468   exec_hdr (abfd) = &(rawptr->e);
469   
470   /* For simplicity's sake we just make all the sections right here. */
471   
472   obj_textsec (abfd) = (asection *)NULL;
473   obj_datasec (abfd) = (asection *)NULL;
474   obj_bsssec (abfd) = (asection *)NULL;
475   bfd_make_section (abfd, ".text");
476   bfd_make_section (abfd, ".data");
477   bfd_make_section (abfd, ".bss");
478   bfd_make_section (abfd, BFD_ABS_SECTION_NAME);
479   bfd_make_section (abfd, BFD_UND_SECTION_NAME);
480   bfd_make_section (abfd, BFD_COM_SECTION_NAME);
481   
482   return true;
483 }
484
485
486 /*
487 FUNCTION
488         aout_<size>_machine_type
489
490 DESCRIPTION
491         Keep track of machine architecture and machine type for
492         a.out's. Return the machine_type for a particular
493         arch&machine, or M_UNKNOWN if that exact arch&machine can't be
494         represented in a.out format. 
495
496         If the architecture is understood, machine type 0 (default)
497         should always be understood.  
498
499 EXAMPLE
500         enum machine_type  aout_<size>_machine_type
501          (enum bfd_architecture arch,
502           unsigned long machine));
503 */
504
505 enum machine_type
506 DEFUN(NAME(aout,machine_type),(arch, machine),
507       enum bfd_architecture arch AND
508       unsigned long machine)
509 {
510   enum machine_type arch_flags;
511     
512   arch_flags = M_UNKNOWN;
513     
514   switch (arch) {
515   case bfd_arch_sparc:
516     if (machine == 0)   arch_flags = M_SPARC;
517     break;
518       
519   case bfd_arch_m68k:
520     switch (machine) {
521     case 0:             arch_flags = M_68010; break;
522     case 68000:         arch_flags = M_UNKNOWN; break;
523     case 68010:         arch_flags = M_68010; break;
524     case 68020:         arch_flags = M_68020; break;
525     default:            arch_flags = M_UNKNOWN; break;
526     }
527     break;
528       
529   case bfd_arch_i386:
530     if (machine == 0)   arch_flags = M_386;
531     break;
532       
533   case bfd_arch_a29k:
534     if (machine == 0)   arch_flags = M_29K;
535     break;
536       
537   default:
538     arch_flags = M_UNKNOWN;
539     break;
540   }
541   return arch_flags;
542 }
543
544
545 /*
546 FUNCTION
547         aout_<size>_set_arch_mach
548
549 DESCRIPTION
550         Sets the architecture and the machine of the BFD to those
551         values supplied. Verifies that the format can support the
552         architecture required.
553
554 EXAMPLE
555         boolean aout_<size>_set_arch_mach,
556          (bfd *,
557           enum bfd_architecture,
558           unsigned long machine));
559 */
560
561 boolean
562 DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
563       bfd *abfd AND
564       enum bfd_architecture arch AND
565       unsigned long machine)
566 {
567   bfd_default_set_arch_mach(abfd, arch, machine);
568   if (arch != bfd_arch_unknown &&
569       NAME(aout,machine_type) (arch, machine) == M_UNKNOWN)
570     return false;               /* We can't represent this type */
571   return true;                  /* We're easy ... */
572 }
573
574 /*
575 FUNCTION
576         aout_<size>new_section_hook
577   
578 DESCRIPTION
579         Called by the BFD in response to a @code{bfd_make_section}
580         request.
581
582 EXAMPLE
583         boolean aout_<size>_new_section_hook,
584            (bfd *abfd,
585             asection *newsect));
586 */
587 boolean
588 DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
589         bfd *abfd AND
590         asection *newsect)
591 {
592   /* align to double at least */
593   newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
594
595     
596   if (bfd_get_format (abfd) == bfd_object) 
597   {
598     if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
599         obj_textsec(abfd)= newsect;
600         newsect->target_index = N_TEXT | N_EXT;
601         return true;
602       }
603       
604     if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
605         obj_datasec(abfd) = newsect;
606         newsect->target_index = N_DATA | N_EXT;
607         return true;
608       }
609       
610     if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
611         obj_bsssec(abfd) = newsect;
612         newsect->target_index = N_BSS | N_EXT;
613         return true;
614       }
615
616   }
617     
618   /* We allow more than three sections internally */
619   return true;
620 }
621
622 boolean
623   DEFUN(NAME(aout,set_section_contents),(abfd, section, location, offset, count),
624         bfd *abfd AND
625         sec_ptr section AND
626         PTR location AND
627         file_ptr offset AND
628         bfd_size_type count)
629 {
630   file_ptr text_end;
631   bfd_size_type text_size;
632   if (abfd->output_has_begun == false)
633       {                         /* set by bfd.c handler */
634         switch (abfd->direction)
635             {
636             case read_direction:
637             case no_direction:
638               bfd_error = invalid_operation;
639               return false;
640                 
641             case both_direction:
642               break;
643                 
644             case write_direction:
645               if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL)) 
646                   {
647                     bfd_error = invalid_operation;
648                     return false;
649                   }
650               obj_textsec(abfd)->_raw_size =          
651                   align_power(obj_textsec(abfd)->_raw_size,
652                               obj_textsec(abfd)->alignment_power);
653
654               text_size = obj_textsec (abfd)->_raw_size;
655               /* Rule (heuristic) for when to pad to a new page.
656                * Note that there are (at least) two ways demand-paged
657                * (ZMAGIC) files have been handled.  Most Berkeley-based systems
658                * start the text segment at (PAGE_SIZE).  However, newer
659                * versions of SUNOS start the text segment right after the
660                * exec header; the latter is counted in the text segment size,
661                * and is paged in by the kernel with the rest of the text. */
662               if (!(abfd->flags & D_PAGED))
663                 { /* Not demand-paged. */
664                   obj_textsec(abfd)->filepos = adata(abfd).exec_bytes_size;
665                 }
666               else if (obj_textsec(abfd)->vma % adata(abfd).page_size
667                     < adata(abfd).exec_bytes_size)
668                 { /* Old-style demand-paged. */
669                   obj_textsec(abfd)->filepos = adata(abfd).page_size;
670                 }
671               else
672                 { /* Sunos-style demand-paged. */
673                   obj_textsec(abfd)->filepos = adata(abfd).exec_bytes_size;
674                   text_size += adata(abfd).exec_bytes_size;
675                 }
676               text_end = obj_textsec(abfd)->_raw_size + obj_textsec(abfd)->filepos;
677               if (abfd->flags & (D_PAGED|WP_TEXT))
678                 {
679                   bfd_size_type text_pad =
680                       BFD_ALIGN(text_size, adata(abfd).segment_size)
681                          - text_size;
682                   text_end += text_pad;
683                   obj_textsec(abfd)->_raw_size += text_pad;
684                 }
685               obj_datasec(abfd)->filepos = text_end;
686               obj_datasec(abfd)->_raw_size =
687                   align_power(obj_datasec(abfd)->_raw_size,
688                               obj_datasec(abfd)->alignment_power);
689             }
690       }
691
692   /* regardless, once we know what we're doing, we might as well get going */
693   if (section != obj_bsssec(abfd)) 
694       {
695         bfd_seek (abfd, section->filepos + offset, SEEK_SET);
696     
697         if (count) {
698           return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
699             true : false;
700         }
701         return true;
702       }
703   return true;
704 }
705 \f
706 /* Classify stabs symbols */
707
708 #define sym_in_text_section(sym) \
709   (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
710
711 #define sym_in_data_section(sym) \
712   (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
713
714 #define sym_in_bss_section(sym) \
715   (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
716
717 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
718   zero in the "value" field.  Nonzeroes there are fortrancommon
719   symbols.  */
720 #define sym_is_undefined(sym) \
721   ((sym)->type == (N_UNDF | N_EXT) && (sym)->symbol.value == 0)
722
723 /* Symbol is a global definition if N_EXT is on and if it has
724   a nonzero type field.  */
725 #define sym_is_global_defn(sym) \
726   (((sym)->type & N_EXT) && (sym)->type & N_TYPE)
727
728 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
729   are on.  */
730 #define sym_is_debugger_info(sym) \
731   ((sym)->type & ~(N_EXT | N_TYPE))
732
733 #define sym_is_fortrancommon(sym)       \
734   (((sym)->type == (N_EXT)) && (sym)->symbol.value != 0)
735
736 /* Symbol is absolute if it has N_ABS set */
737 #define sym_is_absolute(sym) \
738   (((sym)->type  & N_TYPE)== N_ABS)
739
740
741 #define sym_is_indirect(sym) \
742   (((sym)->type & N_ABS)== N_ABS)
743
744 /* Only in their own functions for ease of debugging; when sym flags have
745   stabilised these should be inlined into their (single) caller */
746   
747 static void
748 DEFUN(translate_from_native_sym_flags,(sym_pointer, cache_ptr, abfd),
749       struct external_nlist *sym_pointer AND
750       aout_symbol_type *cache_ptr AND
751       bfd *abfd)
752 {
753   switch (cache_ptr->type & N_TYPE) 
754   {
755   case N_SETA:
756   case N_SETT:
757   case N_SETD:
758   case N_SETB:
759   {
760     char *copy = bfd_alloc(abfd, strlen(cache_ptr->symbol.name)+1);
761     asection *section ;
762     asection *into_section;
763       
764     arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
765     strcpy(copy, cache_ptr->symbol.name);
766
767     /* Make sure that this bfd has a section with the right contructor
768        name */
769     section = bfd_get_section_by_name (abfd, copy);
770     if (!section)
771      section = bfd_make_section(abfd,copy);
772
773     /* Build a relocation entry for the constructor */
774     switch ( (cache_ptr->type  & N_TYPE) ) 
775     {
776     case N_SETA:
777       into_section = &bfd_abs_section;
778       break;
779     case N_SETT:
780       into_section = (asection *)obj_textsec(abfd);
781       break;
782     case N_SETD:
783       into_section = (asection *)obj_datasec(abfd);
784       break;
785     case N_SETB:
786       into_section = (asection *)obj_bsssec(abfd);
787       break;
788     default:
789       abort();
790     }
791
792     /* Build a relocation pointing into the constuctor section
793        pointing at the symbol in the set vector specified */
794
795     reloc->relent.addend = cache_ptr->symbol.value;
796     cache_ptr->symbol.section =  into_section->symbol->section;
797     reloc->relent.sym_ptr_ptr  = into_section->symbol_ptr_ptr;
798
799           
800     /* We modify the symbol to belong to a section depending upon the
801        name of the symbol - probably __CTOR__ or __DTOR__ but we don't
802        really care, and add to the size of the section to contain a
803        pointer to the symbol. Build a reloc entry to relocate to this
804        symbol attached to this section.  */
805           
806     section->flags = SEC_CONSTRUCTOR;
807
808           
809     section->reloc_count++;
810     section->alignment_power = 2;
811
812     reloc->next = section->constructor_chain;
813     section->constructor_chain = reloc;
814     reloc->relent.address = section->_raw_size;
815     section->_raw_size += sizeof(int *);
816
817     reloc->relent.howto = howto_table_ext + CTOR_TABLE_RELOC_IDX;
818     cache_ptr->symbol.flags |=  BSF_DEBUGGING  | BSF_CONSTRUCTOR;
819   }
820     break;
821   default:
822     if (cache_ptr->type ==  N_WARNING) 
823     {
824       /* This symbol is the text of a warning message, the next symbol
825          is the symbol to associate the warning with */
826       cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
827       cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
828       /* We furgle with the next symbol in place. We don't want it to be undefined, we'll trample the type */
829       (sym_pointer+1)->e_type[0] = 0xff;
830       break;
831     }
832     if ((cache_ptr->type | N_EXT) == (N_INDR | N_EXT)) {
833         /* Two symbols in a row for an INDR message. The first symbol
834            contains the name we will match, the second symbol contains the
835            name the first name is translated into. It is supplied to us
836            undefined. This is good, since we want to pull in any files which
837            define it */
838         cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT;
839         cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
840         cache_ptr->symbol.section = &bfd_und_section;
841         break;
842       }
843
844       
845     if (sym_is_debugger_info (cache_ptr)) {
846         cache_ptr->symbol.flags = BSF_DEBUGGING ;
847         /* Work out the section correct for this symbol */
848         switch (cache_ptr->type & N_TYPE) 
849         {
850         case N_TEXT:
851         case N_FN:
852           cache_ptr->symbol.section = obj_textsec (abfd);
853           cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
854           break;
855         case N_DATA:
856           cache_ptr->symbol.value  -= obj_datasec(abfd)->vma;
857           cache_ptr->symbol.section = obj_datasec (abfd);
858           break;
859         case N_BSS :
860           cache_ptr->symbol.section = obj_bsssec (abfd);
861           cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
862           break;
863         default:
864         case N_ABS:
865
866           cache_ptr->symbol.section = &bfd_abs_section;
867           break;
868         }
869       }
870     else {
871
872         if (sym_is_fortrancommon (cache_ptr))
873         {
874           cache_ptr->symbol.flags = 0;
875           cache_ptr->symbol.section = &bfd_com_section;
876         }
877         else {
878
879
880           }
881           
882         /* In a.out, the value of a symbol is always relative to the 
883          * start of the file, if this is a data symbol we'll subtract
884          * the size of the text section to get the section relative
885          * value. If this is a bss symbol (which would be strange)
886          * we'll subtract the size of the previous two sections
887          * to find the section relative address.
888          */
889           
890         if (sym_in_text_section (cache_ptr))   {
891             cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
892             cache_ptr->symbol.section = obj_textsec (abfd);
893           }
894         else if (sym_in_data_section (cache_ptr)){
895             cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
896             cache_ptr->symbol.section = obj_datasec (abfd);
897           }
898         else if (sym_in_bss_section(cache_ptr)) {
899             cache_ptr->symbol.section = obj_bsssec (abfd);
900             cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
901           }
902         else  if (sym_is_undefined (cache_ptr)) {
903             cache_ptr->symbol.flags = 0;
904             cache_ptr->symbol.section = &bfd_und_section;
905           }
906         else if (sym_is_absolute(cache_ptr))
907         {
908           cache_ptr->symbol.section = &bfd_abs_section;
909         }
910             
911         if (sym_is_global_defn (cache_ptr)) 
912         {
913           cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
914         } 
915         else 
916         {
917           cache_ptr->symbol.flags = BSF_LOCAL;
918         }
919       }
920   }
921 }
922
923
924
925 static void
926 DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
927      struct external_nlist *sym_pointer AND
928      asymbol *cache_ptr AND
929      bfd *abfd)
930 {
931   bfd_vma value = cache_ptr->value;
932
933   if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
934       sym_pointer->e_type[0] |= N_BSS;
935     }
936   else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
937       sym_pointer->e_type[0] |= N_DATA;
938     }
939   else  if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
940       sym_pointer->e_type[0] |= N_TEXT;
941     }
942   else if (bfd_get_output_section(cache_ptr) == &bfd_abs_section) 
943   {
944     sym_pointer->e_type[0] |= N_ABS;
945   }
946   else if (bfd_get_output_section(cache_ptr) == &bfd_und_section) 
947   {
948     sym_pointer->e_type[0] = (N_UNDF | N_EXT);
949   }
950   else if (bfd_get_output_section(cache_ptr) == &bfd_com_section) {
951       sym_pointer->e_type[0] = (N_UNDF | N_EXT);
952     }    
953   else {    
954       bfd_error_vector.nonrepresentable_section(abfd,
955                                                 bfd_get_output_section(cache_ptr)->name);
956     }
957   /* Turn the symbol from section relative to absolute again */
958     
959   value +=  cache_ptr->section->output_section->vma  + cache_ptr->section->output_offset ;
960
961
962   if (cache_ptr->flags & (BSF_WARNING)) {
963       (sym_pointer+1)->e_type[0] = 1;
964     }  
965     
966   if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
967       sym_pointer->e_type[0] |= N_EXT;
968     }
969   if (cache_ptr->flags & BSF_DEBUGGING) {
970       sym_pointer->e_type [0]= ((aout_symbol_type *)cache_ptr)->type;
971     }
972
973   PUT_WORD(abfd, value, sym_pointer->e_value);
974 }
975 \f
976 /* Native-level interface to symbols. */
977
978 /* We read the symbols into a buffer, which is discarded when this
979 function exits.  We read the strings into a buffer large enough to
980 hold them all plus all the cached symbol entries. */
981
982 asymbol *
983 DEFUN(NAME(aout,make_empty_symbol),(abfd),
984       bfd *abfd)
985 {
986   aout_symbol_type  *new =
987     (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
988   new->symbol.the_bfd = abfd;
989     
990   return &new->symbol;
991 }
992
993 boolean
994 DEFUN(NAME(aout,slurp_symbol_table),(abfd),
995       bfd *abfd)
996 {
997   bfd_size_type symbol_size;
998   bfd_size_type string_size;
999   unsigned char string_chars[BYTES_IN_WORD];
1000   struct external_nlist *syms;
1001   char *strings;
1002   aout_symbol_type *cached;
1003     
1004   /* If there's no work to be done, don't do any */
1005   if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1006   symbol_size = exec_hdr(abfd)->a_syms;
1007   if (symbol_size == 0) {
1008     bfd_error = no_symbols;
1009     return false;
1010   }
1011     
1012   bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1013   if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD)
1014     return false;
1015   string_size = GET_WORD (abfd, string_chars);
1016     
1017   strings =(char *) bfd_alloc(abfd, string_size + 1);
1018   cached = (aout_symbol_type *)
1019     bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type)));
1020
1021   /* malloc this, so we can free it if simply. The symbol caching
1022      might want to allocate onto the bfd's obstack  */
1023   syms = (struct external_nlist *) bfd_xmalloc(symbol_size);
1024   bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
1025   if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
1026   bailout:
1027     if (syms)   free (syms);
1028     if (cached) bfd_release (abfd, cached);
1029     if (strings)bfd_release (abfd, strings);
1030     return false;
1031   }
1032     
1033   bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1034   if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
1035     goto bailout;
1036   }
1037     
1038   /* OK, now walk the new symtable, cacheing symbol properties */
1039     {
1040       register struct external_nlist *sym_pointer;
1041       register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd);
1042       register aout_symbol_type *cache_ptr = cached;
1043         
1044       /* Run through table and copy values */
1045       for (sym_pointer = syms, cache_ptr = cached;
1046            sym_pointer < sym_end; sym_pointer++, cache_ptr++) 
1047           {
1048             bfd_vma x = GET_WORD(abfd, sym_pointer->e_strx);
1049             cache_ptr->symbol.the_bfd = abfd;
1050             if (x)
1051               cache_ptr->symbol.name = x + strings;
1052             else
1053               cache_ptr->symbol.name = (char *)NULL;
1054               
1055             cache_ptr->symbol.value = GET_SWORD(abfd,  sym_pointer->e_value);
1056             cache_ptr->desc = bfd_get_16(abfd, sym_pointer->e_desc);
1057             cache_ptr->other =bfd_get_8(abfd, sym_pointer->e_other);
1058             cache_ptr->type = bfd_get_8(abfd,  sym_pointer->e_type);
1059             cache_ptr->symbol.udata = 0;
1060             translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1061           }
1062     }
1063     
1064   obj_aout_symbols (abfd) =  cached;
1065   free((PTR)syms);
1066     
1067   return true;
1068 }
1069
1070
1071 void
1072 DEFUN(NAME(aout,write_syms),(abfd),
1073       bfd *abfd)
1074   {
1075     unsigned int count ;
1076     asymbol **generic = bfd_get_outsymbols (abfd);
1077     
1078     bfd_size_type stindex = BYTES_IN_WORD; /* initial string length */
1079     
1080     for (count = 0; count < bfd_get_symcount (abfd); count++) {
1081       asymbol *g = generic[count];
1082       struct external_nlist nsp;
1083
1084
1085       if (g->name) {
1086         unsigned int length = strlen(g->name) +1;
1087         PUT_WORD  (abfd, stindex, (unsigned char *)nsp.e_strx);
1088         stindex += length;
1089       }
1090       else 
1091
1092       {
1093         PUT_WORD  (abfd, 0, (unsigned char *)nsp.e_strx);
1094       }
1095       
1096       if (g->the_bfd->xvec->flavour == abfd->xvec->flavour) 
1097           {
1098             bfd_h_put_16(abfd, aout_symbol(g)->desc,  nsp.e_desc);
1099             bfd_h_put_8(abfd, aout_symbol(g)->other,  nsp.e_other);
1100             bfd_h_put_8(abfd, aout_symbol(g)->type,  nsp.e_type);
1101           }
1102       else
1103           {
1104             bfd_h_put_16(abfd,0, nsp.e_desc);
1105             bfd_h_put_8(abfd, 0,  nsp.e_other);
1106             bfd_h_put_8(abfd, 0,  nsp.e_type);
1107           }
1108
1109       translate_to_native_sym_flags (&nsp, g, abfd);
1110
1111       bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd);
1112     }
1113     
1114     /* Now output the strings.  Be sure to put string length into correct
1115        byte ordering before writing it.  */
1116       {
1117         char buffer[BYTES_IN_WORD];
1118         PUT_WORD  (abfd, stindex, (unsigned char *)buffer);
1119     
1120         bfd_write((PTR)buffer, 1, BYTES_IN_WORD, abfd);
1121       }
1122     generic = bfd_get_outsymbols(abfd);
1123     for (count = 0; count < bfd_get_symcount(abfd); count++) 
1124         {
1125           asymbol *g = *(generic++);
1126           
1127           if (g->name)
1128               {
1129                 size_t length = strlen(g->name)+1;
1130                 bfd_write((PTR)g->name, 1, length, abfd);
1131               }
1132             g->KEEPIT = (KEEPITTYPE) count;
1133         }
1134   }
1135
1136
1137
1138 unsigned int
1139 DEFUN(NAME(aout,get_symtab),(abfd, location),
1140       bfd *abfd AND
1141       asymbol **location)
1142 {
1143     unsigned int counter = 0;
1144     aout_symbol_type *symbase;
1145     
1146     if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1147     
1148     for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1149       *(location++) = (asymbol *)( symbase++);
1150     *location++ =0;
1151     return bfd_get_symcount(abfd);
1152 }
1153
1154 \f
1155 /* Standard reloc stuff */
1156 /* Output standard relocation information to a file in target byte order. */
1157
1158 void
1159 DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
1160       bfd *abfd AND
1161       arelent *g AND
1162       struct reloc_std_external *natptr)
1163 {
1164   int r_index;
1165   asymbol *sym = *(g->sym_ptr_ptr);
1166   int r_extern;
1167   unsigned int r_length;
1168   int r_pcrel;
1169   int r_baserel, r_jmptable, r_relative;
1170   unsigned int r_addend;
1171   asection *output_section = sym->section->output_section;
1172   
1173   PUT_WORD(abfd, g->address, natptr->r_address);
1174     
1175   r_length = g->howto->size ;   /* Size as a power of two */
1176   r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC? */
1177   /* r_baserel, r_jmptable, r_relative???  FIXME-soon */
1178   r_baserel = 0;
1179   r_jmptable = 0;
1180   r_relative = 0;
1181     
1182   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
1183     
1184   /* name was clobbered by aout_write_syms to be symbol index */
1185
1186   if (output_section == &bfd_abs_section) 
1187   {
1188     r_extern = 0;
1189     r_index = N_ABS;
1190     r_addend += sym->value;
1191   }
1192   else if (output_section == &bfd_com_section 
1193            || output_section == &bfd_und_section) 
1194   {
1195     /* Fill in symbol */
1196     r_extern = 1;
1197     r_index =  stoi((*(g->sym_ptr_ptr))->KEEPIT);
1198   }
1199   else 
1200   {
1201     /* Just an ordinary section */
1202     r_extern = 0;
1203     r_index  = output_section->target_index;      
1204   }
1205     
1206   /* now the fun stuff */
1207   if (abfd->xvec->header_byteorder_big_p != false) {
1208       natptr->r_index[0] = r_index >> 16;
1209       natptr->r_index[1] = r_index >> 8;
1210       natptr->r_index[2] = r_index;
1211       natptr->r_type[0] =
1212        (r_extern?    RELOC_STD_BITS_EXTERN_BIG: 0)
1213         | (r_pcrel?     RELOC_STD_BITS_PCREL_BIG: 0)
1214          | (r_baserel?   RELOC_STD_BITS_BASEREL_BIG: 0)
1215           | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_BIG: 0)
1216            | (r_relative?  RELOC_STD_BITS_RELATIVE_BIG: 0)
1217             | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG);
1218     } else {
1219         natptr->r_index[2] = r_index >> 16;
1220         natptr->r_index[1] = r_index >> 8;
1221         natptr->r_index[0] = r_index;
1222         natptr->r_type[0] =
1223          (r_extern?    RELOC_STD_BITS_EXTERN_LITTLE: 0)
1224           | (r_pcrel?     RELOC_STD_BITS_PCREL_LITTLE: 0)
1225            | (r_baserel?   RELOC_STD_BITS_BASEREL_LITTLE: 0)
1226             | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1227              | (r_relative?  RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1228               | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE);
1229       }
1230 }
1231
1232
1233 /* Extended stuff */
1234 /* Output extended relocation information to a file in target byte order. */
1235
1236 void
1237 DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
1238       bfd *abfd AND
1239       arelent *g AND
1240       register struct reloc_ext_external *natptr)
1241 {
1242   int r_index;
1243   int r_extern;
1244   unsigned int r_type;
1245   unsigned int r_addend;
1246   asymbol *sym = *(g->sym_ptr_ptr);    
1247   asection *output_section = sym->section->output_section;
1248   
1249   PUT_WORD (abfd, g->address, natptr->r_address);
1250     
1251   r_type = (unsigned int) g->howto->type;
1252     
1253   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
1254
1255
1256   if (output_section == &bfd_abs_section) 
1257   {
1258     r_extern = 0;
1259     r_index = N_ABS;
1260     r_addend += sym->value;
1261   }
1262   else if (output_section == &bfd_com_section 
1263            || output_section == &bfd_und_section) 
1264   {
1265     /* Fill in symbol */
1266     r_extern = 1;
1267     r_index =  stoi((*(g->sym_ptr_ptr))->KEEPIT);
1268   }
1269   else 
1270   {
1271     /* Just an ordinary section */
1272     r_extern = 0;
1273     r_index  = output_section->target_index;      
1274   }
1275          
1276          
1277   /* now the fun stuff */
1278   if (abfd->xvec->header_byteorder_big_p != false) {
1279       natptr->r_index[0] = r_index >> 16;
1280       natptr->r_index[1] = r_index >> 8;
1281       natptr->r_index[2] = r_index;
1282       natptr->r_type[0] =
1283        (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1284         | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1285     } else {
1286         natptr->r_index[2] = r_index >> 16;
1287         natptr->r_index[1] = r_index >> 8;
1288         natptr->r_index[0] = r_index;
1289         natptr->r_type[0] =
1290          (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1291           | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1292       }
1293
1294   PUT_WORD (abfd, r_addend, natptr->r_addend);
1295 }
1296
1297 /* BFD deals internally with all things based from the section they're
1298    in. so, something in 10 bytes into a text section  with a base of
1299    50 would have a symbol (.text+10) and know .text vma was 50. 
1300
1301    Aout keeps all it's symbols based from zero, so the symbol would
1302    contain 60. This macro subs the base of each section from the value
1303    to give the true offset from the section */
1304
1305
1306 #define MOVE_ADDRESS(ad)                                                \
1307   if (r_extern) {                                                       \
1308    /* undefined symbol */                                               \
1309      cache_ptr->sym_ptr_ptr = symbols + r_index;                        \
1310      cache_ptr->addend = ad;                                            \
1311      } else {                                                           \
1312     /* defined, section relative. replace symbol with pointer to        \
1313        symbol which points to section  */                               \
1314     switch (r_index) {                                                  \
1315     case N_TEXT:                                                        \
1316     case N_TEXT | N_EXT:                                                \
1317       cache_ptr->sym_ptr_ptr  = obj_textsec(abfd)->symbol_ptr_ptr;      \
1318       cache_ptr->addend = ad  - su->textsec->vma;                       \
1319       break;                                                            \
1320     case N_DATA:                                                        \
1321     case N_DATA | N_EXT:                                                \
1322       cache_ptr->sym_ptr_ptr  = obj_datasec(abfd)->symbol_ptr_ptr;      \
1323       cache_ptr->addend = ad - su->datasec->vma;                        \
1324       break;                                                            \
1325     case N_BSS:                                                         \
1326     case N_BSS | N_EXT:                                                 \
1327       cache_ptr->sym_ptr_ptr  = obj_bsssec(abfd)->symbol_ptr_ptr;       \
1328       cache_ptr->addend = ad - su->bsssec->vma;                         \
1329       break;                                                            \
1330     default:                                                            \
1331     case N_ABS:                                                         \
1332     case N_ABS | N_EXT:                                                 \
1333      cache_ptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;   \
1334       cache_ptr->addend = ad;                                           \
1335       break;                                                            \
1336     }                                                                   \
1337   }                                                                     \
1338
1339 void
1340 DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
1341       bfd *abfd AND
1342       struct reloc_ext_external *bytes AND
1343       arelent *cache_ptr AND
1344       asymbol **symbols)
1345 {
1346   int r_index;
1347   int r_extern;
1348   unsigned int r_type;
1349   struct aoutdata *su = &(abfd->tdata.aout_data->a);
1350
1351   cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
1352
1353   /* now the fun stuff */
1354   if (abfd->xvec->header_byteorder_big_p != false) {
1355     r_index =  (bytes->r_index[0] << 16)
1356              | (bytes->r_index[1] << 8)
1357              |  bytes->r_index[2];
1358     r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
1359     r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
1360                                       >> RELOC_EXT_BITS_TYPE_SH_BIG;
1361   } else {
1362     r_index =  (bytes->r_index[2] << 16)
1363              | (bytes->r_index[1] << 8)
1364              |  bytes->r_index[0];
1365     r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1366     r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1367                                       >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1368   }
1369
1370   cache_ptr->howto =  howto_table_ext + r_type;
1371   MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend));
1372 }
1373
1374 void
1375 DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
1376   bfd *abfd AND
1377   struct reloc_std_external *bytes AND
1378   arelent *cache_ptr AND
1379   asymbol **symbols)
1380 {
1381   int r_index;
1382   int r_extern;
1383   unsigned int r_length;
1384   int r_pcrel;
1385   int r_baserel, r_jmptable, r_relative;
1386   struct aoutdata  *su = &(abfd->tdata.aout_data->a);
1387
1388   cache_ptr->address = (int32_type)(bfd_h_get_32 (abfd, bytes->r_address));
1389
1390   /* now the fun stuff */
1391   if (abfd->xvec->header_byteorder_big_p != false) {
1392     r_index =  (bytes->r_index[0] << 16)
1393       | (bytes->r_index[1] << 8)
1394         |  bytes->r_index[2];
1395     r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
1396     r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
1397     r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
1398     r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1399     r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
1400     r_length  =       (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) 
1401                         >> RELOC_STD_BITS_LENGTH_SH_BIG;
1402   } else {
1403     r_index =  (bytes->r_index[2] << 16)
1404       | (bytes->r_index[1] << 8)
1405         |  bytes->r_index[0];
1406     r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1407     r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
1408     r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1409     r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1410     r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1411     r_length  =       (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) 
1412                         >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1413   }
1414
1415   cache_ptr->howto =  howto_table_std + r_length + 4 * r_pcrel;
1416   /* FIXME-soon:  Roll baserel, jmptable, relative bits into howto setting */
1417
1418   MOVE_ADDRESS(0);
1419 }
1420
1421 /* Reloc hackery */
1422
1423 boolean
1424 DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
1425       bfd *abfd AND
1426       sec_ptr asect AND
1427       asymbol **symbols)
1428 {
1429   unsigned int count;
1430   bfd_size_type reloc_size;
1431   PTR relocs;
1432   arelent *reloc_cache;
1433   size_t each_size;
1434
1435   if (asect->relocation) return true;
1436
1437   if (asect->flags & SEC_CONSTRUCTOR) return true;
1438
1439   if (asect == obj_datasec (abfd)) {
1440     reloc_size = exec_hdr(abfd)->a_drsize;
1441     goto doit;
1442   }
1443
1444   if (asect == obj_textsec (abfd)) {
1445     reloc_size = exec_hdr(abfd)->a_trsize;
1446     goto doit;
1447   }
1448
1449   bfd_error = invalid_operation;
1450   return false;
1451
1452  doit:
1453   bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1454   each_size = obj_reloc_entry_size (abfd);
1455
1456   count = reloc_size / each_size;
1457
1458
1459   reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1460                                                        (arelent)));
1461   if (!reloc_cache) {
1462 nomem:
1463     bfd_error = no_memory;
1464     return false;
1465   }
1466
1467   relocs = (PTR) bfd_alloc (abfd, reloc_size);
1468   if (!relocs) {
1469     bfd_release (abfd, reloc_cache);
1470     goto nomem;
1471   }
1472
1473   if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1474     bfd_release (abfd, relocs);
1475     bfd_release (abfd, reloc_cache);
1476     bfd_error = system_call_error;
1477     return false;
1478   }
1479
1480   if (each_size == RELOC_EXT_SIZE) {
1481     register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
1482     unsigned int counter = 0;
1483     arelent *cache_ptr = reloc_cache;
1484
1485     for (; counter < count; counter++, rptr++, cache_ptr++) {
1486       NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
1487     }
1488   } else {
1489     register struct reloc_std_external *rptr = (struct reloc_std_external*) relocs;
1490     unsigned int counter = 0;
1491     arelent *cache_ptr = reloc_cache;
1492
1493     for (; counter < count; counter++, rptr++, cache_ptr++) {
1494         NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
1495     }
1496
1497   }
1498
1499   bfd_release (abfd,relocs);
1500   asect->relocation = reloc_cache;
1501   asect->reloc_count = count;
1502   return true;
1503 }
1504
1505
1506
1507 /* Write out a relocation section into an object file.  */
1508
1509 boolean
1510 DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
1511       bfd *abfd AND
1512       asection *section)
1513 {
1514   arelent **generic;
1515   unsigned char *native, *natptr;
1516   size_t each_size;
1517
1518   unsigned int count = section->reloc_count;
1519   size_t natsize;
1520
1521   if (count == 0) return true;
1522
1523   each_size = obj_reloc_entry_size (abfd);
1524   natsize = each_size * count;
1525   native = (unsigned char *) bfd_zalloc (abfd, natsize);
1526   if (!native) {
1527     bfd_error = no_memory;
1528     return false;
1529   }
1530
1531   generic = section->orelocation;
1532
1533   if (each_size == RELOC_EXT_SIZE) 
1534     {
1535       for (natptr = native;
1536            count != 0;
1537            --count, natptr += each_size, ++generic)
1538         NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
1539     }
1540   else 
1541     {
1542       for (natptr = native;
1543            count != 0;
1544            --count, natptr += each_size, ++generic)
1545         NAME(aout,swap_std_reloc_out)(abfd, *generic, (struct reloc_std_external *)natptr);
1546     }
1547
1548   if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1549     bfd_release(abfd, native);
1550     return false;
1551   }
1552   bfd_release (abfd, native);
1553
1554   return true;
1555 }
1556
1557 /* This is stupid.  This function should be a boolean predicate */
1558 unsigned int
1559 DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
1560       bfd *abfd AND
1561       sec_ptr section AND
1562       arelent **relptr AND
1563       asymbol **symbols)
1564 {
1565   arelent *tblptr = section->relocation;
1566   unsigned int count;
1567
1568   if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
1569     return 0;
1570
1571   if (section->flags & SEC_CONSTRUCTOR) {
1572     arelent_chain *chain = section->constructor_chain;
1573     for (count = 0; count < section->reloc_count; count ++) {
1574       *relptr ++ = &chain->relent;
1575       chain = chain->next;
1576     }
1577   }
1578   else {
1579     tblptr = section->relocation;
1580     if (!tblptr) return 0;
1581
1582     for (count = 0; count++ < section->reloc_count;) 
1583       {
1584         *relptr++ = tblptr++;
1585       }
1586   }
1587   *relptr = 0;
1588
1589   return section->reloc_count;
1590 }
1591
1592 unsigned int
1593 DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
1594      bfd *abfd AND
1595      sec_ptr asect)
1596 {
1597   if (bfd_get_format (abfd) != bfd_object) {
1598     bfd_error = invalid_operation;
1599     return 0;
1600   }
1601   if (asect->flags & SEC_CONSTRUCTOR) {
1602     return (sizeof (arelent *) * (asect->reloc_count+1));
1603   }
1604
1605
1606   if (asect == obj_datasec (abfd))
1607     return (sizeof (arelent *) *
1608             ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
1609              +1));
1610
1611   if (asect == obj_textsec (abfd))
1612     return (sizeof (arelent *) *
1613             ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
1614              +1));
1615
1616   bfd_error = invalid_operation;
1617   return 0;
1618 }
1619
1620 \f
1621  unsigned int
1622 DEFUN(NAME(aout,get_symtab_upper_bound),(abfd),
1623      bfd *abfd)
1624 {
1625   if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1626
1627   return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1628 }
1629  alent *
1630 DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
1631       bfd *ignore_abfd AND
1632       asymbol *ignore_symbol)
1633 {
1634 return (alent *)NULL;
1635 }
1636
1637
1638 void 
1639 DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
1640       bfd *ignore_abfd AND
1641       PTR afile AND
1642       asymbol *symbol AND
1643       bfd_print_symbol_type how)
1644 {
1645   FILE *file = (FILE *)afile;
1646
1647   switch (how) {
1648   case bfd_print_symbol_name:
1649     if (symbol->name)
1650       fprintf(file,"%s", symbol->name);
1651     break;
1652   case bfd_print_symbol_more:
1653     fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1654             (unsigned)(aout_symbol(symbol)->other & 0xff),
1655             (unsigned)(aout_symbol(symbol)->type));
1656     break;
1657   case bfd_print_symbol_all:
1658     {
1659    CONST char *section_name = symbol->section->name;
1660
1661
1662       bfd_print_symbol_vandf((PTR)file,symbol);
1663
1664       fprintf(file," %-5s %04x %02x %02x",
1665               section_name,
1666               (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1667               (unsigned)(aout_symbol(symbol)->other & 0xff),
1668               (unsigned)(aout_symbol(symbol)->type  & 0xff));
1669       if (symbol->name)
1670         fprintf(file," %s", symbol->name);
1671     }
1672     break;
1673   case bfd_print_symbol_nm:
1674     {
1675       int section_code = bfd_decode_symclass  (symbol);
1676
1677       if (section_code == 'U')
1678         fprintf(file, "        ");
1679       fprintf_vma(file, symbol->value+symbol->section->vma);
1680       if (section_code == '?')
1681         {
1682           int type_code = aout_symbol(symbol)->type  & 0xff;
1683           char *stab_name = aout_stab_name(type_code);
1684           char buf[10];
1685           if (stab_name == NULL)
1686             {
1687               sprintf(buf, "(%d)", type_code);
1688               stab_name = buf;
1689             }
1690           fprintf(file," - %02x %04x %5s",
1691                   (unsigned)(aout_symbol(symbol)->other & 0xff),
1692                   (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1693                   stab_name);
1694         }
1695       else
1696         fprintf(file," %c", section_code);
1697       if (symbol->name)
1698         fprintf(file," %s", symbol->name);
1699     }
1700     break;
1701   }
1702 }
1703
1704 /* 
1705  provided a BFD, a section and an offset into the section, calculate
1706  and return the name of the source file and the line nearest to the
1707  wanted location.
1708 */
1709  
1710 boolean
1711 DEFUN(NAME(aout,find_nearest_line),(abfd,
1712                                      section,
1713                                      symbols,
1714                                      offset,
1715                                      filename_ptr,
1716                                      functionname_ptr,
1717                                      line_ptr),
1718       bfd *abfd AND
1719       asection *section AND
1720       asymbol **symbols AND
1721       bfd_vma offset AND
1722       CONST char **filename_ptr AND
1723       CONST char **functionname_ptr AND
1724       unsigned int *line_ptr)
1725 {
1726   /* Run down the file looking for the filename, function and linenumber */
1727   asymbol **p;
1728   static  char buffer[100];
1729   static  char filename_buffer[200];
1730   CONST char *directory_name = NULL;
1731   CONST char *main_file_name = NULL;
1732   CONST char *current_file_name = NULL;
1733   CONST char *line_file_name = NULL; /* Value of current_file_name at line number. */
1734   bfd_vma high_line_vma = ~0;
1735   bfd_vma low_func_vma = 0;
1736   asymbol *func = 0;
1737   *filename_ptr = abfd->filename;
1738   *functionname_ptr = 0;
1739   *line_ptr = 0;
1740   if (symbols != (asymbol **)NULL) {
1741     for (p = symbols; *p; p++) {
1742       aout_symbol_type  *q = (aout_symbol_type *)(*p);
1743     next:
1744       switch (q->type){
1745       case N_SO:
1746         main_file_name = current_file_name = q->symbol.name;
1747         /* Look ahead to next symbol to check if that too is an N_SO. */
1748         p++;
1749         if (*p == NULL)
1750           break;
1751         q = (aout_symbol_type *)(*p);
1752         if (q->type != (int)N_SO)
1753           goto next;
1754
1755         /* Found a second N_SO  First is directory; second is filename. */
1756         directory_name = current_file_name;
1757         main_file_name = current_file_name = q->symbol.name;
1758         if (obj_textsec(abfd) != section)
1759           goto done;
1760         break;
1761       case N_SOL:
1762         current_file_name = q->symbol.name;
1763         break;
1764
1765       case N_SLINE:
1766
1767       case N_DSLINE:
1768       case N_BSLINE:
1769         /* We'll keep this if it resolves nearer than the one we have already */
1770         if (q->symbol.value >= offset &&
1771             q->symbol.value < high_line_vma) {
1772           *line_ptr = q->desc;
1773           high_line_vma = q->symbol.value;
1774           line_file_name = current_file_name;
1775         }
1776         break;
1777       case N_FUN:
1778         {
1779           /* We'll keep this if it is nearer than the one we have already */
1780           if (q->symbol.value >= low_func_vma &&
1781               q->symbol.value <= offset) {
1782             low_func_vma = q->symbol.value;
1783             func = (asymbol *)q;
1784           }
1785           if (*line_ptr && func) {
1786             CONST char *function = func->name;
1787             char *p;
1788             strncpy(buffer, function, sizeof(buffer)-1);
1789             buffer[sizeof(buffer)-1] = 0;
1790             /* Have to remove : stuff */
1791             p = strchr(buffer,':');
1792             if (p != NULL) { *p = '\0'; }
1793             *functionname_ptr = buffer;
1794             goto done;
1795
1796           }
1797         }
1798         break;
1799       }
1800     }
1801   }
1802
1803  done:
1804   if (*line_ptr)
1805     main_file_name = line_file_name;
1806   if (main_file_name) {
1807       if (main_file_name[0] == '/' || directory_name == NULL)
1808           *filename_ptr = main_file_name;
1809       else {
1810           sprintf(filename_buffer, "%.140s%.50s",
1811                   directory_name, main_file_name);
1812           *filename_ptr = filename_buffer;
1813       }
1814   }
1815   return true;
1816
1817 }
1818
1819 int 
1820 DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
1821       bfd *abfd AND
1822       boolean execable)
1823 {
1824   return adata(abfd).exec_bytes_size;
1825 }