23687b38b08abf09ff6f0877f758552f33348b70
[platform/upstream/binutils.git] / bfd / bout.c
1 /* BFD back-end for Intel 960 b.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 #include "bfd.h"
23 #include "sysdep.h"
24 #include "libbfd.h"
25 #include "seclet.h"
26 #include "bout.h"
27
28 #include "aout/stab_gnu.h"
29 #include "libaout.h"            /* BFD a.out internal data structures */
30
31
32 extern bfd_error_vector_type bfd_error_vector;
33 PROTO (static boolean, b_out_squirt_out_relocs,(bfd *abfd, asection *section));
34 PROTO (static bfd_target *, b_out_callback, (bfd *));
35
36 PROTO (boolean, aout_32_slurp_symbol_table, (bfd *abfd));
37 PROTO (void , aout_32_write_syms, ());
38
39 /* Swaps the information in an executable header taken from a raw byte
40    stream memory image, into the internal exec_header structure.  */
41
42 PROTO(void, bout_swap_exec_header_in,
43       (bfd *abfd,
44       struct external_exec *raw_bytes,
45       struct internal_exec *execp));
46          
47 void
48 DEFUN(bout_swap_exec_header_in,(abfd, raw_bytes, execp),
49       bfd *abfd AND
50       struct external_exec *raw_bytes AND
51       struct internal_exec *execp)
52 {
53   struct external_exec *bytes = (struct external_exec *)raw_bytes;
54
55   /* Now fill in fields in the execp, from the bytes in the raw data.  */
56   execp->a_info   = bfd_h_get_32 (abfd, bytes->e_info);
57   execp->a_text   = GET_WORD (abfd, bytes->e_text);
58   execp->a_data   = GET_WORD (abfd, bytes->e_data);
59   execp->a_bss    = GET_WORD (abfd, bytes->e_bss);
60   execp->a_syms   = GET_WORD (abfd, bytes->e_syms);
61   execp->a_entry  = GET_WORD (abfd, bytes->e_entry);
62   execp->a_trsize = GET_WORD (abfd, bytes->e_trsize);
63   execp->a_drsize = GET_WORD (abfd, bytes->e_drsize);
64   execp->a_tload  = GET_WORD (abfd, bytes->e_tload);
65   execp->a_dload  = GET_WORD (abfd, bytes->e_dload);
66   execp->a_talign = bytes->e_talign[0];
67   execp->a_dalign = bytes->e_dalign[0];
68   execp->a_balign = bytes->e_balign[0];
69   execp->a_relaxable = bytes->e_relaxable[0];
70 }
71
72 /* Swaps the information in an internal exec header structure into the
73    supplied buffer ready for writing to disk.  */
74
75 PROTO(void, bout_swap_exec_header_out,
76           (bfd *abfd,
77            struct internal_exec *execp,
78            struct external_exec *raw_bytes));
79 void
80 DEFUN(bout_swap_exec_header_out,(abfd, execp, raw_bytes),
81      bfd *abfd AND
82      struct internal_exec *execp AND 
83      struct external_exec *raw_bytes)
84 {
85   struct external_exec *bytes = (struct external_exec *)raw_bytes;
86
87   /* Now fill in fields in the raw data, from the fields in the exec struct. */
88   bfd_h_put_32 (abfd, execp->a_info  , bytes->e_info);
89   PUT_WORD (abfd, execp->a_text  , bytes->e_text);
90   PUT_WORD (abfd, execp->a_data  , bytes->e_data);
91   PUT_WORD (abfd, execp->a_bss   , bytes->e_bss);
92   PUT_WORD (abfd, execp->a_syms  , bytes->e_syms);
93   PUT_WORD (abfd, execp->a_entry , bytes->e_entry);
94   PUT_WORD (abfd, execp->a_trsize, bytes->e_trsize);
95   PUT_WORD (abfd, execp->a_drsize, bytes->e_drsize);
96   PUT_WORD (abfd, execp->a_tload , bytes->e_tload);
97   PUT_WORD (abfd, execp->a_dload , bytes->e_dload);
98   bytes->e_talign[0] = execp->a_talign;
99   bytes->e_dalign[0] = execp->a_dalign;
100   bytes->e_balign[0] = execp->a_balign;
101   bytes->e_relaxable[0] = execp->a_relaxable;
102 }
103
104
105 static bfd_target *
106 b_out_object_p (abfd)
107      bfd *abfd;
108 {
109   struct internal_exec anexec;
110   struct external_exec exec_bytes;
111
112   if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
113       != EXEC_BYTES_SIZE) {
114     bfd_error = wrong_format;
115     return 0;
116   }
117
118   anexec.a_info = bfd_h_get_32 (abfd, exec_bytes.e_info);
119
120   if (N_BADMAG (anexec)) {
121     bfd_error = wrong_format;
122     return 0;
123   }
124
125   bout_swap_exec_header_in (abfd, &exec_bytes, &anexec);
126   return aout_32_some_aout_object_p (abfd, &anexec, b_out_callback);
127 }
128
129
130 /* Finish up the opening of a b.out file for reading.  Fill in all the
131    fields that are not handled by common code.  */
132
133 static bfd_target *
134 b_out_callback (abfd)
135      bfd *abfd;
136 {
137   struct internal_exec *execp = exec_hdr (abfd);
138   unsigned long bss_start;
139
140   /* Architecture and machine type */
141   bfd_set_arch_mach(abfd, 
142                     bfd_arch_i960, /* B.out only used on i960 */
143                     bfd_mach_i960_core /* Default */
144                     );
145
146   /* The positions of the string table and symbol table.  */
147   obj_str_filepos (abfd) = N_STROFF (*execp);
148   obj_sym_filepos (abfd) = N_SYMOFF (*execp);
149
150   /* The alignments of the sections */
151   obj_textsec (abfd)->alignment_power = execp->a_talign;
152   obj_datasec (abfd)->alignment_power = execp->a_dalign;
153   obj_bsssec  (abfd)->alignment_power = execp->a_balign;
154
155   /* The starting addresses of the sections.  */
156   obj_textsec (abfd)->vma = execp->a_tload;
157   obj_datasec (abfd)->vma = execp->a_dload;
158
159   /* And reload the sizes, since the aout module zaps them */
160   obj_textsec (abfd)->_raw_size = execp->a_text;
161
162   bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section */
163   obj_bsssec (abfd)->vma = align_power (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   adata(abfd).page_size = 1;    /* Not applicable. */
174   adata(abfd).segment_size = 1; /* Not applicable. */
175   adata(abfd).exec_bytes_size = EXEC_BYTES_SIZE;
176
177   if (execp->a_relaxable)
178    abfd->flags |= BFD_IS_RELAXABLE;
179   return abfd->xvec;
180 }
181
182 struct bout_data_struct {
183     struct aoutdata a;
184     struct internal_exec e;
185 };
186
187 static boolean
188 b_out_mkobject (abfd)
189      bfd *abfd;
190 {
191   struct bout_data_struct *rawptr;
192
193   rawptr = (struct bout_data_struct *) bfd_zalloc (abfd, sizeof (struct bout_data_struct));
194   if (rawptr == NULL) {
195       bfd_error = no_memory;
196       return false;
197     }
198
199   abfd->tdata.bout_data = rawptr;
200   exec_hdr (abfd) = &rawptr->e;
201
202   /* For simplicity's sake we just make all the sections right here. */
203   obj_textsec (abfd) = (asection *)NULL;
204   obj_datasec (abfd) = (asection *)NULL;
205   obj_bsssec (abfd) = (asection *)NULL;
206
207   bfd_make_section (abfd, ".text");
208   bfd_make_section (abfd, ".data");
209   bfd_make_section (abfd, ".bss");
210
211   return true;
212 }
213
214 static boolean
215 b_out_write_object_contents (abfd)
216      bfd *abfd;
217 {
218   struct external_exec swapped_hdr;
219
220   exec_hdr (abfd)->a_info = BMAGIC;
221
222   exec_hdr (abfd)->a_text = obj_textsec (abfd)->_raw_size;
223   exec_hdr (abfd)->a_data = obj_datasec (abfd)->_raw_size;
224   exec_hdr (abfd)->a_bss = obj_bsssec (abfd)->_raw_size;
225   exec_hdr (abfd)->a_syms = bfd_get_symcount (abfd) * sizeof (struct nlist);
226   exec_hdr (abfd)->a_entry = bfd_get_start_address (abfd);
227   exec_hdr (abfd)->a_trsize = ((obj_textsec (abfd)->reloc_count) *
228                                sizeof (struct relocation_info));
229   exec_hdr (abfd)->a_drsize = ((obj_datasec (abfd)->reloc_count) *
230                                sizeof (struct relocation_info));
231
232   exec_hdr (abfd)->a_talign = obj_textsec (abfd)->alignment_power;
233   exec_hdr (abfd)->a_dalign = obj_datasec (abfd)->alignment_power;
234   exec_hdr (abfd)->a_balign = obj_bsssec (abfd)->alignment_power;
235
236   exec_hdr (abfd)->a_tload = obj_textsec (abfd)->vma;
237   exec_hdr (abfd)->a_dload = obj_datasec (abfd)->vma;
238
239   bout_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
240
241   bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
242   bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd);
243
244   /* Now write out reloc info, followed by syms and strings */
245   if (bfd_get_symcount (abfd) != 0) 
246     {
247       bfd_seek (abfd, (file_ptr)(N_SYMOFF(*exec_hdr(abfd))), SEEK_SET);
248
249       aout_32_write_syms (abfd);
250
251       bfd_seek (abfd, (file_ptr)(N_TROFF(*exec_hdr(abfd))), SEEK_SET);
252
253       if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
254       bfd_seek (abfd, (file_ptr)(N_DROFF(*exec_hdr(abfd))), SEEK_SET);
255
256       if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
257     }
258   return true;
259 }
260 \f
261 /** Some reloc hackery */
262
263 #define CALLS    0x66003800     /* Template for 'calls' instruction     */
264 #define BAL      0x0b000000     /* Template for 'bal' instruction */
265 #define BALX     0x85000000     /* Template for 'balx' instruction      */
266 #define BAL_MASK 0x00ffffff
267 #define CALL     0x09000000
268 #define PCREL13_MASK 0x1fff
269 /* Magic to turn callx into calljx */
270 static bfd_reloc_status_type 
271 DEFUN (calljx_callback, (abfd, reloc_entry,  src, dst, input_section, seclet),
272        bfd *abfd AND
273        arelent *reloc_entry AND
274        PTR src AND
275        PTR dst AND
276        asection *input_section AND
277        bfd_seclet_type *seclet)
278 {
279   int  word = bfd_get_32(abfd, src);
280   asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
281   aout_symbol_type  *symbol = aout_symbol(symbol_in);
282
283   if (symbol_in->section == &bfd_und_section)
284   {
285     bfd_error_vector.undefined_symbol(reloc_entry, seclet);
286   }
287
288   if (IS_CALLNAME(symbol->other)) 
289   {
290
291     aout_symbol_type *balsym = symbol+1;
292     int inst = bfd_get_32(abfd, (bfd_byte *) src-4);
293     /* The next symbol should be an N_BALNAME */
294     BFD_ASSERT(IS_BALNAME(balsym->other));
295     inst &= BAL_MASK;
296     inst |= BALX;
297     bfd_put_32(abfd, inst, (bfd_byte *) dst-4);
298     symbol = balsym;
299   }
300
301     word += symbol->symbol.section->output_offset +
302      symbol->symbol.section->output_section->vma +
303       symbol->symbol.value + reloc_entry->addend;
304
305   bfd_put_32(abfd, word, dst);
306   return bfd_reloc_ok;
307 }
308
309
310 /* Magic to turn call into callj */
311 static bfd_reloc_status_type 
312 DEFUN (callj_callback, (abfd, reloc_entry,  data, srcidx,dstidx,
313                         input_section, seclet),
314        bfd *abfd AND
315        arelent *reloc_entry AND
316        PTR data AND
317        unsigned int srcidx AND
318        unsigned int dstidx AND
319        asection *input_section AND
320        bfd_seclet_type *seclet)
321 {
322   int  word = bfd_get_32(abfd, (bfd_byte *) data + srcidx);
323   asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
324
325   aout_symbol_type  *symbol = aout_symbol(symbol_in);
326
327   if (symbol_in->section == &bfd_und_section)
328   {
329     bfd_error_vector.undefined_symbol(reloc_entry, seclet);
330   }
331
332   if (IS_OTHER(symbol->other)) 
333   {
334     /* Call to a system procedure - replace code with system
335        procedure number */
336     word = CALLS | (symbol->other - 1);
337
338   }
339
340   else  if (IS_CALLNAME(symbol->other)) 
341   {
342     aout_symbol_type *balsym = symbol+1;
343     /* The next symbol should be an N_BALNAME */
344     BFD_ASSERT(IS_BALNAME(balsym->other));
345
346     /* We are calling a leaf - so replace the call instruction
347        with a bal */
348
349     word = BAL |
350      (((word & BAL_MASK) +
351        balsym->symbol.section->output_offset +
352        balsym->symbol.section->output_section->vma+
353        balsym->symbol.value + reloc_entry->addend - dstidx -
354        ( input_section->output_section->vma + input_section->output_offset))
355       & BAL_MASK);
356
357
358   }
359   else 
360   {
361
362     word = CALL |
363      (((word & BAL_MASK) + 
364        symbol->symbol.section->output_offset +
365        symbol->symbol.section->output_section->vma+
366        symbol->symbol.value + reloc_entry->addend - dstidx -
367        ( input_section->output_section->vma + input_section->output_offset))
368       & BAL_MASK);
369   }
370   bfd_put_32(abfd, word, (bfd_byte *) data + dstidx);
371   return bfd_reloc_ok;
372 }
373
374 /* type rshift size  bitsize    pcrel   bitpos  absolute overflow check*/
375
376 #define ABS32CODE 0
377 #define ABS32CODE_SHRUNK 1 
378 #define PCREL24 2
379 #define CALLJ 3
380 #define ABS32 4
381 #define PCREL13 5
382 #define ABS32_MAYBE_RELAXABLE 1
383 #define ABS32_WAS_RELAXABLE 2
384
385 #define ALIGNER 10
386 #define ALIGNDONE 11
387 static reloc_howto_type howto_reloc_callj =
388 HOWTO(CALLJ, 0, 2, 24, true, 0, true, true, 0,"callj", true, 0x00ffffff, 0x00ffffff,false);
389 static  reloc_howto_type howto_reloc_abs32 =
390 HOWTO(ABS32, 0, 2, 32, false, 0, true, true,0,"abs32", true, 0xffffffff,0xffffffff,false);
391 static reloc_howto_type howto_reloc_pcrel24 =
392 HOWTO(PCREL24, 0, 2, 24, true, 0, true, true,0,"pcrel24", true, 0x00ffffff,0x00ffffff,false);
393
394 static reloc_howto_type howto_reloc_pcrel13 =
395 HOWTO(PCREL13, 0, 2, 13, true, 0, true, true,0,"pcrel13", true, 0x00001fff,0x00001fff,false);
396
397
398 static reloc_howto_type howto_reloc_abs32codeshrunk = 
399 HOWTO(ABS32CODE_SHRUNK, 0, 2, 24, true, 0, true, true, 0,"callx->callj", true, 0x00ffffff, 0x00ffffff,false);
400
401 static  reloc_howto_type howto_reloc_abs32code =
402 HOWTO(ABS32CODE, 0, 2, 32, false, 0, true, true,0,"callx", true, 0xffffffff,0xffffffff,false);
403
404 static reloc_howto_type howto_align_table[] = {
405   HOWTO (ALIGNER, 0, 0x1, 0, false, 0, false, false, 0, "align16", false, 0, 0, false),
406   HOWTO (ALIGNER, 0, 0x3, 0, false, 0, false, false, 0, "align32", false, 0, 0, false),
407   HOWTO (ALIGNER, 0, 0x7, 0, false, 0, false, false, 0, "align64", false, 0, 0, false),
408   HOWTO (ALIGNER, 0, 0xf, 0, false, 0, false, false, 0, "align128", false, 0, 0, false),
409 };
410
411 static reloc_howto_type howto_done_align_table[] = {
412   HOWTO (ALIGNDONE, 0x1, 0x1, 0, false, 0, false, false, 0, "donealign16", false, 0, 0, false),
413   HOWTO (ALIGNDONE, 0x3, 0x3, 0, false, 0, false, false, 0, "donealign32", false, 0, 0, false),
414   HOWTO (ALIGNDONE, 0x7, 0x7, 0, false, 0, false, false, 0, "donealign64", false, 0, 0, false),
415   HOWTO (ALIGNDONE, 0xf, 0xf, 0, false, 0, false, false, 0, "donealign128", false, 0, 0, false),
416 };
417
418 static reloc_howto_type *
419 b_out_reloc_type_lookup (abfd, code)
420      bfd *abfd;
421      bfd_reloc_code_real_type code;
422 {
423   switch (code)
424     {
425     default:
426       return 0;
427     case BFD_RELOC_I960_CALLJ:
428       return &howto_reloc_callj;
429     case BFD_RELOC_32:
430       return &howto_reloc_abs32;
431     case BFD_RELOC_24_PCREL:
432       return &howto_reloc_pcrel24;
433     }
434 }
435
436 /* Allocate enough room for all the reloc entries, plus pointers to them all */
437
438 static boolean
439 b_out_slurp_reloc_table (abfd, asect, symbols)
440      bfd *abfd;
441      sec_ptr asect;
442      asymbol **symbols;
443 {
444   register struct relocation_info *rptr;
445   unsigned int counter ;
446   arelent *cache_ptr ;
447   int extern_mask, pcrel_mask, callj_mask, length_shift;
448   int incode_mask;
449   int size_mask;
450   bfd_vma prev_addr = 0;
451   unsigned int count;
452   size_t  reloc_size;
453   struct relocation_info *relocs;
454   arelent *reloc_cache;
455
456   if (asect->relocation) return true;
457   if (!aout_32_slurp_symbol_table (abfd)) return false;
458
459   if (asect == obj_datasec (abfd)) {
460     reloc_size = exec_hdr(abfd)->a_drsize;
461     goto doit;
462   }
463
464   if (asect == obj_textsec (abfd)) {
465     reloc_size = exec_hdr(abfd)->a_trsize;
466     goto doit;
467   }
468
469   bfd_error = invalid_operation;
470   return false;
471
472  doit:
473   bfd_seek (abfd, (file_ptr)(asect->rel_filepos),  SEEK_SET);
474   count = reloc_size / sizeof (struct relocation_info);
475
476   relocs = (struct relocation_info *) bfd_xmalloc (reloc_size);
477   if (!relocs) {
478     bfd_error = no_memory;
479     return false;
480   }
481   reloc_cache = (arelent *) bfd_xmalloc ((count+1) * sizeof (arelent));
482   if (!reloc_cache) {
483     free ((char*)relocs);
484     bfd_error = no_memory;
485     return false;
486   }
487
488   if (bfd_read ((PTR) relocs, 1, reloc_size, abfd) != reloc_size) {
489     bfd_error = system_call_error;
490     free (reloc_cache);
491     free (relocs);
492     return false;
493   }
494
495
496   
497   if (abfd->xvec->header_byteorder_big_p) {
498     /* big-endian bit field allocation order */
499     pcrel_mask  = 0x80;
500     extern_mask = 0x10;
501     incode_mask = 0x08;
502     callj_mask  = 0x02;
503     size_mask =   0x20;
504     length_shift = 5;
505   } else {
506     /* little-endian bit field allocation order */
507     pcrel_mask  = 0x01;
508     extern_mask = 0x08;
509     incode_mask = 0x10;
510     callj_mask  = 0x40;
511     size_mask   = 0x02;
512     length_shift = 1;
513   }
514
515   for (rptr = relocs, cache_ptr = reloc_cache, counter = 0;
516        counter < count;
517        counter++, rptr++, cache_ptr++) 
518   {
519     unsigned char *raw = (unsigned char *)rptr;
520     unsigned int symnum;
521     cache_ptr->address = bfd_h_get_32 (abfd, raw + 0);
522     cache_ptr->howto = 0;
523     if (abfd->xvec->header_byteorder_big_p) 
524     {
525       symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6];
526     } 
527     else
528     {
529       symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4];
530     }
531
532     if (raw[7] & extern_mask) 
533     {
534       /* if this is set then the r_index is a index into the symbol table;
535        * if the bit is not set then r_index contains a section map.
536        * we either fill in the sym entry with a pointer to the symbol,
537        * or point to the correct section
538        */
539       cache_ptr->sym_ptr_ptr = symbols + symnum;
540       cache_ptr->addend = 0;
541     } else 
542     {
543       /* in a.out symbols are relative to the beginning of the
544        * file rather than sections ?
545        * (look in translate_from_native_sym_flags)
546        * the reloc entry addend has added to it the offset into the
547        * file of the data, so subtract the base to make the reloc
548        * section relative */
549       int s;
550       {
551         /* sign-extend symnum from 24 bits to whatever host uses */
552         s = symnum;
553         if (s & (1 << 23))
554           s |= (~0) << 24;
555       }
556       cache_ptr->sym_ptr_ptr = (asymbol **)NULL;
557       switch (s)
558       {
559        case N_TEXT:
560        case N_TEXT | N_EXT:
561         cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr;
562         cache_ptr->addend = - obj_textsec(abfd)->vma;
563         break;
564        case N_DATA:
565        case N_DATA | N_EXT:
566         cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr;
567         cache_ptr->addend = - obj_datasec(abfd)->vma;
568         break;
569        case N_BSS:
570        case N_BSS | N_EXT:
571         cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;
572         cache_ptr->addend =  - obj_bsssec(abfd)->vma;
573         break;
574        case N_ABS:
575        case N_ABS | N_EXT:
576         cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;
577         cache_ptr->addend = 0;
578         break;
579       case -2: /* .align */
580         if (raw[7] & pcrel_mask)
581           {
582             cache_ptr->howto = &howto_align_table[(raw[7] >> length_shift) & 3];
583             cache_ptr->sym_ptr_ptr = &bfd_abs_symbol;
584           }
585         else
586           {
587             /* .org? */
588             abort ();
589           }
590         cache_ptr->addend = 0;
591         break;
592        default:
593         BFD_ASSERT(0);
594         break;
595       }
596         
597     }
598
599     /* the i960 only has a few relocation types:
600        abs 32-bit and pcrel 24bit.   except for callj's!  */
601     if (cache_ptr->howto != 0)
602       ;
603     else if (raw[7] & callj_mask)
604     {
605       cache_ptr->howto = &howto_reloc_callj;
606     }
607     else if ( raw[7] & pcrel_mask)
608     {
609       if (raw[7] & size_mask)
610        cache_ptr->howto = &howto_reloc_pcrel13;
611       else
612        cache_ptr->howto = &howto_reloc_pcrel24;
613     }
614     else 
615     {
616       if (raw[7] & incode_mask) 
617       {
618         cache_ptr->howto = &howto_reloc_abs32code;
619       }
620       else 
621       {
622         cache_ptr->howto = &howto_reloc_abs32;
623       }
624     }
625     if (cache_ptr->address < prev_addr) 
626     {
627       /* Ouch! this reloc is out of order, insert into the right place
628        */
629       arelent tmp;
630       arelent *cursor = cache_ptr-1;
631       bfd_vma stop = cache_ptr->address;
632       tmp  = *cache_ptr;
633       while (cursor->address > stop && cursor >= reloc_cache)
634       {
635         cursor[1] = cursor[0];
636         cursor--;
637       } 
638       cursor[1] = tmp;
639     }
640     else 
641     {
642       prev_addr = cache_ptr->address;
643     }
644   }
645
646
647   free (relocs);
648   asect->relocation = reloc_cache;
649   asect->reloc_count = count;
650
651
652   return true;
653 }
654
655
656 static boolean
657 b_out_squirt_out_relocs (abfd, section)
658      bfd *abfd;
659      asection *section;
660 {
661
662   arelent **generic;
663   int r_extern;
664   int r_idx;
665   int incode_mask;  
666   int len_1;
667   unsigned int count = section->reloc_count;
668   struct relocation_info *native, *natptr;
669   size_t natsize = count * sizeof (struct relocation_info);
670   int extern_mask, pcrel_mask,  len_2, callj_mask;
671   if (count == 0) return true;
672   generic   = section->orelocation;
673   native = ((struct relocation_info *) bfd_xmalloc (natsize));
674   if (!native) {
675     bfd_error = no_memory;
676     return false;
677   }
678
679   if (abfd->xvec->header_byteorder_big_p) 
680   {
681     /* Big-endian bit field allocation order */
682     pcrel_mask  = 0x80;
683     extern_mask = 0x10;
684     len_2       = 0x40;
685     len_1       = 0x20;
686     callj_mask  = 0x02;
687     incode_mask = 0x08;
688   } 
689   else 
690   {
691     /* Little-endian bit field allocation order */
692     pcrel_mask  = 0x01;
693     extern_mask = 0x08;
694     len_2       = 0x04;
695     len_1       = 0x02;
696     callj_mask  = 0x40;
697     incode_mask = 0x10;
698   }
699
700   for (natptr = native; count > 0; --count, ++natptr, ++generic) 
701   {
702     arelent *g = *generic;
703     unsigned char *raw = (unsigned char *)natptr;
704     asymbol *sym = *(g->sym_ptr_ptr);
705
706     asection *output_section = sym->section->output_section;
707
708     bfd_h_put_32(abfd, g->address, raw);  
709     /* Find a type in the output format which matches the input howto - 
710      * at the moment we assume input format == output format FIXME!!
711      */
712     r_idx = 0;
713     /* FIXME:  Need callj stuff here, and to check the howto entries to
714        be sure they are real for this architecture.  */
715     if (g->howto== &howto_reloc_callj) 
716     {
717       raw[7] = callj_mask + pcrel_mask + len_2;
718     }
719     else if (g->howto == &howto_reloc_pcrel24) 
720     {
721       raw[7] = pcrel_mask + len_2;
722     }
723     else if (g->howto == &howto_reloc_pcrel13) 
724     {
725       raw[7] = pcrel_mask + len_1;
726     }
727     else if (g->howto == &howto_reloc_abs32code) 
728     {
729       raw[7] = len_2 + incode_mask;
730     }
731     else if (g->howto >= howto_align_table
732              && g->howto <= (howto_align_table
733                             + sizeof (howto_align_table) / sizeof (howto_align_table[0])
734                             - 1))
735       {
736         /* symnum == -2; extern_mask not set, pcrel_mask set */
737         r_idx = -2;
738         r_extern = 0;
739         raw[7] = (pcrel_mask
740                   | ((g->howto - howto_align_table) << 1));
741       }
742     else {
743       raw[7] = len_2;
744     }
745
746     if (r_idx != 0)
747       /* already mucked with r_extern, r_idx */;
748     else if (bfd_is_com_section (output_section)
749              || output_section == &bfd_abs_section
750              || output_section == &bfd_und_section) 
751     {
752
753       if (bfd_abs_section.symbol == sym)
754       {
755         /* Whoops, looked like an abs symbol, but is really an offset
756            from the abs section */
757         r_idx = 0;
758         r_extern = 0;
759        }
760       else 
761       {
762         /* Fill in symbol */
763
764         r_extern = 1;
765         r_idx =  stoi((*(g->sym_ptr_ptr))->flags);
766       }
767     }
768     else 
769     {
770       /* Just an ordinary section */
771       r_extern = 0;
772       r_idx  = output_section->target_index;      
773     }
774
775     if (abfd->xvec->header_byteorder_big_p) {
776       raw[4] = (unsigned char) (r_idx >> 16);
777       raw[5] = (unsigned char) (r_idx >>  8);
778       raw[6] = (unsigned char) (r_idx     );
779     } else {
780       raw[6] = (unsigned char) (r_idx >> 16);
781       raw[5] = (unsigned char) (r_idx>>  8);
782       raw[4] = (unsigned char) (r_idx     );
783     }  
784     if (r_extern)
785      raw[7] |= extern_mask; 
786   }
787
788   if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
789     free((PTR)native);
790     return false;
791   }
792   free ((PTR)native);
793
794   return true;
795 }
796
797 /* This is stupid.  This function should be a boolean predicate */
798 static unsigned int
799 b_out_canonicalize_reloc (abfd, section, relptr, symbols)
800      bfd *abfd;
801      sec_ptr section;
802      arelent **relptr;
803      asymbol **symbols;
804 {
805   arelent *tblptr = section->relocation;
806   unsigned int count = 0;
807
808  if (!(tblptr || b_out_slurp_reloc_table (abfd, section, symbols))) return 0;
809   tblptr = section->relocation;
810  if (!tblptr) return 0;
811
812   for (; count++ < section->reloc_count;)
813     *relptr++ = tblptr++;
814
815   *relptr = 0;
816
817   return section->reloc_count;
818 }
819
820 static unsigned int
821 b_out_get_reloc_upper_bound (abfd, asect)
822      bfd *abfd;
823      sec_ptr asect;
824 {
825   if (bfd_get_format (abfd) != bfd_object) {
826     bfd_error = invalid_operation;
827     return 0;
828   }
829
830   if (asect == obj_datasec (abfd))
831     return (sizeof (arelent *) *
832             ((exec_hdr(abfd)->a_drsize / sizeof (struct relocation_info))
833              +1));
834
835   if (asect == obj_textsec (abfd))
836     return (sizeof (arelent *) *
837             ((exec_hdr(abfd)->a_trsize / sizeof (struct relocation_info))
838              +1));
839
840   bfd_error = invalid_operation;
841   return 0;
842 }
843 \f
844 static boolean
845 b_out_set_section_contents (abfd, section, location, offset, count)
846      bfd *abfd;
847      sec_ptr section;
848      unsigned char *location;
849      file_ptr offset;
850       int count;
851 {
852
853   if (abfd->output_has_begun == false) { /* set by bfd.c handler */
854     if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL) /*||
855         (obj_textsec (abfd)->_cooked_size == 0) || (obj_datasec (abfd)->_cooked_size == 0)*/) {
856       bfd_error = invalid_operation;
857       return false;
858     }
859
860     obj_textsec (abfd)->filepos = sizeof(struct internal_exec);
861     obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos 
862                                  +  obj_textsec (abfd)->_raw_size;
863
864   }
865   /* regardless, once we know what we're doing, we might as well get going */
866   bfd_seek (abfd, section->filepos + offset, SEEK_SET);
867
868   if (count != 0) {
869     return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false;
870   }
871   return true;
872 }
873
874 static boolean
875 b_out_set_arch_mach (abfd, arch, machine)
876      bfd *abfd;
877      enum bfd_architecture arch;
878      unsigned long machine;
879 {
880   bfd_default_set_arch_mach(abfd, arch, machine);
881
882   if (arch == bfd_arch_unknown) /* Unknown machine arch is OK */
883     return true;
884   if (arch == bfd_arch_i960)    /* i960 default is OK */
885     switch (machine) {
886     case bfd_mach_i960_core:
887     case bfd_mach_i960_kb_sb:
888     case bfd_mach_i960_mc:
889     case bfd_mach_i960_xa:
890     case bfd_mach_i960_ca:
891     case bfd_mach_i960_ka_sa:
892     case 0:
893       return true;
894     default:
895       return false;
896     }
897
898   return false;
899 }
900
901 static int 
902 DEFUN(b_out_sizeof_headers,(ignore_abfd, ignore),
903       bfd *ignore_abfd AND
904       boolean ignore)
905 {
906   return sizeof(struct internal_exec);
907 }
908
909
910
911 /************************************************************************/
912 static bfd_vma 
913 DEFUN(get_value,(reloc, seclet),
914       arelent  *reloc AND
915       bfd_seclet_type *seclet)
916 {
917   bfd_vma value;
918   asymbol *symbol = *(reloc->sym_ptr_ptr);
919
920   /* A symbol holds a pointer to a section, and an offset from the
921      base of the section.  To relocate, we find where the section will
922      live in the output and add that in */
923
924   if (symbol->section == &bfd_und_section)
925   {
926     /* Ouch, this is an undefined symbol.. */
927     bfd_error_vector.undefined_symbol(reloc, seclet);
928     value = symbol->value;
929   }
930   else 
931   {
932     value = symbol->value +
933      symbol->section->output_offset +
934       symbol->section->output_section->vma;
935   }
936
937   /* Add the value contained in the relocation */
938   value += (short)((reloc->addend) & 0xffff);
939   
940   return value;
941 }
942
943 static void
944 DEFUN(perform_slip,(s, slip, input_section, value),
945       asymbol **s AND
946       unsigned int slip AND
947       asection *input_section AND
948       bfd_vma value)
949 {
950   
951   /* Find all symbols past this point, and make them know
952      what's happened */
953   while (*s) 
954   {
955     asymbol *p = *s;
956     if (p->section == input_section) 
957     {
958       /* This was pointing into this section, so mangle it */
959       if (p->value > value)
960       {
961         p->value -=slip;
962       }
963     }
964     s++;
965         
966   }    
967 }
968 #if 1
969 /* This routine works out if the thing we want to get to can be
970    reached with a 24bit offset instead of a 32 bit one.
971    If it can, then it changes the amode */
972
973 static int 
974 DEFUN(abs32code,(input_section, symbols, r, shrink),
975       asection *input_section AND
976       asymbol **symbols AND
977       arelent *r AND
978       unsigned int shrink) 
979 {
980   bfd_vma value = get_value(r,0);
981   bfd_vma dot = input_section->output_section->vma +  input_section->output_offset + r->address;        
982   bfd_vma gap;
983   
984   /* See if the address we're looking at within 2^23 bytes of where
985      we are, if so then we can use a small branch rather than the
986      jump we were going to */
987
988   gap = value - (dot - shrink);
989   
990
991   if (-1<<23 < (long)gap && (long)gap < 1<<23 )
992   { 
993     /* Change the reloc type from 32bitcode possible 24, to 24bit
994        possible 32 */
995
996     r->howto = &howto_reloc_abs32codeshrunk;
997     /* The place to relc moves back by four bytes */
998     r->address -=4;
999           
1000     /* This will be four bytes smaller in the long run */
1001     shrink += 4 ;
1002     perform_slip(symbols, 4, input_section, r->address-shrink +4);
1003   }      
1004   return shrink;      
1005 }
1006
1007 static int 
1008 DEFUN(aligncode,(input_section, symbols, r, shrink),
1009       asection *input_section AND
1010       asymbol **symbols AND
1011       arelent *r AND
1012       unsigned int shrink) 
1013 {
1014   bfd_vma dot = input_section->output_section->vma +  input_section->output_offset + r->address;        
1015   bfd_vma gap;
1016   bfd_vma old_end;
1017   bfd_vma new_end;
1018   int shrink_delta;
1019   int size = r->howto->size;
1020
1021   /* Reduce the size of the alignment so that it's still aligned but
1022      smaller  - the current size is already the same size as or bigger
1023      than the alignment required.  */
1024
1025   /* calculate the first byte following the padding before we optimize */
1026   old_end = ((dot + size ) & ~size) + size+1;
1027   /* work out where the new end will be - remember that we're smaller
1028      than we used to be */
1029   new_end = ((dot - shrink + size) & ~size);
1030
1031   /* This is the new end */
1032   gap = old_end - ((dot + size) & ~size);
1033
1034   shrink_delta = (old_end - new_end) - shrink;
1035
1036   if (shrink_delta)
1037   { 
1038     /* Change the reloc so that it knows how far to align to */
1039     r->howto = howto_done_align_table + (r->howto - howto_align_table);
1040
1041     /* Encode the stuff into the addend - for future use we need to
1042        know how big the reloc used to be */
1043     r->addend = old_end ;
1044
1045     /* This will be N bytes smaller in the long run, adjust all the symbols */
1046     perform_slip(symbols, shrink_delta, input_section, r->address - shrink );
1047     shrink += shrink_delta;
1048   }      
1049   return shrink;      
1050 }
1051
1052
1053 static boolean 
1054 DEFUN(b_out_relax_section,(abfd, i, symbols),
1055       bfd *abfd AND
1056       asection *i AND
1057       asymbol **symbols)
1058 {
1059   
1060   /* Get enough memory to hold the stuff */
1061   bfd *input_bfd = i->owner;
1062   asection *input_section = i;
1063   int shrink = 0 ;
1064   boolean new = false;
1065   
1066   bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
1067                                                        input_section);
1068   arelent **reloc_vector = (arelent **)alloca(reloc_size);
1069
1070   /* Get the relocs and think about them */
1071   if (bfd_canonicalize_reloc(input_bfd, 
1072                              input_section,
1073                              reloc_vector,
1074                              symbols))
1075   {
1076     arelent **parent;
1077     for (parent = reloc_vector; *parent; parent++) 
1078     {
1079       arelent *r = *parent;
1080       switch (r->howto->type) {
1081        case ALIGNER:
1082         /* An alignment reloc */
1083         shrink = aligncode(input_section, symbols, r,shrink);
1084         new=true;
1085         break;
1086        case ABS32CODE:
1087         /* A 32bit reloc in an addressing mode */
1088         shrink = abs32code(input_section, symbols, r,shrink);
1089         new=true;
1090         break;
1091        case ABS32CODE_SHRUNK:
1092         shrink+=4;
1093         break;
1094       }
1095     }
1096   }
1097   input_section->_cooked_size = input_section->_raw_size - shrink;  
1098
1099   return new;
1100 }
1101
1102 #endif
1103 static bfd_byte *
1104 DEFUN(b_out_get_relocated_section_contents,(in_abfd,
1105                                             seclet,
1106                                             data,
1107                                             relocateable),
1108       bfd *in_abfd AND
1109       bfd_seclet_type *seclet AND
1110       bfd_byte *data AND
1111       boolean relocateable)
1112 {
1113   /* Get enough memory to hold the stuff */
1114   bfd *input_bfd = seclet->u.indirect.section->owner;
1115   asection *input_section = seclet->u.indirect.section;
1116   bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
1117                                                        input_section);
1118   arelent **reloc_vector = (arelent **)alloca(reloc_size);
1119   
1120   /* If producing relocateable output, don't bother to relax.  */
1121   if (relocateable)
1122     return bfd_generic_get_relocated_section_contents (in_abfd, seclet,
1123                                                        data, relocateable);
1124
1125   /* read in the section */
1126   bfd_get_section_contents(input_bfd,
1127                            input_section,
1128                            data,
1129                            0,
1130                            input_section->_raw_size);
1131   
1132   
1133   if (bfd_canonicalize_reloc(input_bfd, 
1134                              input_section,
1135                              reloc_vector,
1136                              seclet->u.indirect.symbols) )
1137   {
1138     arelent **parent = reloc_vector;
1139     arelent *reloc ;
1140     
1141
1142
1143     unsigned int dst_address = 0;
1144     unsigned int src_address = 0;
1145     unsigned int run;
1146     unsigned int idx;
1147     
1148     /* Find how long a run we can do */
1149     while (dst_address < seclet->size) 
1150     {
1151       
1152       reloc = *parent;
1153       if (reloc) 
1154       {
1155         /* Note that the relaxing didn't tie up the addresses in the
1156            relocation, so we use the original address to work out the
1157            run of non-relocated data */
1158         run = reloc->address - src_address;
1159         parent++;
1160         
1161       }
1162       else 
1163       {
1164         run = seclet->size - dst_address;
1165       }
1166       /* Copy the bytes */
1167       for (idx = 0; idx < run; idx++)
1168       {
1169         data[dst_address++] = data[src_address++];
1170       }
1171     
1172       /* Now do the relocation */
1173     
1174       if (reloc) 
1175       {
1176         switch (reloc->howto->type) 
1177         {
1178          case ABS32CODE:
1179           calljx_callback(in_abfd, reloc, src_address + data, dst_address+data,
1180                           input_section, seclet);
1181           src_address+=4;
1182           dst_address+=4;
1183           break;
1184          case ABS32:
1185           bfd_put_32(in_abfd, get_value(reloc, seclet), data+dst_address);
1186           src_address+=4;
1187           dst_address+=4;
1188           break;
1189          case CALLJ:
1190           callj_callback(in_abfd, reloc ,data,src_address,dst_address,
1191                          input_section, seclet);
1192           src_address+=4;
1193           dst_address+=4;
1194           break;
1195          case ALIGNDONE:
1196           src_address = reloc->addend;
1197           dst_address = (dst_address + reloc->howto->size) & ~reloc->howto->size;
1198           break;
1199          case ABS32CODE_SHRUNK: 
1200           /* This used to be a callx, but we've found out that a
1201              callj will reach, so do the right thing */
1202           callj_callback(in_abfd, reloc,data,src_address+4, dst_address,
1203                          input_section, seclet);
1204
1205           dst_address+=4;
1206           src_address+=8;
1207           break;
1208          case PCREL24:
1209          {
1210            long int word = bfd_get_32(in_abfd, data+src_address);
1211            asymbol *symbol = *(reloc->sym_ptr_ptr);
1212            if (symbol->section == &bfd_und_section)
1213            {
1214              bfd_error_vector.undefined_symbol(reloc, seclet);
1215            }
1216            word = (word & ~BAL_MASK) |
1217             (((word & BAL_MASK) +
1218               symbol->section->output_offset +
1219               symbol->section->output_section->vma+
1220               symbol->value + reloc->addend - dst_address -
1221               ( input_section->output_section->vma + input_section->output_offset))
1222              & BAL_MASK);
1223
1224            bfd_put_32(in_abfd,word,  data+dst_address);
1225            dst_address+=4;
1226            src_address+=4;
1227
1228          }
1229           break;
1230
1231          case PCREL13:
1232          {
1233            long int word = bfd_get_32(in_abfd, data+src_address);
1234            asymbol *symbol = *(reloc->sym_ptr_ptr);
1235            if (symbol->section == &bfd_und_section)
1236            {
1237              bfd_error_vector.undefined_symbol(reloc, seclet);
1238            }
1239            word = (word & ~PCREL13_MASK) |
1240             (((word & PCREL13_MASK) +
1241               symbol->section->output_offset +
1242               symbol->section->output_section->vma+
1243               symbol->value + reloc->addend - dst_address -
1244               ( input_section->output_section->vma + input_section->output_offset))
1245              & PCREL13_MASK);
1246
1247            bfd_put_32(in_abfd,word,  data+dst_address);
1248            dst_address+=4;
1249            src_address+=4;
1250
1251          }
1252           break;
1253
1254          default:
1255
1256           abort();
1257         }
1258       }    
1259     }
1260   }
1261   return data;
1262 }
1263 /***********************************************************************/
1264
1265 /* Build the transfer vectors for Big and Little-Endian B.OUT files.  */
1266
1267 /* We don't have core files.  */
1268 #define aout_32_core_file_failing_command _bfd_dummy_core_file_failing_command
1269 #define aout_32_core_file_failing_signal _bfd_dummy_core_file_failing_signal
1270 #define aout_32_core_file_matches_executable_p  \
1271                                 _bfd_dummy_core_file_matches_executable_p
1272
1273 /* We use BSD-Unix generic archive files.  */
1274 #define aout_32_openr_next_archived_file        bfd_generic_openr_next_archived_file
1275 #define aout_32_generic_stat_arch_elt   bfd_generic_stat_arch_elt
1276 #define aout_32_slurp_armap             bfd_slurp_bsd_armap
1277 #define aout_32_slurp_extended_name_table       bfd_true
1278 #define aout_32_write_armap             bsd_write_armap
1279 #define aout_32_truncate_arname         bfd_bsd_truncate_arname
1280
1281 /* We override these routines from the usual a.out file routines.  */
1282 #define aout_32_canonicalize_reloc      b_out_canonicalize_reloc
1283 #define aout_32_get_reloc_upper_bound   b_out_get_reloc_upper_bound
1284 #define aout_32_set_section_contents    b_out_set_section_contents
1285 #define aout_32_set_arch_mach           b_out_set_arch_mach
1286 #define aout_32_sizeof_headers          b_out_sizeof_headers
1287
1288 #define aout_32_bfd_debug_info_start            bfd_void
1289 #define aout_32_bfd_debug_info_end              bfd_void
1290 #define aout_32_bfd_debug_info_accumulate       (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
1291
1292 #define aout_32_bfd_get_relocated_section_contents  b_out_get_relocated_section_contents
1293 #define aout_32_bfd_relax_section                   b_out_relax_section
1294 #define aout_32_bfd_seclet_link                     bfd_generic_seclet_link
1295
1296 bfd_target b_out_vec_big_host =
1297 {
1298   "b.out.big",                  /* name */
1299   bfd_target_aout_flavour,
1300   false,                        /* data byte order is little */
1301   true,                         /* hdr byte order is big */
1302   (HAS_RELOC | EXEC_P |         /* object flags */
1303    HAS_LINENO | HAS_DEBUG |
1304    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
1305   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1306   '_',                          /* symbol leading char */
1307   ' ',                          /* ar_pad_char */
1308   16,                           /* ar_max_namelen */
1309   2,                            /* minumum alignment power */
1310
1311   _do_getl64, _do_putl64,  _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
1312   _do_getb64, _do_putb64,  _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
1313  {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
1314    bfd_generic_archive_p, _bfd_dummy_target},
1315  {bfd_false, b_out_mkobject,    /* bfd_set_format */
1316    _bfd_generic_mkarchive, bfd_false},
1317  {bfd_false, b_out_write_object_contents, /* bfd_write_contents */
1318    _bfd_write_archive_contents, bfd_false},
1319
1320   JUMP_TABLE(aout_32),
1321   b_out_reloc_type_lookup,
1322 };
1323
1324
1325 bfd_target b_out_vec_little_host =
1326 {
1327   "b.out.little",               /* name */
1328   bfd_target_aout_flavour,
1329   false,                        /* data byte order is little */
1330   false,                        /* header byte order is little */
1331   (HAS_RELOC | EXEC_P |         /* object flags */
1332    HAS_LINENO | HAS_DEBUG |
1333    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
1334   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1335     '_',                        /* symbol leading char */
1336   ' ',                          /* ar_pad_char */
1337   16,                           /* ar_max_namelen */
1338      2,                         /* minum align */
1339 _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
1340 _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* hdrs */
1341          
1342     {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
1343        bfd_generic_archive_p, _bfd_dummy_target},
1344     {bfd_false, b_out_mkobject, /* bfd_set_format */
1345        _bfd_generic_mkarchive, bfd_false},
1346     {bfd_false, b_out_write_object_contents,    /* bfd_write_contents */
1347        _bfd_write_archive_contents, bfd_false},
1348   JUMP_TABLE(aout_32),
1349   b_out_reloc_type_lookup,
1350 };