* coff-arm.c: Don't include obstack.h.
authorIan Lance Taylor <ian@airs.com>
Mon, 22 Dec 1997 10:50:06 +0000 (10:50 +0000)
committerIan Lance Taylor <ian@airs.com>
Mon, 22 Dec 1997 10:50:06 +0000 (10:50 +0000)
bfd/coff-arm.c

index 1d9c979566c583c1c076d88dfda338d5474e3c45..ad42902eb33ac1fea596ee78d21cdd89d8ba471b 100644 (file)
@@ -153,7 +153,6 @@ coff_arm_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd,
 }
 
 #define TARGET_UNDERSCORE '_'
-/* #define TARGET_UNDERSCORE '\0' */
 
 #ifndef PCRELOFFSET
 #define PCRELOFFSET true
@@ -730,7 +729,7 @@ arm_reloc_type_lookup(abfd,code)
 static long int global_thumb_glue_size = 0;
 static long int global_arm_glue_size = 0;
 
-static bfd * bfd_of_glue_owner = 0;
+static bfd * bfd_of_glue_owner = NULL;
 
 /* some typedefs for holding instructions */
 typedef unsigned long int insn32;
@@ -802,9 +801,8 @@ find_thumb_glue (info, name, input_bfd)
      char *                 name;
      bfd *                  input_bfd;
 {
-  char *tmp_name = 0;
-
-  struct coff_link_hash_entry *myh = 0;
+  char * tmp_name = 0;
+  struct coff_link_hash_entry * myh = 0;
 
   tmp_name = ((char *)
         bfd_malloc (strlen (name) + strlen (THUMB2ARM_GLUE_ENTRY_NAME)));
@@ -959,8 +957,8 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
      struct internal_syment *syms;
      asection **sections;
 {
-  struct internal_reloc *rel;
-  struct internal_reloc *relend;
+  struct internal_reloc * rel;
+  struct internal_reloc * relend;
 
   rel = relocs;
   relend = rel + input_section->reloc_count;
@@ -1096,7 +1094,9 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
 
                      if ((my_offset & 0x01) == 0x01)
                        {
-                         if (INTERWORK_SET (h_sec->owner) && ! INTERWORK_FLAG (h_sec->owner))
+                         if (h_sec->owner != NULL
+                             && INTERWORK_SET (h_sec->owner)
+                             && ! INTERWORK_FLAG (h_sec->owner))
                            _bfd_error_handler ("%s: warning: interworking not enabled.",
                                                bfd_get_filename (h_sec->owner));
                          
@@ -1165,7 +1165,9 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
                      
                      if ((my_offset & 0x01) == 0x01)
                        {
-                         if (INTERWORK_SET (h_sec->owner) && ! INTERWORK_FLAG (h_sec->owner))
+                         if (h->sec_owner != NULL
+                             && INTERWORK_SET (h_sec->owner)
+                             && ! INTERWORK_FLAG (h_sec->owner))
                            _bfd_error_handler ("%s: warning: interworking not enabled.",
                                                bfd_get_filename (h_sec->owner));
                          
@@ -1201,7 +1203,7 @@ coff_arm_relocate_section (output_bfd, info, input_bfd, input_section,
                        -4;
                      
                      tmp = bfd_get_32 (input_bfd, contents + rel->r_vaddr - input_section->vma);
-                     
+
                      bfd_put_32 (output_bfd,
                                  insert_thumb_branch (tmp, ret_offset),
                                  contents + rel->r_vaddr - input_section->vma);
@@ -1465,11 +1467,13 @@ boolean
 arm_allocate_interworking_sections (info) 
      struct bfd_link_info *info;
 {
-  asection *s;
-  bfd_byte *foo;
+  asection * s;
+  bfd_byte * foo;
+#if 0
   static char test_char = '1';
-
-  if ( global_arm_glue_size != 0 )
+#endif
+  
+  if (global_arm_glue_size != 0)
     {
       BFD_ASSERT (bfd_of_glue_owner != NULL);
       
@@ -1477,8 +1481,10 @@ arm_allocate_interworking_sections (info)
 
       BFD_ASSERT (s != NULL);
       
-      foo = (bfd_byte *) bfd_alloc(bfd_of_glue_owner, global_arm_glue_size);
-      memset(foo, test_char, global_arm_glue_size);
+      foo = (bfd_byte *) bfd_alloc (bfd_of_glue_owner, global_arm_glue_size);
+#if 0      
+      memset (foo, test_char, global_arm_glue_size);
+#endif
       
       s->_raw_size = s->_cooked_size = global_arm_glue_size;
       s->contents = foo;
@@ -1492,8 +1498,10 @@ arm_allocate_interworking_sections (info)
 
       BFD_ASSERT (s != NULL);
       
-      foo = (bfd_byte *) bfd_alloc(bfd_of_glue_owner, global_thumb_glue_size);
-      memset(foo, test_char, global_thumb_glue_size);
+      foo = (bfd_byte *) bfd_alloc (bfd_of_glue_owner, global_thumb_glue_size);
+#if 0
+      memset (foo, test_char, global_thumb_glue_size);
+#endif
       
       s->_raw_size = s->_cooked_size = global_thumb_glue_size;
       s->contents = foo;
@@ -1565,7 +1573,6 @@ record_thumb_to_arm_glue (info, h)
   char *                         tmp_name;
   struct coff_link_hash_entry *  myh;
 
-  
   BFD_ASSERT (bfd_of_glue_owner != NULL);
 
   s = bfd_get_section_by_name (bfd_of_glue_owner, THUMB2ARM_GLUE_SECTION_NAME);
@@ -1850,7 +1857,7 @@ coff_arm_bfd_merge_private_bfd_data (ibfd, obfd)
 }
 
 
-/* Display the flags field */
+/* Display the flags field */
 
 static boolean
 coff_arm_bfd_print_private_bfd_data (abfd, ptr)
@@ -1978,7 +1985,6 @@ coff_arm_bfd_copy_private_bfd_data (src, dest)
  *must* match the definitions on gcc/config/arm/semi.h.  */
 #define LOCAL_LABEL_PREFIX "."
 #define USER_LABEL_PREFIX "_"
-/* #define USER_LABEL_PREFIX "" */
 
 static boolean
 coff_arm_is_local_label_name (abfd, name)
@@ -2015,31 +2021,12 @@ coff_arm_is_local_label_name (abfd, name)
 
 #define coff_bfd_is_local_label_name           coff_arm_is_local_label_name
 #define coff_adjust_symndx                     coff_arm_adjust_symndx
+
 #ifndef COFF_WITH_PE
-#define coff_bfd_final_link                    coff_arm_bfd_final_link 
 #define coff_bfd_merge_private_bfd_data                coff_arm_bfd_merge_private_bfd_data
 #define coff_bfd_print_private_bfd_data                coff_arm_bfd_print_private_bfd_data
 #define coff_bfd_set_private_flags              coff_arm_bfd_set_private_flags
 #define coff_bfd_copy_private_bfd_data          coff_arm_bfd_copy_private_bfd_data
-#endif
-
-#include "coffcode.h"
-
-static boolean
-arm_do_last (abfd)
-     bfd * abfd;
-{
-  if (abfd == bfd_of_glue_owner)
-    return true;
-  else
-    return false;
-}
-
-static bfd *
-arm_get_last()
-{
-  return bfd_of_glue_owner;
-}
 
 /* This piece of machinery exists only to guarantee that the bfd that holds
    the glue section is written last. 
@@ -2047,551 +2034,54 @@ arm_get_last()
    This does depend on bfd_make_section attaching a new section to the
    end of the section list for the bfd. 
 
-   This is otherwise intended to be functionally the same as 
-   cofflink.c:_bfd_coff_final_link(). It is specifically different only 
-   where the ARM_HACKS macro modifies the code. It is left in as a 
-   precise form of comment. krk@cygnus.com  */
-
-#define ARM_HACKS
-
-/* Do the final link step.  */
+   krk@cygnus.com  */
 
-static boolean
-coff_arm_bfd_final_link (abfd, info)
-     bfd *abfd;
-     struct bfd_link_info *info;
+boolean
+coff_arm_link_output_has_begun (sub)
+     bfd * sub;
 {
-  bfd_size_type symesz;
-  struct coff_final_link_info finfo;
-  boolean debug_merge_allocated;
-  asection *o;
-  struct bfd_link_order *p;
-  size_t max_sym_count;
-  size_t max_lineno_count;
-  size_t max_reloc_count;
-  size_t max_output_reloc_count;
-  size_t max_contents_size;
-  file_ptr rel_filepos;
-  unsigned int relsz;
-  file_ptr line_filepos;
-  unsigned int linesz;
-  bfd *sub;
-  bfd_byte *external_relocs = NULL;
-  char strbuf[STRING_SIZE_SIZE];
-
-  symesz = bfd_coff_symesz (abfd);
-
-  finfo.info = info;
-  finfo.output_bfd = abfd;
-  finfo.strtab = NULL;
-  finfo.section_info = NULL;
-  finfo.last_file_index = -1;
-  finfo.last_bf_index = -1;
-  finfo.internal_syms = NULL;
-  finfo.sec_ptrs = NULL;
-  finfo.sym_indices = NULL;
-  finfo.outsyms = NULL;
-  finfo.linenos = NULL;
-  finfo.contents = NULL;
-  finfo.external_relocs = NULL;
-  finfo.internal_relocs = NULL;
-  debug_merge_allocated = false;
-
-  coff_data (abfd)->link_info = info;
-
-  finfo.strtab = _bfd_stringtab_init ();
-  if (finfo.strtab == NULL)
-    goto error_return;
-
-  if (! coff_debug_merge_hash_table_init (&finfo.debug_merge))
-    goto error_return;
-  debug_merge_allocated = true;
-
-  /* Compute the file positions for all the sections.  */
-  if (! abfd->output_has_begun)
-    bfd_coff_compute_section_file_positions (abfd);
-
-  /* Count the line numbers and relocation entries required for the
-     output file.  Set the file positions for the relocs.  */
-  rel_filepos = obj_relocbase (abfd);
-  relsz = bfd_coff_relsz (abfd);
-  max_contents_size = 0;
-  max_lineno_count = 0;
-  max_reloc_count = 0;
-
-  for (o = abfd->sections; o != NULL; o = o->next)
-    {
-      o->reloc_count = 0;
-      o->lineno_count = 0;
-      for (p = o->link_order_head; p != NULL; p = p->next)
-       {
-
-         if (p->type == bfd_indirect_link_order)
-           {
-             asection *sec;
-
-             sec = p->u.indirect.section;
-
-             /* Mark all sections which are to be included in the
-                link.  This will normally be every section.  We need
-                to do this so that we can identify any sections which
-                the linker has decided to not include.  */
-             sec->linker_mark = true;
-
-             if (info->strip == strip_none
-                 || info->strip == strip_some)
-               o->lineno_count += sec->lineno_count;
-
-             if (info->relocateable)
-               o->reloc_count += sec->reloc_count;
-
-             if (sec->_raw_size > max_contents_size)
-               max_contents_size = sec->_raw_size;
-             if (sec->lineno_count > max_lineno_count)
-               max_lineno_count = sec->lineno_count;
-             if (sec->reloc_count > max_reloc_count)
-               max_reloc_count = sec->reloc_count;
-           }
-         else if (info->relocateable
-                  && (p->type == bfd_section_reloc_link_order
-                      || p->type == bfd_symbol_reloc_link_order))
-           ++o->reloc_count;
-       }
-      if (o->reloc_count == 0)
-       o->rel_filepos = 0;
-      else
-       {
-         o->flags |= SEC_RELOC;
-         o->rel_filepos = rel_filepos;
-         rel_filepos += o->reloc_count * relsz;
-       }
-    }
-
-  /* If doing a relocateable link, allocate space for the pointers we
-     need to keep.  */
-  if (info->relocateable)
-    {
-      unsigned int i;
-
-      /* We use section_count + 1, rather than section_count, because
-         the target_index fields are 1 based.  */
-      finfo.section_info =
-       ((struct coff_link_section_info *)
-        bfd_malloc ((abfd->section_count + 1)
-                    * sizeof (struct coff_link_section_info)));
-      if (finfo.section_info == NULL)
-       goto error_return;
-      for (i = 0; i <= abfd->section_count; i++)
-       {
-         finfo.section_info[i].relocs = NULL;
-         finfo.section_info[i].rel_hashes = NULL;
-       }
-    }
-
-  /* We now know the size of the relocs, so we can determine the file
-     positions of the line numbers.  */
-  line_filepos = rel_filepos;
-  linesz = bfd_coff_linesz (abfd);
-  max_output_reloc_count = 0;
-  for (o = abfd->sections; o != NULL; o = o->next)
-    {
-      if (o->lineno_count == 0)
-       o->line_filepos = 0;
-      else
-       {
-         o->line_filepos = line_filepos;
-         line_filepos += o->lineno_count * linesz;
-       }
-
-      if (o->reloc_count != 0)
-       {
-         /* We don't know the indices of global symbols until we have
-             written out all the local symbols.  For each section in
-             the output file, we keep an array of pointers to hash
-             table entries.  Each entry in the array corresponds to a
-             reloc.  When we find a reloc against a global symbol, we
-             set the corresponding entry in this array so that we can
-             fix up the symbol index after we have written out all the
-             local symbols.
-
-            Because of this problem, we also keep the relocs in
-            memory until the end of the link.  This wastes memory,
-            but only when doing a relocateable link, which is not the
-            common case.  */
-         BFD_ASSERT (info->relocateable);
-         finfo.section_info[o->target_index].relocs =
-           ((struct internal_reloc *)
-            bfd_malloc (o->reloc_count * sizeof (struct internal_reloc)));
-         finfo.section_info[o->target_index].rel_hashes =
-           ((struct coff_link_hash_entry **)
-            bfd_malloc (o->reloc_count
-                    * sizeof (struct coff_link_hash_entry *)));
-         if (finfo.section_info[o->target_index].relocs == NULL
-             || finfo.section_info[o->target_index].rel_hashes == NULL)
-           goto error_return;
-
-         if (o->reloc_count > max_output_reloc_count)
-           max_output_reloc_count = o->reloc_count;
-       }
-
-      /* Reset the reloc and lineno counts, so that we can use them to
-        count the number of entries we have output so far.  */
-      o->reloc_count = 0;
-      o->lineno_count = 0;
-    }
-
-  obj_sym_filepos (abfd) = line_filepos;
-
-  /* Figure out the largest number of symbols in an input BFD.  Take
-     the opportunity to clear the output_has_begun fields of all the
-     input BFD's.  */
-  max_sym_count = 0;
-  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
-    {
-      size_t sz;
-
-      sub->output_has_begun = false;
-      sz = obj_raw_syment_count (sub);
-      if (sz > max_sym_count)
-       max_sym_count = sz;
-    }
-
-  /* Allocate some buffers used while linking.  */
-  finfo.internal_syms = ((struct internal_syment *)
-                        bfd_malloc (max_sym_count
-                                    * sizeof (struct internal_syment)));
-  finfo.sec_ptrs = (asection **) bfd_malloc (max_sym_count
-                                            * sizeof (asection *));
-  finfo.sym_indices = (long *) bfd_malloc (max_sym_count * sizeof (long));
-  finfo.outsyms = ((bfd_byte *)
-                  bfd_malloc ((size_t) ((max_sym_count + 1) * symesz)));
-  finfo.linenos = (bfd_byte *) bfd_malloc (max_lineno_count
-                                      * bfd_coff_linesz (abfd));
-  finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
-  finfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz);
-  if (! info->relocateable)
-    finfo.internal_relocs = ((struct internal_reloc *)
-                            bfd_malloc (max_reloc_count
-                                        * sizeof (struct internal_reloc)));
-  if ((finfo.internal_syms == NULL && max_sym_count > 0)
-      || (finfo.sec_ptrs == NULL && max_sym_count > 0)
-      || (finfo.sym_indices == NULL && max_sym_count > 0)
-      || finfo.outsyms == NULL
-      || (finfo.linenos == NULL && max_lineno_count > 0)
-      || (finfo.contents == NULL && max_contents_size > 0)
-      || (finfo.external_relocs == NULL && max_reloc_count > 0)
-      || (! info->relocateable
-         && finfo.internal_relocs == NULL
-         && max_reloc_count > 0))
-    goto error_return;
-
-  /* We now know the position of everything in the file, except that
-     we don't know the size of the symbol table and therefore we don't
-     know where the string table starts.  We just build the string
-     table in memory as we go along.  We process all the relocations
-     for a single input file at once.  */
-  obj_raw_syment_count (abfd) = 0;
-
-  if (coff_backend_info (abfd)->_bfd_coff_start_final_link)
-    {
-      if (! bfd_coff_start_final_link (abfd, info))
-       goto error_return;
-    }
-
-  for (o = abfd->sections; o != NULL; o = o->next)
-    {
-      for (p = o->link_order_head; p != NULL; p = p->next)
-       {
-         if (p->type == bfd_indirect_link_order
-             && (bfd_get_flavour (p->u.indirect.section->owner)
-                 == bfd_target_coff_flavour))
-           {
-             sub = p->u.indirect.section->owner;
-#ifdef ARM_HACKS
-             if (! sub->output_has_begun && !arm_do_last(sub))
-#else
-             if (! sub->output_has_begun)
-#endif
-               {
-                 if (! _bfd_coff_link_input_bfd (&finfo, sub))
-                   goto error_return;
-                 sub->output_has_begun = true;
-               }
-           }
-         else if (p->type == bfd_section_reloc_link_order
-                  || p->type == bfd_symbol_reloc_link_order)
-           {
-             if (! _bfd_coff_reloc_link_order (abfd, &finfo, o, p))
-               goto error_return;
-           }
-         else
-           {
-             if (! _bfd_default_link_order (abfd, info, o, p))
-               goto error_return;
-           }
-       }
-    }
-
-#ifdef ARM_HACKS
-  {
-    extern bfd* arm_get_last();
-    bfd* last_one = arm_get_last();
-    if (last_one)
-      {
-       if (! _bfd_coff_link_input_bfd (&finfo, last_one))
-         goto error_return;
-       last_one->output_has_begun = true;
-      }
-  }
-#endif
-
-  /* Free up the buffers used by _bfd_coff_link_input_bfd.  */
-
-  coff_debug_merge_hash_table_free (&finfo.debug_merge);
-  debug_merge_allocated = false;
-
-  if (finfo.internal_syms != NULL)
-    {
-      free (finfo.internal_syms);
-      finfo.internal_syms = NULL;
-    }
-  if (finfo.sec_ptrs != NULL)
-    {
-      free (finfo.sec_ptrs);
-      finfo.sec_ptrs = NULL;
-    }
-  if (finfo.sym_indices != NULL)
-    {
-      free (finfo.sym_indices);
-      finfo.sym_indices = NULL;
-    }
-  if (finfo.linenos != NULL)
-    {
-      free (finfo.linenos);
-      finfo.linenos = NULL;
-    }
-  if (finfo.contents != NULL)
-    {
-      free (finfo.contents);
-      finfo.contents = NULL;
-    }
-  if (finfo.external_relocs != NULL)
-    {
-      free (finfo.external_relocs);
-      finfo.external_relocs = NULL;
-    }
-  if (finfo.internal_relocs != NULL)
-    {
-      free (finfo.internal_relocs);
-      finfo.internal_relocs = NULL;
-    }
-
-  /* The value of the last C_FILE symbol is supposed to be the symbol
-     index of the first external symbol.  Write it out again if
-     necessary.  */
-  if (finfo.last_file_index != -1
-      && (unsigned int) finfo.last_file.n_value != obj_raw_syment_count (abfd))
-    {
-      finfo.last_file.n_value = obj_raw_syment_count (abfd);
-      bfd_coff_swap_sym_out (abfd, (PTR) &finfo.last_file,
-                            (PTR) finfo.outsyms);
-      if (bfd_seek (abfd,
-                   (obj_sym_filepos (abfd)
-                    + finfo.last_file_index * symesz),
-                   SEEK_SET) != 0
-         || bfd_write (finfo.outsyms, symesz, 1, abfd) != symesz)
-       return false;
-    }
-
-  /* Write out the global symbols.  */
-  finfo.failed = false;
-  coff_link_hash_traverse (coff_hash_table (info), _bfd_coff_write_global_sym,
-                          (PTR) &finfo);
-  if (finfo.failed)
-    goto error_return;
-
-  /* The outsyms buffer is used by _bfd_coff_write_global_sym.  */
-  if (finfo.outsyms != NULL)
-    {
-      free (finfo.outsyms);
-      finfo.outsyms = NULL;
-    }
-
-  if (info->relocateable)
-    {
-      /* Now that we have written out all the global symbols, we know
-        the symbol indices to use for relocs against them, and we can
-        finally write out the relocs.  */
-      external_relocs = ((bfd_byte *)
-                        bfd_malloc (max_output_reloc_count * relsz));
-      if (external_relocs == NULL)
-       goto error_return;
-
-      for (o = abfd->sections; o != NULL; o = o->next)
-       {
-         struct internal_reloc *irel;
-         struct internal_reloc *irelend;
-         struct coff_link_hash_entry **rel_hash;
-         bfd_byte *erel;
-
-         if (o->reloc_count == 0)
-           continue;
-
-         irel = finfo.section_info[o->target_index].relocs;
-         irelend = irel + o->reloc_count;
-         rel_hash = finfo.section_info[o->target_index].rel_hashes;
-         erel = external_relocs;
-         for (; irel < irelend; irel++, rel_hash++, erel += relsz)
-           {
-             if (*rel_hash != NULL)
-               {
-                 BFD_ASSERT ((*rel_hash)->indx >= 0);
-                 irel->r_symndx = (*rel_hash)->indx;
-               }
-             bfd_coff_swap_reloc_out (abfd, (PTR) irel, (PTR) erel);
-           }
-
-         if (bfd_seek (abfd, o->rel_filepos, SEEK_SET) != 0
-             || bfd_write ((PTR) external_relocs, relsz, o->reloc_count,
-                           abfd) != relsz * o->reloc_count)
-           goto error_return;
-       }
-
-      free (external_relocs);
-      external_relocs = NULL;
-    }
-
-  /* Free up the section information.  */
-  if (finfo.section_info != NULL)
-    {
-      unsigned int i;
-
-      for (i = 0; i < abfd->section_count; i++)
-       {
-         if (finfo.section_info[i].relocs != NULL)
-           free (finfo.section_info[i].relocs);
-         if (finfo.section_info[i].rel_hashes != NULL)
-           free (finfo.section_info[i].rel_hashes);
-       }
-      free (finfo.section_info);
-      finfo.section_info = NULL;
-    }
-
-  /* If we have optimized stabs strings, output them.  */
-  if (coff_hash_table (info)->stab_info != NULL)
-    {
-      if (! _bfd_write_stab_strings (abfd, &coff_hash_table (info)->stab_info))
-       return false;
-    }
+  return (sub->output_has_begun || sub == bfd_of_glue_owner);
+}
 
-  /* Write out the string table.  */
-  if (obj_raw_syment_count (abfd) != 0)
+boolean
+coff_arm_final_link_postscript (abfd, pfinfo)
+     bfd * abfd;
+     struct coff_final_link_info * pfinfo;
+{
+  if (bfd_of_glue_owner != NULL)
     {
-      if (bfd_seek (abfd,
-                   (obj_sym_filepos (abfd)
-                    + obj_raw_syment_count (abfd) * symesz),
-                   SEEK_SET) != 0)
-       return false;
-
-#if STRING_SIZE_SIZE == 4
-      bfd_h_put_32 (abfd,
-                   _bfd_stringtab_size (finfo.strtab) + STRING_SIZE_SIZE,
-                   (bfd_byte *) strbuf);
-#else
- #error Change bfd_h_put_32
-#endif
-
-      if (bfd_write (strbuf, 1, STRING_SIZE_SIZE, abfd) != STRING_SIZE_SIZE)
-       return false;
-
-      if (! _bfd_stringtab_emit (abfd, finfo.strtab))
+      if (! _bfd_coff_link_input_bfd (pfinfo, bfd_of_glue_owner))
        return false;
+      bfd_of_glue_owner->output_has_begun = true;
     }
-
-  _bfd_stringtab_free (finfo.strtab);
-
-  /* Setting bfd_get_symcount to 0 will cause write_object_contents to
-     not try to write out the symbols.  */
-  bfd_get_symcount (abfd) = 0;
-
   return true;
+}
+#define coff_link_output_has_begun     coff_arm_link_output_has_begun
+#define coff_final_link_postscript     coff_arm_final_link_postscript
+#endif
 
- error_return:
-  if (debug_merge_allocated)
-    coff_debug_merge_hash_table_free (&finfo.debug_merge);
-  if (finfo.strtab != NULL)
-    _bfd_stringtab_free (finfo.strtab);
-  if (finfo.section_info != NULL)
-    {
-      unsigned int i;
+#define coff_SWAP_sym_in  arm_bfd_coff_swap_sym_in
 
-      for (i = 0; i < abfd->section_count; i++)
-       {
-         if (finfo.section_info[i].relocs != NULL)
-           free (finfo.section_info[i].relocs);
-         if (finfo.section_info[i].rel_hashes != NULL)
-           free (finfo.section_info[i].rel_hashes);
-       }
-      free (finfo.section_info);
-    }
-  if (finfo.internal_syms != NULL)
-    free (finfo.internal_syms);
-  if (finfo.sec_ptrs != NULL)
-    free (finfo.sec_ptrs);
-  if (finfo.sym_indices != NULL)
-    free (finfo.sym_indices);
-  if (finfo.outsyms != NULL)
-    free (finfo.outsyms);
-  if (finfo.linenos != NULL)
-    free (finfo.linenos);
-  if (finfo.contents != NULL)
-    free (finfo.contents);
-  if (finfo.external_relocs != NULL)
-    free (finfo.external_relocs);
-  if (finfo.internal_relocs != NULL)
-    free (finfo.internal_relocs);
-  if (external_relocs != NULL)
-    free (external_relocs);
-  return false;
-}
+static void coff_swap_sym_in PARAMS ((bfd *, PTR, PTR));
 
+/* Sepcial version of symbol swapper, used to grab a bfd
+   onto which the glue sections can be attached.  */
 static void
 arm_bfd_coff_swap_sym_in (abfd, ext1, in1)
-     bfd            *abfd;
-     PTR ext1;
-     PTR in1;
+     bfd abfd;
+     PTR   ext1;
+     PTR   in1;
 {
-  SYMENT *ext = (SYMENT *)ext1;
-  struct internal_syment      *in = (struct internal_syment *)in1;
   flagword flags;
-  register asection *s;
-
-  if( ext->e.e_name[0] == 0) {
-    in->_n._n_n._n_zeroes = 0;
-    in->_n._n_n._n_offset = bfd_h_get_32(abfd, (bfd_byte *) ext->e.e.e_offset);
-  }
-  else {
-#if SYMNMLEN != E_SYMNMLEN
-   -> Error, we need to cope with truncating or extending SYMNMLEN!;
-#else
-    memcpy(in->_n._n_name, ext->e.e_name, SYMNMLEN);
-#endif
-  }
-  in->n_value = bfd_h_get_32(abfd, (bfd_byte *) ext->e_value); 
-  in->n_scnum = bfd_h_get_16(abfd, (bfd_byte *) ext->e_scnum);
-  if (sizeof(ext->e_type) == 2){
-    in->n_type = bfd_h_get_16(abfd, (bfd_byte *) ext->e_type);
-  }
-  else {
-    in->n_type = bfd_h_get_32(abfd, (bfd_byte *) ext->e_type);
-  }
-  in->n_sclass = bfd_h_get_8(abfd, ext->e_sclass);
-  in->n_numaux = bfd_h_get_8(abfd, ext->e_numaux);
-
-  if (bfd_of_glue_owner != 0) /* we already have a toc, so go home */
+  register asection * s;
+
+  /* Do the normal swap in.  */
+  coff_swap_sym_in (abfd, ext1, in1);
+
+  if (bfd_of_glue_owner != NULL) /* we already have a toc, so go home */
     return;
 
-  /* save the bfd for later allocation */
+  /* Save the bfd for later allocation.  */
   bfd_of_glue_owner = abfd;
 
   s = bfd_get_section_by_name (bfd_of_glue_owner , 
@@ -2612,7 +2102,7 @@ arm_bfd_coff_swap_sym_in (abfd, ext1, in1)
        }
     }
 
-  s = bfd_get_section_by_name ( bfd_of_glue_owner , THUMB2ARM_GLUE_SECTION_NAME);
+  s = bfd_get_section_by_name (bfd_of_glue_owner , THUMB2ARM_GLUE_SECTION_NAME);
 
   if (s == NULL) 
     {
@@ -2632,34 +2122,7 @@ arm_bfd_coff_swap_sym_in (abfd, ext1, in1)
   return;
 }
 
-static bfd_coff_backend_data arm_bfd_coff_std_swap_table =
-{
-  coff_swap_aux_in, arm_bfd_coff_swap_sym_in, coff_swap_lineno_in,
-  coff_swap_aux_out, coff_swap_sym_out,
-  coff_swap_lineno_out, coff_swap_reloc_out,
-  coff_swap_filehdr_out, coff_swap_aouthdr_out,
-  coff_swap_scnhdr_out,
-  FILHSZ, AOUTSZ, SCNHSZ, SYMESZ, AUXESZ, RELSZ, LINESZ,
-#ifdef COFF_LONG_FILENAMES
-  true,
-#else
-  false,
-#endif
-#ifdef COFF_LONG_SECTION_NAMES
-  true,
-#else
-  false,
-#endif
-  COFF_DEFAULT_SECTION_ALIGNMENT_POWER,
-  coff_swap_filehdr_in, coff_swap_aouthdr_in, coff_swap_scnhdr_in,
-  coff_swap_reloc_in, coff_bad_format_hook, coff_set_arch_mach_hook,
-  coff_mkobject_hook, styp_to_sec_flags, coff_set_alignment_hook,
-  coff_slurp_symbol_table, symname_in_debug_hook, coff_pointerize_aux_hook,
-  coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
-  coff_sym_is_global, coff_compute_section_file_positions,
-  coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
-  coff_adjust_symndx, coff_link_add_one_symbol
-};
+#include "coffcode.h"
 
 const bfd_target
 #ifdef TARGET_LITTLE_SYM
@@ -2721,7 +2184,7 @@ armcoff_little_vec =
      BFD_JUMP_TABLE_LINK (coff),
      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
 
-  & arm_bfd_coff_std_swap_table,
+  (PTR) & bfd_coff_std_swap_table,
 };
 
 const bfd_target
@@ -2784,5 +2247,5 @@ armcoff_big_vec =
      BFD_JUMP_TABLE_LINK (coff),
      BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
 
-  & arm_bfd_coff_std_swap_table,
+  (PTR) & bfd_coff_std_swap_table,
 };