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