* elf-bfd.h (SYMBOL_REFERENCES_LOCAL, SYMBOL_CALLS_LOCAL): Use..
authorAlan Modra <amodra@gmail.com>
Mon, 21 Jul 2003 00:24:10 +0000 (00:24 +0000)
committerAlan Modra <amodra@gmail.com>
Mon, 21 Jul 2003 00:24:10 +0000 (00:24 +0000)
(_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.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf32-i386.c
bfd/elf32-ppc.c
bfd/elf64-ppc.c
bfd/elf64-x86-64.c
bfd/elflink.c

index 845ae1da23b9aeb8c7bd7da5fa213cae1fc7f1f2..a5b33c884cabaadcbc4c6ae0cb067da635a26a10 100644 (file)
@@ -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.
index 2fc64abb7e7dc8b1f6db873cc0ce44f28ca3c153..2aa0c597e6c51cd4e7c5b33de399837ebe0a42c9 100644 (file)
@@ -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
index 0ddd5078fc21c116d7a89cc1f760dabb04979baa..60bccb8078b00ed5c60bdbb30dfa34d63475d1d8 100644 (file)
@@ -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
index a2eec938b9e318b1c554e3ad6de24318cde5fea9..ebf9dc05894c512fd1648a02367f27161833c47e 100644 (file)
@@ -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);
index 0334d84c9b55d35469e565e94ddefe3f9e5b8fc9..a052cd0d95a7b6e47839bc01ae74196cb6aaf3c1 100644 (file)
@@ -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;
 }
 
index 542f83f5f1157420035da12bcff1cdebdd0f30a9..09a072b5b8eaf9aba974839d12464e0375b69466 100644 (file)
@@ -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
index 2fd588ae1101c2873d09d79386037780494b32a8..322bb3d3fe3e68aeee2b867eecc42da5ebb88979 100644 (file)
@@ -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;
+}