ChangeLog rotatation and copyright year update
[deliverable/binutils-gdb.git] / bfd / ecoff.c
index 0416c23686840ead3e6ff95f5d097df533451aae..f4f45a4a82cd1895cf173ada49fff1f3630ed1cf 100644 (file)
@@ -1,6 +1,5 @@
 /* Generic ECOFF (Extended-COFF) routines.
-   Copyright 1990, 1991, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1990-2015 Free Software Foundation, Inc.
    Original version by Per Bothner.
    Full support added by Ian Lance Taylor, ian@cygnus.com.
 
@@ -8,7 +7,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
 
    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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
-#include "bfd.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "bfdlink.h"
 #include "libbfd.h"
 #include "aout/ar.h"
-#include "aout/ranlib.h"
 #include "aout/stab_gnu.h"
 
 /* FIXME: We need the definitions of N_SET[ADTB], but aout64.h defines
@@ -54,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, gc_mark_from_eh,      */
+  /* linker_mark, linker_has_input, gc_mark, compress_status,      */
      0,           0,                1,       0,
-  /* segment_mark, sec_info_type, use_rela_p, has_tls_reloc,       */
-     0,            0,             0,          0,
-  /* has_gp_reloc, need_finalize_relax, reloc_done,                */
-     0,            0,                   0,
-  /* vma, lma, size, rawsize,                                      */
-     0,   0,   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, 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,   */
@@ -87,7 +86,7 @@ _bfd_ecoff_mkobject (bfd *abfd)
 {
   bfd_size_type amt = sizeof (ecoff_data_type);
 
-  abfd->tdata.ecoff_obj_data = bfd_zalloc (abfd, amt);
+  abfd->tdata.ecoff_obj_data = (struct ecoff_tdata *) bfd_zalloc (abfd, amt);
   if (abfd->tdata.ecoff_obj_data == NULL)
     return FALSE;
 
@@ -191,7 +190,7 @@ _bfd_ecoff_new_section_hook (bfd *abfd, asection *section)
 bfd_boolean
 _bfd_ecoff_set_arch_mach_hook (bfd *abfd, void * filehdr)
 {
-  struct internal_filehdr *internal_f = filehdr;
+  struct internal_filehdr *internal_f = (struct internal_filehdr *) filehdr;
   enum bfd_architecture arch;
   unsigned long mach;
 
@@ -232,6 +231,14 @@ _bfd_ecoff_set_arch_mach_hook (bfd *abfd, void * filehdr)
   return bfd_default_set_arch_mach (abfd, arch, mach);
 }
 
+bfd_boolean
+_bfd_ecoff_no_long_sections (bfd *abfd, int enable)
+{
+  (void) abfd;
+  (void) enable;
+  return FALSE;
+}
+
 /* Get the magic number to use based on the architecture and machine.
    This is the inverse of _bfd_ecoff_set_arch_mach_hook, above.  */
 
@@ -354,7 +361,7 @@ _bfd_ecoff_styp_to_sec_flags (bfd *abfd ATTRIBUTE_UNUSED,
                              asection *section ATTRIBUTE_UNUSED,
                              flagword * flags_ptr)
 {
-  struct internal_scnhdr *internal_s = hdr;
+  struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
   long styp_flags = internal_s->s_flags;
   flagword sec_flags = 0;
 
@@ -602,12 +609,15 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd,
      the symbols, so we swap them here.  */
   amt = internal_symhdr->ifdMax;
   amt *= sizeof (struct fdr);
-  debug->fdr = bfd_alloc (abfd, amt);
+  debug->fdr = (FDR *) bfd_alloc (abfd, amt);
   if (debug->fdr == NULL)
     return FALSE;
   external_fdr_size = backend->debug_swap.external_fdr_size;
   fdr_ptr = debug->fdr;
   fraw_src = (char *) debug->external_fdr;
+  /* PR 17512: file: 3372-1243-0.004.  */
+  if (fraw_src == NULL && internal_symhdr->ifdMax > 0)
+    return FALSE;
   fraw_end = fraw_src + internal_symhdr->ifdMax * external_fdr_size;
   for (; fraw_src < fraw_end; fraw_src += external_fdr_size, fdr_ptr++)
     (*backend->debug_swap.swap_fdr_in) (abfd, (void *) fraw_src, fdr_ptr);
@@ -632,18 +642,18 @@ static asymbol *ecoff_scom_symbol_ptr;
 asymbol *
 _bfd_ecoff_make_empty_symbol (bfd *abfd)
 {
-  ecoff_symbol_type *new;
+  ecoff_symbol_type *new_symbol;
   bfd_size_type amt = sizeof (ecoff_symbol_type);
 
-  new = bfd_zalloc (abfd, amt);
-  if (new == NULL)
+  new_symbol = (ecoff_symbol_type *) bfd_zalloc (abfd, amt);
+  if (new_symbol == NULL)
     return NULL;
-  new->symbol.section = NULL;
-  new->fdr = NULL;
-  new->local = FALSE;
-  new->native = NULL;
-  new->symbol.the_bfd = abfd;
-  return &new->symbol;
+  new_symbol->symbol.section = NULL;
+  new_symbol->fdr = NULL;
+  new_symbol->local = FALSE;
+  new_symbol->native = NULL;
+  new_symbol->symbol.the_bfd = abfd;
+  return &new_symbol->symbol;
 }
 
 /* Set the BFD flags and section for an ECOFF symbol.  */
@@ -870,7 +880,7 @@ _bfd_ecoff_slurp_symbol_table (bfd *abfd)
 
   internal_size = bfd_get_symcount (abfd);
   internal_size *= sizeof (ecoff_symbol_type);
-  internal = bfd_alloc (abfd, internal_size);
+  internal = (ecoff_symbol_type *) bfd_alloc (abfd, internal_size);
   if (internal == NULL)
     return FALSE;
 
@@ -884,12 +894,18 @@ _bfd_ecoff_slurp_symbol_table (bfd *abfd)
       EXTR internal_esym;
 
       (*swap_ext_in) (abfd, (void *) eraw_src, &internal_esym);
+
+      /* PR 17512: file: 3372-1000-0.004.  */
+      if (internal_esym.asym.iss >= ecoff_data (abfd)->debug_info.symbolic_header.issExtMax)
+       return FALSE;
+
       internal_ptr->symbol.name = (ecoff_data (abfd)->debug_info.ssext
                                   + internal_esym.asym.iss);
       if (!ecoff_set_symbol_info (abfd, &internal_esym.asym,
                                  &internal_ptr->symbol, 1,
                                  internal_esym.weakext))
        return FALSE;
+      
       /* The alpha uses a negative ifd field for section symbols.  */
       if (internal_esym.ifd >= 0)
        internal_ptr->fdr = (ecoff_data (abfd)->debug_info.fdr
@@ -931,6 +947,20 @@ _bfd_ecoff_slurp_symbol_table (bfd *abfd)
        }
     }
 
+  /* PR 17512: file: 3372-3080-0.004.
+     A discrepancy between ecoff_data (abfd)->debug_info.symbolic_header.isymMax
+     and ecoff_data (abfd)->debug_info.symbolic_header.ifdMax can mean that
+     we have fewer symbols than we were expecting.  Allow for this by updating
+     the symbol count and warning the user.  */
+  if (internal_ptr - internal < (ptrdiff_t) bfd_get_symcount (abfd))
+    {
+      bfd_get_symcount (abfd) = internal_ptr - internal;
+      (*_bfd_error_handler)
+       (_("%B: warning: isymMax (%ld) is greater than ifdMax (%d)\n"),
+        abfd, ecoff_data (abfd)->debug_info.symbolic_header.isymMax,
+        ecoff_data (abfd)->debug_info.symbolic_header.ifdMax);
+    }
+
   ecoff_data (abfd)->canonical_symbols = internal;
 
   return TRUE;
@@ -1037,7 +1067,7 @@ ecoff_emit_aggregate (bfd *abfd,
   sprintf (string,
           "%s %s { ifd = %u, index = %lu }",
           which, name, ifd,
-          ((long) indx
+          ((unsigned long) indx
            + debug_info->symbolic_header.iextMax));
 }
 
@@ -1568,11 +1598,11 @@ ecoff_slurp_reloc_table (bfd *abfd,
 
   amt = section->reloc_count;
   amt *= sizeof (arelent);
-  internal_relocs = bfd_alloc (abfd, amt);
+  internal_relocs = (arelent *) bfd_alloc (abfd, amt);
 
   external_reloc_size = backend->external_reloc_size;
   amt = external_reloc_size * section->reloc_count;
-  external_relocs = bfd_alloc (abfd, amt);
+  external_relocs = (char *) bfd_alloc (abfd, amt);
   if (internal_relocs == NULL || external_relocs == NULL)
     return FALSE;
   if (bfd_seek (abfd, section->rel_filepos, SEEK_SET) != 0)
@@ -1697,12 +1727,13 @@ _bfd_ecoff_canonicalize_reloc (bfd *abfd,
 
 bfd_boolean
 _bfd_ecoff_find_nearest_line (bfd *abfd,
+                             asymbol **symbols ATTRIBUTE_UNUSED,
                              asection *section,
-                             asymbol **ignore_symbols ATTRIBUTE_UNUSED,
                              bfd_vma offset,
                              const char **filename_ptr,
                              const char **functionname_ptr,
-                             unsigned int *retline_ptr)
+                             unsigned int *retline_ptr,
+                             unsigned int *discriminator_ptr)
 {
   const struct ecoff_debug_swap * const debug_swap
     = &ecoff_backend (abfd)->debug_swap;
@@ -1718,12 +1749,15 @@ _bfd_ecoff_find_nearest_line (bfd *abfd,
     {
       bfd_size_type amt = sizeof (struct ecoff_find_line);
 
-      ecoff_data (abfd)->find_line_info = bfd_zalloc (abfd, amt);
+      ecoff_data (abfd)->find_line_info =
+          (struct ecoff_find_line *) bfd_zalloc (abfd, amt);
       if (ecoff_data (abfd)->find_line_info == NULL)
        return FALSE;
     }
-  line_info = ecoff_data (abfd)->find_line_info;
 
+  if (discriminator_ptr)
+    *discriminator_ptr = 0;
+  line_info = ecoff_data (abfd)->find_line_info;
   return _bfd_ecoff_locate_line (abfd, section, offset, debug_info,
                                 debug_swap, line_info, filename_ptr,
                                 functionname_ptr, retline_ptr);
@@ -1862,7 +1896,8 @@ _bfd_ecoff_set_arch_mach (bfd *abfd,
 /* Get the size of the section headers.  */
 
 int
-_bfd_ecoff_sizeof_headers (bfd *abfd, bfd_boolean reloc ATTRIBUTE_UNUSED)
+_bfd_ecoff_sizeof_headers (bfd *abfd,
+                          struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
   asection *current;
   int c;
@@ -1877,7 +1912,7 @@ _bfd_ecoff_sizeof_headers (bfd *abfd, bfd_boolean reloc ATTRIBUTE_UNUSED)
   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.  */
@@ -1936,13 +1971,13 @@ ecoff_compute_section_file_positions (bfd *abfd)
   const bfd_vma round = ecoff_backend (abfd)->round;
   bfd_size_type amt;
 
-  sofar = _bfd_ecoff_sizeof_headers (abfd, FALSE);
+  sofar = _bfd_ecoff_sizeof_headers (abfd, NULL);
   file_sofar = sofar;
 
   /* Sort the sections by VMA.  */
   amt = abfd->section_count;
   amt *= sizeof (asection *);
-  sorted_hdrs = bfd_malloc (amt);
+  sorted_hdrs = (asection **) bfd_malloc (amt);
   if (sorted_hdrs == NULL)
     return FALSE;
   for (current = abfd->sections, i = 0;
@@ -2357,7 +2392,7 @@ _bfd_ecoff_write_object_contents (bfd *abfd)
     }
 
   if ((abfd->flags & D_PAGED) != 0)
-    text_size = _bfd_ecoff_sizeof_headers (abfd, FALSE);
+    text_size = _bfd_ecoff_sizeof_headers (abfd, NULL);
   else
     text_size = 0;
   text_start = 0;
@@ -2663,7 +2698,7 @@ _bfd_ecoff_write_object_contents (bfd *abfd)
              else
                {
                  const char *name;
-                 unsigned int i;
+                 unsigned int j;
                  static struct
                  {
                    const char * name;
@@ -2690,14 +2725,14 @@ _bfd_ecoff_write_object_contents (bfd *abfd)
 
                  name = bfd_get_section_name (abfd, bfd_get_section (sym));
 
-                 for (i = 0; i < ARRAY_SIZE (section_symndx); i++)
-                   if (streq (name, section_symndx[i].name))
+                 for (j = 0; j < ARRAY_SIZE (section_symndx); j++)
+                   if (streq (name, section_symndx[j].name))
                      {
-                       in.r_symndx = section_symndx[i].r_symndx;
+                       in.r_symndx = section_symndx[j].r_symndx;
                        break;
                      }
 
-                 if (i == ARRAY_SIZE (section_symndx))
+                 if (j == ARRAY_SIZE (section_symndx))
                    abort ();
                  in.r_extern = 0;
                }
@@ -2841,7 +2876,7 @@ _bfd_ecoff_slurp_armap (bfd *abfd)
   struct artdata *ardata;
   unsigned int count;
   char *raw_ptr;
-  struct symdef *symdef_ptr;
+  carsym *symdef_ptr;
   char *stringbase;
   bfd_size_type amt;
 
@@ -2860,7 +2895,7 @@ _bfd_ecoff_slurp_armap (bfd *abfd)
      bfd_slurp_armap, but that seems inappropriate since no other
      target uses this format.  Instead, we check directly for a COFF
      armap.  */
-  if (strneq (nextname, "/               ", 16))
+  if (CONST_STRNEQ (nextname, "/               "))
     return bfd_slurp_armap (abfd);
 
   /* See if the first element is an armap.  */
@@ -2893,9 +2928,9 @@ _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 = bfd_alloc (abfd, parsed_size);
+  raw_armap = (char *) bfd_alloc (abfd, parsed_size);
   if (raw_armap == NULL)
     return FALSE;
 
@@ -2961,12 +2996,12 @@ _bfd_ecoff_slurp_armap (bfd *abfd)
       ++ardata->symdef_count;
 
   amt = ardata->symdef_count;
-  amt *= sizeof (struct symdef);
-  symdef_ptr = bfd_alloc (abfd, amt);
+  amt *= sizeof (carsym);
+  symdef_ptr = (carsym *) bfd_alloc (abfd, amt);
   if (!symdef_ptr)
     return FALSE;
 
-  ardata->symdefs = (carsym *) symdef_ptr;
+  ardata->symdefs = symdef_ptr;
 
   raw_ptr = raw_armap + 4;
   for (i = 0; i < count; i++, raw_ptr += 8)
@@ -2977,7 +3012,7 @@ _bfd_ecoff_slurp_armap (bfd *abfd)
       if (file_offset == 0)
        continue;
       name_offset = H_GET_32 (abfd, raw_ptr);
-      symdef_ptr->s.name = stringbase + name_offset;
+      symdef_ptr->name = stringbase + name_offset;
       symdef_ptr->file_offset = file_offset;
       ++symdef_ptr;
     }
@@ -3049,7 +3084,8 @@ _bfd_ecoff_write_armap (bfd *abfd,
      linker just checks the archive name; the GNU linker may check the
      date.  */
   stat (abfd->filename, &statbuf);
-  sprintf (hdr.ar_date, "%ld", (long) (statbuf.st_mtime + 60));
+  _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
+                   (long) (statbuf.st_mtime + 60));
 
   /* The DECstation uses zeroes for the uid, gid and mode of the
      armap.  */
@@ -3060,7 +3096,7 @@ _bfd_ecoff_write_armap (bfd *abfd,
   hdr.ar_mode[1] = '4';
   hdr.ar_mode[2] = '4';
 
-  sprintf (hdr.ar_size, "%-10d", (int) mapsize);
+  _bfd_ar_spacepad (hdr.ar_size, sizeof (hdr.ar_size), "%-10ld", mapsize);
 
   hdr.ar_fmag[0] = '`';
   hdr.ar_fmag[1] = '\012';
@@ -3078,7 +3114,7 @@ _bfd_ecoff_write_armap (bfd *abfd,
   if (bfd_bwrite ((void *) temp, (bfd_size_type) 4, abfd) != 4)
     return FALSE;
 
-  hashtable = bfd_zalloc (abfd, symdefsize);
+  hashtable = (bfd_byte *) bfd_zalloc (abfd, symdefsize);
   if (!hashtable)
     return FALSE;
 
@@ -3086,7 +3122,7 @@ _bfd_ecoff_write_armap (bfd *abfd,
   last_elt = current;
   for (i = 0; i < orl_count; i++)
     {
-      unsigned int hash, rehash;
+      unsigned int hash, rehash = 0;
 
       /* Advance firstreal to the file position of this archive
         element.  */
@@ -3096,7 +3132,7 @@ _bfd_ecoff_write_armap (bfd *abfd,
            {
              firstreal += arelt_size (current) + sizeof (struct ar_hdr);
              firstreal += firstreal % 2;
-             current = current->next;
+             current = current->archive_next;
            }
          while (current != map[i].u.abfd);
        }
@@ -3152,89 +3188,6 @@ _bfd_ecoff_write_armap (bfd *abfd,
 
   return TRUE;
 }
-
-/* See whether this BFD is an archive.  If it is, read in the armap
-   and the extended name table.  */
-
-const bfd_target *
-_bfd_ecoff_archive_p (bfd *abfd)
-{
-  struct artdata *tdata_hold;
-  char armag[SARMAG + 1];
-  bfd_size_type amt;
-
-  if (bfd_bread ((void *) armag, (bfd_size_type) SARMAG, abfd) != SARMAG)
-    {
-      if (bfd_get_error () != bfd_error_system_call)
-       bfd_set_error (bfd_error_wrong_format);
-      return NULL;
-    }
-
-  if (! strneq (armag, ARMAG, SARMAG))
-    {
-      bfd_set_error (bfd_error_wrong_format);
-      return NULL;
-    }
-
-  tdata_hold = bfd_ardata (abfd);
-
-  amt = sizeof (struct artdata);
-  bfd_ardata (abfd) = bfd_zalloc (abfd, amt);
-  if (bfd_ardata (abfd) == NULL)
-    {
-      bfd_ardata (abfd) = tdata_hold;
-      return NULL;
-    }
-
-  bfd_ardata (abfd)->first_file_filepos = SARMAG;
-  /* Already cleared by bfd_zalloc above.
-     bfd_ardata (abfd)->cache = NULL;
-     bfd_ardata (abfd)->archive_head = NULL;
-     bfd_ardata (abfd)->symdefs = NULL;
-     bfd_ardata (abfd)->extended_names = NULL;
-     bfd_ardata (abfd)->extended_names_size = 0;
-     bfd_ardata (abfd)->tdata = NULL;  */
-
-  if (! _bfd_ecoff_slurp_armap (abfd)
-      || ! _bfd_ecoff_slurp_extended_name_table (abfd))
-    {
-      bfd_release (abfd, bfd_ardata (abfd));
-      bfd_ardata (abfd) = tdata_hold;
-      return NULL;
-    }
-
-  if (bfd_has_map (abfd))
-    {
-      bfd *first;
-
-      /* This archive has a map, so we may presume that the contents
-        are object files.  Make sure that if the first file in the
-        archive can be recognized as an object file, it is for this
-        target.  If not, assume that this is the wrong format.  If
-        the first file is not an object file, somebody is doing
-        something weird, and we permit it so that ar -t will work.  */
-
-      first = bfd_openr_next_archived_file (abfd, NULL);
-      if (first != NULL)
-       {
-         first->target_defaulted = FALSE;
-         if (bfd_check_format (first, bfd_object)
-             && first->xvec != abfd->xvec)
-           {
-             /* We ought to close `first' here, but we can't, because
-                we have no way to remove it from the archive cache.
-                It's almost impossible to figure out when we can
-                release bfd_ardata.  FIXME.  */
-             bfd_set_error (bfd_error_wrong_object_format);
-             bfd_ardata (abfd) = tdata_hold;
-             return NULL;
-           }
-         /* And we ought to close `first' here too.  */
-       }
-    }
-
-  return abfd->xvec;
-}
 \f
 /* ECOFF linker code.  */
 
@@ -3281,7 +3234,7 @@ _bfd_ecoff_bfd_link_hash_table_create (bfd *abfd)
   struct ecoff_link_hash_table *ret;
   bfd_size_type amt = sizeof (struct ecoff_link_hash_table);
 
-  ret = bfd_malloc (amt);
+  ret = (struct ecoff_link_hash_table *) bfd_malloc (amt);
   if (ret == NULL)
     return NULL;
   if (!_bfd_link_hash_table_init (&ret->root, abfd,
@@ -3300,14 +3253,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.  */
 
@@ -3339,7 +3284,7 @@ ecoff_link_add_externals (bfd *abfd,
 
   amt = ext_count;
   amt *= sizeof (struct bfd_link_hash_entry *);
-  sym_hash = bfd_alloc (abfd, amt);
+  sym_hash = (struct bfd_link_hash_entry **) bfd_alloc (abfd, amt);
   if (!sym_hash)
     return FALSE;
   ecoff_data (abfd)->sym_hashes = (struct ecoff_link_hash_entry **) sym_hash;
@@ -3483,7 +3428,7 @@ ecoff_link_add_externals (bfd *abfd,
 
       /* If we are building an ECOFF hash table, save the external
         symbol information.  */
-      if (info->hash->creator->flavour == bfd_get_flavour (abfd))
+      if (bfd_get_flavour (info->output_bfd) == bfd_get_flavour (abfd))
        {
          if (h->abfd == NULL
              || (! bfd_is_und_section (section)
@@ -3553,7 +3498,7 @@ ecoff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
       || bfd_bread (external_ext, esize, abfd) != esize)
     goto error_return;
 
-  ssext = bfd_malloc ((bfd_size_type) symhdr->issExtMax);
+  ssext = (char *) bfd_malloc ((bfd_size_type) symhdr->issExtMax);
   if (ssext == NULL && symhdr->issExtMax != 0)
     goto error_return;
 
@@ -3584,124 +3529,23 @@ ecoff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
 static bfd_boolean
 ecoff_link_check_archive_element (bfd *abfd,
                                  struct bfd_link_info *info,
+                                 struct bfd_link_hash_entry *h,
+                                 const char *name,
                                  bfd_boolean *pneeded)
 {
-  const struct ecoff_backend_data * const backend = ecoff_backend (abfd);
-  void (* const swap_ext_in) (bfd *, void *, EXTR *)
-    = backend->debug_swap.swap_ext_in;
-  HDRR *symhdr;
-  bfd_size_type external_ext_size;
-  void * external_ext = NULL;
-  bfd_size_type esize;
-  char *ssext = NULL;
-  char *ext_ptr;
-  char *ext_end;
-
   *pneeded = FALSE;
 
-  if (! ecoff_slurp_symbolic_header (abfd))
-    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 = 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;
-  ext_end = ext_ptr + esize;
-  for (; ext_ptr < ext_end; ext_ptr += external_ext_size)
-    {
-      EXTR esym;
-      bfd_boolean def;
-      const char *name;
-      struct bfd_link_hash_entry *h;
-
-      (*swap_ext_in) (abfd, (void *) ext_ptr, &esym);
-
-      /* See if this symbol defines something.  */
-      if (esym.asym.st != stGlobal
-         && esym.asym.st != stLabel
-         && esym.asym.st != stProc)
-       continue;
-
-      switch (esym.asym.sc)
-       {
-       case scText:
-       case scData:
-       case scBss:
-       case scAbs:
-       case scSData:
-       case scSBss:
-       case scRData:
-       case scCommon:
-       case scSCommon:
-       case scInit:
-       case scFini:
-       case scRConst:
-         def = TRUE;
-         break;
-       default:
-         def = FALSE;
-         break;
-       }
-
-      if (! def)
-       continue;
-
-      name = ssext + esym.asym.iss;
-      h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
-
-      /* Unlike the generic linker, we do not pull in elements because
-        of common symbols.  */
-      if (h == NULL
-         || h->type != bfd_link_hash_undefined)
-       continue;
-
-      /* Include this element.  */
-      if (! (*info->callbacks->add_archive_element) (info, abfd, name))
-       goto error_return;
-      if (! ecoff_link_add_externals (abfd, info, external_ext, ssext))
-       goto error_return;
+  /* Unlike the generic linker, we do not pull in elements because
+     of common symbols.  */
+  if (h->type != bfd_link_hash_undefined)
+    return TRUE;
 
-      *pneeded = TRUE;
-      goto successful_return;
-    }
+  /* Include this element.  */
+  if (!(*info->callbacks->add_archive_element) (info, abfd, name, &abfd))
+    return FALSE;
+  *pneeded = TRUE;
 
- successful_return:
-  if (external_ext != NULL)
-    free (external_ext);
-  if (ssext != NULL)
-    free (ssext);
-  return TRUE;
- error_return:
-  if (external_ext != NULL)
-    free (external_ext);
-  if (ssext != NULL)
-    free (ssext);
-  return FALSE;
+  return ecoff_link_add_object_symbols (abfd, info);
 }
 
 /* Add the symbols from an archive file to the global hash table.
@@ -3756,7 +3600,7 @@ ecoff_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
   while (*pundef != NULL)
     {
       struct bfd_link_hash_entry *h;
-      unsigned int hash, rehash;
+      unsigned int hash, rehash = 0;
       unsigned int file_offset;
       const char *name;
       bfd *element;
@@ -3846,7 +3690,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;
@@ -3908,7 +3753,7 @@ ecoff_final_link_debug_accumulate (bfd *output_bfd,
   else                                                                  \
     {                                                                   \
       bfd_size_type amt = (bfd_size_type) size * symhdr->count;                 \
-      debug->ptr = bfd_malloc (amt);                                    \
+      debug->ptr = (type) bfd_malloc (amt);                              \
       if (debug->ptr == NULL)                                           \
        {                                                                \
           ret = FALSE;                                                  \
@@ -4153,7 +3998,7 @@ ecoff_reloc_link_order (bfd *output_bfd,
       bfd_byte *buf;
 
       size = bfd_get_reloc_size (rel.howto);
-      buf = bfd_zmalloc (size);
+      buf = (bfd_byte *) bfd_zmalloc (size);
       if (buf == NULL)
        return FALSE;
       rstat = _bfd_relocate_contents (rel.howto, output_bfd,
@@ -4262,7 +4107,7 @@ ecoff_reloc_link_order (bfd *output_bfd,
 
   /* Get some memory and swap out the reloc.  */
   external_reloc_size = ecoff_backend (output_bfd)->external_reloc_size;
-  rbuf = bfd_malloc (external_reloc_size);
+  rbuf = (bfd_byte *) bfd_malloc (external_reloc_size);
   if (rbuf == NULL)
     return FALSE;
 
@@ -4286,8 +4131,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;
@@ -4485,7 +4331,7 @@ _bfd_ecoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
   /* Accumulate the debugging symbols from each input BFD.  */
   for (input_bfd = info->input_bfds;
        input_bfd != NULL;
-       input_bfd = input_bfd->link_next)
+       input_bfd = input_bfd->link.next)
     {
       bfd_boolean ret;
 
@@ -4518,9 +4364,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.034405 seconds and 4 git commands to generate.