* elf-bfd.h (ELF_LINK_NON_ELF): Define.
authorIan Lance Taylor <ian@airs.com>
Thu, 1 Feb 1996 23:15:23 +0000 (23:15 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 1 Feb 1996 23:15:23 +0000 (23:15 +0000)
* elf.c (_bfd_elf_link_hash_newfunc): Set elf_link_hash_flags to
ELF_LINK_NON_ELF.
* elflink.h (elf_link_add_object_symbols): Reset ELF_LINK_NON_ELF
flag for a newly defined symbol.
(NAME(bfd_elf,record_link_assignment)): Likewise.
(elf_adjust_dynamic_symbol): If ELF_LINK_NON_ELF is set, try to
set the DEF or REF_REGULAR flags correctly.

bfd/ChangeLog
bfd/elf.c
bfd/elflink.h

index ee583e27b180d99ae4c41c889ad97495a75e4f0e..00466ea6d98b33f63d88e21d82fb78cdf1e5e608 100644 (file)
@@ -1,5 +1,14 @@
 Thu Feb  1 16:04:06 1996  Ian Lance Taylor  <ian@cygnus.com>
 
+       * elf-bfd.h (ELF_LINK_NON_ELF): Define.
+       * elf.c (_bfd_elf_link_hash_newfunc): Set elf_link_hash_flags to
+       ELF_LINK_NON_ELF.
+       * elflink.h (elf_link_add_object_symbols): Reset ELF_LINK_NON_ELF
+       flag for a newly defined symbol.
+       (NAME(bfd_elf,record_link_assignment)): Likewise.
+       (elf_adjust_dynamic_symbol): If ELF_LINK_NON_ELF is set, try to
+       set the DEF or REF_REGULAR flags correctly.
+
        * Makefile.in (bfd-in2.h): Make bfd.h, not protos, in docdir.
        (libbfd.h, libcoff.h): Corresponding change.
 
index be1cbc88e5774c0a0c353030f0ac7956cbc1e8ea..4313d5e733312e39030521cbaa32f42475dd462d 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -556,7 +556,11 @@ _bfd_elf_link_hash_newfunc (entry, table, string)
       ret->plt_offset = (bfd_vma) -1;
       ret->linker_section_pointer = (elf_linker_section_pointers_t *)0;
       ret->type = STT_NOTYPE;
-      ret->elf_link_hash_flags = 0;
+      /* Assume that we have been called by a non-ELF symbol reader.
+         This flag is then reset by the code which reads an ELF input
+         file.  This ensures that a symbol created by a non-ELF symbol
+         reader will have the flag set correctly.  */
+      ret->elf_link_hash_flags = ELF_LINK_NON_ELF;
     }
 
   return (struct bfd_hash_entry *) ret;
index f1cf498049d80048300646d00f64a610b5f293b0..beab0d0adc64ff5b33c35a340bd0792c14c0abac 100644 (file)
@@ -643,6 +643,9 @@ elf_link_add_object_symbols (abfd, info)
            goto error_return;
          *sym_hash = h;
 
+         if (h->root.type == bfd_link_hash_new)
+           h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;
+
          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;
@@ -1231,6 +1234,9 @@ NAME(bfd_elf,record_link_assignment) (output_bfd, info, name, provide)
   if (h == NULL)
     return false;
 
+  if (h->root.type == bfd_link_hash_new)
+    h->elf_link_hash_flags &=~ ELF_LINK_NON_ELF;
+
   /* If this symbol is being provided by the linker script, and it is
      currently defined by a dynamic object, but not by a regular
      object, then mark it as undefined so that the generic linker will
@@ -1507,6 +1513,35 @@ elf_adjust_dynamic_symbol (h, data)
   bfd *dynobj;
   struct elf_backend_data *bed;
 
+  /* If this symbol was mentioned in a non-ELF file, try to set
+     DEF_REGULAR and REF_REGULAR correctly.  This is the only way to
+     permit a non-ELF file to correctly refer to a symbol defined in
+     an ELF dynamic object.  */
+  if ((h->elf_link_hash_flags & ELF_LINK_NON_ELF) != 0)
+    {
+      if (h->root.type != bfd_link_hash_defined
+         && h->root.type != bfd_link_hash_defweak)
+       h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
+      else
+       {
+         if (bfd_get_flavour (h->root.u.def.section->owner)
+             == bfd_target_elf_flavour)
+           h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
+         else
+           h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+       }
+
+      if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
+         || (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0)
+       {
+         if (! _bfd_elf_link_record_dynamic_symbol (eif->info, h))
+           {
+             eif->failed = true;
+             return false;
+           }
+       }
+    }
+
   /* If -Bsymbolic was used (which means to bind references to global
      symbols to the definition within the shared object), and this
      symbol was defined in a regular object, then it actually doesn't