diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 29 | ||||
-rw-r--r-- | bfd/elfxx-mips.c | 95 |
2 files changed, 64 insertions, 60 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 8dee0b4..581e89b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,34 @@ 2008-08-07 Richard Sandiford <rdsandiford@googlemail.com> + * elfxx-mips.c (mips_got_info): Add a "reloc_only_gotno" field. + (mips_elf_got_section): Delete. + (mips_elf_sort_hash_table): Use g->reloc_only_gotno to decide + how many reloc-only entries there are. + (mips_elf_count_got_symbols): Adjust g->reloc_only_gotno as + well as g->global_gotno. + (mips_elf_make_got_per_bfd): Initialize reloc_only_gotno. + (mips_elf_multi_got): Likewise. Use gg->reloc_only_gotno + rather than gg->assigned_gotno to store the number of + reloc-only GOT entries. + (mips_elf_create_got_section): Remove the MAYBE_EXCLUDE parameter. + Initialize reloc_only_gotno. + (mips_elf_calculate_relocation): Check htab->got_info instead of + dynobj when deciding whether to call mips_elf_adjust_gp, + (_bfd_mips_elf_create_dynamic_sections): Adjust the call + to mips_elf_create_got_section. + (mips_elf_record_relocs): Likewise. Remove redundant + "dynobj == NULL" code. Do not use mips_elf_create_got_section + or mips_elf_record_global_got_symbol for R_MIPS_32, R_MIPS_REL32 + and R_MIPS_64; limit global_got_area to GGA_RELOC_ONLY instead. + (_bfd_mips_elf_finish_dynamic_symbol): Use htab->sgot instead + of mips_elf_got_section. + (_bfd_mips_vxworks_finish_dynamic_symbol): Likewise. + (_bfd_mips_elf_finish_dynamic_sections): Likewise. + Move the initial assignment of G to the block that uses it; + it is used for an unrelated purpose later. + +2008-08-07 Richard Sandiford <rdsandiford@googlemail.com> + * elfxx-mips.c (count_section_dynsyms): Move before the new first use. (mips_elf_sort_hash_table): Take the output bfd as a parameter. Remove the MAX_LOCAL parameter. Exit early if there are no diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 297c361..36c94d5 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -145,6 +145,8 @@ struct mips_got_info struct elf_link_hash_entry *global_gotsym; /* The number of global .got entries. */ unsigned int global_gotno; + /* The number of global .got entries that are in the GGA_RELOC_ONLY area. */ + unsigned int reloc_only_gotno; /* The number of .got slots used for TLS. */ unsigned int tls_gotno; /* The first unused TLS .got entry. Used only during @@ -2280,19 +2282,6 @@ mips_elf_rel_dyn_section (struct bfd_link_info *info, bfd_boolean create_p) return sreloc; } -/* Returns the GOT section, if it hasn't been excluded. */ - -static asection * -mips_elf_got_section (struct bfd_link_info *info) -{ - struct mips_elf_link_hash_table *htab; - - htab = mips_elf_hash_table (info); - if (htab->sgot == NULL || (htab->sgot->flags & SEC_EXCLUDE) != 0) - return NULL; - return htab->sgot; -} - /* Count the number of relocations needed for a TLS GOT entry, with access types from TLS_TYPE, and symbol H (or a local symbol if H is NULL). */ @@ -2423,12 +2412,14 @@ mips_elf_initialize_tls_slots (bfd *abfd, bfd_vma got_offset, struct mips_elf_link_hash_entry *h, bfd_vma value) { + struct mips_elf_link_hash_table *htab; int indx; asection *sreloc, *sgot; bfd_vma offset, offset2; bfd_boolean need_relocs = FALSE; - sgot = mips_elf_got_section (info); + htab = mips_elf_hash_table (info); + sgot = htab->sgot; indx = 0; if (h != NULL) @@ -2954,16 +2945,9 @@ mips_elf_sort_hash_table (bfd *abfd, struct bfd_link_info *info) return TRUE; hsd.low = NULL; - hsd.max_unref_got_dynindx = - hsd.min_got_dynindx = elf_hash_table (info)->dynsymcount - /* In the multi-got case, assigned_gotno of the master got_info - indicate the number of entries that aren't referenced in the - primary GOT, but that must have entries because there are - dynamic relocations that reference it. Since they aren't - referenced, we move them to the end of the GOT, so that they - don't prevent other entries that are referenced from getting - too large offsets. */ - - (g->next ? g->assigned_gotno : 0); + hsd.max_unref_got_dynindx + = hsd.min_got_dynindx + = (elf_hash_table (info)->dynsymcount - g->reloc_only_gotno); hsd.max_non_got_dynindx = count_section_dynsyms (abfd, info) + 1; mips_elf_link_hash_traverse (((struct mips_elf_link_hash_table *) elf_hash_table (info)), @@ -3413,7 +3397,11 @@ mips_elf_count_got_symbols (struct mips_elf_link_hash_entry *h, void *data) h->global_got_area = GGA_NONE; } else - g->global_gotno++; + { + g->global_gotno++; + if (h->global_got_area == GGA_RELOC_ONLY) + g->reloc_only_gotno++; + } } return 1; } @@ -3492,6 +3480,7 @@ mips_elf_get_got_for_bfd (struct htab *bfd2got, bfd *output_bfd, g->global_gotsym = NULL; g->global_gotno = 0; + g->reloc_only_gotno = 0; g->local_gotno = 0; g->page_gotno = 0; g->assigned_gotno = -1; @@ -3912,6 +3901,7 @@ mips_elf_multi_got (bfd *abfd, struct bfd_link_info *info, g->next->global_gotsym = NULL; g->next->global_gotno = 0; + g->next->reloc_only_gotno = 0; g->next->local_gotno = 0; g->next->page_gotno = 0; g->next->tls_gotno = 0; @@ -3964,7 +3954,7 @@ mips_elf_multi_got (bfd *abfd, struct bfd_link_info *info, /* Every symbol that is referenced in a dynamic relocation must be present in the primary GOT, so arrange for them to appear after those that are actually referenced. */ - gg->assigned_gotno = gg->global_gotno - g->global_gotno; + gg->reloc_only_gotno = gg->global_gotno - g->global_gotno; g->global_gotno = gg->global_gotno; set_got_offset_arg.g = NULL; @@ -4224,8 +4214,7 @@ mips_elf_create_compact_rel_section /* Create the .got section to hold the global offset table. */ static bfd_boolean -mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info, - bfd_boolean maybe_exclude) +mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info) { flagword flags; register asection *s; @@ -4238,20 +4227,12 @@ mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info, htab = mips_elf_hash_table (info); /* This function may be called more than once. */ - s = htab->sgot; - if (s) - { - if (! maybe_exclude) - s->flags &= ~SEC_EXCLUDE; - return TRUE; - } + if (htab->sgot) + return TRUE; flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED); - if (maybe_exclude) - flags |= SEC_EXCLUDE; - /* We have to use an alignment of 2**4 here because this is hardcoded in the function stub generation and in the linker script. */ s = bfd_make_section_with_flags (abfd, ".got", flags); @@ -4285,6 +4266,7 @@ mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info, return FALSE; g->global_gotsym = NULL; g->global_gotno = 0; + g->reloc_only_gotno = 0; g->tls_gotno = 0; g->local_gotno = MIPS_RESERVED_GOTNO (info); g->page_gotno = 0; @@ -4642,7 +4624,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, gp0 = _bfd_get_gp_value (input_bfd); gp = _bfd_get_gp_value (abfd); - if (dynobj) + if (htab->got_info) gp += mips_elf_adjust_gp (abfd, htab->got_info, input_bfd); if (gnu_local_gp_p) @@ -6417,7 +6399,7 @@ _bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) } /* We need to create .got section. */ - if (! mips_elf_create_got_section (abfd, info, FALSE)) + if (!mips_elf_create_got_section (abfd, info)) return FALSE; if (! mips_elf_rel_dyn_section (info, TRUE)) @@ -7039,7 +7021,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, case R_MIPS_TLS_LDM: if (dynobj == NULL) elf_hash_table (info)->dynobj = dynobj = abfd; - if (! mips_elf_create_got_section (dynobj, info, FALSE)) + if (!mips_elf_create_got_section (dynobj, info)) return FALSE; if (htab->is_vxworks && !info->shared) { @@ -7301,12 +7283,11 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, between global GOT entries and .dynsym entries. */ if (h != NULL && !htab->is_vxworks) { - if (dynobj == NULL) - elf_hash_table (info)->dynobj = dynobj = abfd; - if (! mips_elf_create_got_section (dynobj, info, TRUE)) - return FALSE; - if (!mips_elf_record_global_got_symbol (h, abfd, info, 0)) - return FALSE; + struct mips_elf_link_hash_entry *hmips; + + hmips = (struct mips_elf_link_hash_entry *) h; + if (hmips->global_got_area > GGA_RELOC_ONLY) + hmips->global_got_area = GGA_RELOC_ONLY; } } @@ -8818,8 +8799,7 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd, BFD_ASSERT (h->dynindx != -1 || h->forced_local); - sgot = mips_elf_got_section (info); - BFD_ASSERT (sgot != NULL); + sgot = htab->sgot; g = htab->got_info; BFD_ASSERT (g != NULL); @@ -9089,8 +9069,7 @@ _bfd_mips_vxworks_finish_dynamic_symbol (bfd *output_bfd, BFD_ASSERT (h->dynindx != -1 || h->forced_local); - sgot = mips_elf_got_section (info); - BFD_ASSERT (sgot != NULL); + sgot = htab->sgot; g = htab->got_info; BFD_ASSERT (g != NULL); @@ -9252,15 +9231,8 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd, sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); - sgot = mips_elf_got_section (info); - if (sgot == NULL) - gg = g = NULL; - else - { - gg = htab->got_info; - g = mips_elf_got_for_ibfd (gg, output_bfd); - BFD_ASSERT (g != NULL); - } + sgot = htab->sgot; + gg = htab->got_info; if (elf_hash_table (info)->dynamic_sections_created) { @@ -9268,6 +9240,9 @@ _bfd_mips_elf_finish_dynamic_sections (bfd *output_bfd, int dyn_to_skip = 0, dyn_skipped = 0; BFD_ASSERT (sdyn != NULL); + BFD_ASSERT (gg != NULL); + + g = mips_elf_got_for_ibfd (gg, output_bfd); BFD_ASSERT (g != NULL); for (b = sdyn->contents; |