LD/ELF: Unify STB_GNU_UNIQUE handling
[deliverable/binutils-gdb.git] / bfd / coffcode.h
index 48709f4dec799ab2d9454b5627c11dfc1080b490..eef3fa8d1da6be75d83be01a56334a5a11239b9b 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-2016 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;
 .
 .
@@ -928,12 +931,7 @@ handle_COMDAT (bfd * abfd,
 
       bfd_coff_swap_sym_in (abfd, esym, & isym);
 
 
       bfd_coff_swap_sym_in (abfd, esym, & isym);
 
-      if (sizeof (internal_s->s_name) > SYMNMLEN)
-       {
-         /* This case implies that the matching
-            symbol name will be in the string table.  */
-         abort ();
-       }
+      BFD_ASSERT (sizeof (internal_s->s_name) <= SYMNMLEN);
 
       if (isym.n_scnum == section->target_index)
        {
 
       if (isym.n_scnum == section->target_index)
        {
@@ -964,8 +962,12 @@ 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  */
          if (symname == NULL)
          if (symname == NULL)
-           abort ();
+           {
+             _bfd_error_handler (_("%B: unable to load COMDAT section name"), abfd);
+             break;
+           }
 
          switch (seen_state)
            {
 
          switch (seen_state)
            {
@@ -1007,6 +1009,13 @@ handle_COMDAT (bfd * abfd,
 
                seen_state = 1;
 
 
                seen_state = 1;
 
+               /* PR 17512: file: e2cfe54f.  */
+               if (esym + bfd_coff_symesz (abfd) >= esymend)
+                 {
+                   _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,
@@ -1160,7 +1169,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;
@@ -1183,7 +1192,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;
@@ -1343,6 +1352,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
 .{
@@ -1797,6 +1810,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;
 
@@ -2070,7 +2084,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);
 
@@ -2275,6 +2293,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)
                  {
@@ -2498,11 +2518,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 =
@@ -2535,6 +2557,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));
@@ -2557,6 +2580,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)
@@ -2658,10 +2683,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
 
@@ -3143,6 +3174,15 @@ 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)
+           (_("%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;
@@ -3166,9 +3206,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;
@@ -3863,9 +3904,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)
@@ -3888,6 +3930,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:
@@ -4456,11 +4499,11 @@ buy_and_read (bfd *abfd, file_ptr where, bfd_size_type size)
   void * area = bfd_alloc (abfd, size);
 
   if (!area)
   void * area = bfd_alloc (abfd, size);
 
   if (!area)
-    return (NULL);
+    return NULL;
   if (bfd_seek (abfd, where, SEEK_SET) != 0
       || bfd_bread (area, size, abfd) != size)
   if (bfd_seek (abfd, where, SEEK_SET) != 0
       || bfd_bread (area, size, abfd) != size)
-    return (NULL);
-  return (area);
+    return NULL;
+  return area;
 }
 
 /*
 }
 
 /*
@@ -4494,6 +4537,8 @@ coff_sort_func_alent (const void * arg1, const void * arg2)
   const coff_symbol_type *s1 = (const coff_symbol_type *) (al1->u.sym);
   const coff_symbol_type *s2 = (const coff_symbol_type *) (al2->u.sym);
 
   const coff_symbol_type *s1 = (const coff_symbol_type *) (al1->u.sym);
   const coff_symbol_type *s2 = (const coff_symbol_type *) (al2->u.sym);
 
+  if (s1 == NULL || s2 == NULL)
+    return 0;
   if (s1->symbol.value < s2->symbol.value)
     return -1;
   else if (s1->symbol.value > s2->symbol.value)
   if (s1->symbol.value < s2->symbol.value)
     return -1;
   else if (s1->symbol.value > s2->symbol.value)
@@ -4511,9 +4556,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);
 
@@ -4536,35 +4583,65 @@ 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++)
+  for (counter = 0; counter < asect->lineno_count; counter++, src++)
     {
       struct internal_lineno dst;
 
       bfd_coff_swap_lineno_in (abfd, src, &dst);
       cache_ptr->line_number = dst.l_lnno;
     {
       struct internal_lineno dst;
 
       bfd_coff_swap_lineno_in (abfd, src, &dst);
       cache_ptr->line_number = dst.l_lnno;
+      /* Appease memory checkers that get all excited about
+        uninitialised memory when copying alents if u.offset is
+        larger than u.sym.  (64-bit BFD on 32-bit host.)  */
+      memset (&cache_ptr->u, 0, sizeof (cache_ptr->u));
 
       if (cache_ptr->line_number == 0)
        {
 
       if (cache_ptr->line_number == 0)
        {
-         bfd_signed_vma symndx;
+         combined_entry_type * ent;
+         bfd_vma symndx;
          coff_symbol_type *sym;
 
          coff_symbol_type *sym;
 
-         nbr_func++;
+         have_func = FALSE;
          symndx = dst.l_addr.l_symndx;
          symndx = dst.l_addr.l_symndx;
-         if (symndx < 0
-             || (bfd_vma) symndx >= obj_raw_syment_count (abfd))
+         if (symndx >= obj_raw_syment_count (abfd))
            {
              (*_bfd_error_handler)
                (_("%B: warning: illegal symbol index 0x%lx in line number entry %d"),
                 abfd, (long) symndx, counter);
            {
              (*_bfd_error_handler)
                (_("%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)
+               (_("%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)
+             || sym >= obj_symbols (abfd) + bfd_get_symcount (abfd))
+           {
+             (*_bfd_error_handler)
+               (_("%B: warning: illegal symbol in line number entry %d"),
+                abfd, counter);
+             cache_ptr->line_number = -1;
+             ret = FALSE;
+             continue;
+           }
+
+         have_func = TRUE;
+         nbr_func++;
          cache_ptr->u.sym = (asymbol *) sym;
          if (sym->lineno != NULL)
            (*_bfd_error_handler)
          cache_ptr->u.sym = (asymbol *) sym;
          if (sym->lineno != NULL)
            (*_bfd_error_handler)
@@ -4573,17 +4650,21 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
 
          sym->lineno = cache_ptr;
          if (sym->symbol.value < prev_offset)
 
          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
       else
-       cache_ptr->u.offset = dst.l_addr.l_paddr
-         - bfd_section_vma (abfd, asect);
-
+       cache_ptr->u.offset = (dst.l_addr.l_paddr
+                              - bfd_section_vma (abfd, asect));
       cache_ptr++;
       cache_ptr++;
-      src++;
     }
     }
-  cache_ptr->line_number = 0;
+
+  asect->lineno_count = cache_ptr - lineno_cache;
+  memset (cache_ptr, 0, sizeof (*cache_ptr));
   bfd_release (abfd, native_lineno);
 
   /* On some systems (eg AIX5.3) the lineno table may not be sorted.  */
   bfd_release (abfd, native_lineno);
 
   /* On some systems (eg AIX5.3) the lineno table may not be sorted.  */
@@ -4600,15 +4681,17 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
          alent **p = func_table;
          unsigned int i;
 
          alent **p = func_table;
          unsigned int i;
 
-         for (i = 0; i < counter; i++)
+         for (i = 0; i < asect->lineno_count; i++)
            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);
 
          /* Create the new sorted table.  */
          /* Sort by functions.  */
          qsort (func_table, nbr_func, sizeof (alent *), coff_sort_func_alent);
 
          /* Create the new sorted table.  */
-         amt = ((bfd_size_type) asect->lineno_count + 1) * sizeof (alent);
+         amt = (bfd_size_type) asect->lineno_count * sizeof (alent);
          n_lineno_cache = (alent *) bfd_alloc (abfd, amt);
          if (n_lineno_cache != NULL)
            {
          n_lineno_cache = (alent *) bfd_alloc (abfd, amt);
          if (n_lineno_cache != NULL)
            {
@@ -4619,25 +4702,29 @@ coff_slurp_line_table (bfd *abfd, asection *asect)
                  coff_symbol_type *sym;
                  alent *old_ptr = func_table[i];
 
                  coff_symbol_type *sym;
                  alent *old_ptr = func_table[i];
 
-                 /* Copy the function entry and update it.  */
-                 *n_cache_ptr = *old_ptr;
-                 sym = (coff_symbol_type *)n_cache_ptr->u.sym;
-                 sym->lineno = n_cache_ptr;
-                 n_cache_ptr++;
-                 old_ptr++;
-
-                 /* Copy the line number entries.  */
-                 while (old_ptr->line_number != 0)
+                 /* Update the function entry.  */
+                 sym = (coff_symbol_type *) old_ptr->u.sym;
+                 /* PR binutils/17512: Point the lineno to where
+                    this entry will be after the memcpy below.  */
+                 sym->lineno = lineno_cache + (n_cache_ptr - n_lineno_cache);
+                 /* Copy the function and line number entries.  */
+                 do
                    *n_cache_ptr++ = *old_ptr++;
                    *n_cache_ptr++ = *old_ptr++;
+                 while (old_ptr->line_number != 0);
                }
                }
-             n_cache_ptr->line_number = 0;
+             BFD_ASSERT ((bfd_size_type) (n_cache_ptr - n_lineno_cache) == (amt / sizeof (alent)));
+
              memcpy (lineno_cache, n_lineno_cache, amt);
            }
              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
@@ -4652,6 +4739,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;
@@ -4669,7 +4757,7 @@ coff_slurp_symbol_table (bfd * abfd)
 
   amt = obj_raw_syment_count (abfd);
   amt *= sizeof (unsigned int);
 
   amt = obj_raw_syment_count (abfd);
   amt *= sizeof (unsigned int);
-  table_ptr = (unsigned int *) bfd_alloc (abfd, amt);
+  table_ptr = (unsigned int *) bfd_zalloc (abfd, amt);
 
   if (table_ptr == NULL)
     return FALSE;
 
   if (table_ptr == NULL)
     return FALSE;
@@ -4683,14 +4771,17 @@ coff_slurp_symbol_table (bfd * abfd)
        {
          combined_entry_type *src = native_symbols + this_index;
          table_ptr[this_index] = number_of_symbols;
        {
          combined_entry_type *src = native_symbols + this_index;
          table_ptr[this_index] = number_of_symbols;
-         dst->symbol.the_bfd = abfd;
 
 
+         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)
@@ -4964,22 +5055,23 @@ coff_slurp_symbol_table (bfd * abfd)
 #if defined(TIC80COFF) || defined(TICOFF)
            case C_UEXT:        /* Tentative external definition.  */
 #endif
 #if defined(TIC80COFF) || defined(TICOFF)
            case C_UEXT:        /* Tentative external definition.  */
 #endif
-           case C_EXTLAB:      /* External load time label.  */
-           case C_HIDDEN:      /* Ext symbol in dmert public lib.  */
            default:
              (*_bfd_error_handler)
                (_("%B: Unrecognized storage class %d for %s symbol `%s'"),
                 abfd, src->u.syment.n_sclass,
                 dst->symbol.section->name, dst->symbol.name);
            default:
              (*_bfd_error_handler)
                (_("%B: Unrecognized storage class %d for %s symbol `%s'"),
                 abfd, src->u.syment.n_sclass,
                 dst->symbol.section->name, dst->symbol.name);
+             ret = FALSE;
+           case C_EXTLAB:      /* External load time label.  */
+           case C_HIDDEN:      /* Ext symbol in dmert public lib.  */
              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++;
@@ -4998,12 +5090,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
@@ -5062,13 +5155,13 @@ coff_classify_symbol (bfd *abfd,
       if (syment->n_value == 0)
        {
          asection *sec;
       if (syment->n_value == 0)
        {
          asection *sec;
-         char buf[SYMNMLEN + 1];
+         char * name;
+         char buf[SYMNMLEN + 1];
 
 
-         sec = coff_section_from_bfd_index (abfd, syment->n_scnum);
-         if (sec != NULL
-             && (strcmp (bfd_get_section_name (abfd, sec),
-                         _bfd_coff_internal_syment_name (abfd, syment, buf))
-                 == 0))
+         name = _bfd_coff_internal_syment_name (abfd, syment, buf)
+         sec = coff_section_from_bfd_index (abfd, syment->n_scnum);
+         if (sec != NULL && name != NULL
+             && (strcmp (bfd_get_section_name (abfd, sec), name) == 0))
            return COFF_SYMBOL_PE_SECTION;
        }
 #endif
            return COFF_SYMBOL_PE_SECTION;
        }
 #endif
@@ -5137,8 +5230,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              \
@@ -5261,7 +5355,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)
@@ -5386,6 +5480,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
@@ -5584,7 +5680,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] =
 {
@@ -5667,6 +5763,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);
@@ -5905,7 +6002,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
This page took 0.032888 seconds and 4 git commands to generate.