Rewrite __start and __stop symbol handling
[deliverable/binutils-gdb.git] / bfd / coffcode.h
index 4bc80bd25a6f40ca51fa3336d6234e824d7fbe13..3331f4cc51cb5f22e8d4ebe61bd1d21d1d46397b 100644 (file)
@@ -1,5 +1,5 @@
 /* Support for the generic parts of most COFF variants, for BFD.
 /* Support for the generic parts of most COFF variants, for BFD.
-   Copyright (C) 1990-2014 Free Software Foundation, Inc.
+   Copyright (C) 1990-2017 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -307,7 +307,7 @@ CODE_FRAGMENT
 .typedef struct coff_ptr_struct
 .{
 .  {* Remembers the offset from the first symbol in the file for
 .typedef struct coff_ptr_struct
 .{
 .  {* Remembers the offset from the first symbol in the file for
-.     this symbol. Generated by coff_renumber_symbols. *}
+.     this symbol. Generated by coff_renumber_symbols.  *}
 .  unsigned int offset;
 .
 .  {* Should the value of this symbol be renumbered.  Used for
 .  unsigned int offset;
 .
 .  {* Should the value of this symbol be renumbered.  Used for
@@ -315,15 +315,15 @@ CODE_FRAGMENT
 .  unsigned int fix_value : 1;
 .
 .  {* Should the tag field of this symbol be renumbered.
 .  unsigned int fix_value : 1;
 .
 .  {* Should the tag field of this symbol be renumbered.
-.     Created by coff_pointerize_aux. *}
+.     Created by coff_pointerize_aux.  *}
 .  unsigned int fix_tag : 1;
 .
 .  {* Should the endidx field of this symbol be renumbered.
 .  unsigned int fix_tag : 1;
 .
 .  {* Should the endidx field of this symbol be renumbered.
-.     Created by coff_pointerize_aux. *}
+.     Created by coff_pointerize_aux.  *}
 .  unsigned int fix_end : 1;
 .
 .  {* Should the x_csect.x_scnlen field be renumbered.
 .  unsigned int fix_end : 1;
 .
 .  {* Should the x_csect.x_scnlen field be renumbered.
-.     Created by coff_pointerize_aux. *}
+.     Created by coff_pointerize_aux.  *}
 .  unsigned int fix_scnlen : 1;
 .
 .  {* Fix up an XCOFF C_BINCL/C_EINCL symbol.  The value is the
 .  unsigned int fix_scnlen : 1;
 .
 .  {* Fix up an XCOFF C_BINCL/C_EINCL symbol.  The value is the
@@ -331,12 +331,15 @@ CODE_FRAGMENT
 .  unsigned int fix_line : 1;
 .
 .  {* The container for the symbol structure as read and translated
 .  unsigned int fix_line : 1;
 .
 .  {* The container for the symbol structure as read and translated
-.     from the file. *}
+.     from the file.  *}
 .  union
 .  {
 .    union internal_auxent auxent;
 .    struct internal_syment syment;
 .  } u;
 .  union
 .  {
 .    union internal_auxent auxent;
 .    struct internal_syment syment;
 .  } u;
+.
+. {* Selector for the union above.  *}
+. bfd_boolean is_sym;
 .} combined_entry_type;
 .
 .
 .} combined_entry_type;
 .
 .
@@ -959,10 +962,11 @@ handle_COMDAT (bfd * abfd,
          /* All 3 branches use this.  */
          symname = _bfd_coff_internal_syment_name (abfd, &isym, buf);
 
          /* All 3 branches use this.  */
          symname = _bfd_coff_internal_syment_name (abfd, &isym, buf);
 
-         /* PR 17512 file: 078-11867-0.004  */ 
+         /* PR 17512 file: 078-11867-0.004  */
          if (symname == NULL)
            {
          if (symname == NULL)
            {
-             _bfd_error_handler (_("%B: unable to load COMDAT section name"), abfd);
+             _bfd_error_handler (_("%B: unable to load COMDAT section name"),
+                                 abfd);
              break;
            }
 
              break;
            }
 
@@ -1001,11 +1005,22 @@ handle_COMDAT (bfd * abfd,
                   function).  See comment above for more.  */
 
                if (isym.n_sclass == C_STAT && strcmp (name, symname) != 0)
                   function).  See comment above for more.  */
 
                if (isym.n_sclass == C_STAT && strcmp (name, symname) != 0)
-                 _bfd_error_handler (_("%B: warning: COMDAT symbol '%s' does not match section name '%s'"),
+                 /* xgettext:c-format */
+                 _bfd_error_handler (_("%B: warning: COMDAT symbol '%s'"
+                                       " does not match section name '%s'"),
                                      abfd, symname, name);
 
                seen_state = 1;
 
                                      abfd, symname, name);
 
                seen_state = 1;
 
+               /* PR 17512: file: e2cfe54f.  */
+               if (esym + bfd_coff_symesz (abfd) >= esymend)
+                 {
+                   /* xgettext:c-format */
+                   _bfd_error_handler (_("%B: warning: No symbol for"
+                                         " section '%s' found"),
+                                       abfd, symname);
+                   break;
+                 }
                /* This is the section symbol.  */
                bfd_coff_swap_aux_in (abfd, (esym + bfd_coff_symesz (abfd)),
                                      isym.n_type, isym.n_sclass,
                /* This is the section symbol.  */
                bfd_coff_swap_aux_in (abfd, (esym + bfd_coff_symesz (abfd)),
                                      isym.n_type, isym.n_sclass,
@@ -1159,7 +1174,7 @@ styp_to_sec_flags (bfd *abfd,
                   flagword *flags_ptr)
 {
   struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
                   flagword *flags_ptr)
 {
   struct internal_scnhdr *internal_s = (struct internal_scnhdr *) hdr;
-  long styp_flags = internal_s->s_flags;
+  unsigned long styp_flags = internal_s->s_flags;
   flagword sec_flags;
   bfd_boolean result = TRUE;
   bfd_boolean is_dbg = FALSE;
   flagword sec_flags;
   bfd_boolean result = TRUE;
   bfd_boolean is_dbg = FALSE;
@@ -1182,7 +1197,7 @@ styp_to_sec_flags (bfd *abfd,
   /* Process each flag bit in styp_flags in turn.  */
   while (styp_flags)
     {
   /* Process each flag bit in styp_flags in turn.  */
   while (styp_flags)
     {
-      long flag = styp_flags & - styp_flags;
+      unsigned long flag = styp_flags & - styp_flags;
       char * unhandled = NULL;
 
       styp_flags &= ~ flag;
       char * unhandled = NULL;
 
       styp_flags &= ~ flag;
@@ -1226,7 +1241,9 @@ styp_to_sec_flags (bfd *abfd,
          /* Generate a warning message rather using the 'unhandled'
             variable as this will allow some .sys files generate by
             other toolchains to be processed.  See bugzilla issue 196.  */
          /* Generate a warning message rather using the 'unhandled'
             variable as this will allow some .sys files generate by
             other toolchains to be processed.  See bugzilla issue 196.  */
-         _bfd_error_handler (_("%B: Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section %s"),
+         /* xgettext:c-format */
+         _bfd_error_handler (_("%B: Warning: Ignoring section flag"
+                               " IMAGE_SCN_MEM_NOT_PAGED in section %s"),
                              abfd, name);
          break;
        case IMAGE_SCN_MEM_EXECUTE:
                              abfd, name);
          break;
        case IMAGE_SCN_MEM_EXECUTE:
@@ -1292,7 +1309,8 @@ styp_to_sec_flags (bfd *abfd,
       /* If the section flag was not handled, report it here.  */
       if (unhandled != NULL)
        {
       /* If the section flag was not handled, report it here.  */
       if (unhandled != NULL)
        {
-         (*_bfd_error_handler)
+         _bfd_error_handler
+           /* xgettext:c-format */
            (_("%B (%s): Section flag %s (0x%x) ignored"),
             abfd, name, unhandled, flag);
          result = FALSE;
            (_("%B (%s): Section flag %s (0x%x) ignored"),
             abfd, name, unhandled, flag);
          result = FALSE;
@@ -1342,6 +1360,10 @@ CODE_FRAGMENT
 .  COFF_SYMBOL_PE_SECTION
 .};
 .
 .  COFF_SYMBOL_PE_SECTION
 .};
 .
+.typedef asection * (*coff_gc_mark_hook_fn)
+.  (asection *, struct bfd_link_info *, struct internal_reloc *,
+.   struct coff_link_hash_entry *, struct internal_syment *);
+.
 Special entry points for gdb to swap in coff symbol table parts:
 .typedef struct
 .{
 Special entry points for gdb to swap in coff symbol table parts:
 .typedef struct
 .{
@@ -1796,6 +1818,7 @@ coff_new_section_hook (bfd * abfd, asection * section)
      in case this symbol winds up getting written out.  The value 0
      for n_numaux is already correct.  */
 
      in case this symbol winds up getting written out.  The value 0
      for n_numaux is already correct.  */
 
+  native->is_sym = TRUE;
   native->u.syment.n_type = T_NULL;
   native->u.syment.n_sclass = sclass;
 
   native->u.syment.n_type = T_NULL;
   native->u.syment.n_sclass = sclass;
 
@@ -1922,9 +1945,9 @@ coff_set_alignment_hook (bfd * abfd ATTRIBUTE_UNUSED,
       section->rel_filepos += relsz;
     }
   else if (hdr->s_nreloc == 0xffff)
       section->rel_filepos += relsz;
     }
   else if (hdr->s_nreloc == 0xffff)
-    (*_bfd_error_handler)
-      ("%s: warning: claims to have 0xffff relocs, without overflow",
-       bfd_get_filename (abfd));
+    _bfd_error_handler
+      (_("%B: warning: claims to have 0xffff relocs, without overflow"),
+       abfd);
 }
 #undef ALIGN_SET
 #undef ELIFALIGN_SET
 }
 #undef ALIGN_SET
 #undef ELIFALIGN_SET
@@ -2069,7 +2092,11 @@ coff_mkobject_hook (bfd * abfd,
 #endif
 
   if ((internal_f->f_flags & F_GO32STUB) != 0)
 #endif
 
   if ((internal_f->f_flags & F_GO32STUB) != 0)
-    coff->go32stub = (char *) bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE);
+    {
+      coff->go32stub = (char *) bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE);
+      if (coff->go32stub == NULL)
+       return NULL;
+    }
   if (coff->go32stub != NULL)
     memcpy (coff->go32stub, internal_f->go32stub, GO32_STUBSIZE);
 
   if (coff->go32stub != NULL)
     memcpy (coff->go32stub, internal_f->go32stub, GO32_STUBSIZE);
 
@@ -2274,6 +2301,8 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr)
                bfd_size_type amt = bfd_coff_symesz (abfd);
 
                buf = bfd_malloc (amt);
                bfd_size_type amt = bfd_coff_symesz (abfd);
 
                buf = bfd_malloc (amt);
+               if (buf == NULL)
+                 return FALSE;
                if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
                    || bfd_bread (buf, amt, abfd) != amt)
                  {
                if (bfd_seek (abfd, obj_sym_filepos (abfd), SEEK_SET) != 0
                    || bfd_bread (buf, amt, abfd) != amt)
                  {
@@ -2432,7 +2461,7 @@ coff_set_arch_mach_hook (bfd *abfd, void * filehdr)
 #endif
        default:
          arch = bfd_arch_obscure;
 #endif
        default:
          arch = bfd_arch_obscure;
-         (*_bfd_error_handler)
+         _bfd_error_handler
            (_("Unrecognized TI COFF target id '0x%x'"),
             internal_f->f_target_id);
          break;
            (_("Unrecognized TI COFF target id '0x%x'"),
             internal_f->f_target_id);
          break;
@@ -2497,11 +2526,13 @@ coff_pointerize_aux_hook (bfd *abfd ATTRIBUTE_UNUSED,
                          unsigned int indaux,
                          combined_entry_type *aux)
 {
                          unsigned int indaux,
                          combined_entry_type *aux)
 {
+  BFD_ASSERT (symbol->is_sym);
   int n_sclass = symbol->u.syment.n_sclass;
 
   if (CSECT_SYM_P (n_sclass)
       && indaux + 1 == symbol->u.syment.n_numaux)
     {
   int n_sclass = symbol->u.syment.n_sclass;
 
   if (CSECT_SYM_P (n_sclass)
       && indaux + 1 == symbol->u.syment.n_numaux)
     {
+      BFD_ASSERT (! aux->is_sym);
       if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) == XTY_LD)
        {
          aux->u.auxent.x_csect.x_scnlen.p =
       if (SMTYP_SMTYP (aux->u.auxent.x_csect.x_smtyp) == XTY_LD)
        {
          aux->u.auxent.x_csect.x_scnlen.p =
@@ -2534,6 +2565,7 @@ coff_pointerize_aux_hook (bfd *abfd ATTRIBUTE_UNUSED,
   /* Return TRUE if we don't want to pointerize this aux entry, which
      is the case for the lastfirst aux entry for a C_LEAFPROC symbol.  */
   return (indaux == 1
   /* Return TRUE if we don't want to pointerize this aux entry, which
      is the case for the lastfirst aux entry for a C_LEAFPROC symbol.  */
   return (indaux == 1
+         && symbol->is_sym
          && (symbol->u.syment.n_sclass == C_LEAFPROC
              || symbol->u.syment.n_sclass == C_LEAFSTAT
              || symbol->u.syment.n_sclass == C_LEAFEXT));
          && (symbol->u.syment.n_sclass == C_LEAFPROC
              || symbol->u.syment.n_sclass == C_LEAFSTAT
              || symbol->u.syment.n_sclass == C_LEAFEXT));
@@ -2556,6 +2588,8 @@ coff_print_aux (bfd *abfd ATTRIBUTE_UNUSED,
                combined_entry_type *aux ATTRIBUTE_UNUSED,
                unsigned int indaux ATTRIBUTE_UNUSED)
 {
                combined_entry_type *aux ATTRIBUTE_UNUSED,
                unsigned int indaux ATTRIBUTE_UNUSED)
 {
+  BFD_ASSERT (symbol->is_sym);
+  BFD_ASSERT (! aux->is_sym);
 #ifdef RS6000COFF_C
   if (CSECT_SYM_P (symbol->u.syment.n_sclass)
       && indaux + 1 == symbol->u.syment.n_numaux)
 #ifdef RS6000COFF_C
   if (CSECT_SYM_P (symbol->u.syment.n_sclass)
       && indaux + 1 == symbol->u.syment.n_numaux)
@@ -2657,10 +2691,16 @@ coff_write_relocs (bfd * abfd, int first_undef)
        amt = s->reloc_count;
        amt *= sizeof (arelent *);
        p = bfd_malloc (amt);
        amt = s->reloc_count;
        amt *= sizeof (arelent *);
        p = bfd_malloc (amt);
-       if (p == NULL && s->reloc_count > 0)
-         return FALSE;
-       memcpy (p, s->orelocation, (size_t) amt);
-       qsort (p, s->reloc_count, sizeof (arelent *), compare_arelent_ptr);
+       if (p == NULL)
+         {
+           if (s->reloc_count > 0)
+             return FALSE;
+         }
+       else
+         {
+           memcpy (p, s->orelocation, (size_t) amt);
+           qsort (p, s->reloc_count, sizeof (arelent *), compare_arelent_ptr);
+         }
       }
 #endif
 
       }
 #endif
 
@@ -2747,7 +2787,9 @@ coff_write_relocs (bfd * abfd, int first_undef)
                    if (n.r_symndx > obj_conv_table_size (abfd))
                      {
                        bfd_set_error (bfd_error_bad_value);
                    if (n.r_symndx > obj_conv_table_size (abfd))
                      {
                        bfd_set_error (bfd_error_bad_value);
-                       _bfd_error_handler (_("%B: reloc against a non-existant symbol index: %ld"),
+                       /* xgettext:c-format */
+                       _bfd_error_handler (_("%B: reloc against a non-existent"
+                                             " symbol index: %ld"),
                                            abfd, n.r_symndx);
                        return FALSE;
                      }
                                            abfd, n.r_symndx);
                        return FALSE;
                      }
@@ -3142,6 +3184,16 @@ coff_compute_section_file_positions (bfd * abfd)
         This repairs 'ld -r' for arm-wince-pe target.  */
       if (page_size == 0)
        page_size = 1;
         This repairs 'ld -r' for arm-wince-pe target.  */
       if (page_size == 0)
        page_size = 1;
+
+      /* PR 17512: file: 0ac816d3.  */
+      if (page_size < 0)
+       {
+         bfd_set_error (bfd_error_file_too_big);
+         _bfd_error_handler
+           /* xgettext:c-format */
+           (_("%B: page size is too large (0x%x)"), abfd, page_size);
+         return FALSE;
+       }
     }
   else
     page_size = PE_DEF_FILE_ALIGNMENT;
     }
   else
     page_size = PE_DEF_FILE_ALIGNMENT;
@@ -3165,9 +3217,10 @@ coff_compute_section_file_positions (bfd * abfd)
        {
          coff_symbol_type *cf;
 
        {
          coff_symbol_type *cf;
 
-         cf = coff_symbol_from (abfd, *symp);
+         cf = coff_symbol_from (*symp);
          if (cf != NULL
              && cf->native != NULL
          if (cf != NULL
              && cf->native != NULL
+             && cf->native->is_sym
              && SYMNAME_IN_DEBUG (&cf->native->u.syment))
            {
              size_t len;
              && SYMNAME_IN_DEBUG (&cf->native->u.syment))
            {
              size_t len;
@@ -3296,7 +3349,8 @@ coff_compute_section_file_positions (bfd * abfd)
   if (target_index >= bfd_coff_max_nscns (abfd))
     {
       bfd_set_error (bfd_error_file_too_big);
   if (target_index >= bfd_coff_max_nscns (abfd))
     {
       bfd_set_error (bfd_error_file_too_big);
-      (*_bfd_error_handler)
+      _bfd_error_handler
+       /* xgettext:c-format */
        (_("%B: too many sections (%d)"), abfd, target_index);
       return FALSE;
     }
        (_("%B: too many sections (%d)"), abfd, target_index);
       return FALSE;
     }
@@ -3706,7 +3760,9 @@ coff_write_object_contents (bfd * abfd)
                 NUL-terminated.  We use a temporary buffer so that we can still
                 sprintf all eight chars without splatting a terminating NUL
                 over the first byte of the following member (s_paddr).  */
                 NUL-terminated.  We use a temporary buffer so that we can still
                 sprintf all eight chars without splatting a terminating NUL
                 over the first byte of the following member (s_paddr).  */
-             char s_name_buf[SCNNMLEN + 1];
+             /* PR 21096: The +20 is to stop a bogus warning from gcc7 about
+                a possible buffer overflow.  */
+             char s_name_buf[SCNNMLEN + 1 + 20];
 
              /* An inherent limitation of the /nnnnnnn notation used to indicate
                 the offset of the long name in the string table is that we
 
              /* An inherent limitation of the /nnnnnnn notation used to indicate
                 the offset of the long name in the string table is that we
@@ -3714,15 +3770,17 @@ coff_write_object_contents (bfd * abfd)
              if (string_size >= 10000000)
                {
                  bfd_set_error (bfd_error_file_too_big);
              if (string_size >= 10000000)
                {
                  bfd_set_error (bfd_error_file_too_big);
-                 (*_bfd_error_handler)
-                   (_("%B: section %s: string table overflow at offset %ld"),
-                   abfd, current->name, string_size);
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("%B: section %A: string table overflow at offset %ld"),
+                   abfd, current, string_size);
                  return FALSE;
                }
 
                  return FALSE;
                }
 
-             /* snprintf not strictly necessary now we've verified the value
-                has less than eight ASCII digits, but never mind.  */
-             snprintf (s_name_buf, SCNNMLEN + 1, "/%lu", (unsigned long) string_size);
+             /* We do not need to use snprintf here as we have already verfied
+                that string_size is not too big, plus we have an overlarge
+                buffer, just in case.  */
+             sprintf (s_name_buf, "/%lu", (unsigned long) string_size);
              /* Then strncpy takes care of any padding for us.  */
              strncpy (section.s_name, s_name_buf, SCNNMLEN);
              string_size += len + 1;
              /* Then strncpy takes care of any padding for us.  */
              strncpy (section.s_name, s_name_buf, SCNNMLEN);
              string_size += len + 1;
@@ -3862,9 +3920,10 @@ coff_write_object_contents (bfd * abfd)
              /* See if this is the section symbol.  */
              if (strcmp ((*psym)->name, current->name) == 0)
                {
              /* See if this is the section symbol.  */
              if (strcmp ((*psym)->name, current->name) == 0)
                {
-                 csym = coff_symbol_from (abfd, *psym);
+                 csym = coff_symbol_from (*psym);
                  if (csym == NULL
                      || csym->native == NULL
                  if (csym == NULL
                      || csym->native == NULL
+                     || ! csym->native->is_sym
                      || csym->native->u.syment.n_numaux < 1
                      || csym->native->u.syment.n_sclass != C_STAT
                      || csym->native->u.syment.n_type != T_NULL)
                      || csym->native->u.syment.n_numaux < 1
                      || csym->native->u.syment.n_sclass != C_STAT
                      || csym->native->u.syment.n_type != T_NULL)
@@ -3887,6 +3946,7 @@ coff_write_object_contents (bfd * abfd)
                 x_associated field is not currently supported.  */
 
              aux = csym->native + 1;
                 x_associated field is not currently supported.  */
 
              aux = csym->native + 1;
+             BFD_ASSERT (! aux->is_sym);
              switch (current->flags & SEC_LINK_DUPLICATES)
                {
                case SEC_LINK_DUPLICATES_DISCARD:
              switch (current->flags & SEC_LINK_DUPLICATES)
                {
                case SEC_LINK_DUPLICATES_DISCARD:
@@ -4032,6 +4092,8 @@ coff_write_object_contents (bfd * abfd)
     internal_f.f_flags |= F_DYNLOAD;
 #endif
 
     internal_f.f_flags |= F_DYNLOAD;
 #endif
 
+  memset (&internal_a, 0, sizeof internal_a);
+
   /* Set up architecture-dependent stuff.  */
   {
     unsigned int magic = 0;
   /* Set up architecture-dependent stuff.  */
   {
     unsigned int magic = 0;
@@ -4510,9 +4572,11 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
   unsigned int counter;
   alent *cache_ptr;
   bfd_vma prev_offset = 0;
   unsigned int counter;
   alent *cache_ptr;
   bfd_vma prev_offset = 0;
-  int ordered = 1;
+  bfd_boolean ordered = TRUE;
   unsigned int nbr_func;
   LINENO *src;
   unsigned int nbr_func;
   LINENO *src;
+  bfd_boolean have_func;
+  bfd_boolean ret = TRUE;
 
   BFD_ASSERT (asect->lineno == NULL);
 
 
   BFD_ASSERT (asect->lineno == NULL);
 
@@ -4525,7 +4589,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
   native_lineno = (LINENO *) buy_and_read (abfd, asect->line_filepos, amt);
   if (native_lineno == NULL)
     {
   native_lineno = (LINENO *) buy_and_read (abfd, asect->line_filepos, amt);
   if (native_lineno == NULL)
     {
-      (*_bfd_error_handler)
+      _bfd_error_handler
        (_("%B: warning: line number table read failed"), abfd);
       bfd_release (abfd, lineno_cache);
       return FALSE;
        (_("%B: warning: line number table read failed"), abfd);
       bfd_release (abfd, lineno_cache);
       return FALSE;
@@ -4535,6 +4599,7 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
   asect->lineno = lineno_cache;
   src = native_lineno;
   nbr_func = 0;
   asect->lineno = lineno_cache;
   src = native_lineno;
   nbr_func = 0;
+  have_func = FALSE;
 
   for (counter = 0; counter < asect->lineno_count; counter++, src++)
     {
 
   for (counter = 0; counter < asect->lineno_count; counter++, src++)
     {
@@ -4549,46 +4614,69 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
 
       if (cache_ptr->line_number == 0)
        {
 
       if (cache_ptr->line_number == 0)
        {
+         combined_entry_type * ent;
          bfd_vma symndx;
          coff_symbol_type *sym;
 
          bfd_vma symndx;
          coff_symbol_type *sym;
 
+         have_func = FALSE;
          symndx = dst.l_addr.l_symndx;
          if (symndx >= obj_raw_syment_count (abfd))
            {
          symndx = dst.l_addr.l_symndx;
          if (symndx >= obj_raw_syment_count (abfd))
            {
-             (*_bfd_error_handler)
+             _bfd_error_handler
+               /* xgettext:c-format */
                (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"),
                 abfd, (long) symndx, counter);
                (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"),
                 abfd, (long) symndx, counter);
+             cache_ptr->line_number = -1;
+             ret = FALSE;
              continue;
            }
 
              continue;
            }
 
+         ent = obj_raw_syments (abfd) + symndx;
          /* FIXME: We should not be casting between ints and
             pointers like this.  */
          /* FIXME: We should not be casting between ints and
             pointers like this.  */
-         sym = ((coff_symbol_type *)
-                ((symndx + obj_raw_syments (abfd))
-                 ->u.syment._n._n_n._n_zeroes));
+         if (! ent->is_sym)
+           {
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"),
+                abfd, (long) symndx, counter);
+             cache_ptr->line_number = -1;
+             ret = FALSE;
+             continue;
+           }
+         sym = (coff_symbol_type *) (ent->u.syment._n._n_n._n_zeroes);
 
          /* PR 17512 file: 078-10659-0.004  */
          if (sym < obj_symbols (abfd)
 
          /* PR 17512 file: 078-10659-0.004  */
          if (sym < obj_symbols (abfd)
-             || sym >= obj_symbols (abfd) + obj_raw_syment_count (abfd))
+             || sym >= obj_symbols (abfd) + bfd_get_symcount (abfd))
            {
            {
-             (*_bfd_error_handler)
+             _bfd_error_handler
+               /* xgettext:c-format */
                (_("%B: warning: illegal symbol in line number entry %d"),
                 abfd, counter);
                (_("%B: warning: illegal symbol in line number entry %d"),
                 abfd, counter);
+             cache_ptr->line_number = -1;
+             ret = FALSE;
              continue;
            }
 
              continue;
            }
 
+         have_func = TRUE;
          nbr_func++;
          cache_ptr->u.sym = (asymbol *) sym;
          if (sym->lineno != NULL)
          nbr_func++;
          cache_ptr->u.sym = (asymbol *) sym;
          if (sym->lineno != NULL)
-           (*_bfd_error_handler)
+           _bfd_error_handler
+             /* xgettext:c-format */
              (_("%B: warning: duplicate line number information for `%s'"),
               abfd, bfd_asymbol_name (&sym->symbol));
 
          sym->lineno = cache_ptr;
          if (sym->symbol.value < prev_offset)
              (_("%B: warning: duplicate line number information for `%s'"),
               abfd, bfd_asymbol_name (&sym->symbol));
 
          sym->lineno = cache_ptr;
          if (sym->symbol.value < prev_offset)
-           ordered = 0;
+           ordered = FALSE;
          prev_offset = sym->symbol.value;
        }
          prev_offset = sym->symbol.value;
        }
+      else if (!have_func)
+       /* Drop line information that has no associated function.
+          PR 17521: file: 078-10659-0.004.  */
+       continue;
       else
        cache_ptr->u.offset = (dst.l_addr.l_paddr
                               - bfd_section_vma (abfd, asect));
       else
        cache_ptr->u.offset = (dst.l_addr.l_paddr
                               - bfd_section_vma (abfd, asect));
@@ -4617,6 +4705,8 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
            if (lineno_cache[i].line_number == 0)
              *p++ = &lineno_cache[i];
 
            if (lineno_cache[i].line_number == 0)
              *p++ = &lineno_cache[i];
 
+         BFD_ASSERT ((unsigned int) (p - func_table) == nbr_func);
+
          /* Sort by functions.  */
          qsort (func_table, nbr_func, sizeof (alent *), coff_sort_func_alent);
 
          /* Sort by functions.  */
          qsort (func_table, nbr_func, sizeof (alent *), coff_sort_func_alent);
 
@@ -4642,21 +4732,19 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
                    *n_cache_ptr++ = *old_ptr++;
                  while (old_ptr->line_number != 0);
                }
                    *n_cache_ptr++ = *old_ptr++;
                  while (old_ptr->line_number != 0);
                }
-             /* PR 17521: file: 078-10659-0.004.  */
-             if (n_cache_ptr < n_lineno_cache + asect->lineno_count)
-               {
-                 amt = n_cache_ptr - n_lineno_cache;
-                 memcpy (lineno_cache, n_lineno_cache, amt * sizeof (alent));
-                 memset (lineno_cache + amt, 0, (asect->lineno_count - amt) * sizeof (alent));
-               }
-             else
-               memcpy (lineno_cache, n_lineno_cache, amt);
+             BFD_ASSERT ((bfd_size_type) (n_cache_ptr - n_lineno_cache) == (amt / sizeof (alent)));
+
+             memcpy (lineno_cache, n_lineno_cache, amt);
            }
            }
+         else
+           ret = FALSE;
          bfd_release (abfd, func_table);
        }
          bfd_release (abfd, func_table);
        }
+      else
+       ret = FALSE;
     }
 
     }
 
-  return TRUE;
+  return ret;
 }
 
 /* Slurp in the symbol table, converting it to generic form.  Note
 }
 
 /* Slurp in the symbol table, converting it to generic form.  Note
@@ -4671,6 +4759,7 @@ coff_slurp_symbol_table (bfd * abfd)
   unsigned int *table_ptr;
   bfd_size_type amt;
   unsigned int number_of_symbols = 0;
   unsigned int *table_ptr;
   bfd_size_type amt;
   unsigned int number_of_symbols = 0;
+  bfd_boolean ret = TRUE;
 
   if (obj_symbols (abfd))
     return TRUE;
 
   if (obj_symbols (abfd))
     return TRUE;
@@ -4704,12 +4793,15 @@ coff_slurp_symbol_table (bfd * abfd)
          table_ptr[this_index] = number_of_symbols;
 
          dst->symbol.the_bfd = abfd;
          table_ptr[this_index] = number_of_symbols;
 
          dst->symbol.the_bfd = abfd;
+         BFD_ASSERT (src->is_sym);
          dst->symbol.name = (char *) (src->u.syment._n._n_n._n_offset);
          /* We use the native name field to point to the cached field.  */
          src->u.syment._n._n_n._n_zeroes = (bfd_hostptr_t) dst;
          dst->symbol.section = coff_section_from_bfd_index (abfd,
                                                     src->u.syment.n_scnum);
          dst->symbol.flags = 0;
          dst->symbol.name = (char *) (src->u.syment._n._n_n._n_offset);
          /* We use the native name field to point to the cached field.  */
          src->u.syment._n._n_n._n_zeroes = (bfd_hostptr_t) dst;
          dst->symbol.section = coff_section_from_bfd_index (abfd,
                                                     src->u.syment.n_scnum);
          dst->symbol.flags = 0;
+         /* PR 17512: file: 079-7098-0.001:0.1.  */
+         dst->symbol.value = 0;
          dst->done_lineno = FALSE;
 
          switch (src->u.syment.n_sclass)
          dst->done_lineno = FALSE;
 
          switch (src->u.syment.n_sclass)
@@ -4984,21 +5076,26 @@ coff_slurp_symbol_table (bfd * abfd)
            case C_UEXT:        /* Tentative external definition.  */
 #endif
            case C_EXTLAB:      /* External load time label.  */
            case C_UEXT:        /* Tentative external definition.  */
 #endif
            case C_EXTLAB:      /* External load time label.  */
-           case C_HIDDEN:      /* Ext symbol in dmert public lib.  */
            default:
            default:
-             (*_bfd_error_handler)
+             _bfd_error_handler
+               /* xgettext:c-format */
                (_("%B: Unrecognized storage class %d for %s symbol `%s'"),
                 abfd, src->u.syment.n_sclass,
                 dst->symbol.section->name, dst->symbol.name);
                (_("%B: Unrecognized storage class %d for %s symbol `%s'"),
                 abfd, src->u.syment.n_sclass,
                 dst->symbol.section->name, dst->symbol.name);
+             ret = FALSE;
+             /* Fall through.  */
+           case C_HIDDEN:      /* Ext symbol in dmert public lib.  */
+             /* PR 20722: These symbols can also be generated by
+                building DLLs with --gc-sections enabled.  */
              dst->symbol.flags = BSF_DEBUGGING;
              dst->symbol.value = (src->u.syment.n_value);
              break;
            }
 
          dst->native = src;
              dst->symbol.flags = BSF_DEBUGGING;
              dst->symbol.value = (src->u.syment.n_value);
              break;
            }
 
          dst->native = src;
-
          dst->symbol.udata.i = 0;
          dst->lineno = NULL;
          dst->symbol.udata.i = 0;
          dst->lineno = NULL;
+
          this_index += (src->u.syment.n_numaux) + 1;
          dst++;
          number_of_symbols++;
          this_index += (src->u.syment.n_numaux) + 1;
          dst++;
          number_of_symbols++;
@@ -5017,12 +5114,13 @@ coff_slurp_symbol_table (bfd * abfd)
     p = abfd->sections;
     while (p)
       {
     p = abfd->sections;
     while (p)
       {
-       coff_slurp_line_table (abfd, p);
+       if (! coff_slurp_line_table (abfd, p))
+         return FALSE;
        p = p->next;
       }
   }
 
        p = p->next;
       }
   }
 
-  return TRUE;
+  return ret;
 }
 
 /* Classify a COFF symbol.  A couple of targets have globally visible
 }
 
 /* Classify a COFF symbol.  A couple of targets have globally visible
@@ -5083,7 +5181,7 @@ coff_classify_symbol (bfd *abfd,
          asection *sec;
          char * name;
          char buf[SYMNMLEN + 1];
          asection *sec;
          char * name;
          char buf[SYMNMLEN + 1];
+
          name = _bfd_coff_internal_syment_name (abfd, syment, buf)
          sec = coff_section_from_bfd_index (abfd, syment->n_scnum);
          if (sec != NULL && name != NULL
          name = _bfd_coff_internal_syment_name (abfd, syment, buf)
          sec = coff_section_from_bfd_index (abfd, syment->n_scnum);
          if (sec != NULL && name != NULL
@@ -5112,7 +5210,8 @@ coff_classify_symbol (bfd *abfd,
     {
       char buf[SYMNMLEN + 1];
 
     {
       char buf[SYMNMLEN + 1];
 
-      (*_bfd_error_handler)
+      _bfd_error_handler
+       /* xgettext:c-format */
        (_("warning: %B: local symbol `%s' has no section"),
         abfd, _bfd_coff_internal_syment_name (abfd, syment, buf));
     }
        (_("warning: %B: local symbol `%s' has no section"),
         abfd, _bfd_coff_internal_syment_name (abfd, syment, buf));
     }
@@ -5156,8 +5255,9 @@ SUBSUBSECTION
       coffsym = (obj_symbols (abfd)                            \
                 + (cache_ptr->sym_ptr_ptr - symbols));         \
     else if (ptr)                                              \
       coffsym = (obj_symbols (abfd)                            \
                 + (cache_ptr->sym_ptr_ptr - symbols));         \
     else if (ptr)                                              \
-      coffsym = coff_symbol_from (abfd, ptr);                  \
+      coffsym = coff_symbol_from (ptr);                                \
     if (coffsym != NULL                                                \
     if (coffsym != NULL                                                \
+       && coffsym->native->is_sym                              \
        && coffsym->native->u.syment.n_scnum == 0)              \
       cache_ptr->addend = 0;                                   \
     else if (ptr && bfd_asymbol_bfd (ptr) == abfd              \
        && coffsym->native->u.syment.n_scnum == 0)              \
       cache_ptr->addend = 0;                                   \
     else if (ptr && bfd_asymbol_bfd (ptr) == abfd              \
@@ -5217,7 +5317,8 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols)
        {
          if (dst.r_symndx < 0 || dst.r_symndx >= obj_conv_table_size (abfd))
            {
        {
          if (dst.r_symndx < 0 || dst.r_symndx >= obj_conv_table_size (abfd))
            {
-             (*_bfd_error_handler)
+             _bfd_error_handler
+               /* xgettext:c-format */
                (_("%B: warning: illegal symbol index %ld in relocs"),
                 abfd, (long) dst.r_symndx);
              cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
                (_("%B: warning: illegal symbol index %ld in relocs"),
                 abfd, (long) dst.r_symndx);
              cache_ptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
@@ -5256,7 +5357,8 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols)
 
       if (cache_ptr->howto == NULL)
        {
 
       if (cache_ptr->howto == NULL)
        {
-         (*_bfd_error_handler)
+         _bfd_error_handler
+           /* xgettext:c-format */
            (_("%B: illegal relocation type %d at address 0x%lx"),
             abfd, dst.r_type, (long) dst.r_vaddr);
          bfd_set_error (bfd_error_bad_value);
            (_("%B: illegal relocation type %d at address 0x%lx"),
             abfd, dst.r_type, (long) dst.r_vaddr);
          bfd_set_error (bfd_error_bad_value);
@@ -5280,7 +5382,7 @@ coff_slurp_reloc_table (bfd * abfd, sec_ptr asect, asymbol ** symbols)
 static reloc_howto_type *
 coff_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
                     asection *sec ATTRIBUTE_UNUSED,
 static reloc_howto_type *
 coff_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
                     asection *sec ATTRIBUTE_UNUSED,
-                    struct internal_reloc *rel,
+                    struct internal_reloc *rel ATTRIBUTE_UNUSED,
                     struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
                     struct internal_syment *sym ATTRIBUTE_UNUSED,
                     bfd_vma *addendp ATTRIBUTE_UNUSED)
                     struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
                     struct internal_syment *sym ATTRIBUTE_UNUSED,
                     bfd_vma *addendp ATTRIBUTE_UNUSED)
@@ -5337,6 +5439,10 @@ coff_canonicalize_reloc (bfd * abfd,
   return section->reloc_count;
 }
 
   return section->reloc_count;
 }
 
+#ifndef coff_set_reloc
+#define coff_set_reloc _bfd_generic_set_reloc
+#endif
+
 #ifndef coff_reloc16_estimate
 #define coff_reloc16_estimate dummy_reloc16_estimate
 
 #ifndef coff_reloc16_estimate
 #define coff_reloc16_estimate dummy_reloc16_estimate
 
@@ -5405,6 +5511,8 @@ dummy_reloc16_extra_cases (bfd *abfd ATTRIBUTE_UNUSED,
   _bfd_generic_copy_link_hash_symbol_type
 #define coff_bfd_link_split_section  _bfd_generic_link_split_section
 
   _bfd_generic_copy_link_hash_symbol_type
 #define coff_bfd_link_split_section  _bfd_generic_link_split_section
 
+#define coff_bfd_link_check_relocs   _bfd_generic_link_check_relocs
+
 #ifndef coff_start_final_link
 #define coff_start_final_link NULL
 #endif
 #ifndef coff_start_final_link
 #define coff_start_final_link NULL
 #endif
@@ -5603,7 +5711,7 @@ static bfd_coff_backend_data ticoff1_swap_table =
 #endif
 
 #ifdef COFF_WITH_PE_BIGOBJ
 #endif
 
 #ifdef COFF_WITH_PE_BIGOBJ
-/* The UUID for bigobj files.  */
+/* The UID for bigobj files.  */
 
 static const char header_bigobj_classid[16] =
 {
 
 static const char header_bigobj_classid[16] =
 {
@@ -5686,6 +5794,7 @@ coff_bigobj_swap_sym_in (bfd * abfd, void * ext1, void * in1)
     }
 
   in->n_value = H_GET_32 (abfd, ext->e_value);
     }
 
   in->n_value = H_GET_32 (abfd, ext->e_value);
+  BFD_ASSERT (sizeof (in->n_scnum) >= 4);
   in->n_scnum = H_GET_32 (abfd, ext->e_scnum);
   in->n_type = H_GET_16 (abfd, ext->e_type);
   in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
   in->n_scnum = H_GET_32 (abfd, ext->e_scnum);
   in->n_type = H_GET_16 (abfd, ext->e_type);
   in->n_sclass = H_GET_8 (abfd, ext->e_sclass);
@@ -5924,7 +6033,7 @@ static bfd_coff_backend_data bigobj_swap_table =
 #endif
 
 #ifndef coff_bfd_gc_sections
 #endif
 
 #ifndef coff_bfd_gc_sections
-#define coff_bfd_gc_sections               bfd_generic_gc_sections
+#define coff_bfd_gc_sections               bfd_coff_gc_sections
 #endif
 
 #ifndef coff_bfd_lookup_section_flags
 #endif
 
 #ifndef coff_bfd_lookup_section_flags
@@ -5952,6 +6061,10 @@ static bfd_coff_backend_data bigobj_swap_table =
 #define coff_bfd_define_common_symbol      bfd_generic_define_common_symbol
 #endif
 
 #define coff_bfd_define_common_symbol      bfd_generic_define_common_symbol
 #endif
 
+#ifndef coff_bfd_define_start_stop
+#define coff_bfd_define_start_stop         bfd_generic_define_start_stop
+#endif
+
 #define CREATE_BIG_COFF_TARGET_VEC(VAR, NAME, EXTRA_O_FLAGS, EXTRA_S_FLAGS, UNDER, ALTERNATIVE, SWAP_TABLE)    \
 const bfd_target VAR =                                                 \
 {                                                                      \
 #define CREATE_BIG_COFF_TARGET_VEC(VAR, NAME, EXTRA_O_FLAGS, EXTRA_S_FLAGS, UNDER, ALTERNATIVE, SWAP_TABLE)    \
 const bfd_target VAR =                                                 \
 {                                                                      \
This page took 0.055788 seconds and 4 git commands to generate.