aboutsummaryrefslogtreecommitdiff
path: root/binutils/readelf.c
diff options
context:
space:
mode:
authorNelson Chu <nelson.chu@sifive.com>2021-08-11 01:26:39 -0700
committerNelson Chu <nelson.chu@sifive.com>2021-11-19 09:32:19 +0800
commit8155b8539b55bca87378129e02009cd8907d8c8c (patch)
tree30524e98925e912c02387ae7b2bd0c58b9bb6ff4 /binutils/readelf.c
parentfccf4ba5adaf69cac1875a194d8ee99dabf50c70 (diff)
downloadgdb-8155b8539b55bca87378129e02009cd8907d8c8c.zip
gdb-8155b8539b55bca87378129e02009cd8907d8c8c.tar.gz
gdb-8155b8539b55bca87378129e02009cd8907d8c8c.tar.bz2
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.
Diffstat (limited to 'binutils/readelf.c')
-rw-r--r--binutils/readelf.c39
1 files changed, 39 insertions, 0 deletions
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;