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