New entry point in the transfer vector - bfd_relax_section.
authorSteve Chamberlain <sac@cygnus>
Tue, 28 Jan 1992 06:01:25 +0000 (06:01 +0000)
committerSteve Chamberlain <sac@cygnus>
Tue, 28 Jan 1992 06:01:25 +0000 (06:01 +0000)
* aout-target.h: add to vector, call generic_relax
* bfd-in.h: add to vector
* bfd.c: add #define for vector
* bout.c: add to vector, call generic_relax
* coffcode.h: add to vector, also now has coff specific relax code
for the relaxable H8/300 relocs. Also clean up abs section cruft.
* elf.c: call generic_relax
* ieee.c: call new vector, clean up some bugs due to the creation
of bfd_abs_section
* libbfd.h: add bfd_generic_relax_section EXFUN
* oasys.c: call generic_relax
* reloc.c: implement generic_relax
* seclet.c: moved much of this into coffcode.h
* srec.c: call generic_relax
* targets.c: define new transfer vector

bfd/ChangeLog
bfd/bfd.c
bfd/coffcode.h
bfd/seclet.c

index 2f73749756bd92ed3b85a2dc71d03d7cd636656d..f53aa5e1018070545f2e05f70354adec382cdea1 100644 (file)
@@ -1,3 +1,25 @@
+Mon Jan 27 19:44:08 1992  Steve Chamberlain  (sac at rtl.cygnus.com)
+
+       New entry point in the transfer vector - bfd_relax_section.
+
+       * aout-target.h: add to vector, call generic_relax
+       * bfd-in.h: add to vector
+       * bfd.c: add #define for vector
+       * bout.c: add to vector, call generic_relax
+       * coffcode.h: add to vector, also now has coff specific relax code
+       for the relaxable H8/300 relocs. Also clean up abs section cruft.
+       * elf.c: call generic_relax
+       * ieee.c: call new vector, clean up some bugs due to the creation
+       of bfd_abs_section
+       * libbfd.h: add bfd_generic_relax_section EXFUN
+       * oasys.c: call generic_relax
+       * reloc.c: implement generic_relax
+       * seclet.c: moved much of this into coffcode.h
+       * srec.c: call generic_relax
+       * targets.c: define new transfer vector
+
+       
+
 Fri Jan 24 14:40:17 1992  Steve Chamberlain  (sac at rtl.cygnus.com)
 
        * everything: now modified to use smaller reloc type. Self hosts
index 7d919da7c81faa063dfc35b8e7de0e703a841cc8..17574a3afefb0ebac01baabea42bd170d6d8f89b 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -573,6 +573,10 @@ DESCRIPTION
 .
 .#define bfd_get_relocated_section_contents(abfd, seclet) \
 .      BFD_SEND (abfd, _bfd_get_relocated_section_contents, (abfd, seclet))
+.
+.#define bfd_relax_section(abfd, section, symbols) \
+.       BFD_SEND (abfd, _bfd_relax_section, (abfd, section, symbols))
+
 */
 
 
index 3662269eccf7172d16ae1edefb644a1e78466507..7862f844cfbf799f2680ea7d9804460c4a8389b6 100644 (file)
@@ -18,6 +18,10 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+/* 
+Most of this hacked by  Steve Chamberlain,
+                       sac@cygnus.com 
+*/
 /*
 
 SECTION
@@ -256,7 +260,10 @@ CODE_FRAGMENT
 
 */
 
-/* Most of this hacked by Steve Chamberlain, steve@cygnus.com */
+#include "seclet.h"
+extern bfd_error_vector_type bfd_error_vector;
+
+
 
 
 #define PUTWORD bfd_h_put_32
@@ -882,11 +889,17 @@ DEFUN(coff_new_section_hook,(abfd_ignore, section),
   return true;
 }
 
+static asection bfd_debug_section = 
+{ "*DEBUG*" };
+
+
+
 static void
 DEFUN(make_abs_section,(abfd),
       bfd *abfd)
 {
-  abort();
+    
+
   
 }
 
@@ -965,7 +978,7 @@ DEFUN(coff_mkobject,(abfd),
     return false;
   }
   coff_data(abfd)->relocbase = 0;
-  make_abs_section(abfd);
+/*  make_abs_section(abfd);*/
   return true;
 }
 
@@ -1379,10 +1392,13 @@ DEFUN(coff_mangle_symbols,(bfd_ptr),
            if (a->fix_tag) {
              a->u.auxent.x_sym.x_tagndx.l =
                a->u.auxent.x_sym.x_tagndx.p->offset;
+             a->fix_tag = 0;
            }
            if (a->fix_end) {
              a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l =
                a->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p->offset;
+             a->fix_end = 0;
+             
            }
 
          }
@@ -1456,20 +1472,37 @@ unsigned int written)
   int             class =  native->u.syment.n_sclass;
   SYMENT buf;
   unsigned int j;
-  native->u.syment.n_scnum = symbol->section->output_section->target_index;
+  if (symbol->section == &bfd_abs_section) 
+  {
+    native->u.syment.n_scnum = N_ABS;
+  }
+  else if (symbol->section == &bfd_debug_section) 
+  {
+    native->u.syment.n_scnum = N_DEBUG;
+  }
+  else if (symbol->section == &bfd_und_section)   
+  {
+    native->u.syment.n_scnum = N_UNDEF;
+  }
+  else 
+  {
+    native->u.syment.n_scnum =
+     symbol->section->output_section->target_index;
+  }
+  
   
   coff_fix_symbol_name(abfd, symbol, native);
 
   coff_swap_sym_out(abfd, &native->u.syment, &buf);
   bfd_write((PTR)& buf, 1, SYMESZ, abfd);
   for (j = 0; j != native->u.syment.n_numaux;  j++)
-      {
-       AUXENT buf1;
-       bzero((PTR)&buf, AUXESZ);
-       coff_swap_aux_out(abfd,
-                        &( (native + j + 1)->u.auxent), type, class, &buf1);
-       bfd_write((PTR) (&buf1), 1, AUXESZ, abfd);
-      }
+  {
+    AUXENT buf1;
+    bzero((PTR)&buf, AUXESZ);
+    coff_swap_aux_out(abfd,
+                     &( (native + j + 1)->u.auxent), type, class, &buf1);
+    bfd_write((PTR) (&buf1), 1, AUXESZ, abfd);
+  }
   /*
     Reuse somewhere in the symbol to keep the index
     */
@@ -1496,7 +1529,8 @@ DEFUN(coff_write_alien_symbol,(abfd, symbol, written),
 #ifdef I960
   native->u.syment.n_flags =  0;
 #endif
-  if (symbol->section == &bfd_und_section) {
+  if (symbol->section == &bfd_und_section) 
+  {
       native->u.syment.n_scnum =  N_UNDEF;
       native->u.syment.n_value =  symbol->value;
     }
@@ -2033,7 +2067,7 @@ DEFUN(coff_compute_section_file_positions,(abfd),
       old_sofar= sofar;
       sofar = BFD_ALIGN(sofar, 1 << current->alignment_power);
       if (previous != (asection *)NULL) {
-         previous->_cooked_size += sofar - old_sofar;
+         previous->_raw_size += sofar - old_sofar;
        }
     }
 
@@ -2046,7 +2080,7 @@ DEFUN(coff_compute_section_file_positions,(abfd),
       current->filepos = sofar;
 
       /* make sure that this section is of the right size too */
-      old_sofar =  sofar += current->_cooked_size;
+      old_sofar =  sofar += current->_raw_size;
       sofar = BFD_ALIGN(sofar, 1 << current->alignment_power);
       current->_raw_size += sofar - old_sofar ;
 
@@ -2091,15 +2125,13 @@ DEFUN(coff_write_object_contents,(abfd),
   for (current = abfd->sections; current != (asection *)NULL; 
        current = current->next) 
   {
-    if (current->name[0] != '*') 
-    {
       current->target_index = count;
-      count++;
-    }
   }
   
     
 
+
+
   if(abfd->output_has_begun == false) {
       coff_compute_section_file_positions(abfd);
     }
@@ -2195,12 +2227,12 @@ DEFUN(coff_write_object_contents,(abfd),
        strncpy(&(section.s_name[0]), current->name, 8);
        section.s_vaddr = current->vma + pad;
        section.s_paddr = current->vma + pad;
-       section.s_size = current->_cooked_size - pad;
+       section.s_size = current->_raw_size - pad;
        /*
          If this section has no size or is unloadable then the scnptr
          will be 0 too
          */
-       if (current->_cooked_size - pad == 0 ||
+       if (current->_raw_size - pad == 0 ||
            (current->flags & SEC_LOAD) == 0) {
            section.s_scnptr = 0;
          }
@@ -2359,15 +2391,15 @@ DEFUN(coff_write_object_contents,(abfd),
     }
 #endif                         /* NO_COFF_SYMBOLS */
   if (text_sec) {
-      internal_a.tsize = bfd_get_section_size_after_reloc(text_sec);
+      internal_a.tsize = bfd_get_section_size_before_reloc(text_sec);
       internal_a.text_start = internal_a.tsize ? text_sec->vma : 0;
     }
   if (data_sec) {
-      internal_a.dsize = bfd_get_section_size_after_reloc(data_sec);
+      internal_a.dsize = bfd_get_section_size_before_reloc(data_sec);
       internal_a.data_start = internal_a.dsize ? data_sec->vma      : 0;
     }
   if (bss_sec) {
-      internal_a.bsize = bfd_get_section_size_after_reloc(bss_sec);
+      internal_a.bsize = bfd_get_section_size_before_reloc(bss_sec);
     }
 
   internal_a.entry = bfd_get_start_address(abfd);
@@ -2411,14 +2443,15 @@ combined_entry_type *auxent)
 
   /* Otherwise patch up */
   if (ISFCN(type) || ISTAG(class) || class == C_BLOCK) {
-    auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = table_base +
-      auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l;
-    auxent->fix_end = 1;
-  }
+      auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p = table_base +
+       auxent->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l;
+      auxent->fix_end = 1;
+    }
   if (auxent->u.auxent.x_sym.x_tagndx.l != 0) {
-    auxent->u.auxent.x_sym.x_tagndx.p = table_base +  auxent->u.auxent.x_sym.x_tagndx.l;
-    auxent->fix_tag = 1;
-  }
+      auxent->u.auxent.x_sym.x_tagndx.p =
+       table_base +  auxent->u.auxent.x_sym.x_tagndx.l;
+      auxent->fix_tag = 1;
+    }
 }
 
 #endif /* NO_COFF_SYMBOLS */
@@ -2753,6 +2786,20 @@ DEFUN(section_from_bfd_index,(abfd, index),
       int             index)
 {
   struct sec *answer = abfd->sections;
+
+  if (index == N_ABS) 
+  {
+    return &bfd_abs_section;
+  }
+  if (index == N_UNDEF)
+  {
+    return &bfd_und_section;
+  }
+  if(index == N_DEBUG)
+  {
+    return &bfd_debug_section;
+    
+  }
   
   while (answer) {
       if (answer->target_index == index)
@@ -3033,7 +3080,7 @@ DEFUN(coff_slurp_symbol_table,(abfd),
        break;
       }
 
-      BFD_ASSERT(dst->symbol.flags != 0);
+/*      BFD_ASSERT(dst->symbol.flags != 0);*/
 
       dst->native = src;
 
@@ -3446,6 +3493,384 @@ DEFUN(coff_sizeof_headers,(abfd, reloc),
     return size;
 }
 
+static bfd_vma 
+DEFUN(get_value,(reloc, seclet),
+      arelent  *reloc AND
+      bfd_seclet_type *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 */
+
+  if (symbol->section == &bfd_und_section)
+  {
+    /* Ouch, this is an undefined symbol.. */
+    bfd_error_vector.undefined_symbol(reloc, seclet);
+    value = symbol->value;
+  }
+  else 
+  {
+    value = symbol->value +
+     symbol->section->output_offset +
+      symbol->section->output_section->vma;
+  }
+  
+  
+  /* Add the value contained in the relocation */
+  value += (short)((reloc->addend) & 0xffff);
+  
+  return value;
+}
+
+static void
+DEFUN(perform_slip,(s, slip, input_section, value),
+      asymbol **s AND
+      unsigned int slip AND
+      asection *input_section AND
+      bfd_vma value)
+{
+  
+  /* Find all symbols past this point, and make them know
+     what's happened */
+  while (*s) 
+  {
+    asymbol *p = *s;
+    if (p->section == input_section) 
+    {
+      /* This was pointing into this section, so mangle it */
+      if (p->value > value)
+      {
+       p->value -=2;
+      }
+    }
+    s++;
+       
+  }    
+}
+static int 
+DEFUN(movb1,(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);
+       
+  if (value >= 0xff00)
+  { 
+
+    /* Change the reloc type from 16bit, possible 8 to 8bit
+       possible 16 */
+    r->howto = r->howto + 1;     
+    /* The place to relc moves back by one */
+    r->address -=1;
+         
+    /* This will be two bytes smaller in the long run */
+    shrink +=2 ;
+    perform_slip(symbols, 2, input_section, r->address - shrink +1);
+
+         
+  }      
+  return shrink;      
+}
+
+static int 
+DEFUN(jmp1,(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;
+  
+  /* See if the address we're looking at within 127 bytes of where
+     we are, if so then we can use a small branch rather than the
+     jump we were going to */
+
+  gap = value - (dot - shrink);
+  
+
+  if (-120 < (long)gap && (long)gap < 120 )
+  { 
+
+    /* Change the reloc type from 16bit, possible 8 to 8bit
+       possible 16 */
+    r->howto = r->howto + 1;     
+    /* The place to relc moves back by one */
+    r->address -=1;
+         
+    /* This will be two bytes smaller in the long run */
+    shrink +=2 ;
+    perform_slip(symbols, 2, input_section, r->address-shrink +1);
+
+         
+  }      
+  return shrink;      
+}
+
+extern boolean 
+DEFUN(bfd_coff_relax_section,(abfd, i, symbols, seclet),
+      bfd *abfd AND
+      asection *i AND
+      asymbol **symbols AND
+      bfd_seclet_type *seclet)
+{
+  
+  /* Get enough memory to hold the stuff */
+  bfd *input_bfd = i->owner;
+  asection *input_section = i;
+  int shrink = 0 ;
+  int new = 0;
+  
+  bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
+                                                      input_section);
+  arelent **reloc_vector = (arelent **)bfd_xmalloc(reloc_size);
+
+  /* Get the relocs and think about them */
+  if (bfd_canonicalize_reloc(input_bfd, 
+                            input_section,
+                            reloc_vector,
+                            symbols))
+  {
+    arelent **parent;
+    for (parent = reloc_vector; *parent; parent++) 
+    {
+      arelent *r = *parent;
+      switch (r->howto->type) {
+       case R_MOVB2:
+       case R_JMP2:
+         
+         shrink+=2;
+         break;
+         
+       case R_MOVB1:
+         shrink = movb1(input_section, symbols, r, shrink);
+         new = 1;
+         
+         break;
+       case R_JMP1:
+         shrink = jmp1(input_section, symbols, r, shrink);
+         new = 1;
+         
+         break;
+       }
+    }
+
+  }
+  input_section->_cooked_size -= shrink;  
+  free((char *)reloc_vector);
+  return new;
+}
+
+static bfd_byte *
+DEFUN(bfd_coff_get_relocated_section_contents,(in_abfd, seclet),
+      bfd *in_abfd AND
+      bfd_seclet_type *seclet)
+
+{
+  asymbol **symbols = 0;
+  extern bfd *output_bfd;
+
+  /* Get enough memory to hold the stuff */
+  bfd *input_bfd = seclet->u.indirect.section->owner;
+  asection *input_section = seclet->u.indirect.section;
+
+  char *data = malloc(input_section->_raw_size);
+  char *dst = data;
+  char *prev_dst = data;
+
+  unsigned int gap = 0;
+
+  bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
+                                                      input_section);
+  arelent **reloc_vector = (arelent **)bfd_xmalloc(reloc_size);
+  
+  /* read in the section */
+  bfd_get_section_contents(input_bfd,
+                          input_section,
+                          data,
+                          0,
+                          input_section->_raw_size);
+  
+  
+  if (bfd_canonicalize_reloc(input_bfd, 
+                            input_section,
+                            reloc_vector,
+                            seclet->u.indirect.symbols) )
+  {
+    arelent **parent = reloc_vector;
+    arelent *reloc ;
+    
+
+
+    unsigned int dst_address = 0;
+    unsigned int src_address = 0;
+    unsigned int run;
+    unsigned int idx;
+    
+    /* Find how long a run we can do */
+    while (dst_address < seclet->size) 
+    {
+      
+      reloc = *parent;
+      if (reloc) 
+      {
+       /* Note that the relaxing didn't tie up the addresses in the
+          relocation, so we use the original address to work out the
+          run of non-relocated data */
+       run = reloc->address - src_address;
+       parent++;
+       
+      }
+      else 
+      {
+       run = seclet->size - dst_address;
+      }
+      /* Copy the bytes */
+      for (idx = 0; idx < run; idx++)
+      {
+       data[dst_address++] = data[src_address++];
+      }
+    
+      /* Now do the relocation */
+    
+      if (reloc) 
+      {
+       switch (reloc->howto->type) 
+       {
+       case R_JMP2:
+         /* Speciial relaxed type */
+       {
+         bfd_vma dot = seclet->offset + dst_address + seclet->u.indirect.section->output_section->vma;   
+         int   gap = get_value(reloc,seclet)-dot-1;
+         if ((gap & ~0xff  ) != 0 &&((gap & 0xff00)!= 0xff00)) abort();
+
+         bfd_put_8(in_abfd,gap,   data+dst_address);
+
+         switch (data[dst_address-1]) 
+         {
+           
+         case 0x5e:
+           /* jsr -> bsr */
+           bfd_put_8(in_abfd, 0x55, data+dst_address-1);
+           break;
+         case 0x5a:     
+           /* jmp ->bra */
+           bfd_put_8(in_abfd, 0x40, data+dst_address-1);
+           break;
+         
+         default:
+           abort();
+         
+         }
+       
+       
+
+            
+         dst_address++;
+         src_address+=3;
+  
+         break;
+       }
+
+            
+       case R_MOVB2:
+         /* Special relaxed type, there will be a gap between where we
+            get stuff from and where we put stuff to now 
+            
+            for a mov.b @aa:16 -> mov.b @aa:8
+            opcode 0x6a 0x0y offset
+            ->     0x2y off
+            */
+         if (data[dst_address-1] != 0x6a)
+          abort();
+         switch (data[dst_address] & 0xf0) 
+         {
+         case 0x00:
+           /* Src is memory */
+           data[dst_address-1] = (data[src_address] & 0xf) | 0x20;
+           break;
+         case 0x80:
+           /* Src is reg */
+           data[dst_address-1] = (data[src_address] & 0xf) | 0x30;
+           break;
+         default:
+           abort();
+         }
+       
+         /* the offset must fit ! after all, what was all the relaxing
+            about ? */
+
+         bfd_put_8(in_abfd, get_value(reloc, seclet), data + dst_address);
+
+         /* Note the magic - src goes up by two bytes, but dst by only
+            one */
+         dst_address+=1;
+         src_address+=3;
+       
+         break;
+         /* PCrel 8 bits */
+       case R_PCRBYTE:   
+       {
+         bfd_vma dot = seclet->offset + dst_address + seclet->u.indirect.section->output_section->vma;   
+         int   gap = get_value(reloc,seclet)-dot;
+         if (gap > 127 || gap < -128) 
+         {
+           bfd_error_vector.reloc_value_truncated(reloc, seclet);
+         }
+         
+         bfd_put_8(in_abfd,gap,   data+dst_address);
+         dst_address++;
+         src_address++;
+  
+         break;
+       }
+
+       case R_RELBYTE:
+       {
+         unsigned  int gap =get_value(reloc,seclet);
+         if (gap > 256)
+         {
+           bfd_error_vector.reloc_value_truncated(reloc, seclet);
+         }
+         
+         bfd_put_8(in_abfd, gap, data+dst_address);
+         dst_address+=1;
+         src_address+=1;
+
+
+       }
+         break; 
+       case R_JMP1:
+         /* A relword which would have like to have been a pcrel */
+       case R_MOVB1:   
+         /* A relword which would like to have been modified but
+            didn't make it */
+       case R_RELWORD:
+         bfd_put_16(in_abfd, get_value(reloc,seclet), data+dst_address);
+         dst_address+=2;
+         src_address+=2;
+         break;
+       
+       default:
+         abort();
+       }
+      }    
+    }
+  }
+  free((char *)reloc_vector);
+  return data;
+  
+}
+
 
 #define coff_core_file_failing_command _bfd_dummy_core_file_failing_command
 #define coff_core_file_failing_signal  _bfd_dummy_core_file_failing_signal
@@ -3461,5 +3886,6 @@ DEFUN(coff_sizeof_headers,(abfd, reloc),
 #define coff_bfd_debug_info_start              bfd_void
 #define coff_bfd_debug_info_end                bfd_void
 #define coff_bfd_debug_info_accumulate (PROTO(void,(*),(bfd*, struct sec *))) bfd_void
-#define coff_bfd_get_relocated_section_contents \
- bfd_generic_get_relocated_section_contents
+#define coff_bfd_get_relocated_section_contents  bfd_generic_get_relocated_section_contents
+#define coff_bfd_relax_section bfd_generic_relax_section
+
index 4088f0eb9ba482f411535789c99cea9bc6e6baa6..8deef00dec03cdce9fb9b1a81de8b1ebd1d4712a 100644 (file)
@@ -50,248 +50,7 @@ DEFUN(bfd_new_seclet,(abfd, section),
 
 #define MAX_ERRORS_IN_A_ROW 10
 extern bfd_error_vector_type bfd_error_vector;
-bfd_vma 
-DEFUN(get_value,(reloc, seclet),
-      arelent  *reloc AND
-      bfd_seclet_type *seclet)
-{
-  bfd_vma value;
-  if (reloc->sym_ptr_ptr) 
-  {
-    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 */
-
-    if (symbol->section == (asection *)NULL) 
-    {
-      /* Ouch, this is an undefined symbol.. */
-      bfd_error_vector.undefined_symbol(reloc, seclet);
-      value = symbol->value;
-    }
-    else 
-    {
-      value = symbol->value +
-       symbol->section->output_offset +
-       symbol->section->output_section->vma;
-    }  
-  }
-  
-  else 
-  {
-    value = 0;  
-  }
-  
-  /* Add the value contained in the relocation */
-  value += (short)((reloc->addend) & 0xffff);
-  
-  return value;
-  
-
-}
-
-static char *
-DEFUN(foo_bfd_get_relocated_section_contents,(seclet),
-      bfd_seclet_type *seclet)
-
-{
-  asymbol **symbols = 0;
-  extern bfd *output_bfd;
-  bfd *abfd;    
-
-  /* Get enough memory to hold the stuff */
-  bfd *input_bfd = seclet->u.indirect.section->owner;
-  asection *input_section = seclet->u.indirect.section;
-
-  char *data = malloc(input_section->_raw_size);
-  char *dst = data;
-  char *prev_dst = data;
-  unsigned int gap = 0;
-
-  bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
-                                                      input_section);
-  arelent **reloc_vector = (arelent **)ldmalloc(reloc_size);
-  abfd = output_bfd;
-  
-  /* read in the section */
-  bfd_get_section_contents(input_bfd,
-                          input_section,
-                          data,
-                          0,
-                          input_section->_raw_size);
-  
-  
-  if (bfd_canonicalize_reloc(input_bfd, 
-                            input_section,
-                            reloc_vector,
-                            seclet->u.indirect.symbols) )
-  {
-    arelent **parent = reloc_vector;
-    arelent *reloc ;
-    
-
-
-    unsigned int dst_address = 0;
-    unsigned int src_address = 0;
-    unsigned int run;
-    unsigned int idx;
-    
-    /* Find how long a run we can do */
-    while (dst_address < seclet->size) 
-    {
-      
-      reloc = *parent;
-      if (reloc) 
-      {
-       /* Note that the relaxing didn't tie up the addresses in the
-          relocation, so we use the original address to work out the
-          run of non-relocated data */
-       run = reloc->address - src_address;
-       parent++;
-       
-      }
-      else 
-      {
-       run = seclet->size - dst_address;
-      }
-      /* Copy the bytes */
-      for (idx = 0; idx < run; idx++)
-      {
-       data[dst_address++] = data[src_address++];
-      }
-    
-      /* Now do the relocation */
-    
-      if (reloc) 
-      {
-       switch (reloc->howto->type) 
-       {
-       case R_JMP2:
-         /* Speciial relaxed type */
-       {
-         bfd_vma dot = seclet->offset + dst_address + seclet->u.indirect.section->output_section->vma;   
-         int   gap = get_value(reloc,seclet)-dot-1;
-         if ((gap & ~0xff  ) != 0 &&((gap & 0xff00)!= 0xff00)) abort();
-
-         bfd_put_8(abfd,gap,   data+dst_address);
-
-         switch (data[dst_address-1]) 
-         {
-           
-         case 0x5e:
-           /* jsr -> bsr */
-           bfd_put_8(abfd, 0x55, data+dst_address-1);
-           break;
-         case 0x5a:     
-           /* jmp ->bra */
-           bfd_put_8(abfd, 0x40, data+dst_address-1);
-           break;
-         
-         default:
-           abort();
-         
-         }
-       
-       
 
-            
-         dst_address++;
-         src_address+=3;
-  
-         break;
-       }
-
-            
-       case R_MOVB2:
-         /* Special relaxed type, there will be a gap between where we
-            get stuff from and where we put stuff to now 
-            
-            for a mov.b @aa:16 -> mov.b @aa:8
-            opcode 0x6a 0x0y offset
-            ->     0x2y off
-            */
-         if (data[dst_address-1] != 0x6a)
-          abort();
-         switch (data[dst_address] & 0xf0) 
-         {
-         case 0x00:
-           /* Src is memory */
-           data[dst_address-1] = (data[src_address] & 0xf) | 0x20;
-           break;
-         case 0x80:
-           /* Src is reg */
-           data[dst_address-1] = (data[src_address] & 0xf) | 0x30;
-           break;
-         default:
-           abort();
-         }
-       
-         /* the offset must fit ! after all, what was all the relaxing
-            about ? */
-
-         bfd_put_8(abfd, get_value(reloc, seclet), data + dst_address);
-
-         /* Note the magic - src goes up by two bytes, but dst by only
-            one */
-         dst_address+=1;
-         src_address+=3;
-       
-         break;
-         /* PCrel 8 bits */
-       case R_PCRBYTE:   
-       {
-         bfd_vma dot = seclet->offset + dst_address + seclet->u.indirect.section->output_section->vma;   
-         int   gap = get_value(reloc,seclet)-dot;
-         if (gap > 127 || gap < -128) 
-         {
-           bfd_error_vector.reloc_value_truncated(reloc, seclet);
-         }
-         
-         bfd_put_8(abfd,gap,   data+dst_address);
-         dst_address++;
-         src_address++;
-  
-         break;
-       }
-
-       case R_RELBYTE:
-       {
-         unsigned  int gap =get_value(reloc,seclet);
-         if (gap > 256)
-         {
-           bfd_error_vector.reloc_value_truncated(reloc, seclet);
-         }
-         
-         bfd_put_8(abfd, gap, data+dst_address);
-         dst_address+=1;
-         src_address+=1;
-
-
-       }
-         break; 
-       case R_JMP1:
-         /* A relword which would have like to have been a pcrel */
-       case R_MOVB1:   
-         /* A relword which would like to have been modified but
-            didn't make it */
-       case R_RELWORD:
-         bfd_put_16(abfd, get_value(reloc,seclet), data+dst_address);
-         dst_address+=2;
-         src_address+=2;
-         break;
-       
-       default:
-         abort();
-       }
-      }    
-    }
-  }
-  free((char *)reloc_vector);
-  return data;
-  
-}
 
 void
 DEFUN(rel,(abfd, seclet, output_section),