diff options
-rw-r--r-- | bfd/ChangeLog | 13 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 10 | ||||
-rw-r--r-- | bfd/elflink.c | 24 | ||||
-rw-r--r-- | bfd/elfxx-target.h | 4 |
4 files changed, 46 insertions, 5 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4e8db373f3..650ff2ed8d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,16 @@ +2008-11-21 Hans-Peter Nilsson <hp@axis.com> + + * elf-bfd.h (struct elf_backend_data): New member got_elt_size. + (_bfd_elf_default_got_elt_size): Declare. + * elflink.c (struct alloc_got_off_arg): Replace member got_elt_size + by new member info. + (elf_gc_allocate_got_offsets): Adjust for calling bed->got_elt_size + to get the element size instead of using a gofarg entry. + (bfd_elf_gc_common_finalize_got_offsets): Similar. + (_bfd_elf_default_got_elt_size): New function. + * elfxx-target.h: New macro elf_backend_got_elt_size. + (elfNN_bed): Use it. + 2008-11-20 Tristan Gingold <gingold@adacore.com> * bfdwin.c: Fix comment. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 9615a4a536..0fd1ed219d 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1147,6 +1147,12 @@ struct elf_backend_data so-called reserved entries on some systems. */ bfd_vma got_header_size; + /* The size of the GOT entry for the symbol pointed to by H if non-NULL, + otherwise by the local symbol with index SYMNDX in IBFD. */ + bfd_vma (*got_elt_size) (bfd *, struct bfd_link_info *, + struct elf_link_hash_entry *h, + bfd *ibfd, unsigned long symndx); + /* The vendor name to use for a processor-standard attributes section. */ const char *obj_attrs_vendor; @@ -2070,6 +2076,10 @@ extern asection *_bfd_elf_common_section extern void _bfd_dwarf2_cleanup_debug_info (bfd *); +extern bfd_vma _bfd_elf_default_got_elt_size +(bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, bfd *, + unsigned long); + extern bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn (bfd *, arelent *, struct bfd_symbol *, void *, asection *, bfd *, char **); diff --git a/bfd/elflink.c b/bfd/elflink.c index f2015ee6dc..55173ff95c 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -11786,7 +11786,7 @@ bfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED, struct alloc_got_off_arg { bfd_vma gotoff; - unsigned int got_elt_size; + struct bfd_link_info *info; }; /* We need a special top-level link routine to convert got reference counts @@ -11796,6 +11796,8 @@ static bfd_boolean elf_gc_allocate_got_offsets (struct elf_link_hash_entry *h, void *arg) { struct alloc_got_off_arg *gofarg = arg; + bfd *obfd = gofarg->info->output_bfd; + const struct elf_backend_data *bed = get_elf_backend_data (obfd); if (h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; @@ -11803,7 +11805,7 @@ elf_gc_allocate_got_offsets (struct elf_link_hash_entry *h, void *arg) if (h->got.refcount > 0) { h->got.offset = gofarg->gotoff; - gofarg->gotoff += gofarg->got_elt_size; + gofarg->gotoff += bed->got_elt_size (obfd, gofarg->info, h, NULL, 0); } else h->got.offset = (bfd_vma) -1; @@ -11821,9 +11823,10 @@ bfd_elf_gc_common_finalize_got_offsets (bfd *abfd, bfd *i; const struct elf_backend_data *bed = get_elf_backend_data (abfd); bfd_vma gotoff; - unsigned int got_elt_size = bed->s->arch_size / 8; struct alloc_got_off_arg gofarg; + BFD_ASSERT (abfd == info->output_bfd); + if (! is_elf_hash_table (info->hash)) return FALSE; @@ -11859,7 +11862,7 @@ bfd_elf_gc_common_finalize_got_offsets (bfd *abfd, if (local_got[j] > 0) { local_got[j] = gotoff; - gotoff += got_elt_size; + gotoff += bed->got_elt_size (abfd, info, NULL, i, j); } else local_got[j] = (bfd_vma) -1; @@ -11869,7 +11872,7 @@ bfd_elf_gc_common_finalize_got_offsets (bfd *abfd, /* Then the global .got entries. .plt refcounts are handled by adjust_dynamic_symbol */ gofarg.gotoff = gotoff; - gofarg.got_elt_size = got_elt_size; + gofarg.info = info; elf_link_hash_traverse (elf_hash_table (info), elf_gc_allocate_got_offsets, &gofarg); @@ -12255,3 +12258,14 @@ _bfd_elf_common_section (asection *sec ATTRIBUTE_UNUSED) { return bfd_com_section_ptr; } + +bfd_vma +_bfd_elf_default_got_elt_size (bfd *abfd, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + struct elf_link_hash_entry *h ATTRIBUTE_UNUSED, + bfd *ibfd ATTRIBUTE_UNUSED, + unsigned long symndx ATTRIBUTE_UNUSED) +{ + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + return bed->s->arch_size / 8; +} diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index d897c32d1f..811dbf5533 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -446,6 +446,9 @@ #ifndef elf_backend_got_header_size #define elf_backend_got_header_size 0 #endif +#ifndef elf_backend_got_elt_size +#define elf_backend_got_elt_size _bfd_elf_default_got_elt_size +#endif #ifndef elf_backend_obj_attrs_vendor #define elf_backend_obj_attrs_vendor NULL #endif @@ -712,6 +715,7 @@ static struct elf_backend_data elfNN_bed = &elf_backend_size_info, elf_backend_special_sections, elf_backend_got_header_size, + elf_backend_got_elt_size, elf_backend_obj_attrs_vendor, elf_backend_obj_attrs_section, elf_backend_obj_attrs_arg_type, |