[committed] RISC-V: Support STO_RISCV_VARIANT_CC and DT_RISCV_VARIANT_CC.

Message ID 1637287130-27402-1-git-send-email-nelson.chu@sifive.com
State New
Headers show
Series
  • [committed] RISC-V: Support STO_RISCV_VARIANT_CC and DT_RISCV_VARIANT_CC.
Related show

Commit Message

Nelson Chu Nov. 19, 2021, 1:58 a.m.
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.
---
 bfd/elfnn-riscv.c                             | 44 +++++++++++++++-
 binutils/readelf.c                            | 39 ++++++++++++++
 gas/config/tc-riscv.c                         | 55 +++++++++++++++++++
 gas/config/tc-riscv.h                         |  4 ++
 gas/testsuite/gas/riscv/variant_cc-set.d      | 13 +++++
 gas/testsuite/gas/riscv/variant_cc-set.s      | 15 ++++++
 gas/testsuite/gas/riscv/variant_cc.d          |  9 ++++
 gas/testsuite/gas/riscv/variant_cc.s          |  5 ++
 include/elf/riscv.h                           |  6 +++
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp    |  3 ++
 ld/testsuite/ld-riscv-elf/variant_cc-1.s      | 61 +++++++++++++++++++++
 ld/testsuite/ld-riscv-elf/variant_cc-2.s      | 61 +++++++++++++++++++++
 ld/testsuite/ld-riscv-elf/variant_cc-now.d    | 73 +++++++++++++++++++++++++
 ld/testsuite/ld-riscv-elf/variant_cc-r.d      | 76 +++++++++++++++++++++++++++
 ld/testsuite/ld-riscv-elf/variant_cc-shared.d | 73 +++++++++++++++++++++++++
 15 files changed, 536 insertions(+), 1 deletion(-)
 create mode 100644 gas/testsuite/gas/riscv/variant_cc-set.d
 create mode 100644 gas/testsuite/gas/riscv/variant_cc-set.s
 create mode 100644 gas/testsuite/gas/riscv/variant_cc.d
 create mode 100644 gas/testsuite/gas/riscv/variant_cc.s
 create mode 100644 ld/testsuite/ld-riscv-elf/variant_cc-1.s
 create mode 100644 ld/testsuite/ld-riscv-elf/variant_cc-2.s
 create mode 100644 ld/testsuite/ld-riscv-elf/variant_cc-now.d
 create mode 100644 ld/testsuite/ld-riscv-elf/variant_cc-r.d
 create mode 100644 ld/testsuite/ld-riscv-elf/variant_cc-shared.d

-- 
2.7.4

Patch

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 36cbf1e..d8c9066 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -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
 
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 116f879..2e7d285 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -2443,6 +2443,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)
 {
   static char buff[64];
@@ -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);
@@ -12644,6 +12658,28 @@  get_ppc64_symbol_other (unsigned int other)
 }
 
 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)
 {
   const char * result = NULL;
@@ -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;
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 7cc2063..930cfb2 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -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 },
 };
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index d035eed..fbe5e76 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -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
index 0000000..1b01836
--- /dev/null
+++ b/gas/testsuite/gas/riscv/variant_cc-set.d
@@ -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
index 0000000..7b9878d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/variant_cc-set.s
@@ -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
index 0000000..8c1b96a
--- /dev/null
+++ b/gas/testsuite/gas/riscv/variant_cc.d
@@ -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
index 0000000..e4b27f5
--- /dev/null
+++ b/gas/testsuite/gas/riscv/variant_cc.s
@@ -0,0 +1,5 @@ 
+	.text
+	.variant_cc foo
+	.variant_cc func
+func:
+	call	foo
diff --git a/include/elf/riscv.h b/include/elf/riscv.h
index 8082283..6edcf8a 100644
--- a/include/elf/riscv.h
+++ b/include/elf/riscv.h
@@ -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.  */
 
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
index 78a7134..3bd7882 100644
--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
@@ -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
index 0000000..54ae162
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/variant_cc-1.s
@@ -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
index 0000000..d7ca2d4
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/variant_cc-2.s
@@ -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
index 0000000..9453554
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/variant_cc-now.d
@@ -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
index 0000000..5235b8e
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/variant_cc-r.d
@@ -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
index 0000000..ffb69a3
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/variant_cc-shared.d
@@ -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
+#...