RISC-V: Support STO_RISCV_VARIANT_CC and DT_RISCV_VARIANT_CC.
authorNelson Chu <nelson.chu@sifive.com>
Wed, 11 Aug 2021 08:26:39 +0000 (01:26 -0700)
committerNelson Chu <nelson.chu@sifive.com>
Fri, 19 Nov 2021 01:32:19 +0000 (09:32 +0800)
This is the original discussion,
https://github.com/riscv/riscv-elf-psabi-doc/pull/190

And here is the glibc part,
https://sourceware.org/pipermail/libc-alpha/2021-August/129931.html

For binutils part, we need to support a new direcitve: .variant_cc.
The function symbol marked by .variant_cc means it need to be resolved
directly without resolver for dynamic linker.  We also add a new dynamic
entry, STO_RISCV_VARIANT_CC, to indicate there are symbols with the
special attribute in the dynamic symbol table of the object.

I heard that llvm already have supported this in their mainline, so
I think it's time to commit this.

bfd/
* elfnn-riscv.c (riscv_elf_link_hash_table): Added variant_cc
flag. It is used to check if relocations for variant CC symbols
may be present.
(allocate_dynrelocs): If the symbol has STO_RISCV_VARIANT_CC
flag, then raise the variant_cc flag of riscv_elf_link_hash_table.
(riscv_elf_size_dynamic_sections): Added dynamic entry for
variant_cc.
(riscv_elf_merge_symbol_attribute): New function, used to merge
non-visibility st_other attributes, including STO_RISCV_VARIANT_CC.
binutils/
* readelf.c (get_riscv_dynamic_type): New function.
(get_dynamic_type): Called get_riscv_dynamic_type for riscv targets.
(get_riscv_symbol_other): New function.
(get_symbol_other): Called get_riscv_symbol_other for riscv targets.
gas/
* config/tc-riscv.c (s_variant_cc): Marked symbol that it follows a
variant CC convention.
(riscv_elf_copy_symbol_attributes): Same as elf_copy_symbol_attributes,
but without copying st_other.  If a function symbol has special st_other
value set via directives, then attaching an IFUNC resolver to that symbol
should not override the st_other setting.
(riscv_pseudo_table): Support variant_cc diretive.
* config/tc-riscv.h (OBJ_COPY_SYMBOL_ATTRIBUTES): Defined.
* testsuite/gas/riscv/variant_cc-set.d: New testcase.
* testsuite/gas/riscv/variant_cc-set.s: Likewise.
* testsuite/gas/riscv/variant_cc.d: Likewise.
* testsuite/gas/riscv/variant_cc.s: Likewise.
include/
* elf/riscv.h (DT_RISCV_VARIANT_CC): Defined to (DT_LOPROC + 1).
(STO_RISCV_VARIANT_CC): Defined to 0x80.
ld/
* testsuite/ld-riscv-elf/variant_cc-1.s: New testcase.
* testsuite/ld-riscv-elf/variant_cc-2.s: Likewise.
* testsuite/ld-riscv-elf/variant_cc-now.d: Likewise.
* testsuite/ld-riscv-elf/variant_cc-r.d: Likewise.
* testsuite/ld-riscv-elf/variant_cc-shared.d: Likewise.
* testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.

15 files changed:
bfd/elfnn-riscv.c
binutils/readelf.c
gas/config/tc-riscv.c
gas/config/tc-riscv.h
gas/testsuite/gas/riscv/variant_cc-set.d [new file with mode: 0644]
gas/testsuite/gas/riscv/variant_cc-set.s [new file with mode: 0644]
gas/testsuite/gas/riscv/variant_cc.d [new file with mode: 0644]
gas/testsuite/gas/riscv/variant_cc.s [new file with mode: 0644]
include/elf/riscv.h
ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
ld/testsuite/ld-riscv-elf/variant_cc-1.s [new file with mode: 0644]
ld/testsuite/ld-riscv-elf/variant_cc-2.s [new file with mode: 0644]
ld/testsuite/ld-riscv-elf/variant_cc-now.d [new file with mode: 0644]
ld/testsuite/ld-riscv-elf/variant_cc-r.d [new file with mode: 0644]
ld/testsuite/ld-riscv-elf/variant_cc-shared.d [new file with mode: 0644]

index 36cbf1ed15f5fd100f46396744926516265ec8cc..d8c9066ad4841ce286246e40e8c570263d637ce0 100644 (file)
@@ -134,6 +134,9 @@ struct riscv_elf_link_hash_table
   /* The data segment phase, don't relax the section
      when it is exp_seg_relro_adjust.  */
   int *data_segment_phase;
+
+  /* Relocations for variant CC symbols may be present.  */
+  int variant_cc;
 };
 
 /* Instruction access functions. */
@@ -1172,6 +1175,11 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
              h->root.u.def.section = s;
              h->root.u.def.value = h->plt.offset;
            }
+
+         /* If the symbol has STO_RISCV_VARIANT_CC flag, then raise the
+            variant_cc flag of riscv_elf_link_hash_table.  */
+         if (h->other & STO_RISCV_VARIANT_CC)
+           htab->variant_cc = 1;
        }
       else
        {
@@ -1555,7 +1563,18 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
        return false;
     }
 
-  return _bfd_elf_add_dynamic_tags (output_bfd, info, true);
+  /* Add dynamic entries.  */
+  if (elf_hash_table (info)->dynamic_sections_created)
+    {
+      if (!_bfd_elf_add_dynamic_tags (output_bfd, info, true))
+       return false;
+
+      if (htab->variant_cc
+         && !_bfd_elf_add_dynamic_entry (info, DT_RISCV_VARIANT_CC, 0))
+       return false;
+    }
+
+  return true;
 }
 
 #define TP_OFFSET 0
@@ -5227,6 +5246,28 @@ riscv_elf_modify_segment_map (bfd *abfd,
   return true;
 }
 
+/* Merge non-visibility st_other attributes.  */
+
+static void
+riscv_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
+                                 unsigned int st_other,
+                                 bool definition ATTRIBUTE_UNUSED,
+                                 bool dynamic ATTRIBUTE_UNUSED)
+{
+  unsigned int isym_sto = st_other & ~ELF_ST_VISIBILITY (-1);
+  unsigned int h_sto = h->other & ~ELF_ST_VISIBILITY (-1);
+
+  if (isym_sto == h_sto)
+    return;
+
+  if (isym_sto & ~STO_RISCV_VARIANT_CC)
+    _bfd_error_handler (_("unknown attribute for symbol `%s': 0x%02x"),
+                       h->root.root.string, isym_sto);
+
+  if (isym_sto & STO_RISCV_VARIANT_CC)
+    h->other |= STO_RISCV_VARIANT_CC;
+}
+
 #define TARGET_LITTLE_SYM                      riscv_elfNN_vec
 #define TARGET_LITTLE_NAME                     "elfNN-littleriscv"
 #define TARGET_BIG_SYM                         riscv_elfNN_be_vec
@@ -5263,6 +5304,7 @@ riscv_elf_modify_segment_map (bfd *abfd,
 #define elf_backend_additional_program_headers \
   riscv_elf_additional_program_headers
 #define elf_backend_modify_segment_map         riscv_elf_modify_segment_map
+#define elf_backend_merge_symbol_attribute     riscv_elf_merge_symbol_attribute
 
 #define elf_backend_init_index_section         _bfd_elf_init_1_index_section
 
index 116f879c892a05e3297332c17194a5d1a540f659..2e7d28511fb0626782ad4fd9cb151b1a1320ae73 100644 (file)
@@ -2442,6 +2442,17 @@ get_solaris_dynamic_type (unsigned long type)
     }
 }
 
+static const char *
+get_riscv_dynamic_type (unsigned long type)
+{
+  switch (type)
+    {
+    case DT_RISCV_VARIANT_CC:  return "RISCV_VARIANT_CC";
+    default:
+      return NULL;
+    }
+}
+
 static const char *
 get_dynamic_type (Filedata * filedata, unsigned long type)
 {
@@ -2567,6 +2578,9 @@ get_dynamic_type (Filedata * filedata, unsigned long type)
            case EM_ALTERA_NIOS2:
              result = get_nios2_dynamic_type (type);
              break;
+           case EM_RISCV:
+             result = get_riscv_dynamic_type (type);
+             break;
            default:
              if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
                result = get_solaris_dynamic_type (type);
@@ -12643,6 +12657,28 @@ get_ppc64_symbol_other (unsigned int other)
   return NULL;
 }
 
+static const char *
+get_riscv_symbol_other (unsigned int other)
+{
+  static char buf[32];
+  buf[0] = 0;
+
+  if (other & STO_RISCV_VARIANT_CC)
+    {
+      strcat (buf, _(" VARIANT_CC"));
+      other &= ~STO_RISCV_VARIANT_CC;
+    }
+
+  if (other != 0)
+    snprintf (buf, sizeof buf, " %x", other);
+
+
+  if (buf[0] != 0)
+    return buf + 1;
+  else
+    return buf;
+}
+
 static const char *
 get_symbol_other (Filedata * filedata, unsigned int other)
 {
@@ -12669,6 +12705,9 @@ get_symbol_other (Filedata * filedata, unsigned int other)
     case EM_PPC64:
       result = get_ppc64_symbol_other (other);
       break;
+    case EM_RISCV:
+      result = get_riscv_symbol_other (other);
+      break;
     default:
       result = NULL;
       break;
index 7cc2063b198db5d696fa63b3a40d0a14e36ae29e..930cfb2125a3c2f36bc10cbca42a0eb74ccd29db 100644 (file)
@@ -4411,6 +4411,60 @@ s_riscv_attribute (int ignored ATTRIBUTE_UNUSED)
     }
 }
 
+/* Mark symbol that it follows a variant CC convention.  */
+
+static void
+s_variant_cc (int ignored ATTRIBUTE_UNUSED)
+{
+  char *name;
+  char c;
+  symbolS *sym;
+  asymbol *bfdsym;
+  elf_symbol_type *elfsym;
+
+  c = get_symbol_name (&name);
+  if (!*name)
+    as_bad (_("missing symbol name for .variant_cc directive"));
+  sym = symbol_find_or_make (name);
+  restore_line_pointer (c);
+  demand_empty_rest_of_line ();
+
+  bfdsym = symbol_get_bfdsym (sym);
+  elfsym = elf_symbol_from (bfdsym);
+  gas_assert (elfsym);
+  elfsym->internal_elf_sym.st_other |= STO_RISCV_VARIANT_CC;
+}
+
+/* Same as elf_copy_symbol_attributes, but without copying st_other.
+   This is needed so RISC-V specific st_other values can be independently
+   specified for an IFUNC resolver (that is called by the dynamic linker)
+   and the symbol it resolves (aliased to the resolver).  In particular,
+   if a function symbol has special st_other value set via directives,
+   then attaching an IFUNC resolver to that symbol should not override
+   the st_other setting.  Requiring the directive on the IFUNC resolver
+   symbol would be unexpected and problematic in C code, where the two
+   symbols appear as two independent function declarations.  */
+
+void
+riscv_elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
+{
+  struct elf_obj_sy *srcelf = symbol_get_obj (src);
+  struct elf_obj_sy *destelf = symbol_get_obj (dest);
+  if (srcelf->size)
+    {
+      if (destelf->size == NULL)
+       destelf->size = XNEW (expressionS);
+      *destelf->size = *srcelf->size;
+    }
+  else
+    {
+      if (destelf->size != NULL)
+       free (destelf->size);
+      destelf->size = NULL;
+    }
+  S_SET_SIZE (dest, S_GET_SIZE (src));
+}
+
 /* RISC-V pseudo-ops table.  */
 static const pseudo_typeS riscv_pseudo_table[] =
 {
@@ -4425,6 +4479,7 @@ static const pseudo_typeS riscv_pseudo_table[] =
   {"sleb128", s_riscv_leb128, 1},
   {"insn", s_riscv_insn, 0},
   {"attribute", s_riscv_attribute, 0},
+  {"variant_cc", s_variant_cc, 0},
 
   { NULL, NULL, 0 },
 };
index d035eed8a93eb9a484d582d6a9377ad3970abedc..fbe5e765042577ed5c403804898c25ab7e145d5a 100644 (file)
@@ -152,4 +152,8 @@ extern void riscv_init_frag (struct frag *, int);
 #define obj_adjust_symtab() riscv_adjust_symtab ()
 extern void riscv_adjust_symtab (void);
 
+void riscv_elf_copy_symbol_attributes (symbolS *, symbolS *);
+#define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST, SRC)  \
+  riscv_elf_copy_symbol_attributes (DEST, SRC)
+
 #endif /* TC_RISCV */
diff --git a/gas/testsuite/gas/riscv/variant_cc-set.d b/gas/testsuite/gas/riscv/variant_cc-set.d
new file mode 100644 (file)
index 0000000..1b01836
--- /dev/null
@@ -0,0 +1,13 @@
+#as:
+#source: variant_cc-set.s
+#readelf: -Ws
+
+#...
+[      ]+[0-9a-f]+:[   ]+0+[   ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+foo
+#...
+[      ]+[0-9a-f]+:[   ]+0+[   ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+1[    ]+bar
+#...
+[      ]+[0-9a-f]+:[   ]+0+[   ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+alias_foo
+#...
+[      ]+[0-9a-f]+:[   ]+0+[   ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+1[    ]alias_bar
+#...
diff --git a/gas/testsuite/gas/riscv/variant_cc-set.s b/gas/testsuite/gas/riscv/variant_cc-set.s
new file mode 100644 (file)
index 0000000..7b9878d
--- /dev/null
@@ -0,0 +1,15 @@
+       .text
+       .global foo
+       .global bar
+       .global alias_foo
+       .global alias_bar
+       .variant_cc foo
+       .variant_cc alias_foo
+       .set alias_bar, foo
+       .set alias_foo, bar
+foo:
+bar:
+       call    foo
+       call    bar
+       call    alias_foo
+       call    alias_bar
diff --git a/gas/testsuite/gas/riscv/variant_cc.d b/gas/testsuite/gas/riscv/variant_cc.d
new file mode 100644 (file)
index 0000000..8c1b96a
--- /dev/null
@@ -0,0 +1,9 @@
+#as:
+#source: variant_cc.s
+#readelf: -Ws
+
+#...
+[      ]+[0-9a-f]+:[   ]+0+[   ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+func
+#...
+[      ]+[0-9a-f]+:[   ]+0+[   ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+UND[  ]+foo
+#...
diff --git a/gas/testsuite/gas/riscv/variant_cc.s b/gas/testsuite/gas/riscv/variant_cc.s
new file mode 100644 (file)
index 0000000..e4b27f5
--- /dev/null
@@ -0,0 +1,5 @@
+       .text
+       .variant_cc foo
+       .variant_cc func
+func:
+       call    foo
index 80822835cd9ce888c9aa06b18e8643c901d6b1a3..6edcf8ab901e15f392017f557a8cc76aef2813b6 100644 (file)
@@ -117,6 +117,12 @@ END_RELOC_NUMBERS (R_RISCV_max)
 /* The name of the global pointer symbol.  */
 #define RISCV_GP_SYMBOL "__global_pointer$"
 
+/* Processor specific dynamic array tags.  */
+#define DT_RISCV_VARIANT_CC (DT_LOPROC + 1)
+
+/* RISC-V specific values for st_other.  */
+#define STO_RISCV_VARIANT_CC 0x80
+
 /* Additional section types.  */
 #define SHT_RISCV_ATTRIBUTES 0x70000003 /* Section holds attributes.  */
 
index 78a71345bf288fc0c1be64168f4c1b12f496d51e..3bd788208ed591c64b94316fe4c88df754243111 100644 (file)
@@ -169,6 +169,9 @@ if [istarget "riscv*-*-*"] {
 
     run_dump_test "relro-relax-lui"
     run_dump_test "relro-relax-pcrel"
+    run_dump_test "variant_cc-now"
+    run_dump_test "variant_cc-shared"
+    run_dump_test "variant_cc-r"
     run_relax_twice_test
 
     set abis [list rv32gc ilp32 [riscv_choose_ilp32_emul] rv64gc lp64 [riscv_choose_lp64_emul]]
diff --git a/ld/testsuite/ld-riscv-elf/variant_cc-1.s b/ld/testsuite/ld-riscv-elf/variant_cc-1.s
new file mode 100644 (file)
index 0000000..54ae162
--- /dev/null
@@ -0,0 +1,61 @@
+.text
+
+.variant_cc cc_global_default_def
+.variant_cc cc_global_default_undef
+.variant_cc cc_global_default_ifunc
+.variant_cc cc_global_hidden_def
+.variant_cc cc_global_hidden_ifunc
+.variant_cc cc_local
+.variant_cc cc_local_ifunc
+
+.global cc_global_default_def
+.global cc_global_default_undef
+.global cc_global_default_ifunc
+.global cc_global_hidden_def
+.global cc_global_hidden_ifunc
+.global nocc_global_default_def
+.global nocc_global_default_undef
+.global nocc_global_default_ifunc
+.global nocc_global_hidden_def
+.global nocc_global_hidden_ifunc
+
+.hidden cc_global_hidden_def
+.hidden cc_global_hidden_ifunc
+.hidden nocc_global_hidden_def
+.hidden nocc_global_hidden_ifunc
+
+.type cc_global_default_ifunc, %gnu_indirect_function
+.type cc_global_hidden_ifunc, %gnu_indirect_function
+.type cc_local_ifunc, %gnu_indirect_function
+.type nocc_global_default_ifunc, %gnu_indirect_function
+.type nocc_global_hidden_ifunc, %gnu_indirect_function
+.type nocc_local_ifunc, %gnu_indirect_function
+
+cc_global_default_def:
+# cc_global_default_undef:
+cc_global_hidden_def:
+cc_global_default_ifunc:
+cc_global_hidden_ifunc:
+cc_local:
+cc_local_ifunc:
+nocc_global_default_def:
+# nocc_global_default_undef:
+nocc_global_hidden_def:
+nocc_global_default_ifunc:
+nocc_global_hidden_ifunc:
+nocc_local:
+nocc_local_ifunc:
+       call cc_global_default_def
+       call cc_global_default_undef
+       call cc_global_hidden_def
+       call cc_global_default_ifunc
+       call cc_global_hidden_ifunc
+       call cc_local
+       call cc_local_ifunc
+       call nocc_global_default_def
+       call nocc_global_default_undef
+       call nocc_global_hidden_def
+       call nocc_global_default_ifunc
+       call nocc_global_hidden_ifunc
+       call nocc_local
+       call nocc_local_ifunc
diff --git a/ld/testsuite/ld-riscv-elf/variant_cc-2.s b/ld/testsuite/ld-riscv-elf/variant_cc-2.s
new file mode 100644 (file)
index 0000000..d7ca2d4
--- /dev/null
@@ -0,0 +1,61 @@
+.text
+
+.variant_cc cc_global_default_def
+.variant_cc cc_global_default_undef
+.variant_cc cc_global_default_ifunc
+.variant_cc cc_global_hidden_def
+.variant_cc cc_global_hidden_ifunc
+.variant_cc cc_local2
+.variant_cc cc_local2_ifunc
+
+.global cc_global_default_def
+.global cc_global_default_undef
+.global cc_global_default_ifunc
+.global cc_global_hidden_def
+.global cc_global_hidden_ifunc
+.global nocc_global_default_def
+.global nocc_global_default_undef
+.global nocc_global_default_ifunc
+.global nocc_global_hidden_def
+.global nocc_global_hidden_ifunc
+
+.hidden cc_global_hidden_def
+.hidden cc_global_hidden_ifunc
+.hidden nocc_global_hidden_def
+.hidden nocc_global_hidden_ifunc
+
+# .type cc_global_default_ifunc, %gnu_indirect_function
+# .type cc_global_hidden_ifunc, %gnu_indirect_function
+.type cc_local2_ifunc, %gnu_indirect_function
+# .type nocc_global_default_ifunc, %gnu_indirect_function
+# .type nocc_global_hidden_ifunc, %gnu_indirect_function
+.type nocc_local2_ifunc, %gnu_indirect_function
+
+# cc_global_default_def:
+# cc_global_default_undef:
+# cc_global_hidden_def:
+# cc_global_default_ifunc:
+# cc_global_hidden_ifunc:
+cc_local2:
+cc_local2_ifunc:
+# nocc_global_default_def:
+# nocc_global_default_undef:
+# nocc_global_hidden_def:
+# nocc_global_default_ifunc:
+# nocc_global_hidden_ifunc:
+nocc_local2:
+nocc_local2_ifunc:
+       call cc_global_default_def
+       call cc_global_default_undef
+       call cc_global_hidden_def
+       call cc_global_default_ifunc
+       call cc_global_hidden_ifunc
+       call cc_local2
+       call cc_local2_ifunc
+       call nocc_global_default_def
+       call nocc_global_default_undef
+       call nocc_global_hidden_def
+       call nocc_global_default_ifunc
+       call nocc_global_hidden_ifunc
+       call nocc_local2
+       call nocc_local2_ifunc
diff --git a/ld/testsuite/ld-riscv-elf/variant_cc-now.d b/ld/testsuite/ld-riscv-elf/variant_cc-now.d
new file mode 100644 (file)
index 0000000..9453554
--- /dev/null
@@ -0,0 +1,73 @@
+#source: variant_cc-1.s
+#source: variant_cc-2.s
+#ld: -shared --hash-style=sysv -Ttext 0x8000 -z now
+#readelf: -rsW
+
+Relocation section '.rela.plt' at .*
+#...
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_JUMP_SLOT[    ]+0+0000[       ]+nocc_global_default_undef \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_JUMP_SLOT[    ]+0+0000[       ]+cc_global_default_undef \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_JUMP_SLOT[    ]+0+8000[       ]+cc_global_default_def \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_JUMP_SLOT[    ]+0+8000[       ]+nocc_global_default_def \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_JUMP_SLOT[    ]+cc_global_default_ifunc\(\)[  ]+cc_global_default_ifunc \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_IRELATIVE[    ]+8000
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_JUMP_SLOT[    ]+nocc_global_default_ifunc\(\)[        ]+nocc_global_default_ifunc \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_IRELATIVE[    ]+8000
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_IRELATIVE[    ]+8050
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_IRELATIVE[    ]+8050
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_IRELATIVE[    ]+8000
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_IRELATIVE[    ]+8000
+#...
+Symbol table '.dynsym' contains .*
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+UND[  ]+nocc_global_default_undef
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+UND[  ]+cc_global_default_undef
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+IFUNC[        ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_global_default_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+IFUNC[        ]+GLOBAL[       ]+DEFAULT[      ]+1[    ]+nocc_global_default_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_global_default_def
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+1[    ]+nocc_global_default_def
+#...
+Symbol table '.symtab' contains .*
+.*
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_local
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+IFUNC[        ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_local_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+IFUNC[        ]+LOCAL[        ]+DEFAULT[      ]+1[    ]+nocc_local_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+1[    ]+nocc_local
+#...
+[      ]+[0-9a-f]+:[   ]+0+8050[       ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_local2
+#...
+[      ]+[0-9a-f]+:[   ]+0+8050[       ]+0[    ]+IFUNC[        ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_local2_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8050[       ]+0[    ]+IFUNC[        ]+LOCAL[        ]+DEFAULT[      ]+1[    ]+nocc_local2_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8050[       ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+1[    ]+nocc_local2
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_global_hidden_def
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+1[    ]+nocc_global_hidden_def
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+IFUNC[        ]+LOCAL[        ]+DEFAULT[      ]+1[    ]+nocc_global_hidden_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+IFUNC[        ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_global_hidden_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+UND[  ]+nocc_global_default_undef
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+UND[  ]+cc_global_default_undef
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+IFUNC[        ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_global_default_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+IFUNC[        ]+GLOBAL[       ]+DEFAULT[      ]+1[    ]+nocc_global_default_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_global_default_def
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+1[    ]+nocc_global_default_def
+#...
diff --git a/ld/testsuite/ld-riscv-elf/variant_cc-r.d b/ld/testsuite/ld-riscv-elf/variant_cc-r.d
new file mode 100644 (file)
index 0000000..5235b8e
--- /dev/null
@@ -0,0 +1,76 @@
+#source: variant_cc-1.s
+#source: variant_cc-2.s
+#as: -mno-relax
+#ld: -r
+#readelf: -rsW
+
+Relocation section '.rela.text' at .*
+#...
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+0+0000[       ]+cc_global_default_def \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+0+0000[       ]+cc_global_default_undef \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+0+0000[       ]+cc_global_hidden_def \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+cc_global_default_ifunc\(\)[  ]+cc_global_default_ifunc \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+cc_global_hidden_ifunc\(\)[   ]+cc_global_hidden_ifunc \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+0+0000[       ]+cc_local \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+cc_local_ifunc\(\)[   ]+cc_local_ifunc \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+0+0000[       ]+nocc_global_default_def \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+0+0000[       ]+nocc_global_default_undef \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+0+0000[       ]+nocc_global_hidden_def \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+nocc_global_default_ifunc\(\)[        ]+nocc_global_default_ifunc \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+nocc_global_hidden_ifunc\(\)[         ]+nocc_global_hidden_ifunc \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+0+0000[       ]+nocc_local \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+nocc_local_ifunc\(\)[         ]+nocc_local_ifunc \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+0+0000[       ]+cc_global_default_def \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+0+0000[       ]+cc_global_default_undef \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+0+0000[       ]+cc_global_hidden_def \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+cc_global_default_ifunc\(\)[  ]+cc_global_default_ifunc \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+cc_global_hidden_ifunc\(\)[   ]+cc_global_hidden_ifunc \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+0+0070[       ]+cc_local2 \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+cc_local2_ifunc\(\)[  ]+cc_local2_ifunc \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+0+0000[       ]+nocc_global_default_def \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+0+0000[       ]+nocc_global_default_undef \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+0+0000[       ]+nocc_global_hidden_def \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+nocc_global_default_ifunc\(\)[        ]+nocc_global_default_ifunc \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+nocc_global_hidden_ifunc\(\)[         ]+nocc_global_hidden_ifunc \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+0+0070[       ]+nocc_local2 \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_CALL[         ]+nocc_local2_ifunc\(\)[        ]+nocc_local2_ifunc \+ 0
+#...
+Symbol table '.symtab' contains .*
+.*
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_local
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+IFUNC[        ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_local_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+IFUNC[        ]+LOCAL[        ]+DEFAULT[      ]+1[    ]+nocc_local_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+1[    ]+nocc_local
+#...
+[      ]+[0-9a-f]+:[   ]+0+0070[       ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_local2
+#...
+[      ]+[0-9a-f]+:[   ]+0+0070[       ]+0[    ]+IFUNC[        ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_local2_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+0070[       ]+0[    ]+IFUNC[        ]+LOCAL[        ]+DEFAULT[      ]+1[    ]+nocc_local2_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+0070[       ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+1[    ]+nocc_local2
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+UND[  ]+nocc_global_default_undef
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+HIDDEN[       ]+\[VARIANT_CC\][       ]+1[    ]+cc_global_hidden_def
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+UND[  ]+cc_global_default_undef
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+IFUNC[        ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_global_default_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+HIDDEN[       ]+1[    ]+nocc_global_hidden_def
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+IFUNC[        ]+GLOBAL[       ]+HIDDEN[       ]+1[    ]+nocc_global_hidden_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+IFUNC[        ]+GLOBAL[       ]+DEFAULT[      ]+1[    ]+nocc_global_default_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_global_default_def
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+1[    ]+nocc_global_default_def
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+IFUNC[        ]+GLOBAL[       ]+HIDDEN[       ]+\[VARIANT_CC\][       ]+1[    ]+cc_global_hidden_ifunc
+#...
diff --git a/ld/testsuite/ld-riscv-elf/variant_cc-shared.d b/ld/testsuite/ld-riscv-elf/variant_cc-shared.d
new file mode 100644 (file)
index 0000000..ffb69a3
--- /dev/null
@@ -0,0 +1,73 @@
+#source: variant_cc-1.s
+#source: variant_cc-2.s
+#ld: -shared --hash-style=sysv -Ttext 0x8000
+#readelf: -rsW
+
+Relocation section '.rela.plt' at .*
+#...
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_JUMP_SLOT[    ]+0+0000[       ]+nocc_global_default_undef \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_JUMP_SLOT[    ]+0+0000[       ]+cc_global_default_undef \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_JUMP_SLOT[    ]+0+8000[       ]+cc_global_default_def \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_JUMP_SLOT[    ]+0+8000[       ]+nocc_global_default_def \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_JUMP_SLOT[    ]+cc_global_default_ifunc\(\)[  ]+cc_global_default_ifunc \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_IRELATIVE[    ]+8000
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_JUMP_SLOT[    ]+nocc_global_default_ifunc\(\)[        ]+nocc_global_default_ifunc \+ 0
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_IRELATIVE[    ]+8000
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_IRELATIVE[    ]+8050
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_IRELATIVE[    ]+8050
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_IRELATIVE[    ]+8000
+[0-9a-f]+[     ]+[0-9a-f]+[    ]+R_RISCV_IRELATIVE[    ]+8000
+#...
+Symbol table '.dynsym' contains .*
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+UND[  ]+nocc_global_default_undef
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+UND[  ]+cc_global_default_undef
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+IFUNC[        ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_global_default_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+IFUNC[        ]+GLOBAL[       ]+DEFAULT[      ]+1[    ]+nocc_global_default_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_global_default_def
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+1[    ]+nocc_global_default_def
+#...
+Symbol table '.symtab' contains .*
+.*
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_local
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+IFUNC[        ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_local_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+IFUNC[        ]+LOCAL[        ]+DEFAULT[      ]+1[    ]+nocc_local_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+1[    ]+nocc_local
+#...
+[      ]+[0-9a-f]+:[   ]+0+8050[       ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_local2
+#...
+[      ]+[0-9a-f]+:[   ]+0+8050[       ]+0[    ]+IFUNC[        ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_local2_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8050[       ]+0[    ]+IFUNC[        ]+LOCAL[        ]+DEFAULT[      ]+1[    ]+nocc_local2_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8050[       ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+1[    ]+nocc_local2
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_global_hidden_def
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+NOTYPE[       ]+LOCAL[        ]+DEFAULT[      ]+1[    ]+nocc_global_hidden_def
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+IFUNC[        ]+LOCAL[        ]+DEFAULT[      ]+1[    ]+nocc_global_hidden_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+IFUNC[        ]+LOCAL[        ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_global_hidden_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+UND[  ]+nocc_global_default_undef
+#...
+[      ]+[0-9a-f]+:[   ]+0+0000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+UND[  ]+cc_global_default_undef
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+IFUNC[        ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_global_default_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+IFUNC[        ]+GLOBAL[       ]+DEFAULT[      ]+1[    ]+nocc_global_default_ifunc
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+\[VARIANT_CC\][       ]+1[    ]+cc_global_default_def
+#...
+[      ]+[0-9a-f]+:[   ]+0+8000[       ]+0[    ]+NOTYPE[       ]+GLOBAL[       ]+DEFAULT[      ]+1[    ]+nocc_global_default_def
+#...