* elfxx-mips.c (mips_elf_calculate_relocation): Avoid generating

relocations for undefined weak symbols with non-default visibility.
	(_bfd_mips_elf_check_relocs): Use possibly_dynamic_relocs for
	global symbols in shared libraries.
	(allocate_dynrelocs): New function.
	(_bfd_mips_elf_adjust_dynamic_symbol): Do not handle
	possibly_dynamic_relocs here.
	(_bfd_mips_elf_size_dynamic_sections): Call allocate_dynrelocs.
This commit is contained in:
Daniel Jacobowitz 2008-07-28 22:14:53 +00:00
parent bae98fe013
commit 9a59ad6b6f
2 changed files with 89 additions and 18 deletions

View file

@ -1,3 +1,14 @@
2008-07-28 Daniel Jacobowitz <dan@codesourcery.com>
* elfxx-mips.c (mips_elf_calculate_relocation): Avoid generating
relocations for undefined weak symbols with non-default visibility.
(_bfd_mips_elf_check_relocs): Use possibly_dynamic_relocs for
global symbols in shared libraries.
(allocate_dynrelocs): New function.
(_bfd_mips_elf_adjust_dynamic_symbol): Do not handle
possibly_dynamic_relocs here.
(_bfd_mips_elf_size_dynamic_sections): Call allocate_dynrelocs.
2008-07-28 Alexandre Oliva <aoliva@redhat.com>
* elf32-i386.c (struct elf_i386_link_hash_table): Added field

View file

@ -4509,6 +4509,9 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
&& h->root.def_dynamic
&& !h->root.def_regular))
&& r_symndx != 0
&& (h == NULL
|| h->root.root.type != bfd_link_hash_undefweak
|| ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
&& (input_section->flags & SEC_ALLOC) != 0)
{
/* If we're creating a shared library, or this relocation is
@ -7008,7 +7011,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
if (sreloc == NULL)
return FALSE;
}
if (info->shared)
if (info->shared && h == NULL)
{
/* When creating a shared object, we must copy these
reloc types into the output file as R_MIPS_REL32
@ -7023,8 +7026,17 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
{
struct mips_elf_link_hash_entry *hmips;
/* We only need to copy this reloc if the symbol is
defined in a dynamic object. */
/* For a shared object, we must copy this relocation
unless the symbol turns out to be undefined and
weak with non-default visibility, in which case
it will be left as zero.
We could elide R_MIPS_REL32 for locally binding symbols
in shared libraries, but do not yet do so.
For an executable, we only need to copy this
reloc if the symbol is defined in a dynamic
object. */
hmips = (struct mips_elf_link_hash_entry *) h;
++hmips->possibly_dynamic_relocs;
if (MIPS_ELF_READONLY_SECTION (sec))
@ -7289,6 +7301,66 @@ _bfd_mips_relax_section (bfd *abfd, asection *sec,
return FALSE;
}
/* Allocate space for global sym dynamic relocs. */
static bfd_boolean
allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{
struct bfd_link_info *info = inf;
bfd *dynobj;
struct mips_elf_link_hash_entry *hmips;
struct mips_elf_link_hash_table *htab;
htab = mips_elf_hash_table (info);
dynobj = elf_hash_table (info)->dynobj;
hmips = (struct mips_elf_link_hash_entry *) h;
/* VxWorks executables are handled elsewhere; we only need to
allocate relocations in shared objects. */
if (htab->is_vxworks && !info->shared)
return TRUE;
/* If this symbol is defined in a dynamic object, or we are creating
a shared library, we will need to copy any R_MIPS_32 or
R_MIPS_REL32 relocs against it into the output file. */
if (! info->relocatable
&& hmips->possibly_dynamic_relocs != 0
&& (h->root.type == bfd_link_hash_defweak
|| !h->def_regular
|| info->shared))
{
bfd_boolean do_copy = TRUE;
if (h->root.type == bfd_link_hash_undefweak)
{
/* Do not copy relocations for undefined weak symbols with
non-default visibility. */
if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
do_copy = FALSE;
/* Make sure undefined weak symbols are output as a dynamic
symbol in PIEs. */
else if (h->dynindx == -1 && !h->forced_local)
{
if (! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
}
}
if (do_copy)
{
mips_elf_allocate_dynamic_relocations
(dynobj, info, hmips->possibly_dynamic_relocs);
if (hmips->readonly_reloc)
/* We tell the dynamic linker that there are relocations
against the text segment. */
info->flags |= DF_TEXTREL;
}
}
return TRUE;
}
/* Adjust a symbol defined by a dynamic object and referenced by a
regular object. The current definition is in some section of the
dynamic object, but we're not including those sections. We have to
@ -7315,22 +7387,7 @@ _bfd_mips_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
&& h->ref_regular
&& !h->def_regular)));
/* If this symbol is defined in a dynamic object, we need to copy
any R_MIPS_32 or R_MIPS_REL32 relocs against it into the output
file. */
hmips = (struct mips_elf_link_hash_entry *) h;
if (! info->relocatable
&& hmips->possibly_dynamic_relocs != 0
&& (h->root.type == bfd_link_hash_defweak
|| !h->def_regular))
{
mips_elf_allocate_dynamic_relocations
(dynobj, info, hmips->possibly_dynamic_relocs);
if (hmips->readonly_reloc)
/* We tell the dynamic linker that there are relocations
against the text segment. */
info->flags |= DF_TEXTREL;
}
/* For a function, create a stub, if allowed. */
if (! hmips->no_fn_stub
@ -7724,6 +7781,9 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
}
}
/* Allocate space for global sym dynamic relocs. */
elf_link_hash_traverse (&htab->root, allocate_dynrelocs, (PTR) info);
/* The check_relocs and adjust_dynamic_symbol entry points have
determined the sizes of the various dynamic sections. Allocate
memory for them. */