eeaa2ba306160bcbcd68cfdd7308f2976b474f85
[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   default:
599     arch_flags = M_UNKNOWN;
600     break;
601   }
602   return arch_flags;
603 }
604
605
606 /*
607 FUNCTION
608         aout_<size>_set_arch_mach
609
610 DESCRIPTION
611         Sets the architecture and the machine of the BFD to those
612         values supplied. Verifies that the format can support the
613         architecture required.
614
615 SYNOPSIS
616         boolean aout_<size>_set_arch_mach,
617          (bfd *,
618           enum bfd_architecture,
619           unsigned long machine));
620 */
621
622 boolean
623 DEFUN(NAME(aout,set_arch_mach),(abfd, arch, machine),
624       bfd *abfd AND
625       enum bfd_architecture arch AND
626       unsigned long machine)
627 {
628   bfd_default_set_arch_mach(abfd, arch, machine);
629   if (arch != bfd_arch_unknown &&
630       NAME(aout,machine_type) (arch, machine) == M_UNKNOWN)
631     return false;               /* We can't represent this type */
632
633   /* Determine the size of a relocation entry */
634   switch (arch) {
635   case bfd_arch_sparc:
636   case bfd_arch_a29k:
637     obj_reloc_entry_size (abfd) = RELOC_EXT_SIZE;
638     break;
639   default:
640     obj_reloc_entry_size (abfd) = RELOC_STD_SIZE;
641     break;
642   }
643
644   return (*aout_backend_info(abfd)->set_sizes) (abfd);
645 }
646
647 boolean
648 DEFUN (NAME (aout,adjust_sizes_and_vmas), (abfd, text_size, text_end),
649        bfd *abfd AND bfd_size_type *text_size AND file_ptr *text_end)
650 {
651   struct internal_exec *execp = exec_hdr (abfd);
652   if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL)) 
653     {
654       bfd_error = invalid_operation;
655       return false;
656     }
657   if (adata(abfd).magic != undecided_magic) return true;
658   obj_textsec(abfd)->_raw_size =              
659     align_power(obj_textsec(abfd)->_raw_size,
660                 obj_textsec(abfd)->alignment_power);
661
662   *text_size = obj_textsec (abfd)->_raw_size;
663   /* Rule (heuristic) for when to pad to a new page.  Note that there
664    * are (at least) two ways demand-paged (ZMAGIC) files have been
665    * handled.  Most Berkeley-based systems start the text segment at
666    * (PAGE_SIZE).  However, newer versions of SUNOS start the text
667    * segment right after the exec header; the latter is counted in the
668    * text segment size, and is paged in by the kernel with the rest of
669    * the text. */
670
671   /* This perhaps isn't the right way to do this, but made it simpler for me
672      to understand enough to implement it.  Better would probably be to go
673      right from BFD flags to alignment/positioning characteristics.  But the
674      old code was sloppy enough about handling the flags, and had enough
675      other magic, that it was a little hard for me to understand.  I think
676      I understand it better now, but I haven't time to do the cleanup this
677      minute.  */
678   if (adata(abfd).magic == undecided_magic)
679     {
680       if (abfd->flags & D_PAGED)
681         /* whether or not WP_TEXT is set */
682         adata(abfd).magic = z_magic;
683       else if (abfd->flags & WP_TEXT)
684         adata(abfd).magic = n_magic;
685       else
686         adata(abfd).magic = o_magic;
687     }
688
689 #ifdef BFD_AOUT_DEBUG /* requires gcc2 */
690 #if __GNUC__ >= 2
691   fprintf (stderr, "%s text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x,%x>\n",
692            ({ char *str;
693               switch (adata(abfd).magic) {
694               case n_magic: str = "NMAGIC"; break;
695               case o_magic: str = "OMAGIC"; break;
696               case z_magic: str = "ZMAGIC"; break;
697               default: abort ();
698               }
699               str;
700             }),
701            obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size, obj_textsec(abfd)->alignment_power,
702            obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size, obj_datasec(abfd)->alignment_power,
703            obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size, obj_bsssec(abfd)->alignment_power);
704 #endif
705 #endif
706
707   switch (adata(abfd).magic)
708     {
709     case o_magic:
710       {
711         file_ptr pos = adata (abfd).exec_bytes_size;
712         bfd_vma vma = 0;
713         int pad = 0;
714
715         obj_textsec(abfd)->filepos = pos;
716         pos += obj_textsec(abfd)->_raw_size;
717         vma += obj_textsec(abfd)->_raw_size;
718         if (!obj_datasec(abfd)->user_set_vma)
719           {
720 #if 0       /* ?? Does alignment in the file image really matter? */
721             pad = align_power (vma, obj_datasec(abfd)->alignment_power) - vma;
722 #endif
723             obj_textsec(abfd)->_raw_size += pad;
724             pos += pad;
725             vma += pad;
726             obj_datasec(abfd)->vma = vma;
727           }
728         obj_datasec(abfd)->filepos = pos;
729         pos += obj_datasec(abfd)->_raw_size;
730         vma += obj_datasec(abfd)->_raw_size;
731         if (!obj_bsssec(abfd)->user_set_vma)
732           {
733 #if 0
734             pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
735 #endif
736             obj_datasec(abfd)->_raw_size += pad;
737             pos += pad;
738             vma += pad;
739             obj_bsssec(abfd)->vma = vma;
740           }
741         obj_bsssec(abfd)->filepos = pos;
742         execp->a_text = obj_textsec(abfd)->_raw_size;
743         execp->a_data = obj_datasec(abfd)->_raw_size;
744         execp->a_bss = obj_bsssec(abfd)->_raw_size;
745         N_SET_MAGIC (*execp, OMAGIC);
746       }
747       break;
748     case z_magic:
749       {
750         bfd_size_type data_pad, text_pad;
751         file_ptr text_end;
752         CONST struct aout_backend_data *abdp;
753         int ztih;
754         bfd_vma data_vma;
755
756         abdp = aout_backend_info (abfd);
757         ztih = abdp && abdp->text_includes_header;
758         obj_textsec(abfd)->filepos = (ztih
759                                       ? adata(abfd).exec_bytes_size
760                                       : adata(abfd).page_size);
761         if (! obj_textsec(abfd)->user_set_vma)
762           /* ?? Do we really need to check for relocs here?  */
763           obj_textsec(abfd)->vma = ((abfd->flags & HAS_RELOC)
764                                     ? 0
765                                     : (ztih
766                                        ? (abdp->default_text_vma
767                                           + adata(abfd).exec_bytes_size)
768                                        : abdp->default_text_vma));
769         /* Could take strange alignment of text section into account here?  */
770
771         /* Find start of data.  */
772         text_end = obj_textsec(abfd)->filepos + obj_textsec(abfd)->_raw_size;
773         text_pad = BFD_ALIGN (text_end, adata(abfd).page_size) - text_end;
774         obj_textsec(abfd)->_raw_size += text_pad;
775         text_end += text_pad;
776
777         if (!obj_datasec(abfd)->user_set_vma)
778           {
779             bfd_vma vma;
780             vma = obj_textsec(abfd)->vma + obj_textsec(abfd)->_raw_size;
781             obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
782           }
783         data_vma = obj_datasec(abfd)->vma;
784         if (abdp && abdp->zmagic_mapped_contiguous)
785           {
786             text_pad = (obj_datasec(abfd)->vma
787                         - obj_textsec(abfd)->vma
788                         - obj_textsec(abfd)->_raw_size);
789             obj_textsec(abfd)->_raw_size += text_pad;
790           }
791         obj_datasec(abfd)->filepos = (obj_textsec(abfd)->filepos
792                                       + obj_textsec(abfd)->_raw_size);
793
794         /* Fix up exec header while we're at it.  */
795         execp->a_text = obj_textsec(abfd)->_raw_size;
796         if (ztih && (!abdp || (abdp && !abdp->exec_header_not_counted)))
797           execp->a_text += adata(abfd).exec_bytes_size;
798         N_SET_MAGIC (*execp, ZMAGIC);
799         /* Spec says data section should be rounded up to page boundary.  */
800         /* If extra space in page is left after data section, fudge data
801            in the header so that the bss section looks smaller by that
802            amount.  We'll start the bss section there, and lie to the OS.  */
803         obj_datasec(abfd)->_raw_size
804           = align_power (obj_datasec(abfd)->_raw_size,
805                          obj_bsssec(abfd)->alignment_power);
806         execp->a_data = BFD_ALIGN (obj_datasec(abfd)->_raw_size,
807                                    adata(abfd).page_size);
808         data_pad = execp->a_data - obj_datasec(abfd)->_raw_size;
809         /* This code is almost surely botched.  It'll only get tested
810            for the case where the application does explicitly set the VMA
811            of the BSS section.  */
812         if (obj_bsssec(abfd)->user_set_vma
813             && (obj_bsssec(abfd)->vma
814                 > BFD_ALIGN (obj_datasec(abfd)->vma
815                              + obj_datasec(abfd)->_raw_size,
816                              adata(abfd).page_size)))
817           {
818             /* Can't play with squeezing into data pages; fix this code.  */
819             abort ();
820           }
821         if (!obj_bsssec(abfd)->user_set_vma)
822           obj_bsssec(abfd)->vma = (obj_datasec(abfd)->vma
823                                    + obj_datasec(abfd)->_raw_size);
824         if (data_pad > obj_bsssec(abfd)->_raw_size)
825           execp->a_bss = 0;
826         else
827           execp->a_bss = obj_bsssec(abfd)->_raw_size - data_pad;
828       }
829       break;
830     case n_magic:
831       {
832         file_ptr pos = adata(abfd).exec_bytes_size;
833         bfd_vma vma = 0;
834         int pad;
835
836         obj_textsec(abfd)->filepos = pos;
837         if (!obj_textsec(abfd)->user_set_vma)
838           obj_textsec(abfd)->vma = vma;
839         else
840           vma = obj_textsec(abfd)->vma;
841         pos += obj_textsec(abfd)->_raw_size;
842         vma += obj_textsec(abfd)->_raw_size;
843         obj_datasec(abfd)->filepos = pos;
844         if (!obj_datasec(abfd)->user_set_vma)
845           obj_datasec(abfd)->vma = BFD_ALIGN (vma, adata(abfd).segment_size);
846         vma = obj_datasec(abfd)->vma;
847
848         /* Since BSS follows data immediately, see if it needs alignment.  */
849         vma += obj_datasec(abfd)->_raw_size;
850         pad = align_power (vma, obj_bsssec(abfd)->alignment_power) - vma;
851         obj_datasec(abfd)->_raw_size += pad;
852         pos += obj_datasec(abfd)->_raw_size;
853
854         if (!obj_bsssec(abfd)->user_set_vma)
855           obj_bsssec(abfd)->vma = vma;
856         else
857           vma = obj_bsssec(abfd)->vma;
858       }
859       execp->a_text = obj_textsec(abfd)->_raw_size;
860       execp->a_data = obj_datasec(abfd)->_raw_size;
861       execp->a_bss = obj_bsssec(abfd)->_raw_size;
862       N_SET_MAGIC (*execp, NMAGIC);
863       break;
864     default:
865       abort ();
866     }
867 #ifdef BFD_AOUT_DEBUG
868   fprintf (stderr, "       text=<%x,%x,%x> data=<%x,%x,%x> bss=<%x,%x>\n",
869            obj_textsec(abfd)->vma, obj_textsec(abfd)->_raw_size, obj_textsec(abfd)->filepos,
870            obj_datasec(abfd)->vma, obj_datasec(abfd)->_raw_size, obj_datasec(abfd)->filepos,
871            obj_bsssec(abfd)->vma, obj_bsssec(abfd)->_raw_size);
872 #endif
873   return true;
874 }
875
876 /*
877 FUNCTION
878         aout_<size>_new_section_hook
879   
880 DESCRIPTION
881         Called by the BFD in response to a @code{bfd_make_section}
882         request.
883
884 SYNOPSIS
885         boolean aout_<size>_new_section_hook,
886            (bfd *abfd,
887             asection *newsect));
888 */
889 boolean
890 DEFUN(NAME(aout,new_section_hook),(abfd, newsect),
891         bfd *abfd AND
892         asection *newsect)
893 {
894   /* align to double at least */
895   newsect->alignment_power = bfd_get_arch_info(abfd)->section_align_power;
896
897     
898   if (bfd_get_format (abfd) == bfd_object) 
899   {
900     if (obj_textsec(abfd) == NULL && !strcmp(newsect->name, ".text")) {
901         obj_textsec(abfd)= newsect;
902         newsect->target_index = N_TEXT | N_EXT;
903         return true;
904       }
905       
906     if (obj_datasec(abfd) == NULL && !strcmp(newsect->name, ".data")) {
907         obj_datasec(abfd) = newsect;
908         newsect->target_index = N_DATA | N_EXT;
909         return true;
910       }
911       
912     if (obj_bsssec(abfd) == NULL && !strcmp(newsect->name, ".bss")) {
913         obj_bsssec(abfd) = newsect;
914         newsect->target_index = N_BSS | N_EXT;
915         return true;
916       }
917
918   }
919     
920   /* We allow more than three sections internally */
921   return true;
922 }
923
924 boolean
925   DEFUN(NAME(aout,set_section_contents),(abfd, section, location, offset, count),
926         bfd *abfd AND
927         sec_ptr section AND
928         PTR location AND
929         file_ptr offset AND
930         bfd_size_type count)
931 {
932   file_ptr text_end;
933   bfd_size_type text_size;
934
935   if (abfd->output_has_begun == false)
936       {                         /* set by bfd.c handler */
937         switch (abfd->direction)
938             {
939             case read_direction:
940             case no_direction:
941               bfd_error = invalid_operation;
942               return false;
943
944             case write_direction:
945               if (NAME(aout,adjust_sizes_and_vmas) (abfd,
946                                                     &text_size,
947                                                     &text_end) == false)
948                 return false;
949             case both_direction:
950               break;
951             }
952       }
953
954   /* regardless, once we know what we're doing, we might as well get going */
955   if (section != obj_bsssec(abfd)) 
956       {
957         bfd_seek (abfd, section->filepos + offset, SEEK_SET);
958     
959         if (count) {
960           return (bfd_write ((PTR)location, 1, count, abfd) == count) ?
961             true : false;
962         }
963         return true;
964       }
965   return true;
966 }
967 \f
968 /* Classify stabs symbols */
969
970 #define sym_in_text_section(sym) \
971   (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_TEXT)
972
973 #define sym_in_data_section(sym) \
974   (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_DATA)
975
976 #define sym_in_bss_section(sym) \
977   (((sym)->type  & (N_ABS | N_TEXT | N_DATA | N_BSS))== N_BSS)
978
979 /* Symbol is undefined if type is N_UNDF|N_EXT and if it has
980   zero in the "value" field.  Nonzeroes there are fortrancommon
981   symbols.  */
982 #define sym_is_undefined(sym) \
983   ((sym)->type == (N_UNDF | N_EXT) && (sym)->symbol.value == 0)
984
985 /* Symbol is a global definition if N_EXT is on and if it has
986   a nonzero type field.  */
987 #define sym_is_global_defn(sym) \
988   (((sym)->type & N_EXT) && (sym)->type & N_TYPE)
989
990 /* Symbol is debugger info if any bits outside N_TYPE or N_EXT
991   are on.  */
992 #define sym_is_debugger_info(sym) \
993   ((sym)->type & ~(N_EXT | N_TYPE))
994
995 #define sym_is_fortrancommon(sym)       \
996   (((sym)->type == (N_EXT)) && (sym)->symbol.value != 0)
997
998 /* Symbol is absolute if it has N_ABS set */
999 #define sym_is_absolute(sym) \
1000   (((sym)->type  & N_TYPE)== N_ABS)
1001
1002
1003 #define sym_is_indirect(sym) \
1004   (((sym)->type & N_ABS)== N_ABS)
1005
1006 /* Only in their own functions for ease of debugging; when sym flags have
1007   stabilised these should be inlined into their (single) caller */
1008   
1009 static void
1010 DEFUN(translate_from_native_sym_flags,(sym_pointer, cache_ptr, abfd),
1011       struct external_nlist *sym_pointer AND
1012       aout_symbol_type *cache_ptr AND
1013       bfd *abfd)
1014 {
1015   switch (cache_ptr->type & N_TYPE) 
1016   {
1017   case N_SETA:
1018   case N_SETT:
1019   case N_SETD:
1020   case N_SETB:
1021   {
1022     char *copy = bfd_alloc(abfd, strlen(cache_ptr->symbol.name)+1);
1023     asection *section ;
1024     asection *into_section;
1025       
1026     arelent_chain *reloc = (arelent_chain *)bfd_alloc(abfd, sizeof(arelent_chain));
1027     strcpy(copy, cache_ptr->symbol.name);
1028
1029     /* Make sure that this bfd has a section with the right contructor
1030        name */
1031     section = bfd_get_section_by_name (abfd, copy);
1032     if (!section)
1033      section = bfd_make_section(abfd,copy);
1034
1035     /* Build a relocation entry for the constructor */
1036     switch ( (cache_ptr->type  & N_TYPE) ) 
1037     {
1038     case N_SETA:
1039       into_section = &bfd_abs_section;
1040       break;
1041     case N_SETT:
1042       into_section = (asection *)obj_textsec(abfd);
1043       break;
1044     case N_SETD:
1045       into_section = (asection *)obj_datasec(abfd);
1046       break;
1047     case N_SETB:
1048       into_section = (asection *)obj_bsssec(abfd);
1049       break;
1050     default:
1051       abort();
1052     }
1053
1054     /* Build a relocation pointing into the constuctor section
1055        pointing at the symbol in the set vector specified */
1056
1057     reloc->relent.addend = cache_ptr->symbol.value;
1058     cache_ptr->symbol.section =  into_section->symbol->section;
1059     reloc->relent.sym_ptr_ptr  = into_section->symbol_ptr_ptr;
1060
1061           
1062     /* We modify the symbol to belong to a section depending upon the
1063        name of the symbol - probably __CTOR__ or __DTOR__ but we don't
1064        really care, and add to the size of the section to contain a
1065        pointer to the symbol. Build a reloc entry to relocate to this
1066        symbol attached to this section.  */
1067           
1068     section->flags = SEC_CONSTRUCTOR;
1069
1070           
1071     section->reloc_count++;
1072     section->alignment_power = 2;
1073
1074     reloc->next = section->constructor_chain;
1075     section->constructor_chain = reloc;
1076     reloc->relent.address = section->_raw_size;
1077     section->_raw_size += sizeof(int *);
1078
1079     reloc->relent.howto = howto_table_ext + CTOR_TABLE_RELOC_IDX;
1080     cache_ptr->symbol.flags |=  BSF_DEBUGGING  | BSF_CONSTRUCTOR;
1081   }
1082     break;
1083   default:
1084     if (cache_ptr->type ==  N_WARNING) 
1085     {
1086       /* This symbol is the text of a warning message, the next symbol
1087          is the symbol to associate the warning with */
1088       cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_WARNING;
1089       cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
1090       /* We furgle with the next symbol in place. We don't want it to be undefined, we'll trample the type */
1091       (sym_pointer+1)->e_type[0] = 0xff;
1092       break;
1093     }
1094     if ((cache_ptr->type | N_EXT) == (N_INDR | N_EXT)) {
1095         /* Two symbols in a row for an INDR message. The first symbol
1096            contains the name we will match, the second symbol contains the
1097            name the first name is translated into. It is supplied to us
1098            undefined. This is good, since we want to pull in any files which
1099            define it */
1100         cache_ptr->symbol.flags = BSF_DEBUGGING | BSF_INDIRECT;
1101         cache_ptr->symbol.value = (bfd_vma)((cache_ptr+1));
1102         cache_ptr->symbol.section = &bfd_und_section;
1103         break;
1104       }
1105
1106       
1107     if (sym_is_debugger_info (cache_ptr)) {
1108         cache_ptr->symbol.flags = BSF_DEBUGGING ;
1109         /* Work out the section correct for this symbol */
1110         switch (cache_ptr->type & N_TYPE) 
1111         {
1112         case N_TEXT:
1113         case N_FN:
1114           cache_ptr->symbol.section = obj_textsec (abfd);
1115           cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
1116           break;
1117         case N_DATA:
1118           cache_ptr->symbol.value  -= obj_datasec(abfd)->vma;
1119           cache_ptr->symbol.section = obj_datasec (abfd);
1120           break;
1121         case N_BSS :
1122           cache_ptr->symbol.section = obj_bsssec (abfd);
1123           cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
1124           break;
1125         default:
1126         case N_ABS:
1127
1128           cache_ptr->symbol.section = &bfd_abs_section;
1129           break;
1130         }
1131       }
1132     else {
1133
1134         if (sym_is_fortrancommon (cache_ptr))
1135         {
1136           cache_ptr->symbol.flags = 0;
1137           cache_ptr->symbol.section = &bfd_com_section;
1138         }
1139         else {
1140
1141
1142           }
1143           
1144         /* In a.out, the value of a symbol is always relative to the 
1145          * start of the file, if this is a data symbol we'll subtract
1146          * the size of the text section to get the section relative
1147          * value. If this is a bss symbol (which would be strange)
1148          * we'll subtract the size of the previous two sections
1149          * to find the section relative address.
1150          */
1151           
1152         if (sym_in_text_section (cache_ptr))   {
1153             cache_ptr->symbol.value -= obj_textsec(abfd)->vma;
1154             cache_ptr->symbol.section = obj_textsec (abfd);
1155           }
1156         else if (sym_in_data_section (cache_ptr)){
1157             cache_ptr->symbol.value -= obj_datasec(abfd)->vma;
1158             cache_ptr->symbol.section = obj_datasec (abfd);
1159           }
1160         else if (sym_in_bss_section(cache_ptr)) {
1161             cache_ptr->symbol.section = obj_bsssec (abfd);
1162             cache_ptr->symbol.value -= obj_bsssec(abfd)->vma;
1163           }
1164         else  if (sym_is_undefined (cache_ptr)) {
1165             cache_ptr->symbol.flags = 0;
1166             cache_ptr->symbol.section = &bfd_und_section;
1167           }
1168         else if (sym_is_absolute(cache_ptr))
1169         {
1170           cache_ptr->symbol.section = &bfd_abs_section;
1171         }
1172             
1173         if (sym_is_global_defn (cache_ptr)) 
1174         {
1175           cache_ptr->symbol.flags = BSF_GLOBAL | BSF_EXPORT;
1176         } 
1177         else 
1178         {
1179           cache_ptr->symbol.flags = BSF_LOCAL;
1180         }
1181       }
1182   }
1183 }
1184
1185
1186
1187 static void
1188 DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
1189      struct external_nlist *sym_pointer AND
1190      asymbol *cache_ptr AND
1191      bfd *abfd)
1192 {
1193   bfd_vma value = cache_ptr->value;
1194
1195   /* mask out any existing type bits in case copying from one section
1196      to another */
1197   sym_pointer->e_type[0] &= ~N_TYPE;
1198   
1199   if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
1200       sym_pointer->e_type[0] |= N_BSS;
1201     }
1202   else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
1203       sym_pointer->e_type[0] |= N_DATA;
1204     }
1205   else  if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
1206       sym_pointer->e_type[0] |= N_TEXT;
1207     }
1208   else if (bfd_get_output_section(cache_ptr) == &bfd_abs_section) 
1209   {
1210     sym_pointer->e_type[0] |= N_ABS;
1211   }
1212   else if (bfd_get_output_section(cache_ptr) == &bfd_und_section) 
1213   {
1214     sym_pointer->e_type[0] = (N_UNDF | N_EXT);
1215   }
1216   else if (bfd_get_output_section(cache_ptr) == &bfd_com_section) {
1217       sym_pointer->e_type[0] = (N_UNDF | N_EXT);
1218     }    
1219   else {    
1220       if (cache_ptr->section->output_section) 
1221       {
1222         
1223         bfd_error_vector.nonrepresentable_section(abfd,
1224                                                   bfd_get_output_section(cache_ptr)->name);
1225       }
1226       else 
1227       {
1228         bfd_error_vector.nonrepresentable_section(abfd,
1229                                                   cache_ptr->section->name);
1230         
1231       }
1232       
1233     }
1234   /* Turn the symbol from section relative to absolute again */
1235     
1236   value +=  cache_ptr->section->output_section->vma  + cache_ptr->section->output_offset ;
1237
1238
1239   if (cache_ptr->flags & (BSF_WARNING)) {
1240       (sym_pointer+1)->e_type[0] = 1;
1241     }  
1242     
1243   if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
1244       sym_pointer->e_type[0] |= N_EXT;
1245     }
1246   if (cache_ptr->flags & BSF_DEBUGGING) {
1247       sym_pointer->e_type [0]= ((aout_symbol_type *)cache_ptr)->type;
1248     }
1249
1250   PUT_WORD(abfd, value, sym_pointer->e_value);
1251 }
1252 \f
1253 /* Native-level interface to symbols. */
1254
1255 /* We read the symbols into a buffer, which is discarded when this
1256 function exits.  We read the strings into a buffer large enough to
1257 hold them all plus all the cached symbol entries. */
1258
1259 asymbol *
1260 DEFUN(NAME(aout,make_empty_symbol),(abfd),
1261       bfd *abfd)
1262 {
1263   aout_symbol_type  *new =
1264     (aout_symbol_type *)bfd_zalloc (abfd, sizeof (aout_symbol_type));
1265   new->symbol.the_bfd = abfd;
1266
1267   return &new->symbol;
1268 }
1269
1270 boolean
1271 DEFUN(NAME(aout,slurp_symbol_table),(abfd),
1272       bfd *abfd)
1273 {
1274   bfd_size_type symbol_size;
1275   bfd_size_type string_size;
1276   unsigned char string_chars[BYTES_IN_WORD];
1277   struct external_nlist *syms;
1278   char *strings;
1279   aout_symbol_type *cached;
1280     
1281   /* If there's no work to be done, don't do any */
1282   if (obj_aout_symbols (abfd) != (aout_symbol_type *)NULL) return true;
1283   symbol_size = exec_hdr(abfd)->a_syms;
1284   if (symbol_size == 0) {
1285     bfd_error = no_symbols;
1286     return false;
1287   }
1288     
1289   bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1290   if (bfd_read ((PTR)string_chars, BYTES_IN_WORD, 1, abfd) != BYTES_IN_WORD)
1291     return false;
1292   string_size = GET_WORD (abfd, string_chars);
1293     
1294   strings =(char *) bfd_alloc(abfd, string_size + 1);
1295   cached = (aout_symbol_type *)
1296     bfd_zalloc(abfd, (bfd_size_type)(bfd_get_symcount (abfd) * sizeof(aout_symbol_type)));
1297
1298   /* malloc this, so we can free it if simply. The symbol caching
1299      might want to allocate onto the bfd's obstack  */
1300   syms = (struct external_nlist *) bfd_xmalloc(symbol_size);
1301   bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET);
1302   if (bfd_read ((PTR)syms, 1, symbol_size, abfd) != symbol_size) {
1303   bailout:
1304     if (syms)   free (syms);
1305     if (cached) bfd_release (abfd, cached);
1306     if (strings)bfd_release (abfd, strings);
1307     return false;
1308   }
1309     
1310   bfd_seek (abfd, obj_str_filepos (abfd), SEEK_SET);
1311   if (bfd_read ((PTR)strings, 1, string_size, abfd) != string_size) {
1312     goto bailout;
1313   }
1314     
1315   /* OK, now walk the new symtable, cacheing symbol properties */
1316     {
1317       register struct external_nlist *sym_pointer;
1318       register struct external_nlist *sym_end = syms + bfd_get_symcount (abfd);
1319       register aout_symbol_type *cache_ptr = cached;
1320         
1321       /* Run through table and copy values */
1322       for (sym_pointer = syms, cache_ptr = cached;
1323            sym_pointer < sym_end; sym_pointer++, cache_ptr++) 
1324           {
1325             bfd_vma x = GET_WORD(abfd, sym_pointer->e_strx);
1326             cache_ptr->symbol.the_bfd = abfd;
1327             if (x)
1328               cache_ptr->symbol.name = x + strings;
1329             else
1330               cache_ptr->symbol.name = (char *)NULL;
1331               
1332             cache_ptr->symbol.value = GET_SWORD(abfd,  sym_pointer->e_value);
1333             cache_ptr->desc = bfd_h_get_16(abfd, sym_pointer->e_desc);
1334             cache_ptr->other = bfd_h_get_8(abfd, sym_pointer->e_other);
1335             cache_ptr->type = bfd_h_get_8(abfd,  sym_pointer->e_type);
1336             cache_ptr->symbol.udata = 0;
1337             translate_from_native_sym_flags (sym_pointer, cache_ptr, abfd);
1338           }
1339     }
1340     
1341   obj_aout_symbols (abfd) =  cached;
1342   free((PTR)syms);
1343     
1344   return true;
1345 }
1346
1347
1348 void
1349 DEFUN(NAME(aout,write_syms),(abfd),
1350       bfd *abfd)
1351   {
1352     unsigned int count ;
1353     asymbol **generic = bfd_get_outsymbols (abfd);
1354     
1355     bfd_size_type stindex = BYTES_IN_WORD; /* initial string length */
1356     
1357     for (count = 0; count < bfd_get_symcount (abfd); count++) {
1358       asymbol *g = generic[count];
1359       struct external_nlist nsp;
1360
1361
1362       if (g->name) {
1363         unsigned int length = strlen(g->name) +1;
1364         PUT_WORD  (abfd, stindex, (unsigned char *)nsp.e_strx);
1365         stindex += length;
1366       }
1367       else 
1368
1369       {
1370         PUT_WORD  (abfd, 0, (unsigned char *)nsp.e_strx);
1371       }
1372       
1373       if (bfd_asymbol_flavour(g) == abfd->xvec->flavour) 
1374           {
1375             bfd_h_put_16(abfd, aout_symbol(g)->desc,  nsp.e_desc);
1376             bfd_h_put_8(abfd, aout_symbol(g)->other,  nsp.e_other);
1377             bfd_h_put_8(abfd, aout_symbol(g)->type,  nsp.e_type);
1378           }
1379       else
1380           {
1381             bfd_h_put_16(abfd,0, nsp.e_desc);
1382             bfd_h_put_8(abfd, 0,  nsp.e_other);
1383             bfd_h_put_8(abfd, 0,  nsp.e_type);
1384           }
1385
1386       translate_to_native_sym_flags (&nsp, g, abfd);
1387
1388       bfd_write((PTR)&nsp,1,EXTERNAL_NLIST_SIZE, abfd);
1389     }
1390     
1391     /* Now output the strings.  Be sure to put string length into correct
1392        byte ordering before writing it.  */
1393       {
1394         char buffer[BYTES_IN_WORD];
1395         PUT_WORD  (abfd, stindex, (unsigned char *)buffer);
1396     
1397         bfd_write((PTR)buffer, 1, BYTES_IN_WORD, abfd);
1398       }
1399     generic = bfd_get_outsymbols(abfd);
1400     for (count = 0; count < bfd_get_symcount(abfd); count++) 
1401         {
1402           asymbol *g = *(generic++);
1403           
1404           if (g->name)
1405               {
1406                 size_t length = strlen(g->name)+1;
1407                 bfd_write((PTR)g->name, 1, length, abfd);
1408               }
1409             g->KEEPIT = (KEEPITTYPE) count;
1410         }
1411   }
1412
1413
1414
1415 unsigned int
1416 DEFUN(NAME(aout,get_symtab),(abfd, location),
1417       bfd *abfd AND
1418       asymbol **location)
1419 {
1420     unsigned int counter = 0;
1421     aout_symbol_type *symbase;
1422
1423     if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1424
1425     for (symbase = obj_aout_symbols(abfd); counter++ < bfd_get_symcount (abfd);)
1426       *(location++) = (asymbol *)( symbase++);
1427     *location++ =0;
1428     return bfd_get_symcount (abfd);
1429 }
1430
1431 \f
1432 /* Standard reloc stuff */
1433 /* Output standard relocation information to a file in target byte order. */
1434
1435 void
1436 DEFUN(NAME(aout,swap_std_reloc_out),(abfd, g, natptr),
1437       bfd *abfd AND
1438       arelent *g AND
1439       struct reloc_std_external *natptr)
1440 {
1441   int r_index;
1442   asymbol *sym = *(g->sym_ptr_ptr);
1443   int r_extern;
1444   unsigned int r_length;
1445   int r_pcrel;
1446   int r_baserel, r_jmptable, r_relative;
1447   unsigned int r_addend;
1448   asection *output_section = sym->section->output_section;
1449
1450   PUT_WORD(abfd, g->address, natptr->r_address);
1451
1452   r_length = g->howto->size ;   /* Size as a power of two */
1453   r_pcrel  = (int) g->howto->pc_relative; /* Relative to PC? */
1454   /* r_baserel, r_jmptable, r_relative???  FIXME-soon */
1455   r_baserel = 0;
1456   r_jmptable = 0;
1457   r_relative = 0;
1458     
1459   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
1460     
1461   /* name was clobbered by aout_write_syms to be symbol index */
1462
1463   /* If this relocation is relative to a symbol then set the 
1464      r_index to the symbols index, and the r_extern bit.
1465
1466      Absolute symbols can come in in two ways, either as an offset
1467      from the abs section, or as a symbol which has an abs value.
1468      check for that here
1469      */
1470      
1471
1472   if (output_section == &bfd_com_section 
1473       || output_section == &bfd_abs_section
1474       || output_section == &bfd_und_section) 
1475     {
1476       if (bfd_abs_section.symbol == sym)
1477       {
1478         /* Whoops, looked like an abs symbol, but is really an offset
1479            from the abs section */
1480         r_index = 0;
1481         r_extern = 0;
1482        }
1483       else 
1484       {
1485         /* Fill in symbol */
1486         r_extern = 1;
1487         r_index =  stoi((*(g->sym_ptr_ptr))->KEEPIT);
1488      
1489       }
1490     }
1491   else 
1492     {
1493       /* Just an ordinary section */
1494       r_extern = 0;
1495       r_index  = output_section->target_index;      
1496     }
1497
1498   /* now the fun stuff */
1499   if (abfd->xvec->header_byteorder_big_p != false) {
1500       natptr->r_index[0] = r_index >> 16;
1501       natptr->r_index[1] = r_index >> 8;
1502       natptr->r_index[2] = r_index;
1503       natptr->r_type[0] =
1504        (r_extern?    RELOC_STD_BITS_EXTERN_BIG: 0)
1505         | (r_pcrel?     RELOC_STD_BITS_PCREL_BIG: 0)
1506          | (r_baserel?   RELOC_STD_BITS_BASEREL_BIG: 0)
1507           | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_BIG: 0)
1508            | (r_relative?  RELOC_STD_BITS_RELATIVE_BIG: 0)
1509             | (r_length <<  RELOC_STD_BITS_LENGTH_SH_BIG);
1510     } else {
1511         natptr->r_index[2] = r_index >> 16;
1512         natptr->r_index[1] = r_index >> 8;
1513         natptr->r_index[0] = r_index;
1514         natptr->r_type[0] =
1515          (r_extern?    RELOC_STD_BITS_EXTERN_LITTLE: 0)
1516           | (r_pcrel?     RELOC_STD_BITS_PCREL_LITTLE: 0)
1517            | (r_baserel?   RELOC_STD_BITS_BASEREL_LITTLE: 0)
1518             | (r_jmptable?  RELOC_STD_BITS_JMPTABLE_LITTLE: 0)
1519              | (r_relative?  RELOC_STD_BITS_RELATIVE_LITTLE: 0)
1520               | (r_length <<  RELOC_STD_BITS_LENGTH_SH_LITTLE);
1521       }
1522 }
1523
1524
1525 /* Extended stuff */
1526 /* Output extended relocation information to a file in target byte order. */
1527
1528 void
1529 DEFUN(NAME(aout,swap_ext_reloc_out),(abfd, g, natptr),
1530       bfd *abfd AND
1531       arelent *g AND
1532       register struct reloc_ext_external *natptr)
1533 {
1534   int r_index;
1535   int r_extern;
1536   unsigned int r_type;
1537   unsigned int r_addend;
1538   asymbol *sym = *(g->sym_ptr_ptr);    
1539   asection *output_section = sym->section->output_section;
1540   
1541   PUT_WORD (abfd, g->address, natptr->r_address);
1542     
1543   r_type = (unsigned int) g->howto->type;
1544     
1545   r_addend = g->addend + (*(g->sym_ptr_ptr))->section->output_section->vma;
1546
1547
1548   /* If this relocation is relative to a symbol then set the 
1549      r_index to the symbols index, and the r_extern bit.
1550
1551      Absolute symbols can come in in two ways, either as an offset
1552      from the abs section, or as a symbol which has an abs value.
1553      check for that here
1554      */
1555      
1556   if (output_section == &bfd_com_section 
1557       || output_section == &bfd_abs_section
1558       || output_section == &bfd_und_section) 
1559   {
1560     if (bfd_abs_section.symbol == sym)
1561     {
1562       /* Whoops, looked like an abs symbol, but is really an offset
1563          from the abs section */
1564       r_index = 0;
1565       r_extern = 0;
1566      }
1567     else 
1568     {
1569       r_extern = 1;
1570       r_index =  stoi((*(g->sym_ptr_ptr))->KEEPIT);
1571     }
1572   }
1573   else 
1574   {
1575     /* Just an ordinary section */
1576     r_extern = 0;
1577     r_index  = output_section->target_index;      
1578   }
1579          
1580          
1581   /* now the fun stuff */
1582   if (abfd->xvec->header_byteorder_big_p != false) {
1583     natptr->r_index[0] = r_index >> 16;
1584     natptr->r_index[1] = r_index >> 8;
1585     natptr->r_index[2] = r_index;
1586     natptr->r_type[0] =
1587      (r_extern? RELOC_EXT_BITS_EXTERN_BIG: 0)
1588       | (r_type << RELOC_EXT_BITS_TYPE_SH_BIG);
1589   } else {
1590     natptr->r_index[2] = r_index >> 16;
1591     natptr->r_index[1] = r_index >> 8;
1592     natptr->r_index[0] = r_index;
1593     natptr->r_type[0] =
1594      (r_extern? RELOC_EXT_BITS_EXTERN_LITTLE: 0)
1595       | (r_type << RELOC_EXT_BITS_TYPE_SH_LITTLE);
1596   }
1597
1598   PUT_WORD (abfd, r_addend, natptr->r_addend);
1599 }
1600
1601 /* BFD deals internally with all things based from the section they're
1602    in. so, something in 10 bytes into a text section  with a base of
1603    50 would have a symbol (.text+10) and know .text vma was 50. 
1604
1605    Aout keeps all it's symbols based from zero, so the symbol would
1606    contain 60. This macro subs the base of each section from the value
1607    to give the true offset from the section */
1608
1609
1610 #define MOVE_ADDRESS(ad)                                                \
1611   if (r_extern) {                                                       \
1612    /* undefined symbol */                                               \
1613      cache_ptr->sym_ptr_ptr = symbols + r_index;                        \
1614      cache_ptr->addend = ad;                                            \
1615      } else {                                                           \
1616     /* defined, section relative. replace symbol with pointer to        \
1617        symbol which points to section  */                               \
1618     switch (r_index) {                                                  \
1619     case N_TEXT:                                                        \
1620     case N_TEXT | N_EXT:                                                \
1621       cache_ptr->sym_ptr_ptr  = obj_textsec(abfd)->symbol_ptr_ptr;      \
1622       cache_ptr->addend = ad  - su->textsec->vma;                       \
1623       break;                                                            \
1624     case N_DATA:                                                        \
1625     case N_DATA | N_EXT:                                                \
1626       cache_ptr->sym_ptr_ptr  = obj_datasec(abfd)->symbol_ptr_ptr;      \
1627       cache_ptr->addend = ad - su->datasec->vma;                        \
1628       break;                                                            \
1629     case N_BSS:                                                         \
1630     case N_BSS | N_EXT:                                                 \
1631       cache_ptr->sym_ptr_ptr  = obj_bsssec(abfd)->symbol_ptr_ptr;       \
1632       cache_ptr->addend = ad - su->bsssec->vma;                         \
1633       break;                                                            \
1634     default:                                                            \
1635     case N_ABS:                                                         \
1636     case N_ABS | N_EXT:                                                 \
1637      cache_ptr->sym_ptr_ptr = bfd_abs_section.symbol_ptr_ptr;   \
1638       cache_ptr->addend = ad;                                           \
1639       break;                                                            \
1640     }                                                                   \
1641   }                                                                     \
1642
1643 void
1644 DEFUN(NAME(aout,swap_ext_reloc_in), (abfd, bytes, cache_ptr, symbols),
1645       bfd *abfd AND
1646       struct reloc_ext_external *bytes AND
1647       arelent *cache_ptr AND
1648       asymbol **symbols)
1649 {
1650   int r_index;
1651   int r_extern;
1652   unsigned int r_type;
1653   struct aoutdata *su = &(abfd->tdata.aout_data->a);
1654
1655   cache_ptr->address = (GET_SWORD (abfd, bytes->r_address));
1656
1657   /* now the fun stuff */
1658   if (abfd->xvec->header_byteorder_big_p != false) {
1659     r_index = (  ((int) bytes->r_index[0] << 16)
1660                | ((int) bytes->r_index[1] << 8)
1661                |  (int) bytes->r_index[2]);
1662     r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_BIG));
1663     r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_BIG)
1664                                       >> RELOC_EXT_BITS_TYPE_SH_BIG;
1665   } else {
1666     r_index = (  ((int) bytes->r_index[2] << 16)
1667                | ((int) bytes->r_index[1] << 8)
1668                |  (int) bytes->r_index[0]);
1669     r_extern = (0 != (bytes->r_type[0] & RELOC_EXT_BITS_EXTERN_LITTLE));
1670     r_type   =       (bytes->r_type[0] & RELOC_EXT_BITS_TYPE_LITTLE)
1671                                       >> RELOC_EXT_BITS_TYPE_SH_LITTLE;
1672   }
1673
1674   cache_ptr->howto =  howto_table_ext + r_type;
1675   MOVE_ADDRESS(GET_SWORD(abfd, bytes->r_addend));
1676 }
1677
1678 void
1679 DEFUN(NAME(aout,swap_std_reloc_in), (abfd, bytes, cache_ptr, symbols),
1680   bfd *abfd AND
1681   struct reloc_std_external *bytes AND
1682   arelent *cache_ptr AND
1683   asymbol **symbols)
1684 {
1685   int r_index;
1686   int r_extern;
1687   unsigned int r_length;
1688   int r_pcrel;
1689   int r_baserel, r_jmptable, r_relative;
1690   struct aoutdata  *su = &(abfd->tdata.aout_data->a);
1691
1692   cache_ptr->address = (int32_type)(bfd_h_get_32 (abfd, bytes->r_address));
1693
1694   /* now the fun stuff */
1695   if (abfd->xvec->header_byteorder_big_p != false) {
1696     r_index = (  ((int) bytes->r_index[0] << 16)
1697                | ((int) bytes->r_index[1] << 8)
1698                |  (int) bytes->r_index[2]);
1699     r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_BIG));
1700     r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_BIG));
1701     r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_BIG));
1702     r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_BIG));
1703     r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_BIG));
1704     r_length  =       (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_BIG) 
1705                         >> RELOC_STD_BITS_LENGTH_SH_BIG;
1706   } else {
1707     r_index = (  ((int) bytes->r_index[2] << 16)
1708                | ((int) bytes->r_index[1] << 8)
1709                |  (int) bytes->r_index[0]);
1710     r_extern  = (0 != (bytes->r_type[0] & RELOC_STD_BITS_EXTERN_LITTLE));
1711     r_pcrel   = (0 != (bytes->r_type[0] & RELOC_STD_BITS_PCREL_LITTLE));
1712     r_baserel = (0 != (bytes->r_type[0] & RELOC_STD_BITS_BASEREL_LITTLE));
1713     r_jmptable= (0 != (bytes->r_type[0] & RELOC_STD_BITS_JMPTABLE_LITTLE));
1714     r_relative= (0 != (bytes->r_type[0] & RELOC_STD_BITS_RELATIVE_LITTLE));
1715     r_length  =       (bytes->r_type[0] & RELOC_STD_BITS_LENGTH_LITTLE) 
1716                         >> RELOC_STD_BITS_LENGTH_SH_LITTLE;
1717   }
1718
1719   cache_ptr->howto =  howto_table_std + r_length + 4 * r_pcrel;
1720   /* FIXME-soon:  Roll baserel, jmptable, relative bits into howto setting */
1721
1722   MOVE_ADDRESS(0);
1723 }
1724
1725 /* Reloc hackery */
1726
1727 boolean
1728 DEFUN(NAME(aout,slurp_reloc_table),(abfd, asect, symbols),
1729       bfd *abfd AND
1730       sec_ptr asect AND
1731       asymbol **symbols)
1732 {
1733   unsigned int count;
1734   bfd_size_type reloc_size;
1735   PTR relocs;
1736   arelent *reloc_cache;
1737   size_t each_size;
1738
1739   if (asect->relocation) return true;
1740
1741   if (asect->flags & SEC_CONSTRUCTOR) return true;
1742
1743   if (asect == obj_datasec (abfd)) {
1744     reloc_size = exec_hdr(abfd)->a_drsize;
1745     goto doit;
1746   }
1747
1748   if (asect == obj_textsec (abfd)) {
1749     reloc_size = exec_hdr(abfd)->a_trsize;
1750     goto doit;
1751   }
1752
1753   bfd_error = invalid_operation;
1754   return false;
1755
1756  doit:
1757   bfd_seek (abfd, asect->rel_filepos, SEEK_SET);
1758   each_size = obj_reloc_entry_size (abfd);
1759
1760   count = reloc_size / each_size;
1761
1762
1763   reloc_cache = (arelent *) bfd_zalloc (abfd, (size_t)(count * sizeof
1764                                                        (arelent)));
1765   if (!reloc_cache) {
1766 nomem:
1767     bfd_error = no_memory;
1768     return false;
1769   }
1770
1771   relocs = (PTR) bfd_alloc (abfd, reloc_size);
1772   if (!relocs) {
1773     bfd_release (abfd, reloc_cache);
1774     goto nomem;
1775   }
1776
1777   if (bfd_read (relocs, 1, reloc_size, abfd) != reloc_size) {
1778     bfd_release (abfd, relocs);
1779     bfd_release (abfd, reloc_cache);
1780     bfd_error = system_call_error;
1781     return false;
1782   }
1783
1784   if (each_size == RELOC_EXT_SIZE) {
1785     register struct reloc_ext_external *rptr = (struct reloc_ext_external *) relocs;
1786     unsigned int counter = 0;
1787     arelent *cache_ptr = reloc_cache;
1788
1789     for (; counter < count; counter++, rptr++, cache_ptr++) {
1790       NAME(aout,swap_ext_reloc_in)(abfd, rptr, cache_ptr, symbols);
1791     }
1792   } else {
1793     register struct reloc_std_external *rptr = (struct reloc_std_external*) relocs;
1794     unsigned int counter = 0;
1795     arelent *cache_ptr = reloc_cache;
1796
1797     for (; counter < count; counter++, rptr++, cache_ptr++) {
1798         NAME(aout,swap_std_reloc_in)(abfd, rptr, cache_ptr, symbols);
1799     }
1800
1801   }
1802
1803   bfd_release (abfd,relocs);
1804   asect->relocation = reloc_cache;
1805   asect->reloc_count = count;
1806   return true;
1807 }
1808
1809
1810
1811 /* Write out a relocation section into an object file.  */
1812
1813 boolean
1814 DEFUN(NAME(aout,squirt_out_relocs),(abfd, section),
1815       bfd *abfd AND
1816       asection *section)
1817 {
1818   arelent **generic;
1819   unsigned char *native, *natptr;
1820   size_t each_size;
1821
1822   unsigned int count = section->reloc_count;
1823   size_t natsize;
1824
1825   if (count == 0) return true;
1826
1827   each_size = obj_reloc_entry_size (abfd);
1828   natsize = each_size * count;
1829   native = (unsigned char *) bfd_zalloc (abfd, natsize);
1830   if (!native) {
1831     bfd_error = no_memory;
1832     return false;
1833   }
1834
1835   generic = section->orelocation;
1836
1837   if (each_size == RELOC_EXT_SIZE) 
1838     {
1839       for (natptr = native;
1840            count != 0;
1841            --count, natptr += each_size, ++generic)
1842         NAME(aout,swap_ext_reloc_out) (abfd, *generic, (struct reloc_ext_external *)natptr);
1843     }
1844   else 
1845     {
1846       for (natptr = native;
1847            count != 0;
1848            --count, natptr += each_size, ++generic)
1849         NAME(aout,swap_std_reloc_out)(abfd, *generic, (struct reloc_std_external *)natptr);
1850     }
1851
1852   if ( bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
1853     bfd_release(abfd, native);
1854     return false;
1855   }
1856   bfd_release (abfd, native);
1857
1858   return true;
1859 }
1860
1861 /* This is stupid.  This function should be a boolean predicate */
1862 unsigned int
1863 DEFUN(NAME(aout,canonicalize_reloc),(abfd, section, relptr, symbols),
1864       bfd *abfd AND
1865       sec_ptr section AND
1866       arelent **relptr AND
1867       asymbol **symbols)
1868 {
1869   arelent *tblptr = section->relocation;
1870   unsigned int count;
1871
1872   if (!(tblptr || NAME(aout,slurp_reloc_table)(abfd, section, symbols)))
1873     return 0;
1874
1875   if (section->flags & SEC_CONSTRUCTOR) {
1876     arelent_chain *chain = section->constructor_chain;
1877     for (count = 0; count < section->reloc_count; count ++) {
1878       *relptr ++ = &chain->relent;
1879       chain = chain->next;
1880     }
1881   }
1882   else {
1883     tblptr = section->relocation;
1884     if (!tblptr) return 0;
1885
1886     for (count = 0; count++ < section->reloc_count;) 
1887       {
1888         *relptr++ = tblptr++;
1889       }
1890   }
1891   *relptr = 0;
1892
1893   return section->reloc_count;
1894 }
1895
1896 unsigned int
1897 DEFUN(NAME(aout,get_reloc_upper_bound),(abfd, asect),
1898      bfd *abfd AND
1899      sec_ptr asect)
1900 {
1901   if (bfd_get_format (abfd) != bfd_object) {
1902     bfd_error = invalid_operation;
1903     return 0;
1904   }
1905   if (asect->flags & SEC_CONSTRUCTOR) {
1906     return (sizeof (arelent *) * (asect->reloc_count+1));
1907   }
1908
1909
1910   if (asect == obj_datasec (abfd))
1911     return (sizeof (arelent *) *
1912             ((exec_hdr(abfd)->a_drsize / obj_reloc_entry_size (abfd))
1913              +1));
1914
1915   if (asect == obj_textsec (abfd))
1916     return (sizeof (arelent *) *
1917             ((exec_hdr(abfd)->a_trsize / obj_reloc_entry_size (abfd))
1918              +1));
1919
1920   bfd_error = invalid_operation;
1921   return 0;
1922 }
1923
1924 \f
1925  unsigned int
1926 DEFUN(NAME(aout,get_symtab_upper_bound),(abfd),
1927      bfd *abfd)
1928 {
1929   if (!NAME(aout,slurp_symbol_table)(abfd)) return 0;
1930
1931   return (bfd_get_symcount (abfd)+1) * (sizeof (aout_symbol_type *));
1932 }
1933  alent *
1934 DEFUN(NAME(aout,get_lineno),(ignore_abfd, ignore_symbol),
1935       bfd *ignore_abfd AND
1936       asymbol *ignore_symbol)
1937 {
1938 return (alent *)NULL;
1939 }
1940
1941
1942 void 
1943 DEFUN(NAME(aout,print_symbol),(ignore_abfd, afile, symbol, how),
1944       bfd *ignore_abfd AND
1945       PTR afile AND
1946       asymbol *symbol AND
1947       bfd_print_symbol_type how)
1948 {
1949   FILE *file = (FILE *)afile;
1950
1951   switch (how) {
1952   case bfd_print_symbol_name:
1953     if (symbol->name)
1954       fprintf(file,"%s", symbol->name);
1955     break;
1956   case bfd_print_symbol_more:
1957     fprintf(file,"%4x %2x %2x",(unsigned)(aout_symbol(symbol)->desc & 0xffff),
1958             (unsigned)(aout_symbol(symbol)->other & 0xff),
1959             (unsigned)(aout_symbol(symbol)->type));
1960     break;
1961   case bfd_print_symbol_all:
1962     {
1963    CONST char *section_name = symbol->section->name;
1964
1965
1966       bfd_print_symbol_vandf((PTR)file,symbol);
1967
1968       fprintf(file," %-5s %04x %02x %02x",
1969               section_name,
1970               (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1971               (unsigned)(aout_symbol(symbol)->other & 0xff),
1972               (unsigned)(aout_symbol(symbol)->type  & 0xff));
1973       if (symbol->name)
1974         fprintf(file," %s", symbol->name);
1975     }
1976     break;
1977   case bfd_print_symbol_nm:
1978     {
1979       int section_code = bfd_decode_symclass  (symbol);
1980
1981       if (section_code == 'U')
1982         fprintf(file, "        ");
1983       else
1984         fprintf_vma(file, symbol->value+symbol->section->vma);
1985       if (section_code == '?')
1986         {
1987           int type_code = aout_symbol(symbol)->type  & 0xff;
1988           CONST char *stab_name = aout_stab_name(type_code);
1989           char buf[10];
1990           if (stab_name == NULL)
1991             {
1992               sprintf(buf, "(%d)", type_code);
1993               stab_name = buf;
1994             }
1995           fprintf(file," - %02x %04x %5s",
1996                   (unsigned)(aout_symbol(symbol)->other & 0xff),
1997                   (unsigned)(aout_symbol(symbol)->desc & 0xffff),
1998                   stab_name);
1999         }
2000       else
2001         fprintf(file," %c", section_code);
2002       if (symbol->name)
2003         fprintf(file," %s", symbol->name);
2004     }
2005     break;
2006   }
2007 }
2008
2009 /* 
2010  provided a BFD, a section and an offset into the section, calculate
2011  and return the name of the source file and the line nearest to the
2012  wanted location.
2013 */
2014  
2015 boolean
2016 DEFUN(NAME(aout,find_nearest_line),(abfd,
2017                                      section,
2018                                      symbols,
2019                                      offset,
2020                                      filename_ptr,
2021                                      functionname_ptr,
2022                                      line_ptr),
2023       bfd *abfd AND
2024       asection *section AND
2025       asymbol **symbols AND
2026       bfd_vma offset AND
2027       CONST char **filename_ptr AND
2028       CONST char **functionname_ptr AND
2029       unsigned int *line_ptr)
2030 {
2031   /* Run down the file looking for the filename, function and linenumber */
2032   asymbol **p;
2033   static  char buffer[100];
2034   static  char filename_buffer[200];
2035   CONST char *directory_name = NULL;
2036   CONST char *main_file_name = NULL;
2037   CONST char *current_file_name = NULL;
2038   CONST char *line_file_name = NULL; /* Value of current_file_name at line number. */
2039   bfd_vma high_line_vma = ~0;
2040   bfd_vma low_func_vma = 0;
2041   asymbol *func = 0;
2042   *filename_ptr = abfd->filename;
2043   *functionname_ptr = 0;
2044   *line_ptr = 0;
2045   if (symbols != (asymbol **)NULL) {
2046     for (p = symbols; *p; p++) {
2047       aout_symbol_type  *q = (aout_symbol_type *)(*p);
2048     next:
2049       switch (q->type){
2050       case N_SO:
2051         main_file_name = current_file_name = q->symbol.name;
2052         /* Look ahead to next symbol to check if that too is an N_SO. */
2053         p++;
2054         if (*p == NULL)
2055           break;
2056         q = (aout_symbol_type *)(*p);
2057         if (q->type != (int)N_SO)
2058           goto next;
2059
2060         /* Found a second N_SO  First is directory; second is filename. */
2061         directory_name = current_file_name;
2062         main_file_name = current_file_name = q->symbol.name;
2063         if (obj_textsec(abfd) != section)
2064           goto done;
2065         break;
2066       case N_SOL:
2067         current_file_name = q->symbol.name;
2068         break;
2069
2070       case N_SLINE:
2071
2072       case N_DSLINE:
2073       case N_BSLINE:
2074         /* We'll keep this if it resolves nearer than the one we have already */
2075         if (q->symbol.value >= offset &&
2076             q->symbol.value < high_line_vma) {
2077           *line_ptr = q->desc;
2078           high_line_vma = q->symbol.value;
2079           line_file_name = current_file_name;
2080         }
2081         break;
2082       case N_FUN:
2083         {
2084           /* We'll keep this if it is nearer than the one we have already */
2085           if (q->symbol.value >= low_func_vma &&
2086               q->symbol.value <= offset) {
2087             low_func_vma = q->symbol.value;
2088             func = (asymbol *)q;
2089           }
2090           if (*line_ptr && func) {
2091             CONST char *function = func->name;
2092             char *p;
2093             strncpy(buffer, function, sizeof(buffer)-1);
2094             buffer[sizeof(buffer)-1] = 0;
2095             /* Have to remove : stuff */
2096             p = strchr(buffer,':');
2097             if (p != NULL) { *p = '\0'; }
2098             *functionname_ptr = buffer;
2099             goto done;
2100
2101           }
2102         }
2103         break;
2104       }
2105     }
2106   }
2107
2108  done:
2109   if (*line_ptr)
2110     main_file_name = line_file_name;
2111   if (main_file_name) {
2112       if (main_file_name[0] == '/' || directory_name == NULL)
2113           *filename_ptr = main_file_name;
2114       else {
2115           sprintf(filename_buffer, "%.140s%.50s",
2116                   directory_name, main_file_name);
2117           *filename_ptr = filename_buffer;
2118       }
2119   }
2120   return true;
2121
2122 }
2123
2124 int 
2125 DEFUN(NAME(aout,sizeof_headers),(abfd, execable),
2126       bfd *abfd AND
2127       boolean execable)
2128 {
2129   return adata(abfd).exec_bytes_size;
2130 }