]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2000-09-06 Philip Blundell <philb@gnu.org>
authorPhil Blundell <philb@gnu.org>
Wed, 6 Sep 2000 21:24:15 +0000 (21:24 +0000)
committerPhil Blundell <philb@gnu.org>
Wed, 6 Sep 2000 21:24:15 +0000 (21:24 +0000)
Merge from mainline:

2000-05-31  Ulrich Drepper  <drepper@redhat.com>

* elf.c (_bfd_elf_slurp_version_tables): Correct reading of version
definitions.  We must not assume they are sorted in the file
according to their index numbers.

bfd/ChangeLog
bfd/elf.c

index 0cde26aca87c7cba8537123afbd35bb063352672..ee30aaf1a82d55ef80669ad861fcc662cc7c3d02 100644 (file)
@@ -1,3 +1,13 @@
+2000-09-06  Philip Blundell  <philb@gnu.org>
+
+       Merge from mainline:
+       
+       2000-05-31  Ulrich Drepper  <drepper@redhat.com>
+
+       * elf.c (_bfd_elf_slurp_version_tables): Correct reading of version
+       definitions.  We must not assume they are sorted in the file
+       according to their index numbers.
+
 2000-09-06  Philip Blundell  <philb@gnu.org>
 
        * config.bfd (arm*-*-uclinux*): New target.
index 39b823b9638ca8ae3b5f6eca3ad4606508d60c54..e8e7e3787aba8377880b072e01de15b23637d83b 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4488,18 +4488,13 @@ _bfd_elf_slurp_version_tables (abfd)
       Elf_Internal_Shdr *hdr;
       Elf_External_Verdef *everdef;
       Elf_Internal_Verdef *iverdef;
+      Elf_Internal_Verdef *iverdefarr;
+      Elf_Internal_Verdef iverdefmem;
       unsigned int i;
+      unsigned int maxidx;
 
       hdr = &elf_tdata (abfd)->dynverdef_hdr;
 
-      elf_tdata (abfd)->verdef =
-       ((Elf_Internal_Verdef *)
-        bfd_zalloc (abfd, hdr->sh_info * sizeof (Elf_Internal_Verdef)));
-      if (elf_tdata (abfd)->verdef == NULL)
-       goto error_return;
-
-      elf_tdata (abfd)->cverdefs = hdr->sh_info;
-
       contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
       if (contents == NULL)
        goto error_return;
@@ -4507,15 +4502,42 @@ _bfd_elf_slurp_version_tables (abfd)
          || bfd_read ((PTR) contents, 1, hdr->sh_size, abfd) != hdr->sh_size)
        goto error_return;
 
+      /* We know the number of entries in the section but not the maximum
+        index.  Therefore we have to run through all entries and find
+        the maximum.  */
+      everdef = (Elf_External_Verdef *) contents;
+      maxidx = 0;
+      for (i = 0; i < hdr->sh_info; ++i)
+       {
+         _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
+
+         if ((iverdefmem.vd_ndx & VERSYM_VERSION) > maxidx)
+           maxidx = iverdefmem.vd_ndx & VERSYM_VERSION;
+
+         everdef = ((Elf_External_Verdef *)
+                    ((bfd_byte *) everdef + iverdefmem.vd_next));
+       }
+
+      elf_tdata (abfd)->verdef =
+       ((Elf_Internal_Verdef *)
+        bfd_zalloc (abfd, maxidx * sizeof (Elf_Internal_Verdef)));
+      if (elf_tdata (abfd)->verdef == NULL)
+       goto error_return;
+
+      elf_tdata (abfd)->cverdefs = maxidx;
+
       everdef = (Elf_External_Verdef *) contents;
-      iverdef = elf_tdata (abfd)->verdef;
-      for (i = 0; i < hdr->sh_info; i++, iverdef++)
+      iverdefarr = elf_tdata (abfd)->verdef;
+      for (i = 0; i < hdr->sh_info; i++)
        {
          Elf_External_Verdaux *everdaux;
          Elf_Internal_Verdaux *iverdaux;
          unsigned int j;
 
-         _bfd_elf_swap_verdef_in (abfd, everdef, iverdef);
+         _bfd_elf_swap_verdef_in (abfd, everdef, &iverdefmem);
+
+         iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1];
+         memcpy (iverdef, &iverdefmem, sizeof (Elf_Internal_Verdef));
 
          iverdef->vd_bfd = abfd;