x86: Initialize def_protected
[binutils-gdb.git] / bfd / elf32-i386.c
index 1009c17ff21c1c28caf8b7b14e272abfa68abf60..999cd48ee4a69b49cef2fd87b501aba66bd4f832 100644 (file)
@@ -956,6 +956,18 @@ static const struct elf_i386_backend_data elf_i386_arch_bed =
               || (EH)->has_non_got_reloc                       \
               || !(INFO)->dynamic_undefined_weak))))
 
+/* Should copy relocation be generated for a symbol.  Don't generate
+   copy relocation against a protected symbol defined in a shared
+   object with GNU_PROPERTY_NO_COPY_ON_PROTECTED.  */
+#define SYMBOL_NO_COPYRELOC(INFO, EH) \
+  ((EH)->def_protected \
+   && ((EH)->elf.root.type == bfd_link_hash_defined \
+       || (EH)->elf.root.type == bfd_link_hash_defweak) \
+   && elf_has_no_copy_on_protected ((EH)->elf.root.u.def.section->owner) \
+   && ((EH)->elf.root.u.def.section->owner->flags & DYNAMIC) != 0 \
+   && ((EH)->elf.root.u.def.section->flags & SEC_CODE) == 0)
+
+
 /* i386 ELF linker hash entry.  */
 
 struct elf_i386_link_hash_entry
@@ -995,9 +1007,12 @@ struct elf_i386_link_hash_entry
   /* Don't call finish_dynamic_symbol on this symbol.  */
   unsigned int no_finish_dynamic_symbol : 1;
 
-  /* TRUE if symbol symbol is __tls_get_addr.  */
+  /* TRUE if symbol is __tls_get_addr.  */
   unsigned int tls_get_addr : 1;
 
+  /* TRUE if symbol is defined as a protected symbol.  */
+  unsigned int def_protected : 1;
+
   /* Reference count of C/C++ function pointer relocations in read-write
      section which can be resolved at run-time.  */
   bfd_signed_vma func_pointer_refcount;
@@ -1148,6 +1163,7 @@ elf_i386_link_hash_newfunc (struct bfd_hash_entry *entry,
       eh->has_non_got_reloc = 0;
       eh->no_finish_dynamic_symbol = 0;
       eh->tls_get_addr = 0;
+      eh->def_protected = 0;
       eh->func_pointer_refcount = 0;
       eh->plt_got.offset = (bfd_vma) -1;
       eh->tlsdesc_got = (bfd_vma) -1;
@@ -2590,6 +2606,8 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
        the link may change h->type.  So fix it now.  */
     h->plt.offset = (bfd_vma) -1;
 
+  eh = (struct elf_i386_link_hash_entry *) h;
+
   /* If this is a weak symbol, and there is a real definition, the
      processor independent code will have arranged for us to see the
      real definition first, and we can just use the same value.  */
@@ -2599,7 +2617,9 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
                  || h->u.weakdef->root.type == bfd_link_hash_defweak);
       h->root.u.def.section = h->u.weakdef->root.u.def.section;
       h->root.u.def.value = h->u.weakdef->root.u.def.value;
-      if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
+      if (ELIMINATE_COPY_RELOCS
+         || info->nocopyreloc
+         || SYMBOL_NO_COPYRELOC (info, eh))
        h->non_got_ref = h->u.weakdef->non_got_ref;
       return TRUE;
     }
@@ -2617,12 +2637,11 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* If there are no references to this symbol that do not use the
      GOT nor R_386_GOTOFF relocation, we don't need to generate a copy
      reloc.  */
-  eh = (struct elf_i386_link_hash_entry *) h;
   if (!h->non_got_ref && !eh->gotoff_ref)
     return TRUE;
 
   /* If -z nocopyreloc was given, we won't generate them either.  */
-  if (info->nocopyreloc)
+  if (info->nocopyreloc || SYMBOL_NO_COPYRELOC (info, eh))
     {
       h->non_got_ref = 0;
       return TRUE;
@@ -6802,68 +6821,39 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
          break;
       }
 
-  if (ebfd != NULL)
+  if (ebfd != NULL && features)
     {
-      if (features)
+      /* If features is set, add GNU_PROPERTY_X86_FEATURE_1_IBT and
+        GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
+      prop = _bfd_elf_get_property (ebfd,
+                                   GNU_PROPERTY_X86_FEATURE_1_AND,
+                                   4);
+      prop->u.number |= features;
+      prop->pr_kind = property_number;
+
+      /* Create the GNU property note section if needed.  */
+      if (pbfd == NULL)
        {
-         /* If features is set, add GNU_PROPERTY_X86_FEATURE_1_IBT and
-            GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
-         prop = _bfd_elf_get_property (ebfd,
-                                       GNU_PROPERTY_X86_FEATURE_1_AND,
-                                       4);
-         prop->u.number |= features;
-         prop->pr_kind = property_number;
-
-         /* Create the GNU property note section if needed.  */
-         if (pbfd == NULL)
-           {
-             sec = bfd_make_section_with_flags (ebfd,
-                                                NOTE_GNU_PROPERTY_SECTION_NAME,
-                                                (SEC_ALLOC
-                                                 | SEC_LOAD
-                                                 | SEC_IN_MEMORY
-                                                 | SEC_READONLY
-                                                 | SEC_HAS_CONTENTS
-                                                 | SEC_DATA));
-             if (sec == NULL)
-               info->callbacks->einfo (_("%F: failed to create GNU property section\n"));
+         sec = bfd_make_section_with_flags (ebfd,
+                                            NOTE_GNU_PROPERTY_SECTION_NAME,
+                                            (SEC_ALLOC
+                                             | SEC_LOAD
+                                             | SEC_IN_MEMORY
+                                             | SEC_READONLY
+                                             | SEC_HAS_CONTENTS
+                                             | SEC_DATA));
+         if (sec == NULL)
+           info->callbacks->einfo (_("%F: failed to create GNU property section\n"));
 
-             if (!bfd_set_section_alignment (ebfd, sec, 2))
-               {
+         if (!bfd_set_section_alignment (ebfd, sec, 2))
+           {
 error_alignment:
-                 info->callbacks->einfo (_("%F%A: failed to align section\n"),
-                                         sec);
-               }
-
-             elf_section_type (sec) = SHT_NOTE;
+             info->callbacks->einfo (_("%F%A: failed to align section\n"),
+                                     sec);
            }
-       }
 
-      /* Check GNU_PROPERTY_NO_COPY_ON_PROTECTED.  */
-      for (; pbfd != NULL; pbfd = pbfd->link.next)
-       if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
-           && (pbfd->flags
-               & (DYNAMIC | BFD_LINKER_CREATED | BFD_PLUGIN)) == 0)
-         {
-           elf_property_list *p;
-
-           /* The property list is sorted in order of type.  */
-           for (p = elf_properties (pbfd); p != NULL; p = p->next)
-             {
-               if (GNU_PROPERTY_NO_COPY_ON_PROTECTED
-                   == p->property.pr_type)
-                 {
-                   /* Clear extern_protected_data if
-                      GNU_PROPERTY_NO_COPY_ON_PROTECTED is
-                      set on any input relocatable file.  */
-                   info->extern_protected_data = FALSE;
-                   break;
-                 }
-               else if (GNU_PROPERTY_NO_COPY_ON_PROTECTED
-                        < p->property.pr_type)
-                 break;
-             }
-         }
+         elf_section_type (sec) = SHT_NOTE;
+       }
     }
 
   pbfd = _bfd_elf_link_setup_gnu_properties (info);
@@ -7163,6 +7153,21 @@ elf_i386_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
   return _bfd_elf_link_check_relocs (abfd, info);
 }
 
+static void
+elf_i386_merge_symbol_attribute (struct elf_link_hash_entry *h,
+                                const Elf_Internal_Sym *isym,
+                                bfd_boolean definition,
+                                bfd_boolean dynamic ATTRIBUTE_UNUSED)
+{
+  if (definition)
+    {
+      struct elf_i386_link_hash_entry *eh
+       = (struct elf_i386_link_hash_entry *) h;
+      eh->def_protected = (ELF_ST_VISIBILITY (isym->st_other)
+                          == STV_PROTECTED);
+    }
+}
+
 #define TARGET_LITTLE_SYM              i386_elf32_vec
 #define TARGET_LITTLE_NAME             "elf32-i386"
 #define ELF_ARCH                       bfd_arch_i386
@@ -7218,6 +7223,7 @@ elf_i386_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
 #define elf_backend_parse_gnu_properties      elf_i386_parse_gnu_properties
 #define elf_backend_merge_gnu_properties      elf_i386_merge_gnu_properties
 #define elf_backend_setup_gnu_properties      elf_i386_link_setup_gnu_properties
+#define elf_backend_merge_symbol_attribute    elf_i386_merge_symbol_attribute
 
 #include "elf32-target.h"