AArch64: Add gdbserver MTE support
[deliverable/binutils-gdb.git] / bfd / elfxx-x86.c
index 97de9f2b5373b34c6c67abed105ae05cb1e3087f..6ff9fd56ee732a36e35fd0207bee346392d9f01a 100644 (file)
@@ -1,5 +1,5 @@
 /* x86 specific support for ELF
-   Copyright (C) 2017-2020 Free Software Foundation, Inc.
+   Copyright (C) 2017-2021 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -686,13 +686,13 @@ elf_x86_link_hash_table_free (bfd *obfd)
 static bfd_boolean
 elf_i386_is_reloc_section (const char *secname)
 {
-  return CONST_STRNEQ (secname, ".rel");
+  return startswith (secname, ".rel");
 }
 
 static bfd_boolean
 elf_x86_64_is_reloc_section (const char *secname)
 {
-  return CONST_STRNEQ (secname, ".rela");
+  return startswith (secname, ".rela");
 }
 
 /* Create an x86 ELF linker hash table.  */
@@ -1624,7 +1624,7 @@ _bfd_x86_elf_always_size_sections (bfd *output_bfd,
 
 void
 _bfd_x86_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
-                                    const Elf_Internal_Sym *isym,
+                                    unsigned int st_other,
                                     bfd_boolean definition,
                                     bfd_boolean dynamic ATTRIBUTE_UNUSED)
 {
@@ -1632,8 +1632,7 @@ _bfd_x86_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
     {
       struct elf_x86_link_hash_entry *eh
        = (struct elf_x86_link_hash_entry *) h;
-      eh->def_protected = (ELF_ST_VISIBILITY (isym->st_other)
-                          == STV_PROTECTED);
+      eh->def_protected = ELF_ST_VISIBILITY (st_other) == STV_PROTECTED;
     }
 }
 
@@ -1712,8 +1711,7 @@ _bfd_x86_elf_link_fixup_ifunc_symbol (struct bfd_link_info *info,
       && h->def_regular
       && h->dynindx != -1
       && h->plt.offset != (bfd_vma) -1
-      && h->type == STT_GNU_IFUNC
-      && h->pointer_equality_needed)
+      && h->type == STT_GNU_IFUNC)
     {
       asection *plt_s;
       bfd_vma plt_offset;
@@ -1743,6 +1741,53 @@ _bfd_x86_elf_link_fixup_ifunc_symbol (struct bfd_link_info *info,
     }
 }
 
+/* Report relative relocation.  */
+
+void
+_bfd_x86_elf_link_report_relative_reloc
+  (struct bfd_link_info *info, asection *asect,
+   struct elf_link_hash_entry *h, Elf_Internal_Sym *sym,
+   const char *reloc_name, const void *reloc)
+{
+  const char *name;
+  bfd *abfd;
+  const Elf_Internal_Rela *rel = (const Elf_Internal_Rela *) reloc;
+  char r_offset[30], r_info[30];
+
+  /* Use the output BFD for linker created sections.  */
+  if ((asect->flags & SEC_LINKER_CREATED) != 0)
+    abfd = info->output_bfd;
+  else
+    abfd = asect->owner;
+
+  if (h != NULL && h->root.root.string != NULL)
+    name = h->root.root.string;
+  else
+    name = bfd_elf_sym_name (abfd, &elf_symtab_hdr (abfd), sym, NULL);
+
+  bfd_sprintf_vma (abfd, r_offset, rel->r_offset);
+  bfd_sprintf_vma (abfd, r_info, rel->r_info);
+
+  if (asect->use_rela_p)
+    {
+      char r_addend[30];
+
+      bfd_sprintf_vma (abfd, r_addend, rel->r_addend);
+
+      info->callbacks->einfo
+       (_("%pB: %s (offset: 0x%s, info: 0x%s, addend: 0x%s) against "
+          "'%s' " "for section '%pA' in %pB\n"),
+        info->output_bfd, reloc_name, r_offset, r_info, r_addend,
+        name, asect, abfd);
+    }
+  else
+    info->callbacks->einfo
+      (_("%pB: %s (offset: 0x%s, info: 0x%s) against '%s' for section "
+        "'%pA' in %pB\n"),
+       info->output_bfd, reloc_name, r_offset, r_info, name,
+       asect, abfd);
+}
+
 /* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
 
 bfd_boolean
@@ -2450,8 +2495,15 @@ _bfd_x86_elf_merge_gnu_properties (struct bfd_link_info *info,
                features = GNU_PROPERTY_X86_FEATURE_1_IBT;
              if (htab->params->shstk)
                features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
-             /* Add GNU_PROPERTY_X86_FEATURE_1_IBT and
-                GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
+             if (htab->params->lam_u48)
+               features |= (GNU_PROPERTY_X86_FEATURE_1_LAM_U48
+                            | GNU_PROPERTY_X86_FEATURE_1_LAM_U57);
+             else if (htab->params->lam_u57)
+               features |= GNU_PROPERTY_X86_FEATURE_1_LAM_U57;
+             /* Add GNU_PROPERTY_X86_FEATURE_1_IBT,
+                GNU_PROPERTY_X86_FEATURE_1_SHSTK,
+                GNU_PROPERTY_X86_FEATURE_1_LAM_U48 and
+                GNU_PROPERTY_X86_FEATURE_1_LAM_U57.  */
              aprop->u.number |= features;
            }
          updated = number != (unsigned int) aprop->u.number;
@@ -2471,6 +2523,11 @@ _bfd_x86_elf_merge_gnu_properties (struct bfd_link_info *info,
                features = GNU_PROPERTY_X86_FEATURE_1_IBT;
              if (htab->params->shstk)
                features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
+             if (htab->params->lam_u48)
+               features |= (GNU_PROPERTY_X86_FEATURE_1_LAM_U48
+                            | GNU_PROPERTY_X86_FEATURE_1_LAM_U57);
+             else if (htab->params->lam_u57)
+               features |= GNU_PROPERTY_X86_FEATURE_1_LAM_U57;
            }
          if (features)
            {
@@ -2546,15 +2603,27 @@ _bfd_x86_elf_link_setup_gnu_properties
   if (htab->params->ibt)
     {
       features = GNU_PROPERTY_X86_FEATURE_1_IBT;
-      htab->params->cet_report &= ~cet_report_ibt;
+      htab->params->cet_report &= ~prop_report_ibt;
     }
   if (htab->params->shstk)
     {
       features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
-      htab->params->cet_report &= ~cet_report_shstk;
+      htab->params->cet_report &= ~prop_report_shstk;
+    }
+  if (!(htab->params->cet_report & (prop_report_ibt | prop_report_shstk)))
+    htab->params->cet_report = prop_report_none;
+  if (htab->params->lam_u48)
+    {
+      features |= (GNU_PROPERTY_X86_FEATURE_1_LAM_U48
+                  | GNU_PROPERTY_X86_FEATURE_1_LAM_U57);
+      htab->params->lam_u48_report = prop_report_none;
+      htab->params->lam_u57_report = prop_report_none;
+    }
+  else if (htab->params->lam_u57)
+    {
+      features |= GNU_PROPERTY_X86_FEATURE_1_LAM_U57;
+      htab->params->lam_u57_report = prop_report_none;
     }
-  if (!(htab->params->cet_report & (cet_report_ibt | cet_report_shstk)))
-    htab->params->cet_report = cet_report_none;
 
   switch (htab->params->isa_level)
     {
@@ -2582,8 +2651,10 @@ _bfd_x86_elf_link_setup_gnu_properties
       prop = NULL;
       if (features)
        {
-         /* If features is set, add GNU_PROPERTY_X86_FEATURE_1_IBT and
-            GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
+         /* If features is set, add GNU_PROPERTY_X86_FEATURE_1_IBT,
+            GNU_PROPERTY_X86_FEATURE_1_SHSTK,
+            GNU_PROPERTY_X86_FEATURE_1_LAM_U48 and
+            GNU_PROPERTY_X86_FEATURE_1_LAM_U57.  */
          prop = _bfd_elf_get_property (ebfd,
                                        GNU_PROPERTY_X86_FEATURE_1_AND,
                                        4);
@@ -2626,22 +2697,49 @@ _bfd_x86_elf_link_setup_gnu_properties
        }
     }
 
-  if (htab->params->cet_report)
+  if (htab->params->cet_report
+      || htab->params->lam_u48_report
+      || htab->params->lam_u57_report)
     {
-      /* Report missing IBT and SHSTK properties.  */
+      /* Report missing IBT, SHSTK and LAM properties.  */
       bfd *abfd;
-      const char *msg;
+      const char *warning_msg = _("%P: %pB: warning: missing %s\n");
+      const char *error_msg = _("%X%P: %pB: error: missing %s\n");
+      const char *cet_msg = NULL;
+      const char *lam_u48_msg = NULL;
+      const char *lam_u57_msg = NULL;
+      const char *missing;
       elf_property_list *p;
       bfd_boolean missing_ibt, missing_shstk;
+      bfd_boolean missing_lam_u48, missing_lam_u57;
       bfd_boolean check_ibt
-       = !!(htab->params->cet_report & cet_report_ibt);
+       = (htab->params->cet_report
+          && (htab->params->cet_report & prop_report_ibt));
       bfd_boolean check_shstk
-       = !!(htab->params->cet_report & cet_report_shstk);
+       = (htab->params->cet_report
+          && (htab->params->cet_report & prop_report_shstk));
 
-      if ((htab->params->cet_report & cet_report_warning))
-       msg = _("%P: %pB: warning: missing %s\n");
-      else
-       msg = _("%X%P: %pB: error: missing %s\n");
+      if (htab->params->cet_report)
+       {
+         if ((htab->params->cet_report & prop_report_warning))
+           cet_msg = warning_msg;
+         else
+           cet_msg = error_msg;
+       }
+      if (htab->params->lam_u48_report)
+       {
+         if ((htab->params->lam_u48_report & prop_report_warning))
+           lam_u48_msg = warning_msg;
+         else
+           lam_u48_msg = error_msg;
+       }
+      if (htab->params->lam_u57_report)
+       {
+         if ((htab->params->lam_u57_report & prop_report_warning))
+           lam_u57_msg = warning_msg;
+         else
+           lam_u57_msg = error_msg;
+       }
 
       for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
        if (!(abfd->flags & (DYNAMIC | BFD_PLUGIN | BFD_LINKER_CREATED))
@@ -2653,23 +2751,38 @@ _bfd_x86_elf_link_setup_gnu_properties
 
            missing_ibt = check_ibt;
            missing_shstk = check_shstk;
+           missing_lam_u48 = !!lam_u48_msg;
+           missing_lam_u57 = !!lam_u57_msg;
            if (p)
              {
                missing_ibt &= !(p->property.u.number
                                 & GNU_PROPERTY_X86_FEATURE_1_IBT);
                missing_shstk &= !(p->property.u.number
                                   & GNU_PROPERTY_X86_FEATURE_1_SHSTK);
+               missing_lam_u48 &= !(p->property.u.number
+                                    & GNU_PROPERTY_X86_FEATURE_1_LAM_U48);
+               missing_lam_u57 &= !(p->property.u.number
+                                    & GNU_PROPERTY_X86_FEATURE_1_LAM_U57);
              }
            if (missing_ibt || missing_shstk)
              {
-               const char *missing;
                if (missing_ibt && missing_shstk)
                  missing = _("IBT and SHSTK properties");
                else if (missing_ibt)
                  missing = _("IBT property");
                else
                  missing = _("SHSTK property");
-               info->callbacks->einfo (msg, abfd, missing);
+               info->callbacks->einfo (cet_msg, abfd, missing);
+             }
+           if (missing_lam_u48)
+             {
+               missing = _("LAM_U48 property");
+               info->callbacks->einfo (lam_u48_msg, abfd, missing);
+             }
+           if (missing_lam_u57)
+             {
+               missing = _("LAM_U57 property");
+               info->callbacks->einfo (lam_u57_msg, abfd, missing);
              }
          }
     }
@@ -3009,8 +3122,7 @@ _bfd_x86_elf_link_setup_gnu_properties
 
 void
 _bfd_x86_elf_link_fixup_gnu_properties
-  (struct bfd_link_info *info ATTRIBUTE_UNUSED,
-   elf_property_list **listp)
+  (struct bfd_link_info *info, elf_property_list **listp)
 {
   elf_property_list *p;
 
@@ -3038,6 +3150,12 @@ _bfd_x86_elf_link_fixup_gnu_properties
              continue;
            }
 
+         /* Keep LAM features only for 64-bit output.  */
+         if (type == GNU_PROPERTY_X86_FEATURE_1_AND
+             && !ABI_64_P (info->output_bfd))
+           p->property.u.number &= ~(GNU_PROPERTY_X86_FEATURE_1_LAM_U48
+                                     | GNU_PROPERTY_X86_FEATURE_1_LAM_U57);
+
          listp = &p->next;
        }
       else if (type > GNU_PROPERTY_HIPROC)
This page took 0.031749 seconds and 4 git commands to generate.