From 2dc8dd17cd595bd7a1b0824c83380af52e633fc1 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Wed, 16 Jan 2019 13:14:59 -0800 Subject: RISC-V: Support ELF attribute for gas and readelf. 2019-01-16 Kito Cheng Nelson Chu bfd/ * elfnn-riscv.c (riscv_elf_obj_attrs_arg_type): New. (elf_backend_obj_attrs_vendor): Define. (elf_backend_obj_attrs_section_type): Likewise. (elf_backend_obj_attrs_section): Likewise. (elf_backend_obj_attrs_arg_type): Define as riscv_elf_obj_attrs_arg_type. * elfxx-riscv.c (riscv_estimate_digit): New. (riscv_estimate_arch_strlen1): Likewise. (riscv_estimate_arch_strlen): Likewise. (riscv_arch_str1): Likewise. (riscv_arch_str): Likewise. * elfxx-riscv.h (riscv_arch_str): Declare. binutils/ * readelf.c (get_riscv_section_type_name): New function. (get_section_type_name): Add handler for RISC-V. (riscv_attr_tag_t): Declare. (riscv_attr_tag): New. (display_riscv_attribute): New function. (process_attributes): Add handler for RISC-V. * testsuite/binutils-all/strip-3.d: Remove .riscv.attribute section. gas/ * config/tc-riscv.c (DEFAULT_RISCV_ATTR): Define to 0 if not defined. (riscv_set_options): Add `arch_attr` field. (riscv_opts): Set default value for arch_attr. (riscv_write_out_arch_attr): New. (riscv_set_public_attributes): Likewise. (riscv_md_end): Likewise. (riscv_convert_symbolic_attribute): Likewise. (s_riscv_attribute): Likewise. (explicit_arch_attr): Likewise. (riscv_pseudo_table): Add .attribute to the table. (options): Add OPTION_ARCH_ATTR and OPTION_NO_ARCH_ATTR enumeration constants. (md_longopts): Add `march-attr' and `mno-arch-attr' options. (md_parse_option): Handle the new options. (md_show_usage): Document the `march-attr' option. * config/tc-riscv.h (md_end): Define as riscv_md_end (riscv_md_end): Declare. (CONVERT_SYMBOLIC_ATTRIBUTE): Define as riscv_convert_symbolic_attribute. (riscv_convert_symbolic_attribute): Declare. (start_assemble): Declare. * testsuite/gas/elf/elf.exp: Adjust test case for section2.e. * testsuite/gas/elf/section2.e-riscv: New. * testsuite/gas/riscv/attribute-01.d: New test * testsuite/gas/riscv/attribute-02.d: Likewise. * testsuite/gas/riscv/attribute-03.d: Likewise. * testsuite/gas/riscv/attribute-04.d: Likewise. * testsuite/gas/riscv/attribute-04.s: Likewise. * testsuite/gas/riscv/attribute-05.d: Likewise. * testsuite/gas/riscv/attribute-05.s: Likewise. * testsuite/gas/riscv/attribute-06.d: Likewise. * testsuite/gas/riscv/attribute-06.s: Likewise. * testsuite/gas/riscv/attribute-07.d: Likewise. * testsuite/gas/riscv/attribute-07.s: Likewise. * testsuite/gas/riscv/attribute-08.d: Likewise. * testsuite/gas/riscv/attribute-08.s: Likewise. * testsuite/gas/riscv/attribute-unknown.d: Likewise. * testsuite/gas/riscv/attribute-unknown.s: Likewise. * testsuite/gas/riscv/empty.l: Likewise. * doc/c-riscv.texi (.attribute): Add documentation. * configure.ac (--enable-default-riscv-attribute): New options. * configure: Re-generate. * config.in: Re-generate. include/ * elf/riscv.h (SHT_RISCV_ATTRIBUTES): Define. (Tag_RISCV_arch): Likewise. (Tag_RISCV_priv_spec): Likewise. (Tag_RISCV_priv_spec_minor): Likewise. (Tag_RISCV_priv_spec_revision): Likewise. (Tag_RISCV_unaligned_access): Likewise. (Tag_RISCV_stack_align): Likewise. --- bfd/ChangeLog | 16 ++++++++++ bfd/elfnn-riscv.c | 17 +++++++++++ bfd/elfxx-riscv.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ bfd/elfxx-riscv.h | 3 ++ 4 files changed, 125 insertions(+) (limited to 'bfd') diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5e943a1..cea6d70 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,19 @@ +2019-01-16 Kito Cheng + Nelson Chu + + * elfnn-riscv.c (riscv_elf_obj_attrs_arg_type): New. + (elf_backend_obj_attrs_vendor): Define. + (elf_backend_obj_attrs_section_type): Likewise. + (elf_backend_obj_attrs_section): Likewise. + (elf_backend_obj_attrs_arg_type): Define as + riscv_elf_obj_attrs_arg_type. + * elfxx-riscv.c (riscv_estimate_digit): New. + (riscv_estimate_arch_strlen1): Likewise. + (riscv_estimate_arch_strlen): Likewise. + (riscv_arch_str1): Likewise. + (riscv_arch_str): Likewise. + * elfxx-riscv.h (riscv_arch_str): Declare. + 2019-01-14 John Darrington * bfd-in2.h [BFD_RELOC_S12Z_OPR]: New reloc. diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 78ab051..5430f61 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -3654,6 +3654,14 @@ riscv_elf_object_p (bfd *abfd) return TRUE; } +/* Determine whether an object attribute tag takes an integer, a + string or both. */ + +static int +riscv_elf_obj_attrs_arg_type (int tag) +{ + return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL; +} #define TARGET_LITTLE_SYM riscv_elfNN_vec #define TARGET_LITTLE_NAME "elfNN-littleriscv" @@ -3696,4 +3704,13 @@ riscv_elf_object_p (bfd *abfd) #define elf_backend_rela_normal 1 #define elf_backend_default_execstack 0 +#undef elf_backend_obj_attrs_vendor +#define elf_backend_obj_attrs_vendor "riscv" +#undef elf_backend_obj_attrs_arg_type +#define elf_backend_obj_attrs_arg_type riscv_elf_obj_attrs_arg_type +#undef elf_backend_obj_attrs_section_type +#define elf_backend_obj_attrs_section_type SHT_RISCV_ATTRIBUTES +#undef elf_backend_obj_attrs_section +#define elf_backend_obj_attrs_section ".riscv.attributes" + #include "elfNN-target.h" diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index 535ba7b..29592db 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -1484,3 +1484,92 @@ riscv_release_subset_list (riscv_subset_list_t *subset_list) subset_list->tail = NULL; } + +/* Return the number of digits for the input. */ + +static size_t +riscv_estimate_digit (unsigned num) +{ + size_t digit = 0; + if (num == 0) + return 1; + + for (digit = 0; num ; num /= 10) + digit++; + + return digit; +} + +/* Auxiliary function to estimate string length of subset list. */ + +static size_t +riscv_estimate_arch_strlen1 (const riscv_subset_t *subset) +{ + if (subset == NULL) + return 6; /* For rv32/rv64/rv128 and string terminator. */ + + return riscv_estimate_arch_strlen1 (subset->next) + + strlen (subset->name) + + riscv_estimate_digit (subset->major_version) + + 1 /* For version seperator: 'p'. */ + + riscv_estimate_digit (subset->minor_version) + + 1 /* For underscore. */; +} + +/* Estimate the string length of this subset list. */ + +static size_t +riscv_estimate_arch_strlen (const riscv_subset_list_t *subset_list) +{ + return riscv_estimate_arch_strlen1 (subset_list->head); +} + +/* Auxiliary function to convert subset info to string. */ + +static void +riscv_arch_str1 (riscv_subset_t *subset, + char *attr_str, char *buf, size_t bufsz) +{ + const char *underline = "_"; + + if (subset == NULL) + return; + + /* No underline between rvXX and i/e. */ + if ((strcasecmp (subset->name, "i") == 0) + || (strcasecmp (subset->name, "e") == 0)) + underline = ""; + + snprintf (buf, bufsz, "%s%s%dp%d", + underline, + subset->name, + subset->major_version, + subset->minor_version); + + strncat (attr_str, buf, bufsz); + + /* Skip 'i' extension after 'e'. */ + if ((strcasecmp (subset->name, "e") == 0) + && subset->next + && (strcasecmp (subset->next->name, "i") == 0)) + riscv_arch_str1 (subset->next->next, attr_str, buf, bufsz); + else + riscv_arch_str1 (subset->next, attr_str, buf, bufsz); +} + +/* Convert subset info to string with explicit version info. */ + +char * +riscv_arch_str (unsigned xlen, const riscv_subset_list_t *subset) +{ + size_t arch_str_len = riscv_estimate_arch_strlen (subset); + char *attr_str = xmalloc (arch_str_len); + char *buf = xmalloc (arch_str_len); + + snprintf (attr_str, arch_str_len, "rv%u", xlen); + + riscv_arch_str1 (subset->head, attr_str, buf, arch_str_len); + free (buf); + + return attr_str; +} diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h index 03b4484..19f7bd2 100644 --- a/bfd/elfxx-riscv.h +++ b/bfd/elfxx-riscv.h @@ -83,3 +83,6 @@ riscv_supported_std_ext (void); extern void riscv_release_subset_list (riscv_subset_list_t *); + +extern char * +riscv_arch_str (unsigned, const riscv_subset_list_t *); -- cgit v1.1