* aout-adobe.c, aoutf1.h, archive.c, bout.c, coff-rs6000.c,
[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
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),
272        bfd *abfd AND
273        arelent *reloc_entry AND
274        PTR src AND
275        PTR dst AND
276
277        asection *input_section)
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 (IS_CALLNAME(symbol->other)) 
284   {
285
286     aout_symbol_type *balsym = symbol+1;
287     int inst = bfd_get_32(abfd, (bfd_byte *) src-4);
288     /* The next symbol should be an N_BALNAME */
289     BFD_ASSERT(IS_BALNAME(balsym->other));
290     inst &= BAL_MASK;
291     inst |= BALX;
292     bfd_put_32(abfd, inst, (bfd_byte *) dst-4);
293     symbol = balsym;
294   }
295
296     word += symbol->symbol.section->output_offset +
297      symbol->symbol.section->output_section->vma +
298       symbol->symbol.value + reloc_entry->addend;
299
300   bfd_put_32(abfd, word, dst);
301   return bfd_reloc_ok;
302 }
303
304
305 /* Magic to turn call into callj */
306 static bfd_reloc_status_type 
307 DEFUN (callj_callback, (abfd, reloc_entry,  data, srcidx,dstidx, input_section),
308        bfd *abfd AND
309        arelent *reloc_entry AND
310        PTR data AND
311        unsigned int srcidx AND
312        unsigned int dstidx AND
313        asection *input_section )
314 {
315   int  word = bfd_get_32(abfd, (bfd_byte *) data + srcidx);
316   asymbol *symbol_in = *(reloc_entry->sym_ptr_ptr);
317
318   aout_symbol_type  *symbol = aout_symbol(symbol_in);
319
320   if (IS_OTHER(symbol->other)) 
321   {
322     /* Call to a system procedure - replace code with system
323        procedure number */
324     word = CALLS | (symbol->other - 1);
325
326   }
327
328   else  if (IS_CALLNAME(symbol->other)) 
329   {
330     aout_symbol_type *balsym = symbol+1;
331     /* The next symbol should be an N_BALNAME */
332     BFD_ASSERT(IS_BALNAME(balsym->other));
333
334     /* We are calling a leaf - so replace the call instruction
335        with a bal */
336
337     word = BAL |
338      (((word & BAL_MASK) +
339        balsym->symbol.section->output_offset +
340        balsym->symbol.section->output_section->vma+
341        balsym->symbol.value + reloc_entry->addend - dstidx -
342        ( input_section->output_section->vma + input_section->output_offset))
343       & BAL_MASK);
344
345
346   }
347   else 
348   {
349
350     word = CALL |
351      (((word & BAL_MASK) + 
352        symbol->symbol.section->output_offset +
353        symbol->symbol.section->output_section->vma+
354        symbol->symbol.value + reloc_entry->addend - dstidx -
355        ( input_section->output_section->vma + input_section->output_offset))
356       & BAL_MASK);
357   }
358   bfd_put_32(abfd, word, (bfd_byte *) data + dstidx);
359   return bfd_reloc_ok;
360 }
361
362 /* type rshift size  bitsize    pcrel   bitpos  absolute overflow check*/
363
364 #define ABS32CODE 0
365 #define ABS32CODE_SHRUNK 1 
366 #define PCREL24 2
367 #define CALLJ 3
368 #define ABS32 4
369 #define PCREL13 5
370 #define ABS32_MAYBE_RELAXABLE 1
371 #define ABS32_WAS_RELAXABLE 2
372
373 #define ALIGNER 10
374 #define ALIGNDONE 11
375 static reloc_howto_type howto_reloc_callj =
376 HOWTO(CALLJ, 0, 2, 24, true, 0, true, true, 0,"callj", true, 0x00ffffff, 0x00ffffff,false);
377 static  reloc_howto_type howto_reloc_abs32 =
378 HOWTO(ABS32, 0, 2, 32, false, 0, true, true,0,"abs32", true, 0xffffffff,0xffffffff,false);
379 static reloc_howto_type howto_reloc_pcrel24 =
380 HOWTO(PCREL24, 0, 2, 24, true, 0, true, true,0,"pcrel24", true, 0x00ffffff,0x00ffffff,false);
381
382 static reloc_howto_type howto_reloc_pcrel13 =
383 HOWTO(PCREL13, 0, 2, 13, true, 0, true, true,0,"pcrel13", true, 0x00001fff,0x00001fff,false);
384
385
386 static reloc_howto_type howto_reloc_abs32codeshrunk = 
387 HOWTO(ABS32CODE_SHRUNK, 0, 2, 24, true, 0, true, true, 0,"callx->callj", true, 0x00ffffff, 0x00ffffff,false);
388
389 static  reloc_howto_type howto_reloc_abs32code =
390 HOWTO(ABS32CODE, 0, 2, 32, false, 0, true, true,0,"callx", true, 0xffffffff,0xffffffff,false);
391
392 static reloc_howto_type howto_align_table[] = {
393   HOWTO (ALIGNER, 0, 0x1, 0, false, 0, false, false, 0, "align16", false, 0, 0, false),
394   HOWTO (ALIGNER, 0, 0x3, 0, false, 0, false, false, 0, "align32", false, 0, 0, false),
395   HOWTO (ALIGNER, 0, 0x7, 0, false, 0, false, false, 0, "align64", false, 0, 0, false),
396   HOWTO (ALIGNER, 0, 0xf, 0, false, 0, false, false, 0, "align128", false, 0, 0, false),
397 };
398
399 static reloc_howto_type howto_done_align_table[] = {
400   HOWTO (ALIGNDONE, 0x1, 0x1, 0, false, 0, false, false, 0, "donealign16", false, 0, 0, false),
401   HOWTO (ALIGNDONE, 0x3, 0x3, 0, false, 0, false, false, 0, "donealign32", false, 0, 0, false),
402   HOWTO (ALIGNDONE, 0x7, 0x7, 0, false, 0, false, false, 0, "donealign64", false, 0, 0, false),
403   HOWTO (ALIGNDONE, 0xf, 0xf, 0, false, 0, false, false, 0, "donealign128", false, 0, 0, false),
404 };
405
406 static reloc_howto_type *
407 b_out_reloc_type_lookup (abfd, code)
408      bfd *abfd;
409      bfd_reloc_code_real_type code;
410 {
411   switch (code)
412     {
413     default:
414       return 0;
415     case BFD_RELOC_I960_CALLJ:
416       return &howto_reloc_callj;
417     case BFD_RELOC_32:
418       return &howto_reloc_abs32;
419     case BFD_RELOC_24_PCREL:
420       return &howto_reloc_pcrel24;
421     }
422 }
423
424 /* Allocate enough room for all the reloc entries, plus pointers to them all */
425
426 static boolean
427 b_out_slurp_reloc_table (abfd, asect, symbols)
428      bfd *abfd;
429      sec_ptr asect;
430      asymbol **symbols;
431 {
432   register struct relocation_info *rptr;
433   unsigned int counter ;
434   arelent *cache_ptr ;
435   int extern_mask, pcrel_mask, callj_mask, length_shift;
436   int incode_mask;
437   int size_mask;
438   bfd_vma prev_addr = 0;
439   unsigned int count;
440   size_t  reloc_size;
441   struct relocation_info *relocs;
442   arelent *reloc_cache;
443
444   if (asect->relocation) return true;
445   if (!aout_32_slurp_symbol_table (abfd)) return false;
446
447   if (asect == obj_datasec (abfd)) {
448     reloc_size = exec_hdr(abfd)->a_drsize;
449     goto doit;
450   }
451
452   if (asect == obj_textsec (abfd)) {
453     reloc_size = exec_hdr(abfd)->a_trsize;
454     goto doit;
455   }
456
457   bfd_error = invalid_operation;
458   return false;
459
460  doit:
461   bfd_seek (abfd, (file_ptr)(asect->rel_filepos),  SEEK_SET);
462   count = reloc_size / sizeof (struct relocation_info);
463
464   relocs = (struct relocation_info *) bfd_xmalloc (reloc_size);
465   if (!relocs) {
466     bfd_error = no_memory;
467     return false;
468   }
469   reloc_cache = (arelent *) bfd_xmalloc ((count+1) * sizeof (arelent));
470   if (!reloc_cache) {
471     free ((char*)relocs);
472     bfd_error = no_memory;
473     return false;
474   }
475
476   if (bfd_read ((PTR) relocs, 1, reloc_size, abfd) != reloc_size) {
477     bfd_error = system_call_error;
478     free (reloc_cache);
479     free (relocs);
480     return false;
481   }
482
483
484   
485   if (abfd->xvec->header_byteorder_big_p) {
486     /* big-endian bit field allocation order */
487     pcrel_mask  = 0x80;
488     extern_mask = 0x10;
489     incode_mask = 0x08;
490     callj_mask  = 0x02;
491     size_mask =   0x20;
492     length_shift = 5;
493   } else {
494     /* little-endian bit field allocation order */
495     pcrel_mask  = 0x01;
496     extern_mask = 0x08;
497     incode_mask = 0x10;
498     callj_mask  = 0x40;
499     size_mask   = 0x02;
500     length_shift = 1;
501   }
502
503   for (rptr = relocs, cache_ptr = reloc_cache, counter = 0;
504        counter < count;
505        counter++, rptr++, cache_ptr++) 
506   {
507     unsigned char *raw = (unsigned char *)rptr;
508     unsigned int symnum;
509     cache_ptr->address = bfd_h_get_32 (abfd, raw + 0);
510     cache_ptr->howto = 0;
511     if (abfd->xvec->header_byteorder_big_p) 
512     {
513       symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6];
514     } 
515     else
516     {
517       symnum = (raw[6] << 16) | (raw[5] << 8) | raw[4];
518     }
519
520     if (raw[7] & extern_mask) 
521     {
522       /* if this is set then the r_index is a index into the symbol table;
523        * if the bit is not set then r_index contains a section map.
524        * we either fill in the sym entry with a pointer to the symbol,
525        * or point to the correct section
526        */
527       cache_ptr->sym_ptr_ptr = symbols + symnum;
528       cache_ptr->addend = 0;
529     } else 
530     {
531       /* in a.out symbols are relative to the beginning of the
532        * file rather than sections ?
533        * (look in translate_from_native_sym_flags)
534        * the reloc entry addend has added to it the offset into the
535        * file of the data, so subtract the base to make the reloc
536        * section relative */
537       int s;
538       {
539         /* sign-extend symnum from 24 bits to whatever host uses */
540         s = symnum;
541         if (s & (1 << 23))
542           s |= (~0) << 24;
543       }
544       cache_ptr->sym_ptr_ptr = (asymbol **)NULL;
545       switch (s)
546       {
547        case N_TEXT:
548        case N_TEXT | N_EXT:
549         cache_ptr->sym_ptr_ptr = obj_textsec(abfd)->symbol_ptr_ptr;
550         cache_ptr->addend = - obj_textsec(abfd)->vma;
551         break;
552        case N_DATA:
553        case N_DATA | N_EXT:
554         cache_ptr->sym_ptr_ptr = obj_datasec(abfd)->symbol_ptr_ptr;
555         cache_ptr->addend = - obj_datasec(abfd)->vma;
556         break;
557        case N_BSS:
558        case N_BSS | N_EXT:
559         cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;
560         cache_ptr->addend =  - obj_bsssec(abfd)->vma;
561         break;
562        case N_ABS:
563        case N_ABS | N_EXT:
564         cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;
565         cache_ptr->addend = 0;
566         break;
567       case -2: /* .align */
568         if (raw[7] & pcrel_mask)
569           {
570             cache_ptr->howto = &howto_align_table[(raw[7] >> length_shift) & 3];
571             cache_ptr->sym_ptr_ptr = &bfd_abs_symbol;
572           }
573         else
574           {
575             /* .org? */
576             abort ();
577           }
578         cache_ptr->addend = 0;
579         break;
580        default:
581         BFD_ASSERT(0);
582         break;
583       }
584         
585     }
586
587     /* the i960 only has a few relocation types:
588        abs 32-bit and pcrel 24bit.   except for callj's!  */
589     if (cache_ptr->howto != 0)
590       ;
591     else if (raw[7] & callj_mask)
592     {
593       cache_ptr->howto = &howto_reloc_callj;
594     }
595     else if ( raw[7] & pcrel_mask)
596     {
597       if (raw[7] & size_mask)
598        cache_ptr->howto = &howto_reloc_pcrel13;
599       else
600        cache_ptr->howto = &howto_reloc_pcrel24;
601     }
602     else 
603     {
604       if (raw[7] & incode_mask) 
605       {
606         cache_ptr->howto = &howto_reloc_abs32code;
607       }
608       else 
609       {
610         cache_ptr->howto = &howto_reloc_abs32;
611       }
612     }
613     if (cache_ptr->address < prev_addr) 
614     {
615       /* Ouch! this reloc is out of order, insert into the right place
616        */
617       arelent tmp;
618       arelent *cursor = cache_ptr-1;
619       bfd_vma stop = cache_ptr->address;
620       tmp  = *cache_ptr;
621       while (cursor->address > stop && cursor >= reloc_cache)
622       {
623         cursor[1] = cursor[0];
624         cursor--;
625       } 
626       cursor[1] = tmp;
627     }
628     else 
629     {
630       prev_addr = cache_ptr->address;
631     }
632   }
633
634
635   free (relocs);
636   asect->relocation = reloc_cache;
637   asect->reloc_count = count;
638
639
640   return true;
641 }
642
643
644 static boolean
645 b_out_squirt_out_relocs (abfd, section)
646      bfd *abfd;
647      asection *section;
648 {
649
650   arelent **generic;
651   int r_extern;
652   int r_idx;
653   int incode_mask;  
654   int len_1;
655   unsigned int count = section->reloc_count;
656   struct relocation_info *native, *natptr;
657   size_t natsize = count * sizeof (struct relocation_info);
658   int extern_mask, pcrel_mask,  len_2, callj_mask;
659   if (count == 0) return true;
660   generic   = section->orelocation;
661   native = ((struct relocation_info *) bfd_xmalloc (natsize));
662   if (!native) {
663     bfd_error = no_memory;
664     return false;
665   }
666
667   if (abfd->xvec->header_byteorder_big_p) 
668   {
669     /* Big-endian bit field allocation order */
670     pcrel_mask  = 0x80;
671     extern_mask = 0x10;
672     len_2       = 0x40;
673     len_1       = 0x20;
674     callj_mask  = 0x02;
675     incode_mask = 0x08;
676   } 
677   else 
678   {
679     /* Little-endian bit field allocation order */
680     pcrel_mask  = 0x01;
681     extern_mask = 0x08;
682     len_2       = 0x04;
683     len_1       = 0x02;
684     callj_mask  = 0x40;
685     incode_mask = 0x10;
686   }
687
688   for (natptr = native; count > 0; --count, ++natptr, ++generic) 
689   {
690     arelent *g = *generic;
691     unsigned char *raw = (unsigned char *)natptr;
692     asymbol *sym = *(g->sym_ptr_ptr);
693       
694     asection *output_section = sym->section->output_section;
695     bfd_h_put_32(abfd, g->address, raw);  
696     /* Find a type in the output format which matches the input howto - 
697      * at the moment we assume input format == output format FIXME!!
698      */
699     /* FIXME:  Need callj stuff here, and to check the howto entries to
700        be sure they are real for this architecture.  */
701     if (g->howto== &howto_reloc_callj) 
702     {
703       raw[7] = callj_mask + pcrel_mask + len_2;
704     }
705     else if (g->howto == &howto_reloc_pcrel24) 
706     {
707       raw[7] = pcrel_mask + len_2;
708     }
709     else if (g->howto == &howto_reloc_pcrel13) 
710     {
711       raw[7] = pcrel_mask + len_1;
712     }
713     else if (g->howto == &howto_reloc_abs32code) 
714     {
715       raw[7] = len_2 + incode_mask;
716     }
717     else {
718       raw[7] = len_2;
719     }
720     if (output_section == &bfd_com_section 
721         || output_section == &bfd_abs_section
722         || output_section == &bfd_und_section) 
723     {
724
725       if (bfd_abs_section.symbol == sym)
726       {
727         /* Whoops, looked like an abs symbol, but is really an offset
728            from the abs section */
729         r_idx = 0;
730         r_extern = 0;
731        }
732       else 
733       {
734         /* Fill in symbol */
735
736         r_extern = 1;
737         r_idx =  stoi((*(g->sym_ptr_ptr))->flags);
738       }
739     }
740     else 
741     {
742       /* Just an ordinary section */
743       r_extern = 0;
744       r_idx  = output_section->target_index;      
745     }
746
747     if (abfd->xvec->header_byteorder_big_p) {
748       raw[4] = (unsigned char) (r_idx >> 16);
749       raw[5] = (unsigned char) (r_idx >>  8);
750       raw[6] = (unsigned char) (r_idx     );
751     } else {
752       raw[6] = (unsigned char) (r_idx >> 16);
753       raw[5] = (unsigned char) (r_idx>>  8);
754       raw[4] = (unsigned char) (r_idx     );
755     }  
756     if (r_extern)
757      raw[7] |= extern_mask; 
758   }
759
760   if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
761     free((PTR)native);
762     return false;
763   }
764   free ((PTR)native);
765
766   return true;
767 }
768
769 /* This is stupid.  This function should be a boolean predicate */
770 static unsigned int
771 b_out_canonicalize_reloc (abfd, section, relptr, symbols)
772      bfd *abfd;
773      sec_ptr section;
774      arelent **relptr;
775      asymbol **symbols;
776 {
777   arelent *tblptr = section->relocation;
778   unsigned int count = 0;
779
780  if (!(tblptr || b_out_slurp_reloc_table (abfd, section, symbols))) return 0;
781   tblptr = section->relocation;
782  if (!tblptr) return 0;
783
784   for (; count++ < section->reloc_count;)
785     *relptr++ = tblptr++;
786
787   *relptr = 0;
788
789   return section->reloc_count;
790 }
791
792 static unsigned int
793 b_out_get_reloc_upper_bound (abfd, asect)
794      bfd *abfd;
795      sec_ptr asect;
796 {
797   if (bfd_get_format (abfd) != bfd_object) {
798     bfd_error = invalid_operation;
799     return 0;
800   }
801
802   if (asect == obj_datasec (abfd))
803     return (sizeof (arelent *) *
804             ((exec_hdr(abfd)->a_drsize / sizeof (struct relocation_info))
805              +1));
806
807   if (asect == obj_textsec (abfd))
808     return (sizeof (arelent *) *
809             ((exec_hdr(abfd)->a_trsize / sizeof (struct relocation_info))
810              +1));
811
812   bfd_error = invalid_operation;
813   return 0;
814 }
815 \f
816 static boolean
817 b_out_set_section_contents (abfd, section, location, offset, count)
818      bfd *abfd;
819      sec_ptr section;
820      unsigned char *location;
821      file_ptr offset;
822       int count;
823 {
824
825   if (abfd->output_has_begun == false) { /* set by bfd.c handler */
826     if ((obj_textsec (abfd) == NULL) || (obj_datasec (abfd) == NULL) /*||
827         (obj_textsec (abfd)->_cooked_size == 0) || (obj_datasec (abfd)->_cooked_size == 0)*/) {
828       bfd_error = invalid_operation;
829       return false;
830     }
831
832     obj_textsec (abfd)->filepos = sizeof(struct internal_exec);
833     obj_datasec(abfd)->filepos = obj_textsec(abfd)->filepos 
834                                  +  obj_textsec (abfd)->_raw_size;
835
836   }
837   /* regardless, once we know what we're doing, we might as well get going */
838   bfd_seek (abfd, section->filepos + offset, SEEK_SET);
839
840   if (count != 0) {
841     return (bfd_write ((PTR)location, 1, count, abfd) == count) ?true:false;
842   }
843   return true;
844 }
845
846 static boolean
847 b_out_set_arch_mach (abfd, arch, machine)
848      bfd *abfd;
849      enum bfd_architecture arch;
850      unsigned long machine;
851 {
852   bfd_default_set_arch_mach(abfd, arch, machine);
853
854   if (arch == bfd_arch_unknown) /* Unknown machine arch is OK */
855     return true;
856   if (arch == bfd_arch_i960)    /* i960 default is OK */
857     switch (machine) {
858     case bfd_mach_i960_core:
859     case bfd_mach_i960_kb_sb:
860     case bfd_mach_i960_mc:
861     case bfd_mach_i960_xa:
862     case bfd_mach_i960_ca:
863     case bfd_mach_i960_ka_sa:
864     case 0:
865       return true;
866     default:
867       return false;
868     }
869
870   return false;
871 }
872
873 static int 
874 DEFUN(b_out_sizeof_headers,(ignore_abfd, ignore),
875       bfd *ignore_abfd AND
876       boolean ignore)
877 {
878   return sizeof(struct internal_exec);
879 }
880
881
882
883 /************************************************************************/
884 static bfd_vma 
885 DEFUN(get_value,(reloc, seclet),
886       arelent  *reloc AND
887       bfd_seclet_type *seclet)
888 {
889   bfd_vma value;
890   asymbol *symbol = *(reloc->sym_ptr_ptr);
891   /* A symbol holds a pointer to a section, and an offset from the
892      base of the section.  To relocate, we find where the section will
893      live in the output and add that in */
894
895   if (symbol->section == &bfd_und_section)
896   {
897     /* Ouch, this is an undefined symbol.. */
898     bfd_error_vector.undefined_symbol(reloc, seclet);
899     value = symbol->value;
900   }
901   else 
902   {
903     value = symbol->value +
904      symbol->section->output_offset +
905       symbol->section->output_section->vma;
906   }
907   
908   
909   /* Add the value contained in the relocation */
910   value += (short)((reloc->addend) & 0xffff);
911   
912   return value;
913 }
914
915 static void
916 DEFUN(perform_slip,(s, slip, input_section, value),
917       asymbol **s AND
918       unsigned int slip AND
919       asection *input_section AND
920       bfd_vma value)
921 {
922   
923   /* Find all symbols past this point, and make them know
924      what's happened */
925   while (*s) 
926   {
927     asymbol *p = *s;
928     if (p->section == input_section) 
929     {
930       /* This was pointing into this section, so mangle it */
931       if (p->value > value)
932       {
933         p->value -=slip;
934       }
935     }
936     s++;
937         
938   }    
939 }
940 #if 1
941 /* This routine works out if the thing we want to get to can be
942    reached with a 24bit offset instead of a 32 bit one.
943    If it can, then it changes the amode */
944
945 static int 
946 DEFUN(abs32code,(input_section, symbols, r, shrink),
947       asection *input_section AND
948       asymbol **symbols AND
949       arelent *r AND
950       unsigned int shrink) 
951 {
952   bfd_vma value = get_value(r,0);
953   bfd_vma dot = input_section->output_section->vma +  input_section->output_offset + r->address;        
954   bfd_vma gap;
955   
956   /* See if the address we're looking at within 2^23 bytes of where
957      we are, if so then we can use a small branch rather than the
958      jump we were going to */
959
960   gap = value - (dot - shrink);
961   
962
963   if (-1<<23 < (long)gap && (long)gap < 1<<23 )
964   { 
965
966     /* Change the reloc type from 32bitcode possible 24, to 24bit
967        possible 32 */
968
969     r->howto = &howto_reloc_abs32codeshrunk;
970     /* The place to relc moves back by four bytes */
971     r->address -=4;
972           
973     /* This will be four bytes smaller in the long run */
974     shrink += 4 ;
975     perform_slip(symbols, 4, input_section, r->address-shrink +4);
976
977           
978   }      
979   return shrink;      
980 }
981
982 static int 
983 DEFUN(aligncode,(input_section, symbols, r, shrink),
984       asection *input_section AND
985       asymbol **symbols AND
986       arelent *r AND
987       unsigned int shrink) 
988 {
989   bfd_vma value = get_value(r,0);
990
991   bfd_vma dot = input_section->output_section->vma +  input_section->output_offset + r->address;        
992   bfd_vma gap;
993   bfd_vma old_end;
994   bfd_vma new_end;
995     int shrink_delta;
996 int size = r->howto->size;
997   /* Reduce the size of the alignment so that it's still aligned but
998      smaller  - the current size is already the same size as or bigger
999      than the alignment required.  */
1000
1001
1002
1003   /* calculate the first byte following the padding before we optimize */
1004   old_end = ((dot + size ) & ~size) + size+1;
1005   /* work out where the new end will be - remember that we're smaller
1006      than we used to be */
1007   new_end = ((dot - shrink + size) & ~size);
1008
1009   /* This is the new end */
1010   gap = old_end - ((dot + size) & ~size);
1011
1012   shrink_delta = (old_end - new_end) - shrink;
1013
1014   if (shrink_delta)
1015   { 
1016
1017     /* Change the reloc so that it knows how far to align to */
1018     r->howto = howto_done_align_table + (r->howto - howto_align_table);
1019
1020     /* Encode the stuff into the addend - for future use we need to
1021        know how big the reloc used to be */
1022     r->addend = old_end ;
1023
1024     /* This will be N bytes smaller in the long run, adjust all the symbols */
1025
1026     
1027
1028     perform_slip(symbols, shrink_delta, input_section, r->address - shrink );
1029     shrink += shrink_delta;
1030   }      
1031   return shrink;      
1032 }
1033
1034
1035 static boolean 
1036 DEFUN(b_out_relax_section,(abfd, i, symbols),
1037       bfd *abfd AND
1038       asection *i AND
1039       asymbol **symbols)
1040 {
1041   
1042   /* Get enough memory to hold the stuff */
1043   bfd *input_bfd = i->owner;
1044   asection *input_section = i;
1045   int shrink = 0 ;
1046   boolean new = false;
1047   
1048   bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
1049                                                        input_section);
1050   arelent **reloc_vector = (arelent **)alloca(reloc_size);
1051
1052   /* Get the relocs and think about them */
1053   if (bfd_canonicalize_reloc(input_bfd, 
1054                              input_section,
1055                              reloc_vector,
1056                              symbols))
1057   {
1058     arelent **parent;
1059     for (parent = reloc_vector; *parent; parent++) 
1060     {
1061       arelent *r = *parent;
1062       switch (r->howto->type) {
1063        case ALIGNER:
1064         /* An alignment reloc */
1065         shrink = aligncode(input_section, symbols, r,shrink);
1066         new=true;
1067         break;
1068        case ABS32CODE:
1069         /* A 32bit reloc in an addressing mode */
1070         shrink = abs32code(input_section, symbols, r,shrink);
1071         new=true;
1072         break;
1073        case ABS32CODE_SHRUNK:
1074         shrink+=4;
1075         break;
1076       }
1077     }
1078   }
1079   input_section->_cooked_size = input_section->_raw_size - shrink;  
1080
1081   return new;
1082 }
1083
1084 #endif
1085 static bfd_byte *
1086 DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data),
1087       bfd *in_abfd AND
1088       bfd_seclet_type *seclet AND
1089       bfd_byte *data)
1090
1091 {
1092   /* Get enough memory to hold the stuff */
1093   bfd *input_bfd = seclet->u.indirect.section->owner;
1094   asection *input_section = seclet->u.indirect.section;
1095   bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
1096                                                        input_section);
1097   arelent **reloc_vector = (arelent **)alloca(reloc_size);
1098   
1099   /* read in the section */
1100   bfd_get_section_contents(input_bfd,
1101                            input_section,
1102                            data,
1103                            0,
1104                            input_section->_raw_size);
1105   
1106   
1107   if (bfd_canonicalize_reloc(input_bfd, 
1108                              input_section,
1109                              reloc_vector,
1110                              seclet->u.indirect.symbols) )
1111   {
1112     arelent **parent = reloc_vector;
1113     arelent *reloc ;
1114     
1115
1116
1117     unsigned int dst_address = 0;
1118     unsigned int src_address = 0;
1119     unsigned int run;
1120     unsigned int idx;
1121     
1122     /* Find how long a run we can do */
1123     while (dst_address < seclet->size) 
1124     {
1125       
1126       reloc = *parent;
1127       if (reloc) 
1128       {
1129         /* Note that the relaxing didn't tie up the addresses in the
1130            relocation, so we use the original address to work out the
1131            run of non-relocated data */
1132         run = reloc->address - src_address;
1133         parent++;
1134         
1135       }
1136       else 
1137       {
1138         run = seclet->size - dst_address;
1139       }
1140       /* Copy the bytes */
1141       for (idx = 0; idx < run; idx++)
1142       {
1143         data[dst_address++] = data[src_address++];
1144       }
1145     
1146       /* Now do the relocation */
1147     
1148       if (reloc) 
1149       {
1150         switch (reloc->howto->type) 
1151         {
1152          case ABS32CODE:
1153           calljx_callback(in_abfd, reloc, src_address + data, dst_address+data, input_section);
1154           src_address+=4;
1155           dst_address+=4;
1156           break;
1157          case ABS32:
1158           bfd_put_32(in_abfd, get_value(reloc, seclet), data+dst_address);
1159           src_address+=4;
1160           dst_address+=4;
1161           break;
1162          case CALLJ:
1163           callj_callback(in_abfd, reloc ,data,src_address,dst_address,input_section);
1164           src_address+=4;
1165           dst_address+=4;
1166           break;
1167          case ALIGNDONE:
1168           src_address = reloc->addend;
1169           dst_address = (dst_address + reloc->howto->size) & ~reloc->howto->size;
1170           break;
1171          case ABS32CODE_SHRUNK: 
1172           /* This used to be a callx, but we've found out that a
1173              callj will reach, so do the right thing */
1174           callj_callback(in_abfd, reloc,data,src_address+4, dst_address,input_section);
1175
1176           dst_address+=4;
1177           src_address+=8;
1178           break;
1179          case PCREL24:
1180          {
1181            long int word = bfd_get_32(in_abfd, data+src_address);
1182            asymbol *symbol = *(reloc->sym_ptr_ptr);
1183            word = (word & ~BAL_MASK) |
1184             (((word & BAL_MASK) +
1185               symbol->section->output_offset +
1186               symbol->section->output_section->vma+
1187               symbol->value + reloc->addend - dst_address -
1188               ( input_section->output_section->vma + input_section->output_offset))
1189              & BAL_MASK);
1190
1191            bfd_put_32(in_abfd,word,  data+dst_address);
1192            dst_address+=4;
1193            src_address+=4;
1194
1195          }
1196           break;
1197
1198          case PCREL13:
1199          {
1200            long int word = bfd_get_32(in_abfd, data+src_address);
1201            asymbol *symbol = *(reloc->sym_ptr_ptr);
1202            word = (word & ~PCREL13_MASK) |
1203             (((word & PCREL13_MASK) +
1204               symbol->section->output_offset +
1205               symbol->section->output_section->vma+
1206               symbol->value + reloc->addend - dst_address -
1207               ( input_section->output_section->vma + input_section->output_offset))
1208              & PCREL13_MASK);
1209
1210            bfd_put_32(in_abfd,word,  data+dst_address);
1211            dst_address+=4;
1212            src_address+=4;
1213
1214          }
1215           break;
1216
1217          default:
1218
1219           abort();
1220         }
1221       }    
1222     }
1223   }
1224   return data;
1225 }
1226 /***********************************************************************/
1227
1228 /* Build the transfer vectors for Big and Little-Endian B.OUT files.  */
1229
1230 /* We don't have core files.  */
1231 #define aout_32_core_file_failing_command _bfd_dummy_core_file_failing_command
1232 #define aout_32_core_file_failing_signal _bfd_dummy_core_file_failing_signal
1233 #define aout_32_core_file_matches_executable_p  \
1234                                 _bfd_dummy_core_file_matches_executable_p
1235
1236 /* We use BSD-Unix generic archive files.  */
1237 #define aout_32_openr_next_archived_file        bfd_generic_openr_next_archived_file
1238 #define aout_32_generic_stat_arch_elt   bfd_generic_stat_arch_elt
1239 #define aout_32_slurp_armap             bfd_slurp_bsd_armap
1240 #define aout_32_slurp_extended_name_table       bfd_true
1241 #define aout_32_write_armap             bsd_write_armap
1242 #define aout_32_truncate_arname         bfd_bsd_truncate_arname
1243
1244 /* We override these routines from the usual a.out file routines.  */
1245 #define aout_32_canonicalize_reloc      b_out_canonicalize_reloc
1246 #define aout_32_get_reloc_upper_bound   b_out_get_reloc_upper_bound
1247 #define aout_32_set_section_contents    b_out_set_section_contents
1248 #define aout_32_set_arch_mach           b_out_set_arch_mach
1249 #define aout_32_sizeof_headers          b_out_sizeof_headers
1250
1251 #define aout_32_bfd_debug_info_start            bfd_void
1252 #define aout_32_bfd_debug_info_end              bfd_void
1253 #define aout_32_bfd_debug_info_accumulate       (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
1254
1255 #define aout_32_bfd_get_relocated_section_contents  b_out_get_relocated_section_contents
1256 #define aout_32_bfd_relax_section                   b_out_relax_section
1257
1258 bfd_target b_out_vec_big_host =
1259 {
1260   "b.out.big",                  /* name */
1261   bfd_target_aout_flavour,
1262   false,                        /* data byte order is little */
1263   true,                         /* hdr byte order is big */
1264   (HAS_RELOC | EXEC_P |         /* object flags */
1265    HAS_LINENO | HAS_DEBUG |
1266    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
1267   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1268   '_',                          /* symbol leading char */
1269   ' ',                          /* ar_pad_char */
1270   16,                           /* ar_max_namelen */
1271   2,                            /* minumum alignment power */
1272
1273   _do_getl64, _do_putl64,  _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
1274   _do_getb64, _do_putb64,  _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
1275  {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
1276    bfd_generic_archive_p, _bfd_dummy_target},
1277  {bfd_false, b_out_mkobject,    /* bfd_set_format */
1278    _bfd_generic_mkarchive, bfd_false},
1279  {bfd_false, b_out_write_object_contents, /* bfd_write_contents */
1280    _bfd_write_archive_contents, bfd_false},
1281
1282   JUMP_TABLE(aout_32),
1283   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* COFF stuff?! */
1284   b_out_reloc_type_lookup,
1285 };
1286
1287
1288 bfd_target b_out_vec_little_host =
1289 {
1290   "b.out.little",               /* name */
1291   bfd_target_aout_flavour,
1292   false,                        /* data byte order is little */
1293   false,                        /* header byte order is little */
1294   (HAS_RELOC | EXEC_P |         /* object flags */
1295    HAS_LINENO | HAS_DEBUG |
1296    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
1297   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1298     '_',                        /* symbol leading char */
1299   ' ',                          /* ar_pad_char */
1300   16,                           /* ar_max_namelen */
1301      2,                         /* minum align */
1302 _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
1303 _do_getl64, _do_putl64, _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* hdrs */
1304          
1305     {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
1306        bfd_generic_archive_p, _bfd_dummy_target},
1307     {bfd_false, b_out_mkobject, /* bfd_set_format */
1308        _bfd_generic_mkarchive, bfd_false},
1309     {bfd_false, b_out_write_object_contents,    /* bfd_write_contents */
1310        _bfd_write_archive_contents, bfd_false},
1311   JUMP_TABLE(aout_32),
1312   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* COFF stuff?! */
1313   b_out_reloc_type_lookup,
1314 };