Lots of changes from gas-bfd work. Includes:
authorKen Raeburn <raeburn@cygnus>
Tue, 26 May 1992 03:45:31 +0000 (03:45 +0000)
committerKen Raeburn <raeburn@cygnus>
Tue, 26 May 1992 03:45:31 +0000 (03:45 +0000)
 * working reloc lookup support
 * better support for creation of COFF files from scratch
 * misc doc changes, macro tweaks, "const" additions, typo fixes, etc.
 * one or two ugly kludges that should get cleaned up (but what's one
   or two more, in BFD?)
See ChangeLog for details.

bfd/coff-i960.c
bfd/coffcode.h
bfd/cpu-a29k.c
bfd/ctor.c
bfd/reloc.c

index b0a4b9d73f9da1dc945c55fdbc159e89a57b24b1..e0727db91edd6e123dc3d70ed5d97b0013b6ca55 100644 (file)
@@ -27,8 +27,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "sysdep.h"
 #include "libbfd.h"
 #include "obstack.h"
-#include "coff-i960.h"
-#include "internalcoff.h"
+#include "coff/i960.h"
+#include "coff/internal.h"
 #include "libcoff.h"           /* to allow easier abstraction-breaking */
 
 
@@ -37,12 +37,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define BAL_MASK 0x00ffffff
 
 static bfd_reloc_status_type 
-optcall_callback(abfd, reloc_entry, symbol_in, data, ignore_input_section)
-bfd *abfd;
-arelent *reloc_entry;
-asymbol *symbol_in;
-unsigned char *data;
-asection *ignore_input_section;
+DEFUN (optcall_callback, (abfd, reloc_entry, symbol_in, data, ignore_input_section),
+       bfd *abfd AND
+       arelent *reloc_entry AND
+       asymbol *symbol_in AND
+       PTR data AND
+       asection *ignore_input_section)
 {
   /* This item has already been relocated correctly, but we may be
    * able to patch in yet better code - done by digging out the
@@ -70,7 +70,7 @@ asection *ignore_input_section;
         to the correct location */
        {
          union internal_auxent *aux = &((cs->native+2)->u.auxent);
-         int word = bfd_get_32(abfd, data + reloc_entry->address);
+         int word = bfd_get_32(abfd, (bfd_byte *)data + reloc_entry->address);
          int olf = (aux->x_bal.x_balntry - cs->native->u.syment.n_value);
          BFD_ASSERT(cs->native->u.syment.n_numaux==2);
          /* We replace the original call instruction with a bal to */
@@ -80,7 +80,7 @@ asection *ignore_input_section;
          /* offset of the bal entry point */
 
          word = ((word +  olf)  & BAL_MASK) | BAL;
-         bfd_put_32(abfd, word,  data+reloc_entry->address);
+         bfd_put_32(abfd, word, (bfd_byte *) data + reloc_entry->address);
        }
        result = bfd_reloc_ok;
        break;
@@ -97,51 +97,47 @@ asection *ignore_input_section;
   return result;
 }
 
-
-
-static reloc_howto_type howto_table[] = 
-{
-  {0},
-  {1},
-  {2},
-  {3},
-  {4},
-  {5},
-  {6},
-  {7},
-  {8},
-  {9},
-  {10},
-  {11},
-  {12},
-  {13},
-  {14},
-  {15},
-  {16},
-
+static reloc_howto_type howto_rellong =
   { (unsigned int) R_RELLONG, 0, 2, 32,false, 0, true, true,
-      0,"rellong", true, 0xffffffff, 0xffffffff},
-  {18},
-  {19},
-  {20},
-  {21},
-  {22},
-  {23},
-  {24},
-
+      0,"rellong", true, 0xffffffff, 0xffffffff};
+static reloc_howto_type howto_iprmed =
   {  R_IPRMED, 0, 2, 24,true,0, true, true,0,"iprmed ", true,
-       0x00ffffff, 0x00ffffff},
-  {26},
+       0x00ffffff, 0x00ffffff};
+static reloc_howto_type howto_optcall =
   {  R_OPTCALL, 0,2,24,true,0, true, true, optcall_callback,
-       "optcall", true, 0x00ffffff, 0x00ffffff},
+       "optcall", true, 0x00ffffff, 0x00ffffff};
 
-};
+static reloc_howto_type *
+DEFUN (coff_i960_reloc_type_lookup, (abfd, code),
+       bfd *abfd AND
+       bfd_reloc_code_type code)
+{
+  switch (code)
+    {
+    default:
+      return 0;
+    case BFD_RELOC_I960_CALLJ:
+      return &howto_optcall;
+    case BFD_RELOC_32:
+      return &howto_rellong;
+    case BFD_RELOC_24_PCREL:
+      return &howto_iprmed;
+    }
+}
 
 /* The real code is in coffcode.h */
 
 #define RTYPE2HOWTO(cache_ptr, dst) \
-           cache_ptr->howto = howto_table + dst.r_type;
+{                                                      \
+   reloc_howto_type *howto_ptr;                                \
+   switch ((dst)->r_type) {                            \
+     case 17: howto_ptr = &howto_rellong; break;       \
+     case 25: howto_ptr = &howto_iprmed; break;                \
+     case 27: howto_ptr = &howto_optcall; break;       \
+     default: howto_ptr = 0; break;                    \
+     }                                                 \
+   cache_ptr->howto = howto_ptr;                       \
+ }
 
 #include "coffcode.h"
 
@@ -170,8 +166,11 @@ bfd_target icoff_little_vec =
        _bfd_generic_mkarchive, bfd_false},
     {bfd_false, coff_write_object_contents, /* bfd_write_contents */
        _bfd_write_archive_contents, bfd_false},
-  JUMP_TABLE(coff)
-  };
+  JUMP_TABLE(coff),
+  COFF_SWAP_TABLE,
+  coff_i960_reloc_type_lookup,
+  coff_make_debug_symbol,
+};
 
 
 bfd_target icoff_big_vec =
@@ -200,5 +199,7 @@ _do_getb64, _do_putb64,  _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs
   {bfd_false, coff_write_object_contents,      /* bfd_write_contents */
      _bfd_write_archive_contents, bfd_false},
   JUMP_TABLE(coff),
-COFF_SWAP_TABLE
+  COFF_SWAP_TABLE,
+  coff_i960_reloc_type_lookup,
+  coff_make_debug_symbol,
 };
index 6c7eea9974a2d0ddfacc4fd4223314168022b598..cdb94eb9bec520a7abef47b41d8d683e4d47df0f 100644 (file)
@@ -22,6 +22,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 Most of this hacked by  Steve Chamberlain,
                        sac@cygnus.com 
 */
+
+#include <assert.h>
+#include <stdio.h>
+
 /*
 
 SECTION
@@ -377,23 +381,34 @@ static flagword
 DEFUN(styp_to_sec_flags, (styp_flags),
        long    styp_flags)
 {
-    flagword   sec_flags=0;
-
-    if ((styp_flags & STYP_TEXT) || (styp_flags & STYP_DATA))
-       sec_flags = (SEC_LOAD | SEC_ALLOC);
-    else if (styp_flags & STYP_BSS)
-       sec_flags = SEC_ALLOC;
+  flagword     sec_flags=0;
 
-#ifdef STYP_LIT                /* A29k readonly text/data section type */
-    if ((styp_flags & STYP_LIT) == STYP_LIT)
-       sec_flags = (SEC_LOAD | SEC_ALLOC | SEC_READONLY);
-#endif  /* STYP_LIT */
-#ifdef STYP_OTHER_LOAD /* Other loaded sections */
-    if (styp_flags & STYP_OTHER_LOAD)
-       sec_flags = (SEC_LOAD | SEC_ALLOC);
-#endif  /* STYP_SDATA */
+  if ((styp_flags & STYP_TEXT) || (styp_flags & STYP_DATA)) 
+  {
+    sec_flags = SEC_LOAD | SEC_ALLOC;
+  }
+  else if (styp_flags & STYP_BSS) 
+  {
+    sec_flags = SEC_ALLOC;
+  }
+  else
+  {
+    sec_flags = SEC_ALLOC | SEC_LOAD;
+  }
+#ifdef STYP_LIT                        /* A29k readonly text/data section type */
+  if ((styp_flags & STYP_LIT) == STYP_LIT)
+  {
+    sec_flags = (SEC_LOAD | SEC_ALLOC | SEC_READONLY);
+  }
+#endif                         /* STYP_LIT */
+#ifdef STYP_OTHER_LOAD         /* Other loaded sections */
+  if (styp_flags & STYP_OTHER_LOAD)
+  {
+    sec_flags = (SEC_LOAD | SEC_ALLOC);
+  }
+#endif                         /* STYP_SDATA */
 
-    return(sec_flags);
+  return(sec_flags);
 }
 
 #define        get_index(symbol)       ((int) (symbol)->udata)
@@ -884,27 +899,22 @@ DEFUN(coff_swap_scnhdr_out,(abfd, in, out),
 */
 
 static          boolean
-DEFUN(coff_new_section_hook,(abfd_ignore, section),
-      bfd            *abfd_ignore AND
+DEFUN(coff_new_section_hook,(abfd, section),
+      bfd            *abfd AND
       asection       *section)
 {
-  section->alignment_power = abfd_ignore->xvec->align_power_min;
+  section->alignment_power = abfd->xvec->align_power_min;
+  /* Allocate aux records for section symbols, to store size and
+     related info.
+
+     @@ Shouldn't use constant multiplier here!  */
+  coffsymbol (section->symbol)->native =
+    (combined_entry_type *) bfd_zalloc (abfd,
+                                       sizeof (combined_entry_type) * 10);
   return true;
 }
 
-static asection bfd_debug_section = 
-{ "*DEBUG*" };
-
-
-
-static void
-DEFUN(make_abs_section,(abfd),
-      bfd *abfd)
-{
-    
-
-  
-}
+static asection bfd_debug_section = { "*DEBUG*" };
 
 /* Take a section header read from a coff file (in HOST byte order),
    and make a BFD "section" out of it.  */
@@ -1336,6 +1346,30 @@ DEFUN(coff_renumber_symbols,(bfd_ptr),
   unsigned int native_index = 0;
   struct internal_syment *last_file = (struct internal_syment *)NULL;
   unsigned int symbol_index;
+
+  /* COFF demands that undefined symbols come after all other symbols.
+     Since we don't need to impose this extra knowledge on all our client
+     programs, deal with that here.  Sort the symbol table; just move the
+     undefined symbols to the end, leaving the rest alone.  */
+  /* @@ Do we have some condition we could test for, so we don't always
+     have to do this?  I don't think relocatability is quite right, but
+     I'm not certain.  [raeburn:19920508.1711EST]  */
+  {
+    asymbol **newsyms;
+    int i;
+
+    newsyms = (asymbol **) bfd_alloc_by_size_t (bfd_ptr,
+                                               sizeof (asymbol *) * symbol_count);
+    bfd_ptr->outsymbols = newsyms;
+    for (i = 0; i < symbol_count; i++)
+      if (symbol_ptr_ptr[i]->section != &bfd_und_section)
+       *newsyms++ = symbol_ptr_ptr[i];
+    for (i = 0; i < symbol_count; i++)
+      if (symbol_ptr_ptr[i]->section == &bfd_und_section)
+       *newsyms++ = symbol_ptr_ptr[i];
+    symbol_ptr_ptr = bfd_ptr->outsymbols;
+  }
+
   for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
       {
        coff_symbol_type *coff_symbol_ptr = coff_symbol_from(bfd_ptr, symbol_ptr_ptr[symbol_index]);
@@ -1365,6 +1399,7 @@ DEFUN(coff_renumber_symbols,(bfd_ptr),
          native_index++;
        }
       }
+  obj_conv_table_size (bfd_ptr) = native_index;
 }
 
 
@@ -1475,6 +1510,12 @@ unsigned int written)
   int             class =  native->u.syment.n_sclass;
   SYMENT buf;
   unsigned int j;
+
+  /* @@ bfd_debug_section isn't accessible outside this file, but we know
+     that C_FILE symbols belong there.  So move them.  */
+  if (native->u.syment.n_sclass == C_FILE)
+    symbol->section = &bfd_debug_section;
+
   if (symbol->section == &bfd_abs_section) 
   {
     native->u.syment.n_scnum = N_ABS;
@@ -1588,7 +1629,7 @@ coff_symbol_type *symbol AND
 unsigned int written)
 {
   /*
-    Does this symbol have an ascociated line number - if so then
+    Does this symbol have an associated line number - if so then
     make it remember this symbol index. Also tag the auxent of
     this symbol to point to the right place in the lineno table
     */
@@ -1748,9 +1789,20 @@ DEFUN(coff_write_relocs,(abfd),
       struct internal_reloc    n;
       arelent        *q = p[i];
       memset((PTR)&n, 0, sizeof(n));
+
+      /* @@FIXME COFF relocs don't support addends.  Code should probably be
+        in the target-independent code, using a target flag to decide whether
+        to fold the addend into the section contents.  */
+      if (q->addend != 0)
+       abort ();
+
       n.r_vaddr = q->address + s->vma;
       if (q->sym_ptr_ptr) {
        n.r_symndx = get_index((*(q->sym_ptr_ptr)));
+       /* Take notice if the symbol reloc points to a symbol we don't have
+          in our symbol table.  What should we do for this??  */
+       if (n.r_symndx > obj_conv_table_size (abfd))
+         abort ();
       }
 #ifdef SELECT_RELOC
       /* Work out reloc type from what is required */
@@ -1823,6 +1875,7 @@ bfd            *abfd;
     bfd_error = no_memory;
     return (NULL);
   }                            /* on error */
+  new->symbol.section = 0;
   new->native = 0;
   new->lineno = (alent *) NULL;
   new->done_lineno = false;
@@ -1832,6 +1885,26 @@ bfd            *abfd;
 
 #ifndef NO_COFF_SYMBOLS
 
+static asymbol *
+DEFUN (coff_make_debug_symbol, (abfd, ptr, sz),
+       bfd *abfd AND
+       PTR ptr AND
+       unsigned long sz)
+{
+  coff_symbol_type *new = (coff_symbol_type *) bfd_alloc(abfd, sizeof(coff_symbol_type));
+  if (new == NULL) {
+    bfd_error = no_memory;
+    return (NULL);
+  }                            /* on error */
+  /* @@ This shouldn't be using a constant multiplier.  */
+  new->native = (combined_entry_type *) bfd_zalloc (abfd, sizeof (combined_entry_type) * 10);
+  new->symbol.section = &bfd_debug_section;
+  new->lineno = (alent *) NULL;
+  new->done_lineno = false;
+  new->symbol.the_bfd = abfd;
+  return &new->symbol;
+}
+
 static void
 DEFUN(coff_print_symbol,(ignore_abfd, filep, symbol, how),
       bfd            *ignore_abfd AND
@@ -2128,8 +2201,115 @@ DEFUN(coff_compute_section_file_positions,(abfd),
   obj_relocbase(abfd) = sofar;
 }
 
+#ifndef NO_COFF_SYMBOLS
+static asymbol *
+coff_section_symbol (abfd, name)
+     bfd *abfd;
+     char *name;
+{
+  asection *sec = bfd_get_section_by_name (abfd, name);
+  asymbol *sym;
+  combined_entry_type *csym;
+
+  if (!sec)
+    {
+      /* create empty symbol */
+      abort ();
+    }
+  sym = sec->symbol;
+  if (coff_symbol_from (abfd, sym))
+    csym = coff_symbol_from (abfd, sym)->native;
+  else
+    csym = 0;
+  /* Make sure back-end COFF stuff is there.  */
+  if (csym == 0)
+    {
+      struct foo {
+       coff_symbol_type sym;
+       /* @@FIXME This shouldn't use a fixed size!!  */
+       combined_entry_type e[10];
+      };
+      struct foo *f;
+      f = (struct foo *) bfd_alloc_by_size_t (abfd, sizeof (*f));
+      bzero ((char *) f, sizeof (*f));
+      coff_symbol_from (abfd, sym)->native = csym = f->e;
+    }
+  csym[0].u.syment.n_sclass = C_STAT;
+  csym[0].u.syment.n_numaux = 1;
+/*  SF_SET_STATICS (sym);      @@ ??? */
+  if (sec)
+    {
+      csym[1].u.auxent.x_scn.x_scnlen = sec->_raw_size;
+      csym[1].u.auxent.x_scn.x_nreloc = sec->reloc_count;
+      csym[1].u.auxent.x_scn.x_nlinno = sec->lineno_count;
+    }
+  else
+    {
+      csym[1].u.auxent.x_scn.x_scnlen = 0;
+      csym[1].u.auxent.x_scn.x_nreloc = 0;
+      csym[1].u.auxent.x_scn.x_nlinno = 0;
+    }
+  return sym;
+}
 
+/* If .file, .text, .data, .bss symbols are missing, add them.  */
+/* @@ Should we only be adding missing symbols, or overriding the aux
+   values for existing section symbols?  */
+static void
+coff_add_missing_symbols (abfd)
+     bfd *abfd;
+{
+  unsigned int nsyms = bfd_get_symcount (abfd);
+  asymbol **sympp = abfd->outsymbols;
+  asymbol **sympp2;
+  unsigned int i;
+  int need_text = 1, need_data = 1, need_bss = 1, need_file = 1;
+  coff_data_type *cdata = coff_data (abfd);
+
+  for (i = 0; i < nsyms; i++)
+    {
+      coff_symbol_type *csym = coff_symbol_from (abfd, sympp[i]);
+      CONST char *name;
 
+      if (csym->native->u.syment.n_sclass == C_FILE)
+       {
+         need_file = 0;
+         continue;
+       }
+      name = csym->symbol.name;
+      if (!name)
+       continue;
+      if (!strcmp (name, _TEXT))
+       need_text = 0;
+      else if (!strcmp (name, _DATA))
+       need_data = 0;
+      else if (!strcmp (name, _BSS))
+       need_bss = 0;
+    }
+  /* Now i == bfd_get_symcount (abfd).  */
+  /* @@ For now, don't deal with .file symbol.  */
+  need_file = 0;
+
+  if (!need_text && !need_data && !need_bss && !need_file)
+    return;
+  nsyms += need_text + need_data + need_bss + need_file;
+  sympp2 = (asymbol**) bfd_alloc_by_size_t (abfd, nsyms * sizeof (asymbol *));
+  memcpy (sympp2, sympp, i * sizeof (asymbol *));
+  if (need_file)
+    {
+      /* @@ Generate fake .file symbol, in sympp2[i], and increment i.  */
+      abort ();
+    }
+  if (need_text)
+    sympp2[i++] = coff_section_symbol (abfd, _TEXT);
+  if (need_data)
+    sympp2[i++] = coff_section_symbol (abfd, _DATA);
+  if (need_bss)
+    sympp2[i++] = coff_section_symbol (abfd, _BSS);
+  assert (i == nsyms);
+  bfd_set_symtab (abfd, sympp2, nsyms);
+}
+#endif /* NO_COFF_SYMBOLS */
 
 /* SUPPRESS 558 */
 /* SUPPRESS 529 */
@@ -2159,12 +2339,15 @@ DEFUN(coff_write_object_contents,(abfd),
 
   bfd_error = system_call_error;
   /* Number the output sections, starting from one on the first section
-     with a name which doesn't start with a * */
+     with a name which doesn't start with a *.
+     @@ The code doesn't make this check.  Is it supposed to be done,
+     or isn't it??  */
   count = 1;
   for (current = abfd->sections; current != (asection *)NULL; 
        current = current->next) 
   {
       current->target_index = count;
+      count++;
   }
   
     
@@ -2424,6 +2607,7 @@ DEFUN(coff_write_object_contents,(abfd),
 
 #ifndef NO_COFF_SYMBOLS
   if (bfd_get_symcount(abfd) != 0) {
+      coff_add_missing_symbols (abfd);
       coff_renumber_symbols(abfd);
       coff_mangle_symbols(abfd);
       coff_write_symbols(abfd);
@@ -3149,6 +3333,7 @@ DEFUN(coff_slurp_symbol_table,(abfd),
   obj_symbols(abfd) = cached_area;
   obj_raw_syments(abfd) = native_symbols;
 
+  obj_conv_table_size (abfd) = bfd_get_symcount (abfd);
   bfd_get_symcount(abfd) = number_of_symbols;
   obj_convert(abfd) = table_ptr;
   /* Slurp the line tables for each section too */
@@ -3324,16 +3509,18 @@ DEFUN(coff_slurp_reloc_table,(abfd, asect, symbols),
       cache_ptr->address = dst.r_vaddr;
 
       if (dst.r_symndx != -1) 
-      {
+       {
+         /* @@ Should never be greater than count of symbols!  */
+         if (dst.r_symndx >= obj_conv_table_size (abfd))
+           abort ();
          cache_ptr->sym_ptr_ptr = symbols + obj_convert(abfd)[dst.r_symndx];
          ptr = *(cache_ptr->sym_ptr_ptr);
-      }
+       }
       else 
-      {
-       cache_ptr->sym_ptr_ptr= bfd_abs_section.symbol_ptr_ptr;
-        ptr = 0;
-             
-      }
+       {
+         cache_ptr->sym_ptr_ptr= bfd_abs_section.symbol_ptr_ptr;
+         ptr = 0;
+       }
 
       /*
        The symbols definitions that we have read in have been
@@ -3723,15 +3910,15 @@ DEFUN(bfd_coff_relax_section,(abfd, i, symbols),
 }
 
 static bfd_byte *
-DEFUN(bfd_coff_get_relocated_section_contents,(in_abfd, seclet),
+DEFUN(bfd_coff_get_relocated_section_contents,(in_abfd, seclet, data),
       bfd *in_abfd AND
-      bfd_seclet_type *seclet)
+      bfd_seclet_type *seclet AND
+      bfd_byte *data)
 
 {
   /* Get enough memory to hold the stuff */
   bfd *input_bfd = seclet->u.indirect.section->owner;
   asection *input_section = seclet->u.indirect.section;
-  bfd_byte  *data = (bfd_byte *)malloc(input_section->_raw_size);
   bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
                                                       input_section);
   arelent **reloc_vector = (arelent **)bfd_xmalloc(reloc_size);
index 3e1438c282f08781152e865cc616aaebde1bf415..50759ee7e3f3b54165d75a006583f17bc5adc579 100644 (file)
@@ -16,7 +16,6 @@ static bfd_arch_info_type arch_info_struct =
     bfd_default_compatible, 
     bfd_default_scan ,
     0,
-    bfd_default_reloc_type_lookup,
   };
 
 void DEFUN_VOID(bfd_a29k_arch)
index d81df612b48587e74e37742a642ec72ee178f19b..0550aa8faf987b63a40c3deaa928cd91f7ddea94 100644 (file)
@@ -140,9 +140,7 @@ void DEFUN(bfd_constructor_entry,(abfd, symbol_ptr_ptr, type),
        rel_section->constructor_chain = reloc;
        reloc->relent.address = rel_section->_cooked_size;
        /* ask the cpu which howto to use */
-       reloc->relent.howto =
-       bfd_reloc_type_lookup(abfd->arch_info,
-                             BFD_RELOC_CTOR);
+       reloc->relent.howto = bfd_reloc_type_lookup(abfd, BFD_RELOC_CTOR);
        rel_section->_cooked_size += sizeof(int *);
        rel_section->reloc_count++;
    }
index 1c715a5897044693d89f5879e2cdef74656d73c1..93b2af748033718e04e6390c9b4277f6f55530c5 100644 (file)
@@ -295,7 +295,8 @@ CODE_FRAGMENT
 .                                           arelent *reloc_entry,
 .                                            struct symbol_cache_entry *symbol,
 .                                            PTR data,
-.                                            asection *input_section));
+.                                            asection *input_section, 
+.                                            bfd *output_bfd     ));
 .
 .       {* The textual name of the relocation type. *}
 .  char *name;
@@ -450,13 +451,14 @@ DEFUN(bfd_perform_relocation,(abfd,
     flag = bfd_reloc_undefined;
   }
 
-  if (howto->special_function){
+  if (howto->special_function) {
     bfd_reloc_status_type cont;
     cont = howto->special_function(abfd,
                                   reloc_entry,
                                   symbol,
                                   data,
-                                  input_section);
+                                  input_section,
+                                  output_bfd);
     if (cont != bfd_reloc_continue) return cont;
   }
 
@@ -676,7 +678,50 @@ CODE_FRAGMENT
 .          moment probably a 32 bit wide abs address, but the cpu can
 .          choose. *}
 .
-.  BFD_RELOC_CTOR
+.  BFD_RELOC_CTOR,
+.
+.       {* 32 bits wide, simple reloc *}
+.  BFD_RELOC_32,
+.      {* 32 bits, PC-relative *}
+.  BFD_RELOC_32_PCREL,
+.
+.      {* High 22 bits of 32-bit value; simple reloc.  *}
+.  BFD_RELOC_HI22,
+.      {* Low 10 bits.  *}
+.  BFD_RELOC_LO10,
+.
+.      {* Reloc types used for i960/b.out.  *}
+.  BFD_RELOC_24_PCREL,
+.  BFD_RELOC_I960_CALLJ,
+.
+.  BFD_RELOC_16_PCREL,
+.      {* 32-bit pc-relative, shifted right 2 bits (i.e., 30-bit
+.         word displacement, e.g. for SPARC) *}
+.  BFD_RELOC_32_PCREL_S2,
+.
+.  {* now for the sparc/elf codes *}
+.  BFD_RELOC_NONE,             {* actually used *}
+.  BFD_RELOC_SPARC_WDISP22,
+.  BFD_RELOC_SPARC22,
+.  BFD_RELOC_SPARC13,
+.  BFD_RELOC_SPARC_BASE13,
+.  BFD_RELOC_SPARC_GOT10,
+.  BFD_RELOC_SPARC_GOT13,
+.  BFD_RELOC_SPARC_GOT22,
+.  BFD_RELOC_SPARC_PC10,
+.  BFD_RELOC_SPARC_PC22,
+.  BFD_RELOC_SPARC_WPLT30,
+.  BFD_RELOC_SPARC_COPY,
+.  BFD_RELOC_SPARC_GLOB_DAT,
+.  BFD_RELOC_SPARC_JMP_SLOT,
+.  BFD_RELOC_SPARC_RELATIVE,
+.  BFD_RELOC_SPARC_UA32,
+.
+.  {* this one is a.out specific? *}
+.  BFD_RELOC_SPARC_BASE22,
+.
+.  {* this must be the highest numeric value *}
+.  BFD_RELOC_UNUSED
 . } bfd_reloc_code_real_type;
 */
 
@@ -688,8 +733,7 @@ SECTION
 
 SYNOPSIS
        CONST struct reloc_howto_struct *
-       bfd_reloc_type_lookup
-       (CONST bfd_arch_info_type *arch, bfd_reloc_code_type code);
+       bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_type code);
 
 DESCRIPTION
        This routine returns a pointer to a howto struct which when
@@ -701,10 +745,10 @@ DESCRIPTION
 
 CONST struct reloc_howto_struct *
 DEFUN(bfd_reloc_type_lookup,(arch, code),
-       CONST bfd_arch_info_type *arch  AND
-       bfd_reloc_code_type code)
+      bfd *abfd AND
+      bfd_reloc_code_type code)
 {
-  return arch->reloc_type_lookup(arch, code);
+  return BFD_SEND (abfd, reloc_type_lookup, (abfd, code));
 }
 
 static reloc_howto_type bfd_howto_32 =
@@ -764,7 +808,7 @@ SYNOPSIS
 
 DESCRIPTION
        Provides default handling for relaxing for back ends which
-       don't do relaxing - ie does nothing 
+       don't do relaxing -- i.e., does nothing.
 */
 
 boolean
@@ -786,7 +830,8 @@ INTERNAL_FUNCTION
 SYNOPSIS
        bfd_byte *
           bfd_generic_get_relocated_section_contents(bfd *abfd,
-            struct bfd_seclet_struct  *seclet)
+            struct bfd_seclet_struct  *seclet,
+            bfd_byte *data)
 
 DESCRIPTION
        Provides default handling of relocation effort for back ends
@@ -795,9 +840,10 @@ DESCRIPTION
 */
 
 bfd_byte *
-DEFUN(bfd_generic_get_relocated_section_contents,(abfd, seclet),
+DEFUN(bfd_generic_get_relocated_section_contents,(abfd, seclet, data),
       bfd *abfd AND
-      struct bfd_seclet_struct *seclet)
+      struct bfd_seclet_struct *seclet AND
+      bfd_byte *data)
 {
   extern bfd_error_vector_type bfd_error_vector;
 
@@ -805,11 +851,11 @@ DEFUN(bfd_generic_get_relocated_section_contents,(abfd, seclet),
   bfd *input_bfd = seclet->u.indirect.section->owner;
   asection *input_section = seclet->u.indirect.section;
 
-  bfd_byte *data = (bfd_byte *) bfd_xmalloc(input_section->_raw_size);
+
 
   bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd,
                                                       input_section);
-  arelent **reloc_vector = (arelent **) bfd_xmalloc(reloc_size);
+  arelent **reloc_vector = (arelent **) alloca(reloc_size);
   
   /* read in the section */
   bfd_get_section_contents(input_bfd,
@@ -862,7 +908,7 @@ DEFUN(bfd_generic_get_relocated_section_contents,(abfd, seclet),
     }    
   }
 
-  free((char *)reloc_vector);
+
   return data;