Sanity checks on version section
authorAlan Modra <amodra@gmail.com>
Thu, 27 Nov 2014 23:40:44 +0000 (10:10 +1030)
committerAlan Modra <amodra@gmail.com>
Fri, 28 Nov 2014 04:09:28 +0000 (14:39 +1030)
* elf.c (_bfd_elf_slurp_version_tables): Exit loops when vn_next/
vna_next/vd_next/vda_next is zero.  Correct counts.

bfd/ChangeLog
bfd/elf.c

index 8fe5fe6..8a52ebe 100644 (file)
@@ -1,3 +1,8 @@
+2014-11-28  Alan Modra  <amodra@gmail.com>
+
+       * elf.c (_bfd_elf_slurp_version_tables): Exit loops when vn_next/
+       vna_next/vd_next/vda_next is zero.  Correct counts.
+
 2014-11-27  Nick Clifton  <nickc@redhat.com>
 
        PR binutils/17512
index de8d97f..07cb804 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -7307,7 +7307,6 @@ error_return_verref:
          || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
        goto error_return_verref;
 
-      elf_tdata (abfd)->cverrefs = hdr->sh_info;
       elf_tdata (abfd)->verref = (Elf_Internal_Verneed *)
        bfd_zalloc2 (abfd, hdr->sh_info, sizeof (Elf_Internal_Verneed));
 
@@ -7363,10 +7362,17 @@ error_return_verref:
              if (ivernaux->vna_nodename == NULL)
                goto error_return_bad_verref;
 
+             if (ivernaux->vna_other > freeidx)
+               freeidx = ivernaux->vna_other;
+
+             ivernaux->vna_nextptr = NULL;
+             if (ivernaux->vna_next == 0)
+               {
+                 iverneed->vn_cnt = j + 1;
+                 break;
+               }
              if (j + 1 < iverneed->vn_cnt)
                ivernaux->vna_nextptr = ivernaux + 1;
-             else
-               ivernaux->vna_nextptr = NULL;
 
              if (ivernaux->vna_next
                  > (size_t) (contents_end - (bfd_byte *) evernaux))
@@ -7374,15 +7380,13 @@ error_return_verref:
 
              evernaux = ((Elf_External_Vernaux *)
                          ((bfd_byte *) evernaux + ivernaux->vna_next));
-
-             if (ivernaux->vna_other > freeidx)
-               freeidx = ivernaux->vna_other;
            }
 
+         iverneed->vn_nextref = NULL;
+         if (iverneed->vn_next == 0)
+           break;
          if (i + 1 < hdr->sh_info)
            iverneed->vn_nextref = iverneed + 1;
-         else
-           iverneed->vn_nextref = NULL;
 
          if (iverneed->vn_next
              > (size_t) (contents_end - (bfd_byte *) everneed))
@@ -7391,6 +7395,7 @@ error_return_verref:
          everneed = ((Elf_External_Verneed *)
                      ((bfd_byte *) everneed + iverneed->vn_next));
        }
+      elf_tdata (abfd)->cverrefs = i;
 
       free (contents);
       contents = NULL;
@@ -7449,6 +7454,9 @@ error_return_verref:
          if ((iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION)) > maxidx)
            maxidx = iverdefmem.vd_ndx & ((unsigned) VERSYM_VERSION);
 
+         if (iverdefmem.vd_next == 0)
+           break;
+
          if (iverdefmem.vd_next
              > (size_t) (contents_end_def - (bfd_byte *) everdef))
            goto error_return_bad_verdef;
@@ -7518,10 +7526,14 @@ error_return_verref:
              if (iverdaux->vda_nodename == NULL)
                goto error_return_bad_verdef;
 
+             iverdaux->vda_nextptr = NULL;
+             if (iverdaux->vda_next == 0)
+               {
+                 iverdef->vd_cnt = j + 1;
+                 break;
+               }
              if (j + 1 < iverdef->vd_cnt)
                iverdaux->vda_nextptr = iverdaux + 1;
-             else
-               iverdaux->vda_nextptr = NULL;
 
              if (iverdaux->vda_next
                  > (size_t) (contents_end_aux - (bfd_byte *) everdaux))
@@ -7534,10 +7546,11 @@ error_return_verref:
          if (iverdef->vd_cnt)
            iverdef->vd_nodename = iverdef->vd_auxptr->vda_nodename;
 
+         iverdef->vd_nextdef = NULL;
+         if (iverdef->vd_next == 0)
+           break;
          if ((size_t) (iverdef - iverdefarr) + 1 < maxidx)
            iverdef->vd_nextdef = iverdef + 1;
-         else
-           iverdef->vd_nextdef = NULL;
 
          everdef = ((Elf_External_Verdef *)
                     ((bfd_byte *) everdef + iverdef->vd_next));