Fix C++ build for Cygwin
[deliverable/binutils-gdb.git] / bfd / ecoff.c
index efcb9bf75cd3dc081e3a281fbef2e646d497f7fb..4515172983df19c86be9e5ded3b15939b69f2105 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, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 1990-2016 Free Software Foundation, Inc.
    Original version by Per Bothner.
    Full support added by Ian Lance Taylor, ian@cygnus.com.
 
@@ -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;
@@ -508,7 +504,6 @@ _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;
 
   BFD_ASSERT (debug == &ecoff_data (abfd)->debug_info);
@@ -611,14 +606,16 @@ _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 = (FDR *) bfd_alloc (abfd, amt);
+  debug->fdr = (FDR *) bfd_alloc2 (abfd, internal_symhdr->ifdMax,
+                                  sizeof (struct fdr));
   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);
@@ -860,7 +857,6 @@ _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;
@@ -879,9 +875,8 @@ _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 = (ecoff_symbol_type *) bfd_alloc (abfd, internal_size);
+  internal = (ecoff_symbol_type *) bfd_alloc2 (abfd, bfd_get_symcount (abfd),
+                                              sizeof (ecoff_symbol_type));
   if (internal == NULL)
     return FALSE;
 
@@ -895,16 +890,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;
@@ -942,6 +951,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;
@@ -1708,12 +1731,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;
@@ -1734,8 +1758,10 @@ _bfd_ecoff_find_nearest_line (bfd *abfd,
       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);
@@ -1890,7 +1916,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 +2932,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)
@@ -3501,171 +3527,29 @@ 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.  */
 
 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;
 
-  /* 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;
-
-  /* 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;
-      bfd *oldbfd;
-      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.  */
-      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;
+  /* 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.
@@ -4012,7 +3896,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);
@@ -4119,7 +4003,7 @@ ecoff_reloc_link_order (bfd *output_bfd,
 
       size = bfd_get_reloc_size (rel.howto);
       buf = (bfd_byte *) bfd_zmalloc (size);
-      if (buf == NULL)
+      if (buf == NULL && size != 0)
        return FALSE;
       rstat = _bfd_relocate_contents (rel.howto, output_bfd,
                                      (bfd_vma) addend, buf);
@@ -4131,17 +4015,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 (output_bfd, 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,
@@ -4171,10 +4050,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;
@@ -4451,7 +4328,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;
 
@@ -4486,7 +4363,7 @@ _bfd_ecoff_bfd_final_link (bfd *abfd, struct bfd_link_info *info)
   einfo.info = info;
   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
@@ -4516,7 +4393,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
@@ -4536,7 +4413,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;
 
This page took 0.032276 seconds and 4 git commands to generate.