gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / ecoff.c
index a31bdb96b076c295719d7f39762736e4c47d12c3..dcded6f4a7e6bf384f311232958b7fbe74ecd11c 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, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 1990-2020 Free Software Foundation, Inc.
    Original version by Per Bothner.
    Full support added by Ian Lance Taylor, ian@cygnus.com.
 
@@ -25,8 +24,8 @@
 #include "bfd.h"
 #include "bfdlink.h"
 #include "libbfd.h"
+#include "ecoff-bfd.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
 /* This stuff is somewhat copied from coffcode.h.  */
 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,                       */
-     0,           0,                1,
-  /* 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,
-  /* output_offset, output_section, alignment_power,               */
-     0,             NULL,           0,
+  /* name,     id,  section_id, index, next, prev, flags,        */
+     "*DEBUG*", 0,   0,                 0,     NULL, NULL, 0,
+  /* user_set_vma,        */
+     0,
+  /* linker_mark, linker_has_input, gc_mark, compress_status,     */
+     0,                  0,                1,       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,   */
-     NULL,       NULL,        0,           0,       0,
-  /* line_filepos, userdata, contents, lineno, lineno_count,       */
-     0,            NULL,     NULL,     NULL,   0,
-  /* entsize, kept_section, moving_line_filepos,                   */
-     0,       NULL,         0,
-  /* target_index, used_by_bfd, constructor_chain, owner,          */
-     0,            NULL,        NULL,              NULL,
-  /* symbol,                                                       */
+     NULL,      NULL,        0,           0,       0,
+  /* line_filepos, userdata, contents, lineno, lineno_count,      */
+     0,                   NULL,     NULL,     NULL,   0,
+  /* entsize, kept_section, moving_line_filepos,                  */
+     0,              NULL,         0,
+  /* target_index, used_by_bfd, constructor_chain, owner,         */
+     0,                   NULL,        NULL,              NULL,
+  /* symbol,                                                      */
      NULL,
-  /* symbol_ptr_ptr,                                               */
+  /* symbol_ptr_ptr,                                              */
+     NULL,
+  /* map_head, map_tail,                                          */
+     { NULL }, { NULL },
+  /* already_assigned                                             */
      NULL,
-  /* map_head, map_tail                                            */
-     { NULL }, { NULL }
 };
 
 /* Create an ECOFF object.  */
@@ -86,9 +89,9 @@ static asection bfd_debug_section =
 bfd_boolean
 _bfd_ecoff_mkobject (bfd *abfd)
 {
-  bfd_size_type amt = sizeof (ecoff_data_type);
+  size_t 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;
 
@@ -155,14 +158,14 @@ _bfd_ecoff_new_section_hook (bfd *abfd, asection *section)
     { _INIT,   SEC_ALLOC | SEC_CODE | SEC_LOAD },
     { _FINI,   SEC_ALLOC | SEC_CODE | SEC_LOAD },
     { _DATA,   SEC_ALLOC | SEC_DATA | SEC_LOAD },
-    { _SDATA,  SEC_ALLOC | SEC_DATA | SEC_LOAD },
+    { _SDATA,  SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_SMALL_DATA },
     { _RDATA,  SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
-    { _LIT8,   SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
-    { _LIT4,   SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
+    { _LIT8,   SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY | SEC_SMALL_DATA},
+    { _LIT4,   SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY | SEC_SMALL_DATA},
     { _RCONST, SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
     { _PDATA,  SEC_ALLOC | SEC_DATA | SEC_LOAD | SEC_READONLY},
     { _BSS,    SEC_ALLOC},
-    { _SBSS,   SEC_ALLOC},
+    { _SBSS,   SEC_ALLOC | SEC_SMALL_DATA},
     /* An Irix 4 shared libary.  */
     { _LIB,    SEC_COFF_SHARED_LIBRARY}
   };
@@ -184,6 +187,13 @@ _bfd_ecoff_new_section_hook (bfd *abfd, asection *section)
   return _bfd_generic_new_section_hook (abfd, section);
 }
 
+void
+_bfd_ecoff_set_alignment_hook (bfd *abfd ATTRIBUTE_UNUSED,
+                              asection *section ATTRIBUTE_UNUSED,
+                              void *scnhdr ATTRIBUTE_UNUSED)
+{
+}
+
 /* Determine the machine architecture and type.  This is called from
    the generic COFF routines.  It is the inverse of ecoff_get_magic,
    below.  This could be an ECOFF backend routine, with one version
@@ -192,7 +202,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;
 
@@ -233,6 +243,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.  */
 
@@ -288,29 +306,29 @@ ecoff_sec_to_styp_flags (const char *name, flagword flags)
   }
   styp_flags [] =
   {
-    { _TEXT,    STYP_TEXT       },
-    { _DATA,    STYP_DATA       },
-    { _SDATA,   STYP_SDATA      },
-    { _RDATA,   STYP_RDATA      },
-    { _LITA,    STYP_LITA       },
-    { _LIT8,    STYP_LIT8       },
-    { _LIT4,    STYP_LIT4       },
-    { _BSS,     STYP_BSS        },
-    { _SBSS,    STYP_SBSS       },
-    { _INIT,    STYP_ECOFF_INIT },
-    { _FINI,    STYP_ECOFF_FINI },
-    { _PDATA,   STYP_PDATA      },
-    { _XDATA,   STYP_XDATA      },
-    { _LIB,     STYP_ECOFF_LIB  },
-    { _GOT,     STYP_GOT        },
-    { _HASH,    STYP_HASH       },
-    { _DYNAMIC, STYP_DYNAMIC    },
-    { _LIBLIST, STYP_LIBLIST    },
-    { _RELDYN,  STYP_RELDYN     },
-    { _CONFLIC, STYP_CONFLIC    },
-    { _DYNSTR,  STYP_DYNSTR     },
-    { _DYNSYM,  STYP_DYNSYM     },
-    { _RCONST,  STYP_RCONST     }
+    { _TEXT,   STYP_TEXT       },
+    { _DATA,   STYP_DATA       },
+    { _SDATA,  STYP_SDATA      },
+    { _RDATA,  STYP_RDATA      },
+    { _LITA,   STYP_LITA       },
+    { _LIT8,   STYP_LIT8       },
+    { _LIT4,   STYP_LIT4       },
+    { _BSS,    STYP_BSS        },
+    { _SBSS,   STYP_SBSS       },
+    { _INIT,   STYP_ECOFF_INIT },
+    { _FINI,   STYP_ECOFF_FINI },
+    { _PDATA,  STYP_PDATA      },
+    { _XDATA,  STYP_XDATA      },
+    { _LIB,    STYP_ECOFF_LIB  },
+    { _GOT,    STYP_GOT        },
+    { _HASH,   STYP_HASH       },
+    { _DYNAMIC, STYP_DYNAMIC   },
+    { _LIBLIST, STYP_LIBLIST   },
+    { _RELDYN, STYP_RELDYN     },
+    { _CONFLIC, STYP_CONFLIC   },
+    { _DYNSTR, STYP_DYNSTR     },
+    { _DYNSYM, STYP_DYNSYM     },
+    { _RCONST, STYP_RCONST     }
   };
   long styp = 0;
 
@@ -355,7 +373,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;
 
@@ -396,16 +414,19 @@ _bfd_ecoff_styp_to_sec_flags (bfd *abfd ATTRIBUTE_UNUSED,
          || styp_flags == STYP_PDATA
          || styp_flags == STYP_RCONST)
        sec_flags |= SEC_READONLY;
+      if (styp_flags & STYP_SDATA)
+       sec_flags |= SEC_SMALL_DATA;
     }
-  else if ((styp_flags & STYP_BSS)
-          || (styp_flags & STYP_SBSS))
+  else if (styp_flags & STYP_SBSS)
+    sec_flags |= SEC_ALLOC | SEC_SMALL_DATA;
+  else if (styp_flags & STYP_BSS)
     sec_flags |= SEC_ALLOC;
   else if ((styp_flags & STYP_INFO) || styp_flags == STYP_COMMENT)
     sec_flags |= SEC_NEVER_LOAD;
   else if ((styp_flags & STYP_LITA)
           || (styp_flags & STYP_LIT8)
           || (styp_flags & STYP_LIT4))
-    sec_flags |= SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY;
+    sec_flags |= SEC_DATA |SEC_SMALL_DATA | SEC_LOAD | SEC_ALLOC | SEC_READONLY;
   else if (styp_flags & STYP_ECOFF_LIB)
     sec_flags |= SEC_COFF_SHARED_LIBRARY;
   else
@@ -433,7 +454,7 @@ ecoff_slurp_symbolic_header (bfd *abfd)
   /* See whether there is a symbolic header.  */
   if (ecoff_data (abfd)->sym_filepos == 0)
     {
-      bfd_get_symcount (abfd) = 0;
+      abfd->symcount = 0;
       return TRUE;
     }
 
@@ -449,13 +470,12 @@ ecoff_slurp_symbolic_header (bfd *abfd)
     }
 
   /* Read the symbolic information header.  */
-  raw = bfd_malloc (external_hdr_size);
+  if (bfd_seek (abfd, ecoff_data (abfd)->sym_filepos, SEEK_SET) != 0)
+    goto error_return;
+  raw = _bfd_malloc_and_read (abfd, external_hdr_size, external_hdr_size);
   if (raw == NULL)
     goto error_return;
 
-  if (bfd_seek (abfd, ecoff_data (abfd)->sym_filepos, SEEK_SET) != 0
-      || bfd_bread (raw, external_hdr_size, abfd) != external_hdr_size)
-    goto error_return;
   internal_symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
   (*backend->debug_swap.swap_hdr_in) (abfd, raw, internal_symhdr);
 
@@ -466,15 +486,12 @@ ecoff_slurp_symbolic_header (bfd *abfd)
     }
 
   /* Now we can get the correct number of symbols.  */
-  bfd_get_symcount (abfd) = (internal_symhdr->isymMax
-                            + internal_symhdr->iextMax);
+  abfd->symcount = internal_symhdr->isymMax + internal_symhdr->iextMax;
 
-  if (raw != NULL)
-    free (raw);
+  free (raw);
   return TRUE;
  error_return:
-  if (raw != NULL)
-    free (raw);
+  free (raw);
   return FALSE;
 }
 
@@ -498,8 +515,8 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd,
   struct fdr *fdr_ptr;
   bfd_size_type raw_end;
   bfd_size_type cb_end;
-  bfd_size_type amt;
   file_ptr pos;
+  size_t amt;
 
   BFD_ASSERT (debug == &ecoff_data (abfd)->debug_info);
 
@@ -509,7 +526,7 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd,
     return TRUE;
   if (ecoff_data (abfd)->sym_filepos == 0)
     {
-      bfd_get_symcount (abfd) = 0;
+      abfd->symcount = 0;
       return TRUE;
     }
 
@@ -556,18 +573,13 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd,
       ecoff_data (abfd)->sym_filepos = 0;
       return TRUE;
     }
-  raw = bfd_alloc (abfd, raw_size);
-  if (raw == NULL)
-    return FALSE;
-
   pos = ecoff_data (abfd)->sym_filepos;
   pos += backend->debug_swap.external_hdr_size;
-  if (bfd_seek (abfd, pos, SEEK_SET) != 0
-      || bfd_bread (raw, raw_size, abfd) != raw_size)
-    {
-      bfd_release (abfd, raw);
-      return FALSE;
-    }
+  if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+    return FALSE;
+  raw = _bfd_alloc_and_read (abfd, raw_size, raw_size);
+  if (raw == NULL)
+    return FALSE;
 
   ecoff_data (abfd)->raw_syments = raw;
 
@@ -601,14 +613,21 @@ _bfd_ecoff_slurp_symbolic_info (bfd *abfd,
 
      We need to look at the fdr to deal with a lot of information in
      the symbols, so we swap them here.  */
-  amt = internal_symhdr->ifdMax;
-  amt *= sizeof (struct fdr);
-  debug->fdr = bfd_alloc (abfd, amt);
+  if (_bfd_mul_overflow ((unsigned long) internal_symhdr->ifdMax,
+                        sizeof (struct fdr), &amt))
+    {
+      bfd_set_error (bfd_error_file_too_big);
+      return FALSE;
+    }
+  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);
@@ -633,18 +652,18 @@ static asymbol *ecoff_scom_symbol_ptr;
 asymbol *
 _bfd_ecoff_make_empty_symbol (bfd *abfd)
 {
-  ecoff_symbol_type *new;
-  bfd_size_type amt = sizeof (ecoff_symbol_type);
+  ecoff_symbol_type *new_symbol;
+  size_t 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.  */
@@ -690,11 +709,11 @@ ecoff_set_symbol_info (bfd *abfd,
     {
       asym->flags = BSF_LOCAL;
       /* Normally, a local stProc symbol will have a corresponding
-         external symbol.  We mark the local symbol as a debugging
-         symbol, in order to prevent nm from printing both out.
-         Similarly, we mark stLabel and stabs symbols as debugging
-         symbols.  In both cases, we do want to set the value
-         correctly based on the symbol class.  */
+        external symbol.  We mark the local symbol as a debugging
+        symbol, in order to prevent nm from printing both out.
+        Similarly, we mark stLabel and stabs symbols as debugging
+        symbols.  In both cases, we do want to set the value
+        correctly based on the symbol class.  */
       if (ecoff_sym->st == stProc
          || ecoff_sym->st == stLabel
          || ECOFF_IS_STAB (ecoff_sym))
@@ -850,13 +869,13 @@ _bfd_ecoff_slurp_symbol_table (bfd *abfd)
     = backend->debug_swap.swap_ext_in;
   void (* const swap_sym_in) (bfd *, void *, SYMR *)
     = backend->debug_swap.swap_sym_in;
-  bfd_size_type internal_size;
   ecoff_symbol_type *internal;
   ecoff_symbol_type *internal_ptr;
   char *eraw_src;
   char *eraw_end;
   FDR *fdr_ptr;
   FDR *fdr_end;
+  size_t amt;
 
   /* If we've already read in the symbol table, do nothing.  */
   if (ecoff_data (abfd)->canonical_symbols != NULL)
@@ -869,9 +888,13 @@ _bfd_ecoff_slurp_symbol_table (bfd *abfd)
   if (bfd_get_symcount (abfd) == 0)
     return TRUE;
 
-  internal_size = bfd_get_symcount (abfd);
-  internal_size *= sizeof (ecoff_symbol_type);
-  internal = bfd_alloc (abfd, internal_size);
+  if (_bfd_mul_overflow (bfd_get_symcount (abfd),
+                        sizeof (ecoff_symbol_type), &amt))
+    {
+      bfd_set_error (bfd_error_file_too_big);
+      return FALSE;
+    }
+  internal = (ecoff_symbol_type *) bfd_alloc (abfd, amt);
   if (internal == NULL)
     return FALSE;
 
@@ -885,16 +908,30 @@ _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
+         || internal_esym.asym.iss < 0)
+       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
-                            + internal_esym.ifd);
+       {
+         /* PR 17512: file: 3372-1983-0.004.  */
+         if (internal_esym.ifd >= ecoff_data (abfd)->debug_info.symbolic_header.ifdMax)
+           internal_ptr->fdr = NULL;
+         else
+           internal_ptr->fdr = (ecoff_data (abfd)->debug_info.fdr
+                                + internal_esym.ifd);
+       }
       else
        internal_ptr->fdr = NULL;
       internal_ptr->local = FALSE;
@@ -932,6 +969,21 @@ _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))
+    {
+      abfd->symcount = internal_ptr - internal;
+      _bfd_error_handler
+       /* xgettext:c-format */
+       (_("%pB: warning: isymMax (%ld) is greater than ifdMax (%ld)"),
+        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;
@@ -1224,7 +1276,7 @@ ecoff_type_to_string (bfd *abfd, FDR *fdr, unsigned int indx)
       break;
 
     default:
-      sprintf (p1, _("Unknown basic type %d"), (int) basic_type);
+      sprintf (p1, _("unknown basic type %d"), (int) basic_type);
       break;
     }
 
@@ -1244,12 +1296,12 @@ ecoff_type_to_string (bfd *abfd, FDR *fdr, unsigned int indx)
   if (qualifiers[0].type != tqNil)
     {
       /* Snarf up any array bounds in the correct order.  Arrays
-         store 5 successive words in the aux. table:
-               word 0  RNDXR to type of the bounds (ie, int)
-               word 1  Current file descriptor index
-               word 2  low bound
-               word 3  high bound (or -1 if [])
-               word 4  stride size in bits.  */
+        store 5 successive words in the aux. table:
+               word 0  RNDXR to type of the bounds (ie, int)
+               word 1  Current file descriptor index
+               word 2  low bound
+               word 3  high bound (or -1 if [])
+               word 4  stride size in bits.  */
       for (i = 0; i < 7; i++)
        {
          if (qualifiers[i].type == tqArray)
@@ -1503,6 +1555,7 @@ _bfd_ecoff_print_symbol (bfd *abfd,
                if (ECOFF_IS_STAB (&ecoff_ext.asym))
                  ;
                else if (ecoffsymbol (symbol)->local)
+                 /* xgettext:c-format */
                  fprintf (file, _("\n      End+1 symbol: %-7ld   Type:  %s"),
                           ((long)
                            (AUX_GET_ISYM (bigendian,
@@ -1555,7 +1608,7 @@ ecoff_slurp_reloc_table (bfd *abfd,
   arelent *internal_relocs;
   bfd_size_type external_reloc_size;
   bfd_size_type amt;
-  char *external_relocs;
+  bfd_byte *external_relocs;
   arelent *rptr;
   unsigned int i;
 
@@ -1567,20 +1620,23 @@ ecoff_slurp_reloc_table (bfd *abfd,
   if (! _bfd_ecoff_slurp_symbol_table (abfd))
     return FALSE;
 
-  amt = section->reloc_count;
-  amt *= sizeof (arelent);
-  internal_relocs = bfd_alloc (abfd, amt);
-
   external_reloc_size = backend->external_reloc_size;
   amt = external_reloc_size * section->reloc_count;
-  external_relocs = bfd_alloc (abfd, amt);
-  if (internal_relocs == NULL || external_relocs == NULL)
-    return FALSE;
   if (bfd_seek (abfd, section->rel_filepos, SEEK_SET) != 0)
     return FALSE;
-  if (bfd_bread (external_relocs, amt, abfd) != amt)
+  external_relocs = _bfd_malloc_and_read (abfd, amt, amt);
+  if (external_relocs == NULL)
     return FALSE;
 
+  amt = section->reloc_count;
+  amt *= sizeof (arelent);
+  internal_relocs = (arelent *) bfd_alloc (abfd, amt);
+  if (internal_relocs == NULL)
+    {
+      free (external_relocs);
+      return FALSE;
+    }
+
   for (i = 0, rptr = internal_relocs; i < section->reloc_count; i++, rptr++)
     {
       struct internal_reloc intern;
@@ -1635,17 +1691,17 @@ ecoff_slurp_reloc_table (bfd *abfd,
            abort ();
          rptr->sym_ptr_ptr = sec->symbol_ptr_ptr;
 
-         rptr->addend = - bfd_get_section_vma (abfd, sec);
+         rptr->addend = - bfd_section_vma (sec);
        }
 
-      rptr->address = intern.r_vaddr - bfd_get_section_vma (abfd, section);
+      rptr->address = intern.r_vaddr - bfd_section_vma (section);
 
       /* Let the backend select the howto field and do any other
         required processing.  */
       (*backend->adjust_reloc_in) (abfd, &intern, rptr);
     }
 
-  bfd_release (abfd, external_relocs);
+  free (external_relocs);
 
   section->relocation = internal_relocs;
 
@@ -1698,12 +1754,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;
@@ -1717,14 +1774,17 @@ _bfd_ecoff_find_nearest_line (bfd *abfd,
 
   if (ecoff_data (abfd)->find_line_info == NULL)
     {
-      bfd_size_type amt = sizeof (struct ecoff_find_line);
+      size_t 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);
@@ -1879,7 +1939,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.  */
@@ -1944,7 +2004,7 @@ ecoff_compute_section_file_positions (bfd *abfd)
   /* 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;
@@ -2027,8 +2087,8 @@ ecoff_compute_section_file_positions (bfd *abfd)
               && (abfd->flags & D_PAGED) != 0)
        {
          /* Skip up to the next page for an unallocated section, such
-             as the .comment section on the Alpha.  This leaves room
-             for the .bss section.  */
+            as the .comment section on the Alpha.  This leaves room
+            for the .bss section.  */
          first_nonalloc = FALSE;
          sofar = (sofar + round - 1) &~ (round - 1);
          file_sofar = (file_sofar + round - 1) &~ (round - 1);
@@ -2172,22 +2232,6 @@ _bfd_ecoff_set_section_contents (bfd *abfd,
   return TRUE;
 }
 
-/* Get the GP value for an ECOFF file.  This is a hook used by
-   nlmconv.  */
-
-bfd_vma
-bfd_ecoff_get_gp_value (bfd *abfd)
-{
-  if (bfd_get_flavour (abfd) != bfd_target_ecoff_flavour
-      || bfd_get_format (abfd) != bfd_object)
-    {
-      bfd_set_error (bfd_error_invalid_operation);
-      return 0;
-    }
-
-  return ecoff_data (abfd)->gp;
-}
-
 /* Set the GP value for an ECOFF file.  This is a hook used by the
    assembler.  */
 
@@ -2283,7 +2327,7 @@ ecoff_get_extr (asymbol *sym, EXTR *esym)
      symbol.  */
   if ((esym->asym.sc == scUndefined
        || esym->asym.sc == scSUndefined)
-      && ! bfd_is_und_section (bfd_get_section (sym)))
+      && ! bfd_is_und_section (bfd_asymbol_section (sym)))
     esym->asym.sc = scAbs;
 
   /* Adjust the FDR index for the symbol by that used for the input
@@ -2402,7 +2446,7 @@ _bfd_ecoff_write_object_contents (bfd *abfd)
       strncpy (section.s_name, current->name, sizeof section.s_name);
 
       /* This seems to be correct for Irix 4 shared libraries.  */
-      vma = bfd_get_section_vma (abfd, current);
+      vma = bfd_section_vma (current);
       if (streq (current->name, _LIB))
        section.s_vaddr = 0;
       else
@@ -2653,8 +2697,7 @@ _bfd_ecoff_write_object_contents (bfd *abfd)
              if (reloc->howto == NULL)
                continue;
 
-             in.r_vaddr = (reloc->address
-                           + bfd_get_section_vma (abfd, current));
+             in.r_vaddr = reloc->address + bfd_section_vma (current);
              in.r_type = reloc->howto->type;
 
              if ((sym->flags & BSF_SECTION_SYM) == 0)
@@ -2665,7 +2708,7 @@ _bfd_ecoff_write_object_contents (bfd *abfd)
              else
                {
                  const char *name;
-                 unsigned int i;
+                 unsigned int j;
                  static struct
                  {
                    const char * name;
@@ -2690,16 +2733,16 @@ _bfd_ecoff_write_object_contents (bfd *abfd)
                    { _RCONST, RELOC_SECTION_RCONST }
                  };
 
-                 name = bfd_get_section_name (abfd, bfd_get_section (sym));
+                 name = bfd_section_name (bfd_asymbol_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;
                }
@@ -2752,14 +2795,12 @@ _bfd_ecoff_write_object_contents (bfd *abfd)
 
   if (reloc_buff != NULL)
     bfd_release (abfd, reloc_buff);
-  if (buff != NULL)
-    free (buff);
+  free (buff);
   return TRUE;
  error_return:
   if (reloc_buff != NULL)
     bfd_release (abfd, reloc_buff);
-  if (buff != NULL)
-    free (buff);
+  free (buff);
   return FALSE;
 }
 \f
@@ -2793,19 +2834,19 @@ _bfd_ecoff_write_object_contents (bfd *abfd)
 
    The Alpha seems to use ________64E[BL]E[BL]_.  */
 
-#define ARMAP_BIG_ENDIAN               'B'
-#define ARMAP_LITTLE_ENDIAN            'L'
-#define ARMAP_MARKER                   'E'
-#define ARMAP_START_LENGTH             10
+#define ARMAP_BIG_ENDIAN               'B'
+#define ARMAP_LITTLE_ENDIAN            'L'
+#define ARMAP_MARKER                   'E'
+#define ARMAP_START_LENGTH             10
 #define ARMAP_HEADER_MARKER_INDEX      10
-#define ARMAP_HEADER_ENDIAN_INDEX      11
-#define ARMAP_OBJECT_MARKER_INDEX      12
-#define ARMAP_OBJECT_ENDIAN_INDEX      13
-#define ARMAP_END_INDEX                14
-#define ARMAP_END                      "_ "
+#define ARMAP_HEADER_ENDIAN_INDEX      11
+#define ARMAP_OBJECT_MARKER_INDEX      12
+#define ARMAP_OBJECT_ENDIAN_INDEX      13
+#define ARMAP_END_INDEX                        14
+#define ARMAP_END                      "_ "
 
 /* This is a magic number used in the hashing algorithm.  */
-#define ARMAP_HASH_MAGIC               0x9dd68ab5
+#define ARMAP_HASH_MAGIC               0x9dd68ab5
 
 /* This returns the hash value to use for a string.  It also sets
    *REHASH to the rehash adjustment if the first slot is taken.  SIZE
@@ -2838,21 +2879,21 @@ _bfd_ecoff_slurp_armap (bfd *abfd)
   char nextname[17];
   unsigned int i;
   struct areltdata *mapdata;
-  bfd_size_type parsed_size;
+  bfd_size_type parsed_size, stringsize;
   char *raw_armap;
   struct artdata *ardata;
   unsigned int count;
   char *raw_ptr;
-  struct symdef *symdef_ptr;
+  carsym *symdef_ptr;
   char *stringbase;
   bfd_size_type amt;
 
   /* Get the name of the first element.  */
   i = bfd_bread ((void *) nextname, (bfd_size_type) 16, abfd);
   if (i == 0)
-      return TRUE;
+    return TRUE;
   if (i != 16)
-      return FALSE;
+    return FALSE;
 
   if (bfd_seek (abfd, (file_ptr) -16, SEEK_CUR) != 0)
     return FALSE;
@@ -2875,7 +2916,7 @@ _bfd_ecoff_slurp_armap (bfd *abfd)
          && nextname[ARMAP_OBJECT_ENDIAN_INDEX] != ARMAP_LITTLE_ENDIAN)
       || ! strneq (nextname + ARMAP_END_INDEX, ARMAP_END, sizeof ARMAP_END - 1))
     {
-      bfd_has_map (abfd) = FALSE;
+      abfd->has_armap = FALSE;
       return TRUE;
     }
 
@@ -2895,23 +2936,24 @@ _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);
-  if (raw_armap == NULL)
-    return FALSE;
-
-  if (bfd_bread ((void *) raw_armap, parsed_size, abfd) != parsed_size)
+  if (parsed_size + 1 < 9)
     {
-      if (bfd_get_error () != bfd_error_system_call)
-       bfd_set_error (bfd_error_malformed_archive);
-      bfd_release (abfd, (void *) raw_armap);
+      bfd_set_error (bfd_error_malformed_archive);
       return FALSE;
     }
 
+  raw_armap = (char *) _bfd_alloc_and_read (abfd, parsed_size + 1, parsed_size);
+  if (raw_armap == NULL)
+    return FALSE;
+  raw_armap[parsed_size] = 0;
+
   ardata->tdata = (void *) raw_armap;
 
   count = H_GET_32 (abfd, raw_armap);
+  if ((parsed_size - 8) / 8 < count)
+    goto error_malformed;
 
   ardata->symdef_count = 0;
   ardata->cache = NULL;
@@ -2919,6 +2961,7 @@ _bfd_ecoff_slurp_armap (bfd *abfd)
   /* This code used to overlay the symdefs over the raw archive data,
      but that doesn't work on a 64 bit host.  */
   stringbase = raw_armap + count * 8 + 8;
+  stringsize = parsed_size - (count * 8 + 8);
 
 #ifdef CHECK_ARMAP_HASH
   {
@@ -2963,12 +3006,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;
+    goto error_exit;
 
-  ardata->symdefs = (carsym *) symdef_ptr;
+  ardata->symdefs = symdef_ptr;
 
   raw_ptr = raw_armap + 4;
   for (i = 0; i < count; i++, raw_ptr += 8)
@@ -2979,7 +3022,9 @@ _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;
+      if (name_offset > stringsize)
+       goto error_malformed;
+      symdef_ptr->name = stringbase + name_offset;
       symdef_ptr->file_offset = file_offset;
       ++symdef_ptr;
     }
@@ -2987,10 +3032,17 @@ _bfd_ecoff_slurp_armap (bfd *abfd)
   ardata->first_file_filepos = bfd_tell (abfd);
   /* Pad to an even boundary.  */
   ardata->first_file_filepos += ardata->first_file_filepos % 2;
-
-  bfd_has_map (abfd) = TRUE;
-
+  abfd->has_armap = TRUE;
   return TRUE;
+
+ error_malformed:
+  bfd_set_error (bfd_error_malformed_archive);
+ error_exit:
+  ardata->symdef_count = 0;
+  ardata->symdefs = NULL;
+  ardata->tdata = NULL;
+  bfd_release (abfd, raw_armap);
+  return FALSE;
 }
 
 /* Write out an armap.  */
@@ -3050,8 +3102,9 @@ _bfd_ecoff_write_armap (bfd *abfd,
      complain that the index is out of date.  Actually, the Ultrix
      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));
+  stat (bfd_get_filename (abfd), &statbuf);
+  _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.  */
@@ -3062,7 +3115,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';
@@ -3080,7 +3133,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;
 
@@ -3198,9 +3251,9 @@ struct bfd_link_hash_table *
 _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);
+  size_t 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,
@@ -3219,14 +3272,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.  */
 
@@ -3258,7 +3303,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;
@@ -3462,38 +3507,30 @@ ecoff_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
   symhdr = &ecoff_data (abfd)->debug_info.symbolic_header;
 
   /* Read in the external symbols and external strings.  */
+  if (bfd_seek (abfd, symhdr->cbExtOffset, SEEK_SET) != 0)
+    return FALSE;
   external_ext_size = ecoff_backend (abfd)->debug_swap.external_ext_size;
   esize = symhdr->iextMax * external_ext_size;
-  external_ext = bfd_malloc (esize);
+  external_ext = _bfd_malloc_and_read (abfd, esize, 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)
+  if (bfd_seek (abfd, symhdr->cbSsExtOffset, SEEK_SET) != 0)
     goto error_return;
-
-  ssext = bfd_malloc ((bfd_size_type) symhdr->issExtMax);
+  ssext = (char *) _bfd_malloc_and_read (abfd, symhdr->issExtMax,
+                                        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;
-
   result = ecoff_link_add_externals (abfd, info, external_ext, ssext);
 
-  if (ssext != NULL)
-    free (ssext);
-  if (external_ext != NULL)
-    free (external_ext);
+  free (ssext);
+  free (external_ext);
   return result;
 
  error_return:
-  if (ssext != NULL)
-    free (ssext);
-  if (external_ext != NULL)
-    free (external_ext);
+  free (ssext);
+  free (external_ext);
   return FALSE;
 }
 
@@ -3503,124 +3540,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 TRUE;
+  *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.
@@ -3765,7 +3701,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;
@@ -3821,25 +3758,31 @@ ecoff_final_link_debug_accumulate (bfd *output_bfd,
   HDRR *symhdr = &debug->symbolic_header;
   bfd_boolean ret;
 
-#define READ(ptr, offset, count, size, type)                            \
-  if (symhdr->count == 0)                                               \
-    debug->ptr = NULL;                                                  \
-  else                                                                  \
-    {                                                                   \
-      bfd_size_type amt = (bfd_size_type) size * symhdr->count;                 \
-      debug->ptr = bfd_malloc (amt);                                    \
-      if (debug->ptr == NULL)                                           \
-       {                                                                \
-          ret = FALSE;                                                  \
-          goto return_something;                                        \
-       }                                                                \
-      if (bfd_seek (input_bfd, (file_ptr) symhdr->offset, SEEK_SET) != 0 \
-         || bfd_bread (debug->ptr, amt, input_bfd) != amt)              \
-       {                                                                \
-          ret = FALSE;                                                  \
-          goto return_something;                                        \
-       }                                                                \
-    }
+#define READ(ptr, offset, count, size, type)                           \
+  do                                                                   \
+    {                                                                  \
+      size_t amt;                                                      \
+      debug->ptr = NULL;                                               \
+      if (symhdr->count == 0)                                          \
+       break;                                                          \
+      if (_bfd_mul_overflow (size, symhdr->count, &amt))               \
+       {                                                               \
+         bfd_set_error (bfd_error_file_too_big);                       \
+         ret = FALSE;                                                  \
+         goto return_something;                                        \
+       }                                                               \
+      if (bfd_seek (input_bfd, symhdr->offset, SEEK_SET) != 0)         \
+       {                                                               \
+         ret = FALSE;                                                  \
+         goto return_something;                                        \
+       }                                                               \
+      debug->ptr = (type) _bfd_malloc_and_read (input_bfd, amt, amt);  \
+      if (debug->ptr == NULL)                                          \
+       {                                                               \
+         ret = FALSE;                                                  \
+         goto return_something;                                        \
+       }                                                               \
+    } while (0)
 
   /* If raw_syments is not NULL, then the data was already by read by
      _bfd_ecoff_slurp_symbolic_info.  */
@@ -3869,24 +3812,15 @@ ecoff_final_link_debug_accumulate (bfd *output_bfd,
  return_something:
   if (ecoff_data (input_bfd)->raw_syments == NULL)
     {
-      if (debug->line != NULL)
-       free (debug->line);
-      if (debug->external_dnr != NULL)
-       free (debug->external_dnr);
-      if (debug->external_pdr != NULL)
-       free (debug->external_pdr);
-      if (debug->external_sym != NULL)
-       free (debug->external_sym);
-      if (debug->external_opt != NULL)
-       free (debug->external_opt);
-      if (debug->external_aux != NULL)
-       free (debug->external_aux);
-      if (debug->ss != NULL)
-       free (debug->ss);
-      if (debug->external_fdr != NULL)
-       free (debug->external_fdr);
-      if (debug->external_rfd != NULL)
-       free (debug->external_rfd);
+      free (debug->line);
+      free (debug->external_dnr);
+      free (debug->external_pdr);
+      free (debug->external_sym);
+      free (debug->external_opt);
+      free (debug->external_aux);
+      free (debug->ss);
+      free (debug->external_fdr);
+      free (debug->external_rfd);
 
       /* Make sure we don't accidentally follow one of these pointers
         into freed memory.  */
@@ -3939,13 +3873,11 @@ ecoff_indirect_link_order (bfd *output_bfd,
   external_reloc_size = ecoff_backend (input_bfd)->external_reloc_size;
   external_relocs_size = external_reloc_size * input_section->reloc_count;
 
-  external_relocs = bfd_malloc (external_relocs_size);
-  if (external_relocs == NULL && external_relocs_size != 0)
+  if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0)
     goto error_return;
-
-  if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
-      || (bfd_bread (external_relocs, external_relocs_size, input_bfd)
-         != external_relocs_size))
+  external_relocs = _bfd_malloc_and_read (input_bfd, external_relocs_size,
+                                         external_relocs_size);
+  if (external_relocs == NULL && external_relocs_size != 0)
     goto error_return;
 
   /* Relocate the section contents.  */
@@ -3966,7 +3898,7 @@ ecoff_indirect_link_order (bfd *output_bfd,
      modified, and we write them out now.  We use the reloc_count
      field of output_section to keep track of the number of relocs we
      have output so far.  */
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     {
       file_ptr pos = (output_section->rel_filepos
                      + output_section->reloc_count * external_reloc_size);
@@ -3977,17 +3909,13 @@ ecoff_indirect_link_order (bfd *output_bfd,
       output_section->reloc_count += input_section->reloc_count;
     }
 
-  if (contents != NULL)
-    free (contents);
-  if (external_relocs != NULL)
-    free (external_relocs);
+  free (contents);
+  free (external_relocs);
   return TRUE;
 
  error_return:
-  if (contents != NULL)
-    free (contents);
-  if (external_relocs != NULL)
-    free (external_relocs);
+  free (contents);
+  free (external_relocs);
   return FALSE;
 }
 
@@ -4037,7 +3965,7 @@ ecoff_reloc_link_order (bfd *output_bfd,
       struct bfd_link_hash_entry *h;
 
       /* Treat a reloc against a defined symbol as though it were
-         actually against the section.  */
+        actually against the section.  */
       h = bfd_wrapped_link_hash_lookup (output_bfd, info,
                                        link_order->u.reloc.p->u.name,
                                        FALSE, FALSE, FALSE);
@@ -4048,8 +3976,8 @@ ecoff_reloc_link_order (bfd *output_bfd,
          type = bfd_section_reloc_link_order;
          section = h->u.def.section->output_section;
          /* It seems that we ought to add the symbol value to the
-             addend here, but in practice it has already been added
-             because it was passed to constructor_callback.  */
+            addend here, but in practice it has already been added
+            because it was passed to constructor_callback.  */
          addend += section->vma + h->u.def.section->output_offset;
        }
       else
@@ -4072,8 +4000,8 @@ ecoff_reloc_link_order (bfd *output_bfd,
       bfd_byte *buf;
 
       size = bfd_get_reloc_size (rel.howto);
-      buf = bfd_zmalloc (size);
-      if (buf == NULL)
+      buf = (bfd_byte *) bfd_zmalloc (size);
+      if (buf == NULL && size != 0)
        return FALSE;
       rstat = _bfd_relocate_contents (rel.howto, output_bfd,
                                      (bfd_vma) addend, buf);
@@ -4085,17 +4013,12 @@ ecoff_reloc_link_order (bfd *output_bfd,
        case bfd_reloc_outofrange:
          abort ();
        case bfd_reloc_overflow:
-         if (! ((*info->callbacks->reloc_overflow)
-                (info, NULL,
-                 (link_order->type == bfd_section_reloc_link_order
-                  ? bfd_section_name (output_bfd, section)
-                  : link_order->u.reloc.p->u.name),
-                 rel.howto->name, addend, NULL,
-                 NULL, (bfd_vma) 0)))
-           {
-             free (buf);
-             return FALSE;
-           }
+         (*info->callbacks->reloc_overflow)
+           (info, NULL,
+            (link_order->type == bfd_section_reloc_link_order
+             ? bfd_section_name (section)
+             : link_order->u.reloc.p->u.name),
+            rel.howto->name, addend, NULL, NULL, (bfd_vma) 0);
          break;
        }
       ok = bfd_set_section_contents (output_bfd, output_section, (void *) buf,
@@ -4108,8 +4031,7 @@ ecoff_reloc_link_order (bfd *output_bfd,
   rel.addend = 0;
 
   /* Move the information into an internal_reloc structure.  */
-  in.r_vaddr = (rel.address
-               + bfd_get_section_vma (output_bfd, output_section));
+  in.r_vaddr = rel.address + bfd_section_vma (output_section);
   in.r_type = rel.howto->type;
 
   if (type == bfd_symbol_reloc_link_order)
@@ -4125,10 +4047,8 @@ ecoff_reloc_link_order (bfd *output_bfd,
        in.r_symndx = h->indx;
       else
        {
-         if (! ((*info->callbacks->unattached_reloc)
-                (info, link_order->u.reloc.p->u.name, NULL,
-                 NULL, (bfd_vma) 0)))
-           return FALSE;
+         (*info->callbacks->unattached_reloc)
+           (info, link_order->u.reloc.p->u.name, NULL, NULL, (bfd_vma) 0);
          in.r_symndx = 0;
        }
       in.r_extern = 1;
@@ -4161,7 +4081,7 @@ ecoff_reloc_link_order (bfd *output_bfd,
        { _RCONST, RELOC_SECTION_RCONST }
       };
 
-      name = bfd_get_section_name (output_bfd, section);
+      name = bfd_section_name (section);
 
       for (i = 0; i < ARRAY_SIZE (section_symndx); i++)
        if (streq (name, section_symndx[i].name))
@@ -4181,7 +4101,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;
 
@@ -4205,8 +4125,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;
@@ -4273,7 +4194,7 @@ ecoff_link_write_external (struct ecoff_link_hash_entry *h, void * data)
          };
 
          output_section = h->root.u.def.section->output_section;
-         name = bfd_section_name (output_section->owner, output_section);
+         name = bfd_section_name (output_section);
 
          for (i = 0; i < ARRAY_SIZE (section_storage_classes); i++)
            if (streq (name, section_storage_classes[i].name))
@@ -4404,7 +4325,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;
 
@@ -4437,11 +4358,9 @@ _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)
+  if (bfd_link_relocatable (info))
     {
       /* We need to make a pass over the link_orders to count up the
         number of relocations we will need to output, so that we know
@@ -4471,7 +4390,7 @@ _bfd_ecoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
 
   bfd_ecoff_debug_free (handle, abfd, debug, &backend->debug_swap, info);
 
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     {
       /* Now reset the reloc_count field of the sections in the output
         BFD to 0, so that we can use them to keep track of how many
@@ -4491,7 +4410,7 @@ _bfd_ecoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
        ecoff_data (abfd)->gp = (h->u.def.value
                                 + h->u.def.section->output_section->vma
                                 + h->u.def.section->output_offset);
-      else if (info->relocatable)
+      else if (bfd_link_relocatable (info))
        {
          bfd_vma lo;
 
@@ -4544,7 +4463,7 @@ _bfd_ecoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
        }
     }
 
-  bfd_get_symcount (abfd) = symhdr->iextMax + symhdr->isymMax;
+  abfd->symcount = symhdr->iextMax + symhdr->isymMax;
 
   ecoff_data (abfd)->linker = TRUE;
 
This page took 0.043045 seconds and 4 git commands to generate.