From 2dc8dd17cd595bd7a1b0824c83380af52e633fc1 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Wed, 16 Jan 2019 13:14:59 -0800 Subject: [PATCH] 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 + binutils/ChangeLog | 12 ++ binutils/readelf.c | 100 +++++++++++++++ binutils/testsuite/binutils-all/strip-3.d | 2 +- gas/ChangeLog | 47 ++++++++ gas/config.in | 4 + gas/config/tc-riscv.c | 127 ++++++++++++++++++++ gas/config/tc-riscv.h | 6 + gas/configure | 34 +++++- gas/configure.ac | 25 ++++ gas/doc/c-riscv.texi | 53 ++++++++ gas/testsuite/gas/elf/elf.exp | 17 ++- gas/testsuite/gas/elf/section2.e-riscv | 9 ++ gas/testsuite/gas/riscv/attribute-01.d | 6 + gas/testsuite/gas/riscv/attribute-02.d | 6 + gas/testsuite/gas/riscv/attribute-03.d | 6 + gas/testsuite/gas/riscv/attribute-04.d | 6 + gas/testsuite/gas/riscv/attribute-04.s | 1 + gas/testsuite/gas/riscv/attribute-05.d | 11 ++ gas/testsuite/gas/riscv/attribute-05.s | 6 + gas/testsuite/gas/riscv/attribute-06.d | 6 + gas/testsuite/gas/riscv/attribute-06.s | 1 + gas/testsuite/gas/riscv/attribute-07.d | 6 + gas/testsuite/gas/riscv/attribute-07.s | 1 + gas/testsuite/gas/riscv/attribute-08.d | 6 + gas/testsuite/gas/riscv/attribute-08.s | 1 + gas/testsuite/gas/riscv/attribute-unknown.d | 8 ++ gas/testsuite/gas/riscv/attribute-unknown.s | 2 + gas/testsuite/gas/riscv/empty.l | 1 + include/ChangeLog | 10 ++ include/elf/riscv.h | 16 +++ 34 files changed, 654 insertions(+), 7 deletions(-) create mode 100644 gas/testsuite/gas/elf/section2.e-riscv create mode 100644 gas/testsuite/gas/riscv/attribute-01.d create mode 100644 gas/testsuite/gas/riscv/attribute-02.d create mode 100644 gas/testsuite/gas/riscv/attribute-03.d create mode 100644 gas/testsuite/gas/riscv/attribute-04.d create mode 100644 gas/testsuite/gas/riscv/attribute-04.s create mode 100644 gas/testsuite/gas/riscv/attribute-05.d create mode 100644 gas/testsuite/gas/riscv/attribute-05.s create mode 100644 gas/testsuite/gas/riscv/attribute-06.d create mode 100644 gas/testsuite/gas/riscv/attribute-06.s create mode 100644 gas/testsuite/gas/riscv/attribute-07.d create mode 100644 gas/testsuite/gas/riscv/attribute-07.s create mode 100644 gas/testsuite/gas/riscv/attribute-08.d create mode 100644 gas/testsuite/gas/riscv/attribute-08.s create mode 100644 gas/testsuite/gas/riscv/attribute-unknown.d create mode 100644 gas/testsuite/gas/riscv/attribute-unknown.s create mode 100644 gas/testsuite/gas/riscv/empty.l diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5e943a1e809..cea6d704d37 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 78ab0519e88..5430f61a7b8 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 535ba7ba985..29592db9781 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 03b448424d7..19f7bd2ecc9 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 *); diff --git a/binutils/ChangeLog b/binutils/ChangeLog index de167f078b3..bec3ddcd138 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,15 @@ +2019-01-16 Kito Cheng + Nelson Chu + + * 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. + 2019-01-10 Nick Clifton PR 23963 diff --git a/binutils/readelf.c b/binutils/readelf.c index 56b80ccc9fb..b13eb6a43ba 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -4204,6 +4204,16 @@ get_v850_section_type_name (unsigned int sh_type) } } +static const char * +get_riscv_section_type_name (unsigned int sh_type) +{ + switch (sh_type) + { + case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES"; + default: return NULL; + } +} + static const char * get_section_type_name (Filedata * filedata, unsigned int sh_type) { @@ -4284,6 +4294,9 @@ get_section_type_name (Filedata * filedata, unsigned int sh_type) case EM_CYGNUS_V850: result = get_v850_section_type_name (sh_type); break; + case EM_RISCV: + result = get_riscv_section_type_name (sh_type); + break; default: result = NULL; break; @@ -15362,6 +15375,88 @@ display_msp430x_attribute (unsigned char * p, return p; } +struct riscv_attr_tag_t { + const char *name; + int tag; +}; + +static struct riscv_attr_tag_t riscv_attr_tag[] = +{ +#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag} + T(arch), + T(priv_spec), + T(priv_spec_minor), + T(priv_spec_revision), + T(unaligned_access), + T(stack_align), +#undef T +}; + +static unsigned char * +display_riscv_attribute (unsigned char *p, + const unsigned char * const end) +{ + unsigned int len; + int val; + int tag; + struct riscv_attr_tag_t *attr = NULL; + unsigned i; + + tag = read_uleb128 (p, &len, end); + p += len; + + /* Find the name of attribute. */ + for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++) + { + if (riscv_attr_tag[i].tag == tag) + { + attr = &riscv_attr_tag[i]; + break; + } + } + + if (attr) + printf (" %s: ", attr->name); + else + return display_tag_value (tag, p, end); + + switch (tag) + { + case Tag_RISCV_priv_spec: + case Tag_RISCV_priv_spec_minor: + case Tag_RISCV_priv_spec_revision: + val = read_uleb128 (p, &len, end); + p += len; + printf (_("%d\n"), val); + break; + case Tag_RISCV_unaligned_access: + val = read_uleb128 (p, &len, end); + p += len; + switch (val) + { + case 0: + printf (_("No unaligned access\n")); + break; + case 1: + printf (_("Unaligned access\n")); + break; + } + break; + case Tag_RISCV_stack_align: + val = read_uleb128 (p, &len, end); + p += len; + printf (_("%d-bytes\n"), val); + break; + case Tag_RISCV_arch: + p = display_tag_value (-1, p, end); + break; + default: + return display_tag_value (tag, p, end); + } + + return p; +} + static bfd_boolean process_attributes (Filedata * filedata, const char * public_name, @@ -18896,6 +18991,11 @@ process_arch_specific (Filedata * filedata) display_msp430x_attribute, display_generic_attribute); + case EM_RISCV: + return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES, + display_riscv_attribute, + display_generic_attribute); + case EM_NDS32: return process_nds32_specific (filedata); diff --git a/binutils/testsuite/binutils-all/strip-3.d b/binutils/testsuite/binutils-all/strip-3.d index 8a375d81dc0..2a886d2dcc6 100644 --- a/binutils/testsuite/binutils-all/strip-3.d +++ b/binutils/testsuite/binutils-all/strip-3.d @@ -1,6 +1,6 @@ #PROG: strip #source: empty.s -#strip: -R .text -R .data -R .bss -R .ARM.attributes -R .reginfo -R .gnu.attributes -R .MIPS.abiflags -R .pdr -R .xtensa.info -R .ARC.attributes -R .note.gnu.property +#strip: -R .text -R .data -R .bss -R .ARM.attributes -R .reginfo -R .gnu.attributes -R .MIPS.abiflags -R .pdr -R .xtensa.info -R .ARC.attributes -R .note.gnu.property -R .riscv.attributes #readelf: -S --wide #name: strip empty file #target: *-*-linux* *-*-gnu* arm*-*-uclinuxfdpiceabi diff --git a/gas/ChangeLog b/gas/ChangeLog index 2fd79ba65ca..3228342d4b7 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,50 @@ +2019-01-16 Kito Cheng + Nelson Chu + + * 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. + 2019-01-16 John Darrington * config/tc-s12z.c (lex_reg_name): Compare the length of the strings diff --git a/gas/config.in b/gas/config.in index 9c15a070a33..e4c55700afb 100644 --- a/gas/config.in +++ b/gas/config.in @@ -50,6 +50,10 @@ /* Define to 1 if you want to generate x86 relax relocations by default. */ #undef DEFAULT_GENERATE_X86_RELAX_RELOCATIONS +/* Define to 1 if you want to generate RISC-V arch attribute by default. + */ +#undef DEFAULT_RISCV_ATTR + /* Define to 1 if you want to generate GNU x86 used ISA and feature properties by default. */ #undef DEFAULT_X86_USED_NOTE diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index 31b0b1ba8e1..993161568ff 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -59,6 +59,10 @@ struct riscv_cl_insn #define DEFAULT_ARCH "riscv64" #endif +#ifndef DEFAULT_RISCV_ATTR +#define DEFAULT_RISCV_ATTR 0 +#endif + static const char default_arch[] = DEFAULT_ARCH; static unsigned xlen = 0; /* width of an x-register */ @@ -78,6 +82,7 @@ struct riscv_set_options int rvc; /* Generate RVC code. */ int rve; /* Generate RVE code. */ int relax; /* Emit relocs the linker is allowed to relax. */ + int arch_attr; /* Emit arch attribute. */ }; static struct riscv_set_options riscv_opts = @@ -86,6 +91,7 @@ static struct riscv_set_options riscv_opts = 0, /* rvc */ 0, /* rve */ 1, /* relax */ + DEFAULT_RISCV_ATTR, /* arch_attr */ }; static void @@ -170,6 +176,12 @@ const char EXP_CHARS[] = "eE"; /* or 0d1.2345e12 */ const char FLT_CHARS[] = "rRsSfFdDxXpP"; +/* Indicate we are already assemble any instructions or not. */ +static bfd_boolean start_assemble = FALSE; + +/* Indicate arch attribute is explictly set. */ +static bfd_boolean explicit_arch_attr = FALSE; + /* Macros for encoding relaxation state for RVC branches and far jumps. */ #define RELAX_BRANCH_ENCODE(uncond, rvc, length) \ ((relax_substateT) \ @@ -2097,6 +2109,8 @@ md_assemble (char *str) const char *error = riscv_ip (str, &insn, &imm_expr, &imm_reloc, op_hash); + start_assemble = TRUE; + if (error) { as_bad ("%s `%s'", error, str); @@ -2131,6 +2145,8 @@ enum options OPTION_MABI, OPTION_RELAX, OPTION_NO_RELAX, + OPTION_ARCH_ATTR, + OPTION_NO_ARCH_ATTR, OPTION_END_OF_ENUM }; @@ -2143,6 +2159,8 @@ struct option md_longopts[] = {"mabi", required_argument, NULL, OPTION_MABI}, {"mrelax", no_argument, NULL, OPTION_RELAX}, {"mno-relax", no_argument, NULL, OPTION_NO_RELAX}, + {"march-attr", no_argument, NULL, OPTION_ARCH_ATTR}, + {"mno-arch-attr", no_argument, NULL, OPTION_NO_ARCH_ATTR}, {NULL, no_argument, NULL, 0} }; @@ -2213,6 +2231,14 @@ md_parse_option (int c, const char *arg) riscv_opts.relax = FALSE; break; + case OPTION_ARCH_ATTR: + riscv_opts.arch_attr = TRUE; + break; + + case OPTION_NO_ARCH_ATTR: + riscv_opts.arch_attr = FALSE; + break; + default: return 0; } @@ -2948,6 +2974,8 @@ RISC-V options:\n\ -mabi=ABI set the RISC-V ABI\n\ -mrelax enable relax (default)\n\ -mno-relax disable relax\n\ + -march-attr generate RISC-V arch attribute\n\ + -mno-arch-attr don't generate RISC-V arch attribute\n\ ")); } @@ -3031,6 +3059,104 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED) demand_empty_rest_of_line (); } +/* Update arch attributes. */ + +static void +riscv_write_out_arch_attr (void) +{ + const char *arch_str = riscv_arch_str (xlen, &riscv_subsets); + + bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, arch_str); + + xfree ((void *)arch_str); +} + +/* Add the default contents for the .riscv.attributes section. */ + +static void +riscv_set_public_attributes (void) +{ + if (riscv_opts.arch_attr || explicit_arch_attr) + /* Re-write arch attribute to normalize the arch string. */ + riscv_write_out_arch_attr (); +} + +/* Called after all assembly has been done. */ + +void +riscv_md_end (void) +{ + riscv_set_public_attributes (); +} + +/* Given a symbolic attribute NAME, return the proper integer value. + Returns -1 if the attribute is not known. */ + +int +riscv_convert_symbolic_attribute (const char *name) +{ + static const struct + { + const char * name; + const int tag; + } + attribute_table[] = + { + /* When you modify this table you should + also modify the list in doc/c-riscv.texi. */ +#define T(tag) {#tag, Tag_RISCV_##tag}, {"Tag_RISCV_" #tag, Tag_RISCV_##tag} + T(arch), + T(priv_spec), + T(priv_spec_minor), + T(priv_spec_revision), + T(unaligned_access), + T(stack_align), +#undef T + }; + + unsigned int i; + + if (name == NULL) + return -1; + + for (i = 0; i < ARRAY_SIZE (attribute_table); i++) + if (strcmp (name, attribute_table[i].name) == 0) + return attribute_table[i].tag; + + return -1; +} + +/* Parse a .attribute directive. */ + +static void +s_riscv_attribute (int ignored ATTRIBUTE_UNUSED) +{ + int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC); + + if (tag == Tag_RISCV_arch) + { + unsigned old_xlen = xlen; + + explicit_arch_attr = TRUE; + obj_attribute *attr; + attr = elf_known_obj_attributes_proc (stdoutput); + if (!start_assemble) + riscv_set_arch (attr[Tag_RISCV_arch].s); + else + as_fatal (_(".attribute arch must set before any instructions")); + + if (old_xlen != xlen) + { + /* We must re-init bfd again if xlen is changed. */ + unsigned long mach = xlen == 64 ? bfd_mach_riscv64 : bfd_mach_riscv32; + bfd_find_target (riscv_target_format (), stdoutput); + + if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, mach)) + as_warn (_("Could not set architecture and machine")); + } + } +} + /* Pseudo-op table. */ static const pseudo_typeS riscv_pseudo_table[] = @@ -3046,6 +3172,7 @@ static const pseudo_typeS riscv_pseudo_table[] = {"uleb128", s_riscv_leb128, 0}, {"sleb128", s_riscv_leb128, 1}, {"insn", s_riscv_insn, 0}, + {"attribute", s_riscv_attribute, 0}, { NULL, NULL, 0 }, }; diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h index 7548bff9e7c..e1dd508c30b 100644 --- a/gas/config/tc-riscv.h +++ b/gas/config/tc-riscv.h @@ -120,4 +120,10 @@ extern void riscv_elf_final_processing (void); /* Adjust debug_line after relaxation. */ #define DWARF2_USE_FIXED_ADVANCE_PC 1 +#define md_end riscv_md_end +#define CONVERT_SYMBOLIC_ATTRIBUTE riscv_convert_symbolic_attribute + +extern void riscv_md_end (void); +extern int riscv_convert_symbolic_attribute (const char *); + #endif /* TC_RISCV */ diff --git a/gas/configure b/gas/configure index ea85e1b43a3..64de9f19da5 100755 --- a/gas/configure +++ b/gas/configure @@ -809,6 +809,7 @@ enable_x86_relax_relocations enable_elf_stt_common enable_generate_build_notes enable_x86_used_note +enable_default_riscv_attribute enable_werror enable_build_warnings with_cpu @@ -1471,6 +1472,8 @@ Optional Features: generate GNU Build notes if none are provided by the input --enable-x86-used-note generate GNU x86 used ISA and feature properties + --enable-default-riscv-attribute + generate RISC-V arch attribute by default --enable-werror treat compile warnings as errors --enable-build-warnings enable build-time compiler warnings --disable-nls do not use Native Language Support @@ -11337,7 +11340,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11340 "configure" +#line 11343 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11443,7 +11446,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11446 "configure" +#line 11449 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12125,6 +12128,16 @@ if test "${enable_x86_used_note+set}" = set; then : esac fi +# Decide if the RISC-V ELF assembler should default to generating attribute. +ac_default_generate_riscv_attr=unset +# Provide a configuration option to override the default. +# Check whether --enable-default-riscv-attribute was given. +if test "${enable_default_riscv_attribute+set}" = set; then : + enableval=$enable_default_riscv_attribute; case "${enableval}" in + yes) ac_default_generate_riscv_attr=1 ;; + no) ac_default_generate_riscv_attr=0 ;; +esac +fi using_cgen=no @@ -13102,6 +13115,23 @@ cat >>confdefs.h <<_ACEOF _ACEOF +if test ${ac_default_generate_riscv_attr} = unset; then + case ${target_os} in + elf) + ac_default_generate_riscv_attr=1 + ;; + *) + ac_default_generate_riscv_attr=0 + ;; + esac +fi + + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_RISCV_ATTR $ac_default_generate_riscv_attr +_ACEOF + + if test x$ac_default_compressed_debug_sections = xyes ; then $as_echo "#define DEFAULT_FLAG_COMPRESS_DEBUG 1" >>confdefs.h diff --git a/gas/configure.ac b/gas/configure.ac index 2fe9f78608c..105d708253a 100644 --- a/gas/configure.ac +++ b/gas/configure.ac @@ -125,6 +125,16 @@ AC_ARG_ENABLE(x86-used-note, no) ac_default_generate_x86_used_note=0 ;; esac])dnl +# Decide if the RISC-V ELF assembler should default to generating attribute. +ac_default_generate_riscv_attr=unset +# Provide a configuration option to override the default. +AC_ARG_ENABLE(default-riscv-attribute, + AS_HELP_STRING([--enable-default-riscv-attribute], + [generate RISC-V arch attribute by default]), +[case "${enableval}" in + yes) ac_default_generate_riscv_attr=1 ;; + no) ac_default_generate_riscv_attr=0 ;; +esac])dnl using_cgen=no @@ -663,6 +673,21 @@ AC_DEFINE_UNQUOTED(DEFAULT_X86_USED_NOTE, [Define to 1 if you want to generate GNU x86 used ISA and feature properties by default.]) +if test ${ac_default_generate_riscv_attr} = unset; then + case ${target_os} in + elf) + ac_default_generate_riscv_attr=1 + ;; + *) + ac_default_generate_riscv_attr=0 + ;; + esac +fi + +AC_DEFINE_UNQUOTED(DEFAULT_RISCV_ATTR, + $ac_default_generate_riscv_attr, + [Define to 1 if you want to generate RISC-V arch attribute by default.]) + if test x$ac_default_compressed_debug_sections = xyes ; then AC_DEFINE(DEFAULT_FLAG_COMPRESS_DEBUG, 1, [Define if you want compressed debug sections by default.]) fi diff --git a/gas/doc/c-riscv.texi b/gas/doc/c-riscv.texi index 74f626f8018..42d1ce3e5f3 100644 --- a/gas/doc/c-riscv.texi +++ b/gas/doc/c-riscv.texi @@ -18,6 +18,7 @@ * RISC-V-Options:: RISC-V Options * RISC-V-Directives:: RISC-V Directives * RISC-V-Formats:: RISC-V Instruction Formats +* RISC-V-ATTRIBUTE:: RISC-V Object Attribute @end menu @node RISC-V-Options @@ -168,6 +169,15 @@ instruction formats for @samp{.insn} (@ref{RISC-V-Formats}). For example, the instruction @samp{add a0, a1, a2} could be written as @samp{.insn r 0x33, 0, 0, a0, a1, a2}. +@cindex @code{.attribute} directive, RISC-V +@item .attribute @var{tag}, @var{value} +Set the object attribute @var{tag} to @var{value}. + +The @var{tag} is either an attribute number, or one of the following: +@code{Tag_RISCV_arch}, @code{Tag_RISCV_stack_align}, +@code{Tag_RISCV_unaligned_access}, @code{Tag_RISCV_priv_spec}, +@code{Tag_RISCV_priv_spec_minor}, @code{Tag_RISCV_priv_spec_revision}. + @end table @node RISC-V-Formats @@ -409,3 +419,46 @@ with the @samp{.insn} pseudo directive: For the complete list of all instruction format variants see The RISC-V Instruction Set Manual Volume I: User-Level ISA. + +@node RISC-V-ATTRIBUTE +@section RISC-V Object Attribute +@cindex Object Attribute, RISC-V + +RISC-V attributes have a string value if the tag number is odd and an integer +value if the tag number is even. + +@table @r +@item Tag_RISCV_stack_align (4) +Tag_RISCV_strict_align records the N-byte stack alignment for this object. The +default value is 16 for RV32I or RV64I, and 4 for RV32E. + +The smallest value will be used if object files with different +Tag_RISCV_stack_align values are merged. + +@item Tag_RISCV_arch (5) +Tag_RISCV_arch contains a string for the target architecture taken from the +option @option{-march}. Different architectures will be integrated into a +superset when object files are merged. + +Note that the version information of the target architecture must be presented +explicitly in the attribute and abbreviations must be expanded. The version +information, if not given by @option{-march}, must be in accordance with the +default specified by the tool. For example, the architecture @code{RV32I} has +to be recorded in the attribute as @code{RV32I2P0} in which @code{2P0} stands +for the default version of its base ISA. On the other hand, the architecture +@code{RV32G} has to be presented as @code{RV32I2P0_M2P0_A2P0_F2P0_D2P0} in +which the abbreviation @code{G} is expanded to the @code{IMAFD} combination +with default versions of the standard extensions. + +@item Tag_RISCV_unaligned_access (6) +Tag_RISCV_unaligned_access is 0 for files that do not allow any unaligned +memory accesses, and 1 for files that do allow unaligned memory accesses. + +@item Tag_RISCV_priv_spec (8) +@item Tag_RISCV_priv_spec_minor (10) +@item Tag_RISCV_priv_spec_revision (12) +Tag_RISCV_priv_spec contains the major/minor/revision version information of +the privileged specification. It will report errors if object files of +different privileged specification versions are merged. + +@end table diff --git a/gas/testsuite/gas/elf/elf.exp b/gas/testsuite/gas/elf/elf.exp index efd24f8b18e..d616d5de766 100644 --- a/gas/testsuite/gas/elf/elf.exp +++ b/gas/testsuite/gas/elf/elf.exp @@ -76,6 +76,9 @@ if { [is_elf_format] } then { if {[istarget "rx-*-*"]} then { set target_machine -rx } + if {[istarget "riscv*-*-*"]} then { + set target_machine -riscv + } if {[istarget "v850*-*-*"]} then { set target_machine -v850 } @@ -170,10 +173,16 @@ if { [is_elf_format] } then { if {! [istarget "h8300-*-*"]} then { # The h8300 port issues a warning message for # new sections created without atrributes. - if { [istarget "i*86-*-*"] || [istarget "x86_64-*-*"] } then { - run_elf_list_test "section2" "$target_machine" "-al -mx86-used-note=no" "-s" "" - } { - run_elf_list_test "section2" "$target_machine" "-al" "-s" "" + case $target_triplet in { + { i*86-*-* x86_64-*-* } { + run_elf_list_test "section2" "$target_machine" "-al -mx86-used-note=no" "-s" "" + } + { riscv*-*-* } { + run_elf_list_test "section2" "$target_machine" "-al -march-attr" "-s" "" + } + default { + run_elf_list_test "section2" "$target_machine" "-al" "-s" "" + } } } run_dump_test "section3" diff --git a/gas/testsuite/gas/elf/section2.e-riscv b/gas/testsuite/gas/elf/section2.e-riscv new file mode 100644 index 00000000000..115bae2173d --- /dev/null +++ b/gas/testsuite/gas/elf/section2.e-riscv @@ -0,0 +1,9 @@ + +Symbol table '.symtab' contains 6 entries: + +Num: +Value +Size +Type +Bind +Vis +Ndx +Name + +0: 0+0 +0 +NOTYPE +LOCAL +DEFAULT +UND + +1: 0+0 +0 +SECTION +LOCAL +DEFAULT +1 + +2: 0+0 +0 +SECTION +LOCAL +DEFAULT +2 + +3: 0+0 +0 +SECTION +LOCAL +DEFAULT +3 + +4: 0+0 +0 +SECTION +LOCAL +DEFAULT +4 + +5: 0+0 +0 +SECTION +LOCAL +DEFAULT +5 diff --git a/gas/testsuite/gas/riscv/attribute-01.d b/gas/testsuite/gas/riscv/attribute-01.d new file mode 100644 index 00000000000..e22773e22b8 --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-01.d @@ -0,0 +1,6 @@ +#as: -march=rv32g -march-attr +#readelf: -A +#source: empty.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv32i2p0_m2p0_a2p0_f2p0_d2p0" diff --git a/gas/testsuite/gas/riscv/attribute-02.d b/gas/testsuite/gas/riscv/attribute-02.d new file mode 100644 index 00000000000..bc3295be7ef --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-02.d @@ -0,0 +1,6 @@ +#as: -march=rv32gxargle -march-attr +#readelf: -A +#source: empty.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv32i2p0_m2p0_a2p0_f2p0_d2p0_xargle2p0" diff --git a/gas/testsuite/gas/riscv/attribute-03.d b/gas/testsuite/gas/riscv/attribute-03.d new file mode 100644 index 00000000000..78b706a73ad --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-03.d @@ -0,0 +1,6 @@ +#as: -march=rv32gxargle_xfoo -march-attr +#readelf: -A +#source: empty.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv32i2p0_m2p0_a2p0_f2p0_d2p0_xargle2p0_xfoo2p0" diff --git a/gas/testsuite/gas/riscv/attribute-04.d b/gas/testsuite/gas/riscv/attribute-04.d new file mode 100644 index 00000000000..c97bf03d5e4 --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-04.d @@ -0,0 +1,6 @@ +#as: -march-attr +#readelf: -A +#source: attribute-04.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv32i2p0_m2p0_a2p0_f2p0_d2p0" diff --git a/gas/testsuite/gas/riscv/attribute-04.s b/gas/testsuite/gas/riscv/attribute-04.s new file mode 100644 index 00000000000..26362277022 --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-04.s @@ -0,0 +1 @@ + .attribute arch,"rv32g" diff --git a/gas/testsuite/gas/riscv/attribute-05.d b/gas/testsuite/gas/riscv/attribute-05.d new file mode 100644 index 00000000000..f9b65f206b7 --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-05.d @@ -0,0 +1,11 @@ +#as: -march-attr +#readelf: -A +#source: attribute-05.s +Attribute Section: riscv +File Attributes + Tag_RISCV_stack_align: 16-bytes + Tag_RISCV_arch: "rv32i2p0_m2p0_a2p0_f2p0_d2p0" + Tag_RISCV_unaligned_access: Unaligned access + Tag_RISCV_priv_spec: 1 + Tag_RISCV_priv_spec_minor: 2 + Tag_RISCV_priv_spec_revision: 3 diff --git a/gas/testsuite/gas/riscv/attribute-05.s b/gas/testsuite/gas/riscv/attribute-05.s new file mode 100644 index 00000000000..3b3b7f6d561 --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-05.s @@ -0,0 +1,6 @@ + .attribute arch, "rv32g" + .attribute priv_spec, 1 + .attribute priv_spec_minor, 2 + .attribute priv_spec_revision, 3 + .attribute unaligned_access, 1 + .attribute stack_align, 16 diff --git a/gas/testsuite/gas/riscv/attribute-06.d b/gas/testsuite/gas/riscv/attribute-06.d new file mode 100644 index 00000000000..1abeb47383d --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-06.d @@ -0,0 +1,6 @@ +#as: -march=rv32g2p0 -march-attr +#readelf: -A +#source: attribute-06.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv32i2p0" diff --git a/gas/testsuite/gas/riscv/attribute-06.s b/gas/testsuite/gas/riscv/attribute-06.s new file mode 100644 index 00000000000..de50251e908 --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-06.s @@ -0,0 +1 @@ + .attribute arch, "rv32i" diff --git a/gas/testsuite/gas/riscv/attribute-07.d b/gas/testsuite/gas/riscv/attribute-07.d new file mode 100644 index 00000000000..dfd7e6bd6e5 --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-07.d @@ -0,0 +1,6 @@ +#as: -march=rv64g2p0 -march-attr +#readelf: -A +#source: attribute-07.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv64i2p0" diff --git a/gas/testsuite/gas/riscv/attribute-07.s b/gas/testsuite/gas/riscv/attribute-07.s new file mode 100644 index 00000000000..35e6ae3f2ed --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-07.s @@ -0,0 +1 @@ + .attribute arch, "rv64i" diff --git a/gas/testsuite/gas/riscv/attribute-08.d b/gas/testsuite/gas/riscv/attribute-08.d new file mode 100644 index 00000000000..c10ac0ca353 --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-08.d @@ -0,0 +1,6 @@ +#as: -march-attr +#readelf: -A +#source: attribute-08.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: "rv32e1p9" diff --git a/gas/testsuite/gas/riscv/attribute-08.s b/gas/testsuite/gas/riscv/attribute-08.s new file mode 100644 index 00000000000..44e7a8da746 --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-08.s @@ -0,0 +1 @@ + .attribute arch, "rv32e1p9" diff --git a/gas/testsuite/gas/riscv/attribute-unknown.d b/gas/testsuite/gas/riscv/attribute-unknown.d new file mode 100644 index 00000000000..667f21acfc1 --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-unknown.d @@ -0,0 +1,8 @@ +#as: -march-attr +#readelf: -A +#source: attribute-unknown.s +Attribute Section: riscv +File Attributes + Tag_RISCV_arch: [a-zA-Z0-9_\"].* + Tag_unknown_255: "test" + Tag_unknown_256: 123 \(0x7b\) diff --git a/gas/testsuite/gas/riscv/attribute-unknown.s b/gas/testsuite/gas/riscv/attribute-unknown.s new file mode 100644 index 00000000000..7e63a35551e --- /dev/null +++ b/gas/testsuite/gas/riscv/attribute-unknown.s @@ -0,0 +1,2 @@ + .attribute 255, "test" + .attribute 256, 123 diff --git a/gas/testsuite/gas/riscv/empty.l b/gas/testsuite/gas/riscv/empty.l new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/gas/testsuite/gas/riscv/empty.l @@ -0,0 +1 @@ + diff --git a/include/ChangeLog b/include/ChangeLog index e49dbbd06a7..45f52af0eb1 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,13 @@ +2019-01-16 Kito Cheng + + * 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. + 2019-01-14 Pavel I. Kryukov * dis-asm.h: include diff --git a/include/elf/riscv.h b/include/elf/riscv.h index 7b10929443a..2f98aa4a3e0 100644 --- a/include/elf/riscv.h +++ b/include/elf/riscv.h @@ -116,4 +116,20 @@ END_RELOC_NUMBERS (R_RISCV_max) /* The name of the global pointer symbol. */ #define RISCV_GP_SYMBOL "__global_pointer$" +/* Additional section types. */ +#define SHT_RISCV_ATTRIBUTES 0x70000003 /* Section holds attributes. */ + +/* Object attributes. */ + +enum +{ + /* 0-3 are generic. */ + Tag_RISCV_stack_align = 4, + Tag_RISCV_arch = 5, + Tag_RISCV_unaligned_access = 6, + Tag_RISCV_priv_spec = 8, + Tag_RISCV_priv_spec_minor = 10, + Tag_RISCV_priv_spec_revision = 12 +}; + #endif /* _ELF_RISCV_H */ -- 2.30.2