+2004-07-21  Alexandre Oliva  <aoliva@redhat.com>
+
+       * elf-bfd.h (ELF_COMMON_DEF_P): New.
+       * elflink.c (_bfd_elf_symbol_refs_local_p): Use it to handle
+       common definitions.
+       * elf-m10300.c: Use SYMBOL_REFERENCES_LOCAL instead of
+       _bfd_elf_symbol_refs_local_p.
+       * elf32-frv.c (FRVFDPIC_SYM_LOCAL): Remove hack for common
+       symbols.
+
 2004-07-19  H.J. Lu  <hongjiu.lu@intel.com>
 
        * bfd-in.h (dynamic_lib_link_class): Add DYN_NO_ADD_NEEDED and
 
 #define SYMBOL_CALLS_LOCAL(INFO, H) \
   _bfd_elf_symbol_refs_local_p (H, INFO, 1)
 
+/* Common symbols that are turned into definitions don't have the
+   DEF_REGULAR flag set, so they might appear to be undefined.  */
+#define ELF_COMMON_DEF_P(H) \
+  (((H)->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0         \
+   && ((H)->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0      \
+   && (H)->root.type == bfd_link_hash_defined)
+
 /* Records local symbols to be emitted in the dynamic symbol table.  */
 
 struct elf_link_local_dynamic_entry
 
       if (info->shared
          && (input_section->flags & SEC_ALLOC) != 0
          && h != NULL
-         && ! _bfd_elf_symbol_refs_local_p (h, info, 1))
+         && ! SYMBOL_REFERENCES_LOCAL (info, h))
        return bfd_reloc_dangerous;
     }
 
              /* h->dynindx may be -1 if this symbol was marked to
                 become local.  */
              if (h == NULL
-                 || _bfd_elf_symbol_refs_local_p (h, info, 1))
+                 || SYMBOL_REFERENCES_LOCAL (info, h))
                {
                  relocate = TRUE;
                  outrel.r_info = ELF32_R_INFO (0, R_MN10300_RELATIVE);
              BFD_ASSERT (off != (bfd_vma) -1);
 
              if (! elf_hash_table (info)->dynamic_sections_created
-                 || _bfd_elf_symbol_refs_local_p (h, info, 1))
+                 || SYMBOL_REFERENCES_LOCAL (info, h))
                /* This is actually a static link, or it is a
                   -Bsymbolic link and the symbol is defined
                   locally, or the symbol was forced to be local
                       || r_type == R_MN10300_GOT24
                       || r_type == R_MN10300_GOT16)
                      && elf_hash_table (info)->dynamic_sections_created
-                     && !_bfd_elf_symbol_refs_local_p (h, info, 1))
+                     && !SYMBOL_REFERENCES_LOCAL (info, hh))
                  || (r_type == R_MN10300_32
-                     && !_bfd_elf_symbol_refs_local_p (h, info, 1)
+                     && !SYMBOL_REFERENCES_LOCAL (info, hh)
                      && ((input_section->flags & SEC_ALLOC) != 0
                          /* DWARF will emit R_MN10300_32 relocations
                             in its sections against symbols defined
 
    its function descriptor must be assigned by the dynamic linker.  */
 #define FRVFDPIC_SYM_LOCAL(INFO, H) \
   (_bfd_elf_symbol_refs_local_p ((H), (INFO), 1) \
-   || ! elf_hash_table (INFO)->dynamic_sections_created \
-   || (/* The condition below is an ugly hack to get .scommon data to
-         be regarded as local.  For some reason the
-         ELF_LINK_HASH_DEF_REGULAR bit is not set on such common
-         symbols, and the SEC_IS_COMMON bit is not set any longer
-         when we need to perform this test.  Hopefully this
-         approximation is good enough.  */ \
-       ((H)->root.type == bfd_link_hash_defined \
-       || (H)->root.type == bfd_link_hash_defweak) \
-       && (H)->root.u.def.section->output_section \
-       && ((H)->root.u.def.section->flags & SEC_LINKER_CREATED)))
+   || ! elf_hash_table (INFO)->dynamic_sections_created)
 #define FRVFDPIC_FUNCDESC_LOCAL(INFO, H) \
   ((H)->dynindx == -1 || ! elf_hash_table (INFO)->dynamic_sections_created)
 
 
   if (h == NULL)
     return TRUE;
 
+  /* Common symbols that become definitions don't get the DEF_REGULAR
+     flag set, so test it first, and don't bail out.  */
+  if (ELF_COMMON_DEF_P (h))
+    /* Do nothing.  */;
   /* 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)
+  else if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
     return FALSE;
 
   /* Forced local symbols resolve locally.  */