This is the mail archive of the binutils@sourceware.cygnus.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

versioning patch


BFD currently works only by accident when reading in versioning
definitions.  This didn't cause any problems because we only read in
files with versioning generated by GNU ld.  With Solaris ld we get
problems since they don't sort the entries in the verdef section by
index (which is OK).

The patch below fixes the problem.  I've tested it on Solaris and
Linux and will check it in if nobody objects.

-- 
---------------.      drepper at gnu.org  ,-.   1325 Chesapeake Terrace
Ulrich Drepper  \    ,-------------------'   \  Sunnyvale, CA 94089 USA
Red Hat          `--' drepper at redhat.com   `------------------------

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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.

Index: elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.32
diff -u -r1.32 elf.c
--- elf.c	2000/05/29 05:16:19	1.32
+++ elf.c	2000/05/31 15:24:42
@@ -4506,18 +4506,13 @@
       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;
@@ -4525,15 +4520,42 @@
 	  || 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, &iverdefmem);
 
-	  _bfd_elf_swap_verdef_in (abfd, everdef, iverdef);
+	  iverdef = &iverdefarr[(iverdefmem.vd_ndx & VERSYM_VERSION) - 1];
+	  memcpy (iverdef, &iverdefmem, sizeof (Elf_Internal_Verdef));
 
 	  iverdef->vd_bfd = abfd;
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]