versioning patch
Ulrich Drepper
drepper@redhat.com
Wed May 31 08:39:00 GMT 2000
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;
More information about the Binutils
mailing list