* elf-bfd.h (SYMBOL_REFERENCES_LOCAL, SYMBOL_CALLS_LOCAL): Use..
(_bfd_elf_symbol_refs_local_p): ..this. Declare. * elflink.c (_bfd_elf_symbol_refs_local_p): New function. * elf32-i386.c (elf_i386_relocate_section): Remove h NULL test now done in _bfd_elf_symbol_refs_local_p. * elf32-ppc.c (ppc_elf_relocate_section): Likewise. * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. * elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
This commit is contained in:
parent
aaba06d939
commit
f6c52c1368
7 changed files with 74 additions and 18 deletions
|
@ -1,3 +1,14 @@
|
|||
2003-07-21 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf-bfd.h (SYMBOL_REFERENCES_LOCAL, SYMBOL_CALLS_LOCAL): Use..
|
||||
(_bfd_elf_symbol_refs_local_p): ..this. Declare.
|
||||
* elflink.c (_bfd_elf_symbol_refs_local_p): New function.
|
||||
* elf32-i386.c (elf_i386_relocate_section): Remove h NULL test
|
||||
now done in _bfd_elf_symbol_refs_local_p.
|
||||
* elf32-ppc.c (ppc_elf_relocate_section): Likewise.
|
||||
* elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
|
||||
* elf64-x86-64.c (elf64_x86_64_relocate_section): Likewise.
|
||||
|
||||
2003-07-18 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* elflink.c (_bfd_elf_dynamic_symbol_p): Undo the last change.
|
||||
|
|
|
@ -212,11 +212,11 @@ struct elf_link_hash_entry
|
|||
it's necessary for shared libs to also reference the .plt even
|
||||
though the symbol is really local to the shared lib. */
|
||||
#define SYMBOL_REFERENCES_LOCAL(INFO, H) \
|
||||
!_bfd_elf_dynamic_symbol_p (H, INFO, 1)
|
||||
_bfd_elf_symbol_refs_local_p (H, INFO, 0)
|
||||
|
||||
/* Will _calls_ to this symbol always call the version in this object? */
|
||||
#define SYMBOL_CALLS_LOCAL(INFO, H) \
|
||||
!_bfd_elf_dynamic_symbol_p (H, INFO, 0)
|
||||
_bfd_elf_symbol_refs_local_p (H, INFO, 1)
|
||||
|
||||
/* Records local symbols to be emitted in the dynamic symbol table. */
|
||||
|
||||
|
@ -1498,6 +1498,9 @@ extern bfd_boolean _bfd_elf_link_sec_merge_syms
|
|||
extern bfd_boolean _bfd_elf_dynamic_symbol_p
|
||||
PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean));
|
||||
|
||||
extern bfd_boolean _bfd_elf_symbol_refs_local_p
|
||||
PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean));
|
||||
|
||||
extern const bfd_target *bfd_elf32_object_p
|
||||
PARAMS ((bfd *));
|
||||
extern const bfd_target *bfd_elf32_core_file_p
|
||||
|
|
|
@ -2338,8 +2338,7 @@ elf_i386_relocate_section (bfd *output_bfd,
|
|||
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
||||
|| h->root.type != bfd_link_hash_undefweak)
|
||||
&& (r_type != R_386_PC32
|
||||
|| (h != NULL
|
||||
&& !SYMBOL_CALLS_LOCAL (info, h))))
|
||||
|| !SYMBOL_CALLS_LOCAL (info, h)))
|
||||
|| (ELIMINATE_COPY_RELOCS
|
||||
&& !info->shared
|
||||
&& h != NULL
|
||||
|
|
|
@ -5175,9 +5175,8 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||
case R_PPC_REL14_BRNTAKEN:
|
||||
/* If these relocations are not to a named symbol, they can be
|
||||
handled right here, no need to bother the dynamic linker. */
|
||||
if (h == NULL
|
||||
|| strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
|
||||
|| SYMBOL_REFERENCES_LOCAL (info, h))
|
||||
if (SYMBOL_REFERENCES_LOCAL (info, h)
|
||||
|| strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
|
||||
break;
|
||||
/* fall through */
|
||||
|
||||
|
@ -5207,8 +5206,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
||||
|| h->root.type != bfd_link_hash_undefweak)
|
||||
&& (MUST_BE_DYN_RELOC (r_type)
|
||||
|| (h != NULL
|
||||
&& !SYMBOL_CALLS_LOCAL (info, h))))
|
||||
|| !SYMBOL_CALLS_LOCAL (info, h)))
|
||||
|| (ELIMINATE_COPY_RELOCS
|
||||
&& !info->shared
|
||||
&& (input_section->flags & SEC_ALLOC) != 0
|
||||
|
@ -5263,8 +5261,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
|||
|
||||
if (skip)
|
||||
memset (&outrel, 0, sizeof outrel);
|
||||
else if (h != NULL
|
||||
&& !SYMBOL_REFERENCES_LOCAL (info, h))
|
||||
else if (!SYMBOL_REFERENCES_LOCAL (info, h))
|
||||
{
|
||||
unresolved_reloc = FALSE;
|
||||
outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
|
||||
|
|
|
@ -8159,8 +8159,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|
||||
|| h->root.type != bfd_link_hash_undefweak)
|
||||
&& (MUST_BE_DYN_RELOC (r_type)
|
||||
|| (h != NULL
|
||||
&& !SYMBOL_CALLS_LOCAL (info, h))))
|
||||
|| !SYMBOL_CALLS_LOCAL (info, h)))
|
||||
|| (ELIMINATE_COPY_RELOCS
|
||||
&& !info->shared
|
||||
&& h != NULL
|
||||
|
@ -8206,8 +8205,7 @@ ppc64_elf_relocate_section (bfd *output_bfd,
|
|||
|
||||
if (skip)
|
||||
memset (&outrel, 0, sizeof outrel);
|
||||
else if (h != NULL
|
||||
&& !SYMBOL_REFERENCES_LOCAL (info, h)
|
||||
else if (!SYMBOL_REFERENCES_LOCAL (info, h)
|
||||
&& !is_opd
|
||||
&& r_type != R_PPC64_TOC)
|
||||
outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
|
||||
|
@ -8758,7 +8756,7 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
|
|||
s->_raw_size))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -2015,8 +2015,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
|||
&& ((r_type != R_X86_64_PC8
|
||||
&& r_type != R_X86_64_PC16
|
||||
&& r_type != R_X86_64_PC32)
|
||||
|| (h != NULL
|
||||
&& !SYMBOL_CALLS_LOCAL (info, h))))
|
||||
|| !SYMBOL_CALLS_LOCAL (info, h)))
|
||||
|| (ELIMINATE_COPY_RELOCS
|
||||
&& !info->shared
|
||||
&& h != NULL
|
||||
|
|
|
@ -2534,3 +2534,52 @@ _bfd_elf_dynamic_symbol_p (h, info, ignore_protected)
|
|||
us that it remains local. */
|
||||
return !binding_stays_local_p;
|
||||
}
|
||||
|
||||
/* Return true if the symbol referred to by H should be considered
|
||||
to resolve local to the current module, and false otherwise. Differs
|
||||
from (the inverse of) _bfd_elf_dynamic_symbol_p in the treatment of
|
||||
undefined symbols and weak symbols. */
|
||||
|
||||
bfd_boolean
|
||||
_bfd_elf_symbol_refs_local_p (h, info, local_protected)
|
||||
struct elf_link_hash_entry *h;
|
||||
struct bfd_link_info *info;
|
||||
bfd_boolean local_protected;
|
||||
{
|
||||
/* If it's a local sym, of course we resolve locally. */
|
||||
if (h == NULL)
|
||||
return TRUE;
|
||||
|
||||
/* If we don't have a definition in a regular file, then we can't
|
||||
resolve locally. The sym is either undefined or dynamic. */
|
||||
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
|
||||
return FALSE;
|
||||
|
||||
/* Forced local symbols resolve locally. */
|
||||
if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
|
||||
return TRUE;
|
||||
|
||||
/* As do non-dynamic symbols. */
|
||||
if (h->dynindx == -1)
|
||||
return TRUE;
|
||||
|
||||
/* At this point, we know the symbol is defined and dynamic. In an
|
||||
executable it must resolve locally, likewise when building symbolic
|
||||
shared libraries. */
|
||||
if (info->executable || info->symbolic)
|
||||
return TRUE;
|
||||
|
||||
/* Now deal with defined dynamic symbols in shared libraries. Ones
|
||||
with default visibility might not resolve locally. */
|
||||
if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
|
||||
return FALSE;
|
||||
|
||||
/* However, STV_HIDDEN or STV_INTERNAL ones must be local. */
|
||||
if (ELF_ST_VISIBILITY (h->other) != STV_PROTECTED)
|
||||
return TRUE;
|
||||
|
||||
/* Function pointer equality tests may require that STV_PROTECTED
|
||||
symbols be treated as dynamic symbols, even when we know that the
|
||||
dynamic linker will resolve them locally. */
|
||||
return local_protected;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue