aboutsummaryrefslogtreecommitdiff
path: root/bfd/elflink.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2003-07-18 21:09:28 +0000
committerRichard Henderson <rth@redhat.com>2003-07-18 21:09:28 +0000
commit986a241f8b043a790a63bc4e96bb731973a61ff4 (patch)
tree83a1a719061def9eab539e87e9de1f84059395d1 /bfd/elflink.c
parent22b0d388c7f3d6271df8e2193a1c4f4d4a7d973d (diff)
downloadgdb-986a241f8b043a790a63bc4e96bb731973a61ff4.zip
gdb-986a241f8b043a790a63bc4e96bb731973a61ff4.tar.gz
gdb-986a241f8b043a790a63bc4e96bb731973a61ff4.tar.bz2
* elflink.c (_bfd_elf_dynamic_symbol_p): New.
* elf-bfd.h (_bfd_elf_dynamic_symbol_p): Declare it. (SYMBOL_REFERENCES_LOCAL, SYMBOL_CALLS_LOCAL): Use it. * elf32-xtensa.c (xtensa_elf_dynamic_symbol_p): Likewise. * elf64-alpha.c (alpha_elf_dynamic_symbol_p): Likewise. * elf64-hppa.c (elf64_hppa_dynamic_symbol_p): Likewise. * elfxx-ia64.c (elfNN_ia64_dynamic_symbol_p): Likewise. Update all callers to provide the relocation being resolved.
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r--bfd/elflink.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index b448367..2fd588a 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -2474,3 +2474,63 @@ _bfd_elf_link_sec_merge_syms (h, data)
return TRUE;
}
+
+/* Returns false if the symbol referred to by H should be considered
+ to resolve local to the current module, and true if it should be
+ considered to bind dynamically. */
+
+bfd_boolean
+_bfd_elf_dynamic_symbol_p (h, info, ignore_protected)
+ struct elf_link_hash_entry *h;
+ struct bfd_link_info *info;
+ bfd_boolean ignore_protected;
+{
+ bfd_boolean binding_stays_local_p;
+
+ if (h == NULL)
+ return FALSE;
+
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ /* If it was forced local, then clearly it's not dynamic. */
+ if (h->dynindx == -1)
+ return FALSE;
+ if (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL)
+ return FALSE;
+
+ /* Identify the cases where name binding rules say that a
+ visible symbol resolves locally. */
+ binding_stays_local_p = info->executable || info->symbolic;
+
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_INTERNAL:
+ case STV_HIDDEN:
+ return FALSE;
+
+ case STV_PROTECTED:
+ /* Proper resolution for function pointer equality may require
+ that these symbols perhaps be resolved dynamically, even though
+ we should be resolving them to the current module. */
+ if (!ignore_protected)
+ binding_stays_local_p = TRUE;
+ break;
+
+ default:
+ /* With STV_DEFAULT, weak symbols do not bind locally. */
+ if (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_defweak)
+ return TRUE;
+ break;
+ }
+
+ /* If it isn't defined locally, then clearly it's dynamic. */
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
+ return TRUE;
+
+ /* Otherwise, the symbol is dynamic if binding rules don't tell
+ us that it remains local. */
+ return !binding_stays_local_p;
+}