aboutsummaryrefslogtreecommitdiff
path: root/bfd/elflink.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2003-07-21 00:24:10 +0000
committerAlan Modra <amodra@gmail.com>2003-07-21 00:24:10 +0000
commitf6c52c13681f9c80b3e9cbf20464766c7d29e2e3 (patch)
treea6b27b3a1c0ccb9a909322dbe7ff2066bb714285 /bfd/elflink.c
parentaaba06d9395fb75c14d6f9374cfe1a17288ca900 (diff)
downloadfsf-binutils-gdb-f6c52c13681f9c80b3e9cbf20464766c7d29e2e3.zip
fsf-binutils-gdb-f6c52c13681f9c80b3e9cbf20464766c7d29e2e3.tar.gz
fsf-binutils-gdb-f6c52c13681f9c80b3e9cbf20464766c7d29e2e3.tar.bz2
* 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.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r--bfd/elflink.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 2fd588a..322bb3d 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -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;
+}