diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 16 | ||||
-rw-r--r-- | bfd/elfnn-riscv.c | 17 | ||||
-rw-r--r-- | bfd/elfxx-riscv.c | 89 | ||||
-rw-r--r-- | bfd/elfxx-riscv.h | 3 |
4 files changed, 125 insertions, 0 deletions
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 <kito@andestech.com> + Nelson Chu <nelson@andestech.com> + + * 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 <john@darrington.wattle.id.au> * 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 *); |