* libbfd-in.h, bfd-in.h: Eliminate all PROTO calls, replace with
[deliverable/binutils-gdb.git] / bfd / bout.c
index 25ab2a75e7f1e2a6ad8dfb2d05ffbf642c4ebecd..8ab69c23cb38e9bc44c9024612fc9dfd4a13a3b8 100644 (file)
@@ -238,21 +238,20 @@ b_out_write_object_contents (abfd)
 
   bout_swap_exec_header_out (abfd, exec_hdr (abfd), &swapped_hdr);
 
-  bfd_seek (abfd, 0L, SEEK_SET);
+  bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
   bfd_write ((PTR) &swapped_hdr, 1, EXEC_BYTES_SIZE, abfd);
 
   /* Now write out reloc info, followed by syms and strings */
   if (bfd_get_symcount (abfd) != 0) 
     {
-      bfd_seek (abfd,
-               (long)(N_SYMOFF(*exec_hdr(abfd))), SEEK_SET);
+      bfd_seek (abfd, (file_ptr)(N_SYMOFF(*exec_hdr(abfd))), SEEK_SET);
 
       aout_32_write_syms (abfd);
 
-      bfd_seek (abfd,  (long)(N_TROFF(*exec_hdr(abfd))), SEEK_SET);
+      bfd_seek (abfd, (file_ptr)(N_TROFF(*exec_hdr(abfd))), SEEK_SET);
 
       if (!b_out_squirt_out_relocs (abfd, obj_textsec (abfd))) return false;
-      bfd_seek (abfd, (long)(N_DROFF(*exec_hdr(abfd))), SEEK_SET);
+      bfd_seek (abfd, (file_ptr)(N_DROFF(*exec_hdr(abfd))), SEEK_SET);
 
       if (!b_out_squirt_out_relocs (abfd, obj_datasec (abfd))) return false;
     }
@@ -371,6 +370,8 @@ DEFUN (callj_callback, (abfd, reloc_entry,  data, srcidx,dstidx, input_section),
 #define ABS32_MAYBE_RELAXABLE 1
 #define ABS32_WAS_RELAXABLE 2
 
+#define ALIGNER 10
+#define ALIGNDONE 11
 static reloc_howto_type howto_reloc_callj =
 HOWTO(CALLJ, 0, 2, 24, true, 0, true, true, 0,"callj", true, 0x00ffffff, 0x00ffffff,false);
 static  reloc_howto_type howto_reloc_abs32 =
@@ -388,6 +389,20 @@ HOWTO(ABS32CODE_SHRUNK, 0, 2, 24, true, 0, true, true, 0,"callx->callj", true, 0
 static  reloc_howto_type howto_reloc_abs32code =
 HOWTO(ABS32CODE, 0, 2, 32, false, 0, true, true,0,"callx", true, 0xffffffff,0xffffffff,false);
 
+static reloc_howto_type howto_align_table[] = {
+  HOWTO (ALIGNER, 0, 0x1, 0, false, 0, false, false, 0, "align16", false, 0, 0, false),
+  HOWTO (ALIGNER, 0, 0x3, 0, false, 0, false, false, 0, "align32", false, 0, 0, false),
+  HOWTO (ALIGNER, 0, 0x7, 0, false, 0, false, false, 0, "align64", false, 0, 0, false),
+  HOWTO (ALIGNER, 0, 0xf, 0, false, 0, false, false, 0, "align128", false, 0, 0, false),
+};
+
+static reloc_howto_type howto_done_align_table[] = {
+  HOWTO (ALIGNDONE, 0x1, 0x1, 0, false, 0, false, false, 0, "donealign16", false, 0, 0, false),
+  HOWTO (ALIGNDONE, 0x3, 0x3, 0, false, 0, false, false, 0, "donealign32", false, 0, 0, false),
+  HOWTO (ALIGNDONE, 0x7, 0x7, 0, false, 0, false, false, 0, "donealign64", false, 0, 0, false),
+  HOWTO (ALIGNDONE, 0xf, 0xf, 0, false, 0, false, false, 0, "donealign128", false, 0, 0, false),
+};
+
 static reloc_howto_type *
 b_out_reloc_type_lookup (abfd, code)
      bfd *abfd;
@@ -417,7 +432,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
   register struct relocation_info *rptr;
   unsigned int counter ;
   arelent *cache_ptr ;
-  int extern_mask, pcrel_mask, callj_mask;
+  int extern_mask, pcrel_mask, callj_mask, length_shift;
   int incode_mask;
   int size_mask;
   bfd_vma prev_addr = 0;
@@ -443,7 +458,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
   return false;
 
  doit:
-  bfd_seek (abfd, (long)(asect->rel_filepos),  SEEK_SET);
+  bfd_seek (abfd, (file_ptr)(asect->rel_filepos),  SEEK_SET);
   count = reloc_size / sizeof (struct relocation_info);
 
   relocs = (struct relocation_info *) bfd_xmalloc (reloc_size);
@@ -474,6 +489,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
     incode_mask = 0x08;
     callj_mask  = 0x02;
     size_mask =   0x20;
+    length_shift = 5;
   } else {
     /* little-endian bit field allocation order */
     pcrel_mask  = 0x01;
@@ -481,6 +497,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
     incode_mask = 0x10;
     callj_mask  = 0x40;
     size_mask   = 0x02;
+    length_shift = 1;
   }
 
   for (rptr = relocs, cache_ptr = reloc_cache, counter = 0;
@@ -490,6 +507,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
     unsigned char *raw = (unsigned char *)rptr;
     unsigned int symnum;
     cache_ptr->address = bfd_h_get_32 (abfd, raw + 0);
+    cache_ptr->howto = 0;
     if (abfd->xvec->header_byteorder_big_p) 
     {
       symnum = (raw[4] << 16) | (raw[5] << 8) | raw[6];
@@ -516,8 +534,15 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
        * the reloc entry addend has added to it the offset into the
        * file of the data, so subtract the base to make the reloc
        * section relative */
+      int s;
+      {
+       /* sign-extend symnum from 24 bits to whatever host uses */
+       s = symnum;
+       if (s & (1 << 23))
+         s |= (~0) << 24;
+      }
       cache_ptr->sym_ptr_ptr = (asymbol **)NULL;
-      switch (symnum) 
+      switch (s)
       {
        case N_TEXT:
        case N_TEXT | N_EXT:
@@ -539,6 +564,19 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
        cache_ptr->sym_ptr_ptr = obj_bsssec(abfd)->symbol_ptr_ptr;
        cache_ptr->addend = 0;
        break;
+      case -2: /* .align */
+       if (raw[7] & pcrel_mask)
+         {
+           cache_ptr->howto = &howto_align_table[(raw[7] >> length_shift) & 3];
+           cache_ptr->sym_ptr_ptr = &bfd_abs_symbol;
+         }
+       else
+         {
+           /* .org? */
+           abort ();
+         }
+       cache_ptr->addend = 0;
+       break;
        default:
        BFD_ASSERT(0);
        break;
@@ -548,7 +586,9 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
 
     /* the i960 only has a few relocation types:
        abs 32-bit and pcrel 24bit.   except for callj's!  */
-    if (raw[7] & callj_mask)
+    if (cache_ptr->howto != 0)
+      ;
+    else if (raw[7] & callj_mask)
     {
       cache_ptr->howto = &howto_reloc_callj;
     }
@@ -576,10 +616,9 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
        */
       arelent tmp;
       arelent *cursor = cache_ptr-1;
-      unsigned int where = counter;
       bfd_vma stop = cache_ptr->address;
       tmp  = *cache_ptr;
-      while (cursor->address > stop)
+      while (cursor->address > stop && cursor >= reloc_cache)
       {
        cursor[1] = cursor[0];
        cursor--;
@@ -611,21 +650,19 @@ b_out_squirt_out_relocs (abfd, section)
   arelent **generic;
   int r_extern;
   int r_idx;
-  int r_addend;
   int incode_mask;  
   int len_1;
   unsigned int count = section->reloc_count;
   struct relocation_info *native, *natptr;
   size_t natsize = count * sizeof (struct relocation_info);
   int extern_mask, pcrel_mask,  len_2, callj_mask;
-  int len1;
   if (count == 0) return true;
   generic   = section->orelocation;
   native = ((struct relocation_info *) bfd_xmalloc (natsize));
   if (!native) {
-      bfd_error = no_memory;
-      return false;
-    }
+    bfd_error = no_memory;
+    return false;
+  }
 
   if (abfd->xvec->header_byteorder_big_p) 
   {
@@ -637,7 +674,7 @@ b_out_squirt_out_relocs (abfd, section)
     callj_mask  = 0x02;
     incode_mask = 0x08;
   } 
-else 
+  else 
   {
     /* Little-endian bit field allocation order */
     pcrel_mask  = 0x01;
@@ -678,15 +715,27 @@ else
       raw[7] = len_2 + incode_mask;
     }
     else {
-       raw[7] = len_2;
-      }
+      raw[7] = len_2;
+    }
     if (output_section == &bfd_com_section 
        || output_section == &bfd_abs_section
        || output_section == &bfd_und_section) 
     {
-      /* Fill in symbol */
-      r_extern = 1;
-      r_idx =  stoi((*(g->sym_ptr_ptr))->flags);
+
+      if (bfd_abs_section.symbol == sym)
+      {
+       /* Whoops, looked like an abs symbol, but is really an offset
+          from the abs section */
+       r_idx = 0;
+       r_extern = 0;
+       }
+      else 
+      {
+       /* Fill in symbol */
+
+       r_extern = 1;
+       r_idx =  stoi((*(g->sym_ptr_ptr))->flags);
+      }
     }
     else 
     {
@@ -696,22 +745,22 @@ else
     }
 
     if (abfd->xvec->header_byteorder_big_p) {
-       raw[4] = (unsigned char) (r_idx >> 16);
-       raw[5] = (unsigned char) (r_idx >>  8);
-       raw[6] = (unsigned char) (r_idx     );
-      } else {
-         raw[6] = (unsigned char) (r_idx >> 16);
-         raw[5] = (unsigned char) (r_idx>>  8);
-         raw[4] = (unsigned char) (r_idx     );
-       }  
-if (r_extern)
-    raw[7] |= extern_mask; 
+      raw[4] = (unsigned char) (r_idx >> 16);
+      raw[5] = (unsigned char) (r_idx >>  8);
+      raw[6] = (unsigned char) (r_idx     );
+    } else {
+      raw[6] = (unsigned char) (r_idx >> 16);
+      raw[5] = (unsigned char) (r_idx>>  8);
+      raw[4] = (unsigned char) (r_idx     );
+    }  
+    if (r_extern)
+     raw[7] |= extern_mask; 
   }
 
   if (bfd_write ((PTR) native, 1, natsize, abfd) != natsize) {
-      free((PTR)native);
-      return false;
-    }
+    free((PTR)native);
+    return false;
+  }
   free ((PTR)native);
 
   return true;
@@ -839,6 +888,7 @@ DEFUN(get_value,(reloc, seclet),
 {
   bfd_vma value;
   asymbol *symbol = *(reloc->sym_ptr_ptr);
+
   /* A symbol holds a pointer to a section, and an offset from the
      base of the section.  To relocate, we find where the section will
      live in the output and add that in */
@@ -855,8 +905,7 @@ DEFUN(get_value,(reloc, seclet),
      symbol->section->output_offset +
       symbol->section->output_section->vma;
   }
-  
-  
+
   /* Add the value contained in the relocation */
   value += (short)((reloc->addend) & 0xffff);
   
@@ -888,7 +937,7 @@ DEFUN(perform_slip,(s, slip, input_section, value),
        
   }    
 }
-
+#if 1
 /* This routine works out if the thing we want to get to can be
    reached with a 24bit offset instead of a 32 bit one.
    If it can, then it changes the amode */
@@ -901,8 +950,6 @@ DEFUN(abs32code,(input_section, symbols, r, shrink),
       unsigned int shrink) 
 {
   bfd_vma value = get_value(r,0);
-       
-       
   bfd_vma dot = input_section->output_section->vma +  input_section->output_offset + r->address;       
   bfd_vma gap;
   
@@ -915,7 +962,6 @@ DEFUN(abs32code,(input_section, symbols, r, shrink),
 
   if (-1<<23 < (long)gap && (long)gap < 1<<23 )
   { 
-
     /* Change the reloc type from 32bitcode possible 24, to 24bit
        possible 32 */
 
@@ -926,8 +972,51 @@ DEFUN(abs32code,(input_section, symbols, r, shrink),
     /* This will be four bytes smaller in the long run */
     shrink += 4 ;
     perform_slip(symbols, 4, input_section, r->address-shrink +4);
+  }      
+  return shrink;      
+}
 
-         
+static int 
+DEFUN(aligncode,(input_section, symbols, r, shrink),
+      asection *input_section AND
+      asymbol **symbols AND
+      arelent *r AND
+      unsigned int shrink) 
+{
+  bfd_vma dot = input_section->output_section->vma +  input_section->output_offset + r->address;       
+  bfd_vma gap;
+  bfd_vma old_end;
+  bfd_vma new_end;
+  int shrink_delta;
+  int size = r->howto->size;
+
+  /* Reduce the size of the alignment so that it's still aligned but
+     smaller  - the current size is already the same size as or bigger
+     than the alignment required.  */
+
+  /* calculate the first byte following the padding before we optimize */
+  old_end = ((dot + size ) & ~size) + size+1;
+  /* work out where the new end will be - remember that we're smaller
+     than we used to be */
+  new_end = ((dot - shrink + size) & ~size);
+
+  /* This is the new end */
+  gap = old_end - ((dot + size) & ~size);
+
+  shrink_delta = (old_end - new_end) - shrink;
+
+  if (shrink_delta)
+  { 
+    /* Change the reloc so that it knows how far to align to */
+    r->howto = howto_done_align_table + (r->howto - howto_align_table);
+
+    /* Encode the stuff into the addend - for future use we need to
+       know how big the reloc used to be */
+    r->addend = old_end ;
+
+    /* This will be N bytes smaller in the long run, adjust all the symbols */
+    perform_slip(symbols, shrink_delta, input_section, r->address - shrink );
+    shrink += shrink_delta;
   }      
   return shrink;      
 }
@@ -961,6 +1050,11 @@ DEFUN(b_out_relax_section,(abfd, i, symbols),
     {
       arelent *r = *parent;
       switch (r->howto->type) {
+       case ALIGNER:
+       /* An alignment reloc */
+       shrink = aligncode(input_section, symbols, r,shrink);
+       new=true;
+       break;
        case ABS32CODE:
        /* A 32bit reloc in an addressing mode */
        shrink = abs32code(input_section, symbols, r,shrink);
@@ -977,6 +1071,7 @@ DEFUN(b_out_relax_section,(abfd, i, symbols),
   return new;
 }
 
+#endif
 static bfd_byte *
 DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data),
       bfd *in_abfd AND
@@ -1059,6 +1154,10 @@ DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data),
          src_address+=4;
          dst_address+=4;
          break;
+        case ALIGNDONE:
+         src_address = reloc->addend;
+         dst_address = (dst_address + reloc->howto->size) & ~reloc->howto->size;
+         break;
         case ABS32CODE_SHRUNK: 
          /* This used to be a callx, but we've found out that a
             callj will reach, so do the right thing */
@@ -1080,11 +1179,11 @@ DEFUN(b_out_get_relocated_section_contents,(in_abfd, seclet, data),
             & BAL_MASK);
 
           bfd_put_32(in_abfd,word,  data+dst_address);
-         dst_address+=4;
-         src_address+=4;
+          dst_address+=4;
+          src_address+=4;
 
         }
-break;
+         break;
 
         case PCREL13:
         {
@@ -1099,13 +1198,13 @@ break;
             & PCREL13_MASK);
 
           bfd_put_32(in_abfd,word,  data+dst_address);
-         dst_address+=4;
-         src_address+=4;
+          dst_address+=4;
+          src_address+=4;
 
         }
-break;
+         break;
 
-       default:
+        default:
 
          abort();
        }
@@ -1156,18 +1255,19 @@ bfd_target b_out_vec_big_host =
    HAS_LINENO | HAS_DEBUG |
    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+  '_',                         /* symbol leading char */
   ' ',                         /* ar_pad_char */
   16,                          /* ar_max_namelen */
-     2,                                /* minumum alignment power */
+  2,                           /* minumum alignment power */
 
-_do_getl64, _do_putl64,  _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
-_do_getb64, _do_putb64,  _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
   {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
-       bfd_generic_archive_p, _bfd_dummy_target},
   {bfd_false, b_out_mkobject,        /* bfd_set_format */
-       _bfd_generic_mkarchive, bfd_false},
   {bfd_false, b_out_write_object_contents,   /* bfd_write_contents */
-       _bfd_write_archive_contents, bfd_false},
+  _do_getl64, _do_putl64,  _do_getl32, _do_putl32, _do_getl16, _do_putl16, /* data */
+  _do_getb64, _do_putb64,  _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
+ {_bfd_dummy_target, b_out_object_p, /* bfd_check_format */
+   bfd_generic_archive_p, _bfd_dummy_target},
{bfd_false, b_out_mkobject,   /* bfd_set_format */
+   _bfd_generic_mkarchive, bfd_false},
{bfd_false, b_out_write_object_contents, /* bfd_write_contents */
+   _bfd_write_archive_contents, bfd_false},
 
   JUMP_TABLE(aout_32),
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,        /* COFF stuff?! */
@@ -1185,6 +1285,7 @@ bfd_target b_out_vec_little_host =
    HAS_LINENO | HAS_DEBUG |
    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT ),
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
+    '_',                       /* symbol leading char */
   ' ',                         /* ar_pad_char */
   16,                          /* ar_max_namelen */
      2,                                /* minum align */
This page took 0.029993 seconds and 4 git commands to generate.