Avoid testcase build failures with -Wunused-value
[deliverable/binutils-gdb.git] / bfd / elfnn-riscv.c
index 1b530d83dffd76e42aee66ac6d4ef5bd584dcbce..00553f774644d98ac30a2c358014c9a1c0b98137 100644 (file)
@@ -415,37 +415,6 @@ riscv_elf_copy_indirect_symbol (struct bfd_link_info *info,
   edir = (struct riscv_elf_link_hash_entry *) dir;
   eind = (struct riscv_elf_link_hash_entry *) ind;
 
-  if (ind->dyn_relocs != NULL)
-    {
-      if (dir->dyn_relocs != NULL)
-       {
-         struct elf_dyn_relocs **pp;
-         struct elf_dyn_relocs *p;
-
-         /* Add reloc counts against the indirect sym to the direct sym
-            list.  Merge any entries against the same section.  */
-         for (pp = &ind->dyn_relocs; (p = *pp) != NULL; )
-           {
-             struct elf_dyn_relocs *q;
-
-             for (q = dir->dyn_relocs; q != NULL; q = q->next)
-               if (q->sec == p->sec)
-                 {
-                   q->pc_count += p->pc_count;
-                   q->count += p->count;
-                   *pp = p->next;
-                   break;
-                 }
-             if (q == NULL)
-               pp = &p->next;
-           }
-         *pp = dir->dyn_relocs;
-       }
-
-      dir->dyn_relocs = ind->dyn_relocs;
-      ind->dyn_relocs = NULL;
-    }
-
   if (ind->root.type == bfd_link_hash_indirect
       && dir->got.refcount <= 0)
     {
@@ -1119,33 +1088,6 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
   return TRUE;
 }
 
-/* Set DF_TEXTREL if we find any dynamic relocs that apply to
-   read-only sections.  */
-
-static bfd_boolean
-maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
-{
-  asection *sec;
-
-  if (h->root.type == bfd_link_hash_indirect)
-    return TRUE;
-
-  sec = _bfd_elf_readonly_dynrelocs (h);
-  if (sec != NULL)
-    {
-      struct bfd_link_info *info = (struct bfd_link_info *) info_p;
-
-      info->flags |= DF_TEXTREL;
-      info->callbacks->minfo
-       (_("%pB: dynamic relocation against `%pT' in read-only section `%pA'\n"),
-        sec->owner, h->root.root.string, sec);
-
-      /* Not an error, just cut short the traversal.  */
-      return FALSE;
-    }
-  return TRUE;
-}
-
 static bfd_boolean
 riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 {
@@ -1352,7 +1294,8 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
       /* If any dynamic relocs apply to a read-only section,
         then we need a DT_TEXTREL entry.  */
       if ((info->flags & DF_TEXTREL) == 0)
-       elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
+       elf_link_hash_traverse (&htab->elf,
+                               _bfd_elf_maybe_set_textrel, info);
 
       if (info->flags & DF_TEXTREL)
        {
@@ -3044,6 +2987,7 @@ riscv_merge_attributes (bfd *ibfd, struct bfd_link_info *info)
   obj_attribute *in_attr;
   obj_attribute *out_attr;
   bfd_boolean result = TRUE;
+  bfd_boolean priv_attrs_merged = FALSE;
   const char *sec_name = get_elf_backend_data (ibfd)->obj_attrs_section;
   unsigned int i;
 
@@ -3098,20 +3042,78 @@ riscv_merge_attributes (bfd *ibfd, struct bfd_link_info *info)
              out_attr[Tag_RISCV_arch].s = merged_arch;
          }
        break;
+
       case Tag_RISCV_priv_spec:
       case Tag_RISCV_priv_spec_minor:
       case Tag_RISCV_priv_spec_revision:
-       if (out_attr[i].i != in_attr[i].i)
+       /* If we have handled the priv attributes, then skip it.  */
+       if (!priv_attrs_merged)
          {
-           _bfd_error_handler
-             (_("error: %pB: conflicting priv spec version "
-                "(major/minor/revision)."), ibfd);
-           result = FALSE;
+           unsigned int Tag_a = Tag_RISCV_priv_spec;
+           unsigned int Tag_b = Tag_RISCV_priv_spec_minor;
+           unsigned int Tag_c = Tag_RISCV_priv_spec_revision;
+           enum riscv_priv_spec_class in_priv_spec;
+           enum riscv_priv_spec_class out_priv_spec;
+
+           /* Get the priv spec class from elf attribute numbers.  */
+           riscv_get_priv_spec_class_from_numbers (in_attr[Tag_a].i,
+                                                   in_attr[Tag_b].i,
+                                                   in_attr[Tag_c].i,
+                                                   &in_priv_spec);
+           riscv_get_priv_spec_class_from_numbers (out_attr[Tag_a].i,
+                                                   out_attr[Tag_b].i,
+                                                   out_attr[Tag_c].i,
+                                                   &out_priv_spec);
+
+           /* Allow to link the object without the priv specs.  */
+           if (out_priv_spec == PRIV_SPEC_CLASS_NONE)
+             {
+               out_attr[Tag_a].i = in_attr[Tag_a].i;
+               out_attr[Tag_b].i = in_attr[Tag_b].i;
+               out_attr[Tag_c].i = in_attr[Tag_c].i;
+             }
+           else if (in_priv_spec != PRIV_SPEC_CLASS_NONE
+                    && in_priv_spec != out_priv_spec)
+             {
+               _bfd_error_handler
+                 (_("warning: %pB use privilege spec version %u.%u.%u but "
+                    "the output use version %u.%u.%u."),
+                  ibfd,
+                  in_attr[Tag_a].i,
+                  in_attr[Tag_b].i,
+                  in_attr[Tag_c].i,
+                  out_attr[Tag_a].i,
+                  out_attr[Tag_b].i,
+                  out_attr[Tag_c].i);
+
+               /* The priv spec v1.9.1 can be linked with other spec
+                  versions since the conflicts.  We plan to drop the
+                  v1.9.1 in a year or two, so this confict should be
+                  removed in the future.  */
+               if (in_priv_spec == PRIV_SPEC_CLASS_1P9P1
+                   || out_priv_spec == PRIV_SPEC_CLASS_1P9P1)
+                 {
+                   _bfd_error_handler
+                     (_("warning: privilege spec version 1.9.1 can not be "
+                        "linked with other spec versions."));
+                 }
+
+               /* Update the output priv attributes to the newest.  */
+               if (in_priv_spec > out_priv_spec)
+                 {
+                   out_attr[Tag_a].i = in_attr[Tag_a].i;
+                   out_attr[Tag_b].i = in_attr[Tag_b].i;
+                   out_attr[Tag_c].i = in_attr[Tag_c].i;
+                 }
+             }
+           priv_attrs_merged = TRUE;
          }
        break;
+
       case Tag_RISCV_unaligned_access:
        out_attr[i].i |= in_attr[i].i;
        break;
+
       case Tag_RISCV_stack_align:
        if (out_attr[i].i == 0)
          out_attr[i].i = in_attr[i].i;
@@ -3126,6 +3128,7 @@ riscv_merge_attributes (bfd *ibfd, struct bfd_link_info *info)
            result = FALSE;
          }
        break;
+
       default:
        result &= _bfd_elf_merge_unknown_attribute_low (ibfd, obfd, i);
       }
This page took 0.057152 seconds and 4 git commands to generate.