diff options
author | Richard Henderson <rth@redhat.com> | 1998-11-18 04:26:39 +0000 |
---|---|---|
committer | Richard Henderson <rth@redhat.com> | 1998-11-18 04:26:39 +0000 |
commit | 468bc0c5fe3798fe3a63a5aababe3c95ac8616d0 (patch) | |
tree | d744288f73d3f3fc2eba7c788d644d131cc479d8 | |
parent | 206e3a8a5c7bf940cacc468a9b6d2269ea8e6aae (diff) | |
download | gdb-468bc0c5fe3798fe3a63a5aababe3c95ac8616d0.zip gdb-468bc0c5fe3798fe3a63a5aababe3c95ac8616d0.tar.gz gdb-468bc0c5fe3798fe3a63a5aababe3c95ac8616d0.tar.bz2 |
* elf-bfd.h (struct elf_link_hash_entry): Add vtable_entries_size.
* elf.c (_bfd_elf_link_hash_newfunc): Clear it.
* elflink.h (elf_gc_propagate_vtable_entries_used): Copy it, and
respect it as an upper bound on what memory to reference.
(elf_gc_smash_unused_vtentry_relocs): Likewise.
(elf_gc_record_vtentry): Handle as-yet undefined vtables. Set and
update vtable_entries_size appropriately.
-rw-r--r-- | bfd/ChangeLog | 10 | ||||
-rw-r--r-- | bfd/elflink.h | 52 |
2 files changed, 54 insertions, 8 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index bad8000..412a13d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +Tue Nov 17 20:23:35 1998 Richard Henderson <rth@cygnus.com> + + * elf-bfd.h (struct elf_link_hash_entry): Add vtable_entries_size. + * elf.c (_bfd_elf_link_hash_newfunc): Clear it. + * elflink.h (elf_gc_propagate_vtable_entries_used): Copy it, and + respect it as an upper bound on what memory to reference. + (elf_gc_smash_unused_vtentry_relocs): Likewise. + (elf_gc_record_vtentry): Handle as-yet undefined vtables. Set and + update vtable_entries_size appropriately. + Tue Nov 17 15:28:31 1998 Nick Clifton <nickc@cygnus.com> * elf32-fr30.c (fr30_reloc_type_lookup): Used integers to hold diff --git a/bfd/elflink.h b/bfd/elflink.h index 9e372c7..bbd8339 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -5724,6 +5724,7 @@ elf_gc_propagate_vtable_entries_used (h, okp) /* None of this table's entries were referenced. Re-use the parent's table. */ h->vtable_entries_used = h->vtable_parent->vtable_entries_used; + h->vtable_entries_size = h->vtable_parent->vtable_entries_size; } else { @@ -5736,7 +5737,7 @@ elf_gc_propagate_vtable_entries_used (h, okp) pu = h->vtable_parent->vtable_entries_used; if (pu != NULL) { - n = h->vtable_parent->size / FILE_ALIGN; + n = h->vtable_parent->vtable_entries_size / FILE_ALIGN; while (--n != 0) { if (*pu) *cu = true; @@ -5779,7 +5780,8 @@ elf_gc_smash_unused_vtentry_relocs (h, okp) if (rel->r_offset >= hstart && rel->r_offset < hend) { /* If the entry is in use, do nothing. */ - if (h->vtable_entries_used) + if (h->vtable_entries_used + && (rel->r_offset - hstart) < h->vtable_entries_size) { bfd_vma entry = (rel->r_offset - hstart) / FILE_ALIGN; if (h->vtable_entries_used[entry]) @@ -5911,17 +5913,51 @@ elf_gc_record_vtentry (abfd, sec, h, addend) struct elf_link_hash_entry *h; bfd_vma addend; { - if (h->vtable_entries_used == NULL) + if (addend >= h->vtable_entries_size) { + size_t size, bytes; + boolean *ptr = h->vtable_entries_used; + + /* While the symbol is undefined, we have to be prepared to handle + a zero size. */ + if (h->root.type == bfd_link_hash_undefined) + size = addend; + else + { + size = h->size; + if (size < addend) + { + /* Oops! We've got a reference past the defined end of + the table. This is probably a bug -- shall we warn? */ + size = addend; + } + } + /* Allocate one extra entry for use as a "done" flag for the consolidation pass. */ - size_t size = (h->size / FILE_ALIGN + 1) * sizeof(boolean); - h->vtable_entries_used = (boolean *) bfd_alloc (abfd, size); - if (h->vtable_entries_used == NULL) - return false; + bytes = (size / FILE_ALIGN + 1) * sizeof(boolean); + + if (ptr) + { + size_t oldbytes; + + ptr = realloc (ptr-1, bytes); + if (ptr == NULL) + return false; + + oldbytes = (h->vtable_entries_size/FILE_ALIGN + 1) * sizeof(boolean); + memset (ptr + oldbytes, 0, bytes - oldbytes); + } + else + { + ptr = calloc (1, bytes); + if (ptr == NULL) + return false; + } /* And arrange for that done flag to be at index -1. */ - memset (h->vtable_entries_used++, 0, size); + h->vtable_entries_used = ptr+1; + h->vtable_entries_size = size; } h->vtable_entries_used[addend / FILE_ALIGN] = true; |