* bout.c: added support for relaxable alignment relocs.
authorSteve Chamberlain <sac@cygnus>
Thu, 27 Aug 1992 00:35:09 +0000 (00:35 +0000)
committerSteve Chamberlain <sac@cygnus>
Thu, 27 Aug 1992 00:35:09 +0000 (00:35 +0000)
* seclet.c (rel, seclet_dump_seclet, seclet_dump): get the app to
pass down pointer to play area rather than use alloca

bfd/ChangeLog
bfd/bout.c
bfd/seclet.c

index 4860dc85dd53bf76a48663924afa06ed2899941f..eae58422945b18549824d74012d9db9c5749f0cc 100644 (file)
@@ -1,5 +1,10 @@
 Wed Aug 26 14:20:16 1992  Steve Chamberlain  (sac@thepub.cygnus.com)
 
+       * bout.c: added support for relaxable alignment relocs.
+
+       * seclet.c (rel, seclet_dump_seclet, seclet_dump): get the app to
+       pass down pointer to play area rather than use alloca
+
        * cpu-z8k.c (compatible): made static to reduce name space
        polution.
 
index 25ab2a75e7f1e2a6ad8dfb2d05ffbf642c4ebecd..dcabc7798c26e6e006854865fb3df147f73acc9f 100644 (file)
@@ -371,6 +371,8 @@ DEFUN (callj_callback, (abfd, reloc_entry,  data, srcidx,dstidx, input_section),
 #define ABS32_MAYBE_RELAXABLE 1
 #define ABS32_WAS_RELAXABLE 2
 
+#define ALIGN 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 +390,21 @@ 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 (ALIGN, 0, 0x1, 0, 0, 0, 0, 0, 0, "align16", 0, 0, 0, 0),
+  HOWTO (ALIGN, 0, 0x3, 0, 0, 0, 0, 0, 0, "align32", 0, 0, 0, 0),
+  HOWTO (ALIGN, 0, 0x7, 0, 0, 0, 0, 0, 0, "align64", 0, 0, 0, 0),
+  HOWTO (ALIGN, 0, 0xf, 0, 0, 0, 0, 0, 0, "align128", 0, 0, 0, 0),
+};
+
+static reloc_howto_type howto_done_align_table[] = {
+  HOWTO (ALIGNDONE, 0x1, 0x1, 0, 0, 0, 0, 0, 0, "donealign16", 0, 0, 0,0),
+  HOWTO (ALIGNDONE, 0x3, 0x3, 0, 0, 0, 0, 0, 0, "donealign32", 0, 0, 0,0),
+  HOWTO (ALIGNDONE, 0x7, 0x7, 0, 0, 0, 0, 0, 0, "donealign64", 0, 0, 0,0),
+  HOWTO (ALIGNDONE, 0xf, 0xf, 0, 0, 0, 0, 0, 0, "donealign128", 0, 0, 0,0),
+
+};
+
 static reloc_howto_type *
 b_out_reloc_type_lookup (abfd, code)
      bfd *abfd;
@@ -417,7 +434,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;
@@ -474,6 +491,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 +499,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;
@@ -516,8 +535,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 +565,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 +587,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;
     }
@@ -579,7 +620,7 @@ b_out_slurp_reloc_table (abfd, asect, symbols)
       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--;
@@ -888,7 +929,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 +942,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;
   
@@ -932,6 +971,60 @@ DEFUN(abs32code,(input_section, symbols, r, shrink),
   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 value = get_value(r,0);
+       
+
+  bfd_vma dot = input_section->output_section->vma +  input_section->output_offset + r->address;       
+  bfd_vma gap;
+  bfd_vma this_dot;
+  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;      
+}
+
 
 static boolean 
 DEFUN(b_out_relax_section,(abfd, i, symbols),
@@ -961,6 +1054,11 @@ DEFUN(b_out_relax_section,(abfd, i, symbols),
     {
       arelent *r = *parent;
       switch (r->howto->type) {
+       case ALIGN:
+       /* 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 +1075,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 +1158,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 +1183,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 +1202,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();
        }
index e7fb65cda88df2802e1b22869bbd310435ebe9e7..685653f0b90826eeef2d426b97cf8b593dd84ef4 100644 (file)
@@ -52,17 +52,17 @@ extern bfd_error_vector_type bfd_error_vector;
 
 
 void
-DEFUN(rel,(abfd, seclet, output_section),
+DEFUN(rel,(abfd, seclet, output_section, data),
       bfd *abfd AND
       bfd_seclet_type *seclet AND
-      asection *output_section)
+      asection *output_section AND
+      PTR data)
 {
 
   if (output_section->flags & SEC_HAS_CONTENTS 
       && !(output_section->flags & SEC_NEVER_LOAD)
       && seclet->size)
   {
-    bfd_byte *data = (bfd_byte *)alloca(seclet->size);
     data = bfd_get_relocated_section_contents(abfd, seclet, data);
     if(bfd_set_section_contents(abfd,
                                output_section,
@@ -72,22 +72,22 @@ DEFUN(rel,(abfd, seclet, output_section),
     {
       abort();
     }
-
   }
 }
 
 void
-DEFUN(seclet_dump_seclet,(abfd, seclet, section),
+DEFUN(seclet_dump_seclet,(abfd, seclet, section, data),
       bfd *abfd AND
       bfd_seclet_type *seclet AND
-      asection *section)
+      asection *section AND
+      PTR data)
 {
   switch (seclet->type) 
   {
    case bfd_indirect_seclet:
     /* The contents of this section come from another one somewhere
        else */
-    rel(abfd, seclet, section);
+    rel(abfd, seclet, section, data);
     break;
    case bfd_fill_seclet:
     /* Fill in the section with us */
@@ -110,8 +110,9 @@ DEFUN(seclet_dump_seclet,(abfd, seclet, section),
 }
 
 void
-DEFUN(seclet_dump,(abfd),
-      bfd *abfd)
+DEFUN(seclet_dump,(abfd, data),
+      bfd *abfd AND
+      PTR data)
 {
   /* Write all the seclets on the bfd out, relocate etc according to the
      rules */
@@ -122,7 +123,7 @@ DEFUN(seclet_dump,(abfd),
     bfd_seclet_type *p = o->seclets_head;
     while (p != (bfd_seclet_type *)NULL) 
     {
-      seclet_dump_seclet(abfd, p, o);
+      seclet_dump_seclet(abfd, p, o, data);
       p = p ->next;
     }
     o = o->next;
This page took 0.033108 seconds and 4 git commands to generate.