diff options
author | Richard Sandiford <rdsandiford@googlemail.com> | 2007-08-13 21:16:39 +0000 |
---|---|---|
committer | Richard Sandiford <rdsandiford@googlemail.com> | 2007-08-13 21:16:39 +0000 |
commit | 8275b357ad5522cee5ae2bf31b6b762053d84f40 (patch) | |
tree | 1c94a9837e02f8bb67976afd45ab95ba90cb892b /bfd | |
parent | 2cc176786d0ca17cd44eb3701875cd38084e4d37 (diff) | |
download | gdb-8275b357ad5522cee5ae2bf31b6b762053d84f40.zip gdb-8275b357ad5522cee5ae2bf31b6b762053d84f40.tar.gz gdb-8275b357ad5522cee5ae2bf31b6b762053d84f40.tar.bz2 |
bfd/
* elfxx-mips.c (mips_elf_link_hash_table): Add computed_got_sizes.
(mips_elf_record_global_got_symbol): Increment local_gotno for
each forced-local symbol.
(_bfd_mips_elf_check_relocs): Pass forced-local call symbols to
mips_elf_record_global_got_symbol for VxWorks too.
(_bfd_mips_elf_always_size_sections): Set computed_got_sizes
to true after computing the GOT size.
(_bfd_mips_elf_hide_symbol): Increase local_gotno whenever
got.offset == 1. Only adjust global_gotno if computed_got_sizes.
For VxWorks, add a local entry when hiding a symbol that needs a
plt but has not been marked as needing a global got entry.
(_bfd_mips_elf_link_hash_table_create): Set computed_got_sizes to
false.
ld/testsuite/
* ld-mips-elf/vxworks-forced-local-1.d,
* ld-mips-elf/vxworks-forced-local-1.s,
* ld-mips-elf/vxworks-forced-local-1.ver: New test.
* ld-mips-elf/mips-elf.exp: Run it.
* ld-mips-elf/tlsdyn-o32-2.d: Adjust for removal of unnecessary
local GOT entry.
* ld-mips-elf/tlsdyn-o32-2.got: Likewise.
* ld-mips-elf/tlsdyn-o32-3.d: Likewise.
* ld-mips-elf/tlsdyn-o32-3.got: Likewise.
* ld-mips-elf/vxworks1-lib.dd: Likewise.
* ld-mips-elf/vxworks1-lib.rd: Likewise.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 16 | ||||
-rw-r--r-- | bfd/elfxx-mips.c | 52 |
2 files changed, 52 insertions, 16 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ba0c3fc..da56f36 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,19 @@ +2007-08-13 Richard Sandiford <richard@codesourcery.com> + + * elfxx-mips.c (mips_elf_link_hash_table): Add computed_got_sizes. + (mips_elf_record_global_got_symbol): Increment local_gotno for + each forced-local symbol. + (_bfd_mips_elf_check_relocs): Pass forced-local call symbols to + mips_elf_record_global_got_symbol for VxWorks too. + (_bfd_mips_elf_always_size_sections): Set computed_got_sizes + to true after computing the GOT size. + (_bfd_mips_elf_hide_symbol): Increase local_gotno whenever + got.offset == 1. Only adjust global_gotno if computed_got_sizes. + For VxWorks, add a local entry when hiding a symbol that needs a + plt but has not been marked as needing a global got entry. + (_bfd_mips_elf_link_hash_table_create): Set computed_got_sizes to + false. + 2007-08-12 Daniel Jacobowitz <dan@codesourcery.com> * coffgen.c (coff_get_normalized_symtab): Correct cast. diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index fb8e1f7..5abb968 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -323,6 +323,8 @@ struct mips_elf_link_hash_table bfd_vma rld_value; /* This is set if we see any mips16 stub sections. */ bfd_boolean mips16_stubs_seen; + /* True if we've computed the size of the GOT. */ + bfd_boolean computed_got_sizes; /* True if we're generating code for VxWorks. */ bfd_boolean is_vxworks; /* True if we already reported the small-data section overflow. */ @@ -2691,7 +2693,7 @@ mips_elf_create_local_got_entry (bfd *abfd, struct bfd_link_info *info, memcpy (*loc, &entry, sizeof entry); - if (g->assigned_gotno >= g->local_gotno) + if (g->assigned_gotno > g->local_gotno) { (*loc)->gotidx = -1; /* We didn't allocate enough space in the GOT. */ @@ -2876,11 +2878,15 @@ mips_elf_record_global_got_symbol (struct elf_link_hash_entry *h, if (h->got.offset != MINUS_ONE) return TRUE; - /* By setting this to a value other than -1, we are indicating that - there needs to be a GOT entry for H. Avoid using zero, as the - generic ELF copy_indirect_symbol tests for <= 0. */ if (tls_flag == 0) - h->got.offset = 1; + { + /* By setting this to a value other than -1, we are indicating that + there needs to be a GOT entry for H. Avoid using zero, as the + generic ELF copy_indirect_symbol tests for <= 0. */ + h->got.offset = 1; + if (h->forced_local) + g->local_gotno++; + } return TRUE; } @@ -6528,7 +6534,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, /* VxWorks call relocations point the function's .got.plt entry, which will be allocated by adjust_dynamic_symbol. Otherwise, this symbol requires a global GOT entry. */ - if (!htab->is_vxworks + if ((!htab->is_vxworks || h->forced_local) && !mips_elf_record_global_got_symbol (h, abfd, info, g, 0)) return FALSE; @@ -7312,6 +7318,7 @@ _bfd_mips_elf_always_size_sections (bfd *output_bfd, g->tls_assigned_gotno = g->global_gotno + g->local_gotno; htab_traverse (g->got_entries, mips_elf_initialize_tls_index, g); } + htab->computed_got_sizes = TRUE; return TRUE; } @@ -9671,6 +9678,7 @@ _bfd_mips_elf_hide_symbol (struct bfd_link_info *info, asection *got; struct mips_got_info *g; struct mips_elf_link_hash_entry *h; + struct mips_elf_link_hash_table *htab; h = (struct mips_elf_link_hash_entry *) entry; if (h->forced_local) @@ -9678,6 +9686,7 @@ _bfd_mips_elf_hide_symbol (struct bfd_link_info *info, h->forced_local = force_local; dynobj = elf_hash_table (info)->dynobj; + htab = mips_elf_hash_table (info); if (dynobj != NULL && force_local && h->root.type != STT_TLS && (got = mips_elf_got_section (dynobj, TRUE)) != NULL && (g = mips_elf_section_data (got)->u.got_info) != NULL) @@ -9715,20 +9724,30 @@ _bfd_mips_elf_hide_symbol (struct bfd_link_info *info, gg->assigned_gotno--; } } - else if (g->global_gotno == 0 && g->global_gotsym == NULL) - /* If we haven't got through GOT allocation yet, just bump up the - number of local entries, as this symbol won't be counted as - global. */ - g->local_gotno++; else if (h->root.got.offset == 1) { - /* If we're past non-multi-GOT allocation and this symbol had - been marked for a global got entry, give it a local entry - instead. */ - BFD_ASSERT (g->global_gotno > 0); + /* check_relocs didn't know that this symbol would be + forced-local, so add an extra local got entry. */ g->local_gotno++; - g->global_gotno--; + if (htab->computed_got_sizes) + { + /* We'll have treated this symbol as global rather + than local. */ + BFD_ASSERT (g->global_gotno > 0); + g->global_gotno--; + } } + else if (htab->is_vxworks && h->root.needs_plt) + { + /* check_relocs didn't know that this symbol would be + forced-local, so add an extra local got entry. */ + g->local_gotno++; + if (htab->computed_got_sizes) + /* The symbol is only used in call relocations, so we'll + have assumed it only needs a .got.plt entry. Increase + the size of .got accordingly. */ + got->size += MIPS_ELF_GOT_SIZE (dynobj); + } } _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local); @@ -10189,6 +10208,7 @@ _bfd_mips_elf_link_hash_table_create (bfd *abfd) ret->use_rld_obj_head = FALSE; ret->rld_value = 0; ret->mips16_stubs_seen = FALSE; + ret->computed_got_sizes = FALSE; ret->is_vxworks = FALSE; ret->small_data_overflow_reported = FALSE; ret->srelbss = NULL; |