* v850-tdep.c (elf-bfd.h, elf/v850.h): Include.
[deliverable/binutils-gdb.git] / bfd / ecoff.c
index af9d7d6a7ff8bc8bf96fa09cf3def3d2496f86b6..5add50cf506df56ecaa9e3272e18a7e2a7fff6d1 100644 (file)
@@ -1,7 +1,5 @@
 /* Generic ECOFF (Extended-COFF) routines.
-   Copyright 1990, 1991, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright 1990-2013 Free Software Foundation, Inc.
    Original version by Per Bothner.
    Full support added by Ian Lance Taylor, ian@cygnus.com.
 
@@ -55,14 +53,14 @@ static asection bfd_debug_section =
 {
   /* name,      id,  index, next, prev, flags, user_set_vma,       */
      "*DEBUG*", 0,   0,     NULL, NULL, 0,     0,
-  /* linker_mark, linker_has_input, gc_mark, segment_mark,         */
+  /* linker_mark, linker_has_input, gc_mark, compress_status,      */
      0,           0,                1,       0,
-  /* sec_info_type, use_rela_p,                                    */
-     0,             0,
+  /* segment_mark, sec_info_type, use_rela_p,                      */
+     0,            0,             0,
   /* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5,   */
      0,        0,        0,        0,        0,        0,
-  /* vma, lma, size, rawsize, relax, relax_count,                  */
-     0,   0,   0,    0,       0,     0,
+  /* vma, lma, size, rawsize, compressed_size, relax, relax_count, */
+     0,   0,   0,    0,       0,               0,     0,
   /* output_offset, output_section, alignment_power,               */
      0,             NULL,           0,
   /* relocation, orelocation, reloc_count, filepos, rel_filepos,   */
@@ -234,9 +232,7 @@ _bfd_ecoff_set_arch_mach_hook (bfd *abfd, void * filehdr)
 }
 
 bfd_boolean
-_bfd_ecoff_no_long_sections (abfd, enable)
-     bfd *abfd;
-     int enable;
+_bfd_ecoff_no_long_sections (bfd *abfd, int enable)
 {
   (void) abfd;
   (void) enable;
@@ -1890,7 +1886,7 @@ _bfd_ecoff_sizeof_headers (bfd *abfd,
   ret = (bfd_coff_filhsz (abfd)
         + bfd_coff_aoutsz (abfd)
         + c * bfd_coff_scnhsz (abfd));
-  return BFD_ALIGN (ret, 16);
+  return (int) BFD_ALIGN (ret, 16);
 }
 
 /* Get the contents of a section.  */
@@ -2906,7 +2902,7 @@ _bfd_ecoff_slurp_armap (bfd *abfd)
   if (mapdata == NULL)
     return FALSE;
   parsed_size = mapdata->parsed_size;
-  bfd_release (abfd, (void *) mapdata);
+  free (mapdata);
 
   raw_armap = (char *) bfd_alloc (abfd, parsed_size);
   if (raw_armap == NULL)
@@ -3231,14 +3227,6 @@ _bfd_ecoff_bfd_link_hash_table_create (bfd *abfd)
   ((struct ecoff_link_hash_entry *) \
    bfd_link_hash_lookup (&(table)->root, (string), (create), (copy), (follow)))
 
-/* Traverse an ECOFF link hash table.  */
-
-#define ecoff_link_hash_traverse(table, func, info)                    \
-  (bfd_link_hash_traverse                                              \
-   (&(table)->root,                                                    \
-    (bfd_boolean (*) (struct bfd_link_hash_entry *, void *)) (func),   \
-    (info)))
-
 /* Get the ECOFF link hash table from the info structure.  This is
    just a cast.  */
 
@@ -3509,6 +3497,58 @@ ecoff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
   return FALSE;
 }
 
+/* Factored out from ecoff_link_check_archive_element.  */
+
+static bfd_boolean
+read_ext_syms_and_strs (HDRR **symhdr, bfd_size_type *external_ext_size,
+       bfd_size_type *esize, void **external_ext, char **ssext, bfd *abfd,
+       const struct ecoff_backend_data * const backend)
+{
+  if (! ecoff_slurp_symbolic_header (abfd))
+    return FALSE;
+
+  /* If there are no symbols, we don't want it.  */
+  if (bfd_get_symcount (abfd) == 0)
+    return TRUE;
+
+  *symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
+
+  *external_ext_size = backend->debug_swap.external_ext_size;
+  *esize = (*symhdr)->iextMax * *external_ext_size;
+  *external_ext = bfd_malloc (*esize);
+  if (*external_ext == NULL && *esize != 0)
+    return FALSE;
+
+  if (bfd_seek (abfd, (file_ptr) (*symhdr)->cbExtOffset, SEEK_SET) != 0
+      || bfd_bread (*external_ext, *esize, abfd) != *esize)
+    return FALSE;
+
+  *ssext = (char *) bfd_malloc ((bfd_size_type) (*symhdr)->issExtMax);
+  if (*ssext == NULL && (*symhdr)->issExtMax != 0)
+    return FALSE;
+
+  if (bfd_seek (abfd, (file_ptr) (*symhdr)->cbSsExtOffset, SEEK_SET) != 0
+      || (bfd_bread (*ssext, (bfd_size_type) (*symhdr)->issExtMax, abfd)
+         != (bfd_size_type) (*symhdr)->issExtMax))
+    return FALSE;
+  return TRUE;
+}
+
+static bfd_boolean
+reread_ext_syms_and_strs (HDRR **symhdr, bfd_size_type *external_ext_size,
+       bfd_size_type *esize, void **external_ext, char **ssext, bfd *abfd,
+       const struct ecoff_backend_data * const backend)
+{
+  if (*external_ext != NULL)
+    free (*external_ext);
+  *external_ext = NULL;
+  if (*ssext != NULL)
+    free (*ssext);
+  *ssext = NULL;
+  return read_ext_syms_and_strs (symhdr, external_ext_size, esize,
+                               external_ext, ssext, abfd, backend);
+}
+
 /* This is called if we used _bfd_generic_link_add_archive_symbols
    because we were not dealing with an ECOFF archive.  */
 
@@ -3530,35 +3570,15 @@ ecoff_link_check_archive_element (bfd *abfd,
 
   *pneeded = FALSE;
 
-  if (! ecoff_slurp_symbolic_header (abfd))
+  /* Read in the external symbols and external strings.  */
+  if (!read_ext_syms_and_strs (&symhdr, &external_ext_size, &esize,
+       &external_ext, &ssext, abfd, backend))
     goto error_return;
 
   /* If there are no symbols, we don't want it.  */
   if (bfd_get_symcount (abfd) == 0)
     goto successful_return;
 
-  symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
-
-  /* Read in the external symbols and external strings.  */
-  external_ext_size = backend->debug_swap.external_ext_size;
-  esize = symhdr->iextMax * external_ext_size;
-  external_ext = bfd_malloc (esize);
-  if (external_ext == NULL && esize != 0)
-    goto error_return;
-
-  if (bfd_seek (abfd, (file_ptr) symhdr->cbExtOffset, SEEK_SET) != 0
-      || bfd_bread (external_ext, esize, abfd) != esize)
-    goto error_return;
-
-  ssext = (char *) bfd_malloc ((bfd_size_type) symhdr->issExtMax);
-  if (ssext == NULL && symhdr->issExtMax != 0)
-    goto error_return;
-
-  if (bfd_seek (abfd, (file_ptr) symhdr->cbSsExtOffset, SEEK_SET) != 0
-      || (bfd_bread (ssext, (bfd_size_type) symhdr->issExtMax, abfd)
-         != (bfd_size_type) symhdr->issExtMax))
-    goto error_return;
-
   /* Look through the external symbols to see if they define some
      symbol that is currently undefined.  */
   ext_ptr = (char *) external_ext;
@@ -3568,6 +3588,7 @@ ecoff_link_check_archive_element (bfd *abfd,
       EXTR esym;
       bfd_boolean def;
       const char *name;
+      bfd *oldbfd;
       struct bfd_link_hash_entry *h;
 
       (*swap_ext_in) (abfd, (void *) ext_ptr, &esym);
@@ -3612,7 +3633,15 @@ ecoff_link_check_archive_element (bfd *abfd,
        continue;
 
       /* Include this element.  */
-      if (! (*info->callbacks->add_archive_element) (info, abfd, name))
+      oldbfd = abfd;
+      if (!(*info->callbacks
+           ->add_archive_element) (info, abfd, name, &abfd))
+       goto error_return;
+      /* Potentially, the add_archive_element hook may have set a
+        substitute BFD for us.  */
+      if (abfd != oldbfd
+         && !reread_ext_syms_and_strs (&symhdr, &external_ext_size, &esize,
+                                       &external_ext, &ssext, abfd, backend))
        goto error_return;
       if (! ecoff_link_add_externals (abfd, info, external_ext, ssext))
        goto error_return;
@@ -3777,7 +3806,8 @@ ecoff_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
       /* Unlike the generic linker, we know that this element provides
         a definition for an undefined symbol and we know that we want
         to include it.  We don't need to check anything.  */
-      if (! (*info->callbacks->add_archive_element) (info, element, name))
+      if (!(*info->callbacks
+           ->add_archive_element) (info, element, name, &element))
        return FALSE;
       if (! ecoff_link_add_object_symbols (element, info))
        return FALSE;
@@ -4217,8 +4247,9 @@ ecoff_reloc_link_order (bfd *output_bfd,
    the hash table.  */
 
 static bfd_boolean
-ecoff_link_write_external (struct ecoff_link_hash_entry *h, void * data)
+ecoff_link_write_external (struct bfd_hash_entry *bh, void * data)
 {
+  struct ecoff_link_hash_entry *h = (struct ecoff_link_hash_entry *) bh;
   struct extsym_info *einfo = (struct extsym_info *) data;
   bfd *output_bfd = einfo->abfd;
   bfd_boolean strip;
@@ -4449,9 +4480,7 @@ _bfd_ecoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
   /* Write out the external symbols.  */
   einfo.abfd = abfd;
   einfo.info = info;
-  ecoff_link_hash_traverse (ecoff_hash_table (info),
-                           ecoff_link_write_external,
-                           (void *) &einfo);
+  bfd_hash_traverse (&info->hash->table, ecoff_link_write_external, &einfo);
 
   if (info->relocatable)
     {
This page took 0.04197 seconds and 4 git commands to generate.