RISC-V: Support STO_RISCV_VARIANT_CC and DT_RISCV_VARIANT_CC.

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.
This commit is contained in:
Nelson Chu 2021-08-11 01:26:39 -07:00
parent fccf4ba5ad
commit 8155b8539b
15 changed files with 536 additions and 1 deletions

View 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;