/* 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. */
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
{
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
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
#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
}
}
+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)
{
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);
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)
{
case EM_PPC64:
result = get_ppc64_symbol_other (other);
break;
+ case EM_RISCV:
+ result = get_riscv_symbol_other (other);
+ break;
default:
result = NULL;
break;
}
}
+/* 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[] =
{
{"sleb128", s_riscv_leb128, 1},
{"insn", s_riscv_insn, 0},
{"attribute", s_riscv_attribute, 0},
+ {"variant_cc", s_variant_cc, 0},
{ NULL, NULL, 0 },
};
#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 */
--- /dev/null
+#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
+#...
--- /dev/null
+ .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
--- /dev/null
+#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
+#...
--- /dev/null
+ .text
+ .variant_cc foo
+ .variant_cc func
+func:
+ call foo
/* 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. */
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]]
--- /dev/null
+.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
--- /dev/null
+.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
--- /dev/null
+#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
+#...
--- /dev/null
+#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
+#...
--- /dev/null
+#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
+#...