Include bfd.h before sysdep.h, so ansidecl and PROTO() get defined first.
[external/binutils.git] / bfd / bout.c
1 /* BFD back-end for Intel 960 b.out binaries.
2    Copyright (C) 1990-1991 Free Software Foundation, Inc.
3    Written by Cygnus Support.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 /* $Id$ */
22
23 #include "bfd.h"
24 #include "sysdep.h"
25 #include "libbfd.h"
26
27 #include "bout.h"
28
29 #include "stab.gnu.h"
30 #include "libaout.h"            /* BFD a.out internal data structures */
31
32 /* Align an address by rounding it up to a power of two.  It leaves the
33    address unchanged if align == 0 (2^0 = alignment of 1 byte) */
34 #define i960_align(addr, align) \
35         ( ((addr) + ((1<<(align))-1)) & (-1 << (align)))
36
37
38 PROTO (static boolean, b_out_squirt_out_relocs,(bfd *abfd, asection *section));
39 PROTO (static bfd_target *, b_out_callback, (bfd *));
40
41 PROTO (boolean, aout_32_slurp_symbol_table, (bfd *abfd));
42 PROTO (void , aout_32_write_syms, ());
43
44 /* Swaps the information in an executable header taken from a raw byte
45    stream memory image, into the internal exec_header structure.  */
46
47 PROTO(void, bout_swap_exec_header_in,
48       (bfd *abfd,
49       struct external_exec *raw_bytes,
50       struct internal_exec *execp));
51          
52 void
53 DEFUN(bout_swap_exec_header_in,(abfd, raw_bytes, execp),
54       bfd *abfd AND
55       struct external_exec *raw_bytes AND
56       struct internal_exec *execp)
57 {
58   struct external_exec *bytes = (struct external_exec *)raw_bytes;
59
60   /* Now fill in fields in the execp, from the bytes in the raw data.  */
61   execp->a_info   = bfd_h_get_32 (abfd, bytes->e_info);
62   execp->a_text   = GET_WORD (abfd, bytes->e_text);
63   execp->a_data   = GET_WORD (abfd, bytes->e_data);
64   execp->a_bss    = GET_WORD (abfd, bytes->e_bss);
65   execp->a_syms   = GET_WORD (abfd, bytes->e_syms);
66   execp->a_entry  = GET_WORD (abfd, bytes->e_entry);
67   execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
68   execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
69   execp->a_tload  = GET_WORD (abfd, bytes->e_tload);
70   execp->a_dload  = GET_WORD (abfd, bytes->e_dload);
71   execp->a_talign = bytes->e_talign[0];
72   execp->a_dalign = bytes->e_dalign[0];
73   execp->a_balign = bytes->e_balign[0];
74 }
75
76 /* Swaps the information in an internal exec header structure into the
77    supplied buffer ready for writing to disk.  */
78
79 PROTO(void, bout_swap_exec_header_out,
80           (bfd *abfd,
81            struct internal_exec *execp,
82            struct external_exec *raw_bytes));
83 void
84 DEFUN(bout_swap_exec_header_out,(abfd, execp, raw_bytes),
85      bfd *abfd AND
86      struct internal_exec *execp AND 
87      struct external_exec *raw_bytes)
88 {
89   struct external_exec *bytes = (struct external_exec *)raw_bytes;
90
91   /* Now fill in fields in the raw data, from the fields in the exec struct. */
92   bfd_h_put_32 (abfd, execp->a_info  , bytes->e_info);
93   PUT_WORD (abfd, execp->a_text  , bytes->e_text);
94   PUT_WORD (abfd, execp->a_data  , bytes->e_data);
95   PUT_WORD (abfd, execp->a_bss   , bytes->e_bss);
96   PUT_WORD (abfd, execp->a_syms  , bytes->e_syms);
97   PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
98   PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
99   PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
100   PUT_WORD (abfd, execp->a_tload , bytes->e_tload);
101   PUT_WORD (abfd, execp->a_dload , bytes->e_dload);
102   bytes->e_talign[0] = execp->a_talign;
103   bytes->e_dalign[0] = execp->a_dalign;
104   bytes->e_balign[0] = execp->a_balign;
105   bytes->e_unused[0] = 0;               /* Clean structs are godly structs */
106 }
107
108
109 static bfd_target *
110 b_out_object_p (abfd)
111      bfd *abfd;
112 {
113   struct internal_exec anexec;
114   struct external_exec exec_bytes;
115
116   if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
117       != EXEC_BYTES_SIZE) {
118     bfd_error = wrong_format;
119     return 0;
120   }
121
122   anexec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
123
124   if (N_BADMAG (anexec)) {
125     bfd_error = wrong_format;
126     return 0;
127   }
128
129   bout_swap_exec_header_in (abfd, &exec_bytes, &anexec);
130   return aout_32_some_aout_object_p (abfd, &anexec, b_out_callback);
131 }
132
133
134 /* Finish up the opening of a b.out file for reading.  Fill in all the
135    fields that are not handled by common code.  */
136
137 static bfd_target *
138 b_out_callback (abfd)
139      bfd *abfd;
140 {
141   struct internal_exec *execp = exec_hdr (abfd);
142   unsigned long bss_start;
143
144   /* Architecture and machine type */
145   bfd_set_arch_mach(abfd, 
146                     bfd_arch_i960, /* B.out only used on i960 */
147                     bfd_mach_i960_core /* Default */
148                     );
149
150   /* The positions of the string table and symbol table.  */
151   obj_str_filepos (abfd) = N_STROFF (*execp);
152   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
153
154   /* The alignments of the sections */
155   obj_textsec (abfd)->alignment_power = execp->a_talign;
156   obj_datasec (abfd)->alignment_power = execp->a_dalign;
157   obj_bsssec  (abfd)->alignment_power = execp->a_balign;
158
159   /* The starting addresses of the sections.  */
160   obj_textsec (abfd)->vma = execp->a_tload;
161   obj_datasec (abfd)->vma = execp->a_dload;
162   bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section */
163   obj_bsssec (abfd)->vma = i960_align (bss_start, execp->a_balign);
164
165   /* The file positions of the sections */
166   obj_textsec (abfd)->filepos = N_TXTOFF(*execp);
167   obj_datasec (abfd)->filepos = N_DATOFF(*execp);
168
169   /* The file positions of the relocation info */
170   obj_textsec (abfd)->rel_filepos = N_TROFF(*execp);
171   obj_datasec (abfd)->rel_filepos =  N_DROFF(*execp);
172
173   return abfd->xvec;
174 }
175
176 struct container {
177     struct aoutdata a;
178     struct internal_exec e;
179 };
180
181 static boolean
182 b_out_mkobject (abfd)
183      bfd *abfd;
184 {
185   struct container *rawptr;
186
187   rawptr = (struct container *) bfd_zalloc (abfd, sizeof (struct container));
188   if (rawptr == NULL) {
189     bfd_error = no_memory;
190     return false;
191   }
192
193   set_tdata (abfd, &rawptr->a);
194   exec_hdr (abfd) = &rawptr->e;
195
196   /* For simplicity's sake we just make all the sections right here. */
197   obj_textsec (abfd) = (asection *)NULL;
198   obj_datasec (abfd) = (asection *)NULL;
199   obj_bsssec (abfd) = (asection *)NULL;
200
201   bfd_make_section (abfd, ".text");
202   bfd_make_section (abfd, ".data");
203   bfd_make_section (abfd, ".bss");
204
205   return true;
206 }
207
208 static boolean
209 b_out_write_object_contents (abfd)
210      bfd *abfd;
211 {
212   struct external_exec swapped_hdr;
213
214   exec_hdr (abfd)->a_info = BMAGIC;
215
216   exec_hdr (abfd)->a_text = obj_textsec (abfd)->size;
217   exec_hdr (abfd)->a_data = obj_datasec (abfd)->size;
218   exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->size;
219   exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
220   exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
221   exec_hdr (abfd)->a_trsize = ((obj_textsec (abfd)->reloc_count) *
222                                sizeof (struct relocation_info));
223   exec_hdr (abfd)->a_drsize = ((obj_datasec (abfd)->reloc_count) *
224                                sizeof (struct relocation_info));
225
226   exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power;
227   exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power;
228   exec_hdr (abfd)->a_balign = obj_bsssec (abfd)->alignment_power;
229
230   exec_hdr (abfd)->a_tload = obj_textsec (abfd)->vma;
231   exec_hdr (abfd)->a_dload = obj_datasec (abfd)->vma;
232
233   bout_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
234
235   bfd_seek (abfd, 0L, SEEK_SET);
236   bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd);
237
238   /* Now write out reloc info, followed by syms and strings */
239   if (bfd_get_symcount (abfd) != 0) 
240     {
241       bfd_seek (abfd,
242                 (long)(N_SYMOFF(*exec_hdr(abfd))), SEEK_SET);
243
244       aout_32_write_syms (abfd);
245
246       bfd_seek (abfd,   (long)(N_TROFF(*exec_hdr(abfd))), SEEK_SET);
247
248       if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
249       bfd_seek (abfd, (long)(N_DROFF(*exec_hdr(abfd))), SEEK_SET);
250
251       if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
252     }
253   return true;
254 }
255 \f
256 /** Some reloc hackery */
257
258 #define CALLS    0x66003800     /* Template for 'calls' instruction     */
259 #define BAL      0x0b000000     /* Template for 'bal' instruction       */
260 #define BAL_MASK 0x00ffffff
261
262 static bfd_reloc_status_type 
263 callj_callback(abfd, reloc_entry, symbol_in, data, input_section)
264 bfd *abfd;
265 arelent *reloc_entry;
266 asymbol *symbol_in;
267 unsigned char *data;
268 asection *input_section;
269 {
270   int  word = bfd_get_32(abfd, data+reloc_entry->address);
271   aout_symbol_type  *symbol = aout_symbol(symbol_in);
272
273   if (IS_OTHER(symbol->other)) {
274     /* Call to a system procedure - replace code with system
275        procedure number 
276        */
277
278     word = CALLS | (symbol->other - 1);
279     bfd_put_32(abfd, word,  data+reloc_entry->address); /* replace */
280     return bfd_reloc_ok;
281   }
282     
283   if (IS_CALLNAME(symbol->other)) {
284     aout_symbol_type *balsym = symbol+1;
285     /* The next symbol should be an N_BALNAME */
286     BFD_ASSERT(IS_BALNAME(balsym->other));
287
288     /* We are calling a leaf - so replace the call instruction
289        with a bal */
290   
291     word = BAL |
292       (((word & BAL_MASK) +
293         balsym->symbol.section->output_offset +
294         balsym->symbol.section->output_section->vma+
295         balsym->symbol.value + reloc_entry->addend - 
296         ( input_section->output_section->vma + input_section->output_offset))
297        & BAL_MASK);
298
299     bfd_put_32(abfd, word,  data+reloc_entry->address); /* replace */
300     return bfd_reloc_ok;
301   }
302   return bfd_reloc_continue;
303
304 }
305 /* type rshift size  bitsize    pcrel   bitpos  absolute overflow check*/
306
307
308 static reloc_howto_type howto_reloc_callj =
309 HOWTO( 3, 0, 2, 24, true, 0, true, true, callj_callback,"callj", true, 0x00ffffff, 0x00ffffff,false);
310 static  reloc_howto_type howto_reloc_abs32 =
311 HOWTO(1, 0, 2, 32, false, 0, true, true,0,"abs32", true, 0xffffffff,0xffffffff,false);
312 static reloc_howto_type howto_reloc_pcrel24 =
313 HOWTO(2, 0, 2, 24, true, 0, true, true,0,"pcrel24", true, 0x00ffffff,0x00ffffff,false);
314
315 /* Allocate enough room for all the reloc entries, plus pointers to them all */
316
317 static boolean
318 b_out_slurp_reloc_table (abfd, asect, symbols)
319      bfd *abfd;
320      sec_ptr asect;
321      asymbol **symbols;
322 {
323   unsigned int count;
324   size_t  reloc_size;
325   struct relocation_info *relocs;
326   arelent *reloc_cache;
327
328   if (asect->relocation) return true;
329   if (!aout_32_slurp_symbol_table (abfd)) return false;
330
331   if (asect == obj_datasec (abfd)) {
332     reloc_size = exec_hdr(abfd)->a_drsize;
333     goto doit;
334   }
335
336   if (asect == obj_textsec (abfd)) {
337     reloc_size = exec_hdr(abfd)->a_trsize;
338     goto doit;
339   }
340
341   bfd_error = invalid_operation;
342   return false;
343
344  doit:
345   bfd_seek (abfd, (long)(asect->rel_filepos), SEEK_SET);
346   count = reloc_size / sizeof (struct relocation_info);
347
348   relocs = (struct relocation_info *) malloc (reloc_size);
349   if (!relocs) {
350     bfd_error = no_memory;
351     return false;
352   }
353   reloc_cache = (arelent *) malloc ((count+1) * sizeof (arelent));
354   if (!reloc_cache) {
355     free ((char*)relocs);
356     bfd_error = no_memory;
357     return false;
358   }
359
360   if (bfd_read ((PTR) relocs, 1, reloc_size, abfd) != reloc_size) {
361     bfd_error = system_call_error;
362     free (reloc_cache);
363     free (relocs);
364     return false;
365   }
366
367   {
368     register struct relocation_info *rptr = relocs;
369     unsigned int counter = 0;
370     arelent *cache_ptr = reloc_cache;
371     int extern_mask, pcrel_mask, callj_mask;
372   
373     if (abfd->xvec->header_byteorder_big_p) {
374       /* Big-endian bit field allocation order */
375       pcrel_mask  = 0x80;
376       extern_mask = 0x10;
377       callj_mask  = 0x02;
378     } else {
379       /* Little-endian bit field allocation order */
380       pcrel_mask  = 0x01;
381       extern_mask = 0x08;
382       callj_mask  = 0x40;
383     }
384
385     for (; counter < count; counter++, rptr++, cache_ptr++) 
386       {
387         unsigned char *raw = (unsigned char *)rptr;
388         unsigned int symnum;
389         cache_ptr->address = bfd_h_get_32 (abfd, raw + 0);
390         if (abfd->xvec->header_byteorder_big_p) {
391           symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6];
392         } else {
393           symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4];
394         }
395
396         if (raw[7] & extern_mask) {
397           /* If this is set then the r_index is a index into the symbol table;
398            * if the bit is not set then r_index contains a section map.
399            * We either fill in the sym entry with a pointer to the symbol,
400            * or point to the correct section
401            */
402           cache_ptr->sym_ptr_ptr = symbols + symnum;
403           cache_ptr->addend = 0;
404           cache_ptr->section = (asection*)NULL;
405         } else {
406           /* In a.out symbols are relative to the beginning of the
407            * file rather than sections ?
408            * (look in translate_from_native_sym_flags)
409            * The reloc entry addend has added to it the offset into the
410            * file of the data, so subtract the base to make the reloc
411            * section relative */
412           cache_ptr->sym_ptr_ptr = (asymbol **)NULL;
413           switch (symnum) {
414           case N_TEXT:
415           case N_TEXT | N_EXT:
416             cache_ptr->section = obj_textsec(abfd);
417             cache_ptr->addend = -obj_textsec(abfd)->vma;
418             break;
419           case N_DATA:
420           case N_DATA | N_EXT:
421             cache_ptr->section = obj_datasec(abfd);
422             cache_ptr->addend = - obj_datasec(abfd)->vma;
423             break;
424           case N_BSS:
425           case N_BSS | N_EXT:
426             cache_ptr->section = obj_bsssec(abfd);
427             cache_ptr->addend =  - obj_bsssec(abfd)->vma;
428             break;
429           case N_ABS:
430           case N_ABS | N_EXT:
431             BFD_ASSERT(0);
432             break;
433           default:
434             BFD_ASSERT(0);
435             break;
436           }
437         
438         }
439
440         /* The i960 only has a few relocation types:
441            abs 32-bit and pcrel 24bit.   Except for callj's!  */
442         if (raw[7] & callj_mask)
443           cache_ptr->howto = &howto_reloc_callj;
444         else if ( raw[7] & pcrel_mask)
445           cache_ptr->howto = &howto_reloc_pcrel24;
446         else
447           cache_ptr->howto = &howto_reloc_abs32;
448       }
449   }
450
451   free (relocs);
452   asect->relocation = reloc_cache;
453   asect->reloc_count = count;
454   return true;
455 }
456
457
458 static boolean
459 b_out_squirt_out_relocs (abfd, section)
460      bfd *abfd;
461      asection *section;
462 {
463   arelent **generic;
464
465   unsigned int count = section->reloc_count;
466   struct relocation_info *native, *natptr;
467   size_t natsize = count * sizeof (struct relocation_info);
468   int extern_mask, pcrel_mask,  len_2, callj_mask;
469   if (count == 0) return true;
470   generic   = section->orelocation;
471   native = ((struct relocation_info *) malloc (natsize));
472   if (!native) {
473     bfd_error = no_memory;
474     return false;
475   }
476
477    if (abfd->xvec->header_byteorder_big_p) {
478        /* Big-endian bit field allocation order */
479        pcrel_mask  = 0x80;
480        extern_mask = 0x10;
481        len_2       = 0x40;
482       callj_mask  = 0x02;
483    } else {
484        /* Little-endian bit field allocation order */
485        pcrel_mask  = 0x01;
486        extern_mask = 0x08;
487        len_2       = 0x04;
488       callj_mask  = 0x40;
489    }
490
491   for (natptr = native; count > 0; --count, ++natptr, ++generic) 
492     {
493       arelent *g = *generic;
494       unsigned char *raw = (unsigned char *)natptr;
495       unsigned int symnum;
496
497       bfd_h_put_32(abfd, g->address, raw);  
498       /* Find a type in the output format which matches the input howto - 
499        * at the moment we assume input format == output format FIXME!!
500        */
501       /* FIXME:  Need callj stuff here, and to check the howto entries to
502          be sure they are real for this architecture.  */
503       if (g->howto== &howto_reloc_callj) {
504         raw[7] = callj_mask + pcrel_mask + len_2;
505       }
506       else if (g->howto == &howto_reloc_pcrel24) {
507         raw[7] = pcrel_mask +len_2;
508       }
509       else {
510         raw[7] = len_2;
511       }
512       if (g->sym_ptr_ptr != (asymbol **)NULL) 
513         {
514           /* name clobbered by aout_write_syms to be symbol index*/
515           if ((*(g->sym_ptr_ptr))->section) {
516             /* replace the section offset into the addent */
517             g->addend += (*(g->sym_ptr_ptr))->section->vma ;
518           }
519           symnum = stoi((*(g->sym_ptr_ptr))->name);
520           raw[7] |= extern_mask;
521           BFD_ASSERT(g->addend == 0);
522         }
523       else {
524         if (g->section == (asection *)NULL) {
525           symnum = N_ABS;
526           BFD_ASSERT(0);
527         }
528         else  if(g->section->output_section == obj_textsec(abfd)) {
529           symnum = N_TEXT;
530           BFD_ASSERT(g->addend + obj_textsec(abfd)->vma == 0);
531         }
532         else if (g->section->output_section == obj_datasec(abfd)) {
533           symnum  = N_DATA;
534           BFD_ASSERT(g->addend + obj_datasec(abfd)->vma == 0);
535         }
536         else if (g->section->output_section == obj_bsssec(abfd)) {
537           symnum = N_BSS;
538           BFD_ASSERT(g->addend + obj_bsssec(abfd)->vma == 0);
539         }
540         else {
541           BFD_ASSERT(0);
542           symnum = N_ABS;
543         }
544       }
545       if (abfd->xvec->header_byteorder_big_p) {
546         raw[4] = (unsigned char) (symnum >> 16);
547         raw[5] = (unsigned char) (symnum >>  8);
548         raw[6] = (unsigned char) (symnum      );
549       } else {
550         raw[6] = (unsigned char) (symnum >> 16);
551         raw[5] = (unsigned char) (symnum >>  8);
552         raw[4] = (unsigned char) (symnum      );
553       }  
554     }
555
556   if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
557     free((PTR)native);
558     return false;
559   }
560   free ((PTR)native);
561
562   return true;
563 }
564
565 /* This is stupid.  This function should be a boolean predicate */
566 static unsigned int
567 b_out_canonicalize_reloc (abfd, section, relptr, symbols)
568      bfd *abfd;
569      sec_ptr section;
570      arelent **relptr;
571      asymbol **symbols;
572 {
573   arelent *tblptr = section->relocation;
574   unsigned int count = 0;
575
576  if (!(tblptr || b_out_slurp_reloc_table (abfd, section, symbols))) return 0;
577   tblptr = section->relocation;
578  if (!tblptr) return 0;
579
580   for (; count++ < section->reloc_count;)
581     *relptr++ = tblptr++;
582
583   *relptr = 0;
584
585   return section->reloc_count;
586 }
587
588 static unsigned int
589 b_out_get_reloc_upper_bound (abfd, asect)
590      bfd *abfd;
591      sec_ptr asect;
592 {
593   if (bfd_get_format (abfd) != bfd_object) {
594     bfd_error = invalid_operation;
595     return 0;
596   }
597
598   if (asect == obj_datasec (abfd))
599     return (sizeof (arelent *) *
600             ((exec_hdr(abfd)->a_drsize / sizeof (struct relocation_info))
601              +1));
602
603   if (asect == obj_textsec (abfd))
604     return (sizeof (arelent *) *
605             ((exec_hdr(abfd)->a_trsize / sizeof (struct relocation_info))
606              +1));
607
608   bfd_error = invalid_operation;
609   return 0;
610 }
611 \f
612 static boolean
613 b_out_set_section_contents (abfd, section, location, offset, count)
614      bfd *abfd;
615      sec_ptr section;
616      unsigned char *location;
617      file_ptr offset;
618       int count;
619 {
620   if (abfd->output_has_begun == false) { /* set by bfd.c handler */
621     if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL) /*||
622         (obj_textsec (abfd)->size == 0) || (obj_datasec (abfd)->size == 0)*/) {
623       bfd_error = invalid_operation;
624       return false;
625     }
626
627     obj_textsec (abfd)->filepos = sizeof(struct internal_exec);
628     obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos 
629                                 +  obj_textsec (abfd)->size;
630
631   }
632   /* regardless, once we know what we're doing, we might as well get going */
633   bfd_seek (abfd, section->filepos + offset, SEEK_SET);
634
635   if (count != 0) {
636     return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false;
637   }
638   return false;
639 }
640
641 static boolean
642 b_out_set_arch_mach (abfd, arch, machine)
643      bfd *abfd;
644      enum bfd_architecture arch;
645      unsigned long machine;
646 {
647   bfd_default_set_arch_mach(abfd, arch, machine);
648
649   if (arch == bfd_arch_unknown) /* Unknown machine arch is OK */
650     return true;
651   if (arch == bfd_arch_i960)    /* i960 default is OK */
652     switch (machine) {
653     case bfd_mach_i960_core:
654     case bfd_mach_i960_kb_sb:
655     case bfd_mach_i960_mc:
656     case bfd_mach_i960_xa:
657     case bfd_mach_i960_ca:
658     case bfd_mach_i960_ka_sa:
659     case 0:
660       return true;
661     default:
662       return false;
663     }
664
665   return false;
666 }
667
668 static int 
669 DEFUN(b_out_sizeof_headers,(ignore_abfd, ignore),
670       bfd *ignore_abfd AND
671       boolean ignore)
672 {
673   return sizeof(struct internal_exec);
674 }
675
676
677
678
679 /* Build the transfer vectors for Big and Little-Endian B.OUT files.  */
680
681 /* We don't have core files.  */
682 #define aout_32_core_file_failing_command       _bfd_dummy_core_file_failing_command
683 #define aout_32_core_file_failing_signal        _bfd_dummy_core_file_failing_signal
684 #define aout_32_core_file_matches_executable_p  \
685                                 _bfd_dummy_core_file_matches_executable_p
686
687 /* We use BSD-Unix generic archive files.  */
688 #define aout_32_openr_next_archived_file        bfd_generic_openr_next_archived_file
689 #define aout_32_generic_stat_arch_elt   bfd_generic_stat_arch_elt
690 #define aout_32_slurp_armap             bfd_slurp_bsd_armap
691 #define aout_32_slurp_extended_name_table       bfd_true
692 #define aout_32_write_armap             bsd_write_armap
693 #define aout_32_truncate_arname         bfd_bsd_truncate_arname
694
695 /* We override these routines from the usual a.out file routines.  */
696 #define aout_32_canonicalize_reloc      b_out_canonicalize_reloc
697 #define aout_32_get_reloc_upper_bound   b_out_get_reloc_upper_bound
698 #define aout_32_set_section_contents    b_out_set_section_contents
699 #define aout_32_set_arch_mach           b_out_set_arch_mach
700 #define aout_32_sizeof_headers          b_out_sizeof_headers
701
702 #define aout_32_bfd_debug_info_start            bfd_void
703 #define aout_32_bfd_debug_info_end              bfd_void
704 #define aout_32_bfd_debug_info_accumulate       (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
705
706
707 bfd_target b_out_vec_big_host =
708 {
709   "b.out.big",                  /* name */
710   bfd_target_aout_flavour,
711   false,                        /* data byte order is little */
712   true,                         /* hdr byte order is big */
713   (HAS_RELOC | EXEC_P |         /* object flags */
714    HAS_LINENO | HAS_DEBUG |
715    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
716   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
717   ' ',                          /* ar_pad_char */
718   16,                           /* ar_max_namelen */
719      2,                         /* minumum alignment power */
720
721 _do_getl64, _do_putl64,  _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
722 _do_getb64, _do_putb64,  _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
723     {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
724        bfd_generic_archive_p, _bfd_dummy_target},
725     {bfd_false, b_out_mkobject, /* bfd_set_format */
726        _bfd_generic_mkarchive, bfd_false},
727     {bfd_false, b_out_write_object_contents,    /* bfd_write_contents */
728        _bfd_write_archive_contents, bfd_false},
729
730   JUMP_TABLE(aout_32)
731 };
732
733
734 bfd_target b_out_vec_little_host =
735 {
736   "b.out.little",               /* name */
737   bfd_target_aout_flavour,
738   false,                        /* data byte order is little */
739   false,                        /* header byte order is little */
740   (HAS_RELOC | EXEC_P |         /* object flags */
741    HAS_LINENO | HAS_DEBUG |
742    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
743   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
744   ' ',                          /* ar_pad_char */
745   16,                           /* ar_max_namelen */
746      2,                         /* minum align */
747 _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
748 _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* hdrs */
749          
750     {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
751        bfd_generic_archive_p, _bfd_dummy_target},
752     {bfd_false, b_out_mkobject, /* bfd_set_format */
753        _bfd_generic_mkarchive, bfd_false},
754     {bfd_false, b_out_write_object_contents,    /* bfd_write_contents */
755        _bfd_write_archive_contents, bfd_false},
756   JUMP_TABLE(aout_32)
757 };