[PATCH] RISC-V: Dump objects according to the elf architecture attribute.

Nelson Chu nelson.chu@sifive.com
Thu Nov 11 09:16:27 GMT 2021


Committed, but set the default architecture string to rv64gc when
dis-assembling objects, to keep the original behavior.

Thanks
Nelson

On Mon, Nov 8, 2021 at 8:22 PM Nelson Chu <nelson.chu@sifive.com> wrote:
>
> For now we should always generate the elf architecture attribute both for
> elf and linux toolchains, so that we could dump the objects correctly
> according to the generated architecture string.  This patch resolves the
> problem that we probably dump an object with c.nop instructions, but
> in fact the c extension isn't allowed.  Consider the following case,
>
> nelson@LAPTOP-QFSGI1F2:~/test$ cat temp.s
> .option norvc
> .option norelax
> .text
> add     a0, a0, a0
> .byte   0x1
> .balign 16
> nelson@LAPTOP-QFSGI1F2:~/test$ ~/binutils-dev/build-elf32-upstream/build-install/bin/riscv32-unknown-elf-as temp.s -o temp.o
> nelson@LAPTOP-QFSGI1F2:~/test$ ~/binutils-dev/build-elf32-upstream/build-install/bin/riscv32-unknown-elf-objdump -d temp.o
>
> temp.o:     file format elf32-littleriscv
>
> Disassembly of section .text:
>
> 00000000 <.text>:
>    0:   00a50533                add     a0,a0,a0
>    4:   01                      .byte   0x01
>    5:   00                      .byte   0x00
>    6:   0001                    nop
>    8:   00000013                nop
>    c:   00000013                nop
> nelson@LAPTOP-QFSGI1F2:~/test$ ~/binutils-dev/build-elf32-upstream/build-install/bin/riscv32-unknown-elf-readelf -A temp.o
> Attribute Section: riscv
> File Attributes
>   Tag_RISCV_arch: "rv32i2p0_m2p0_a2p0_f2p0_d2p0"
>
> The c.nop at address 0x6 is generated for alignment, but since the rvc isn't
> allowed for this object, dump it as a c.nop instruction looks wrong.  After
> applying this patch, I get the following result,
>
> nelson@LAPTOP-QFSGI1F2:~/test$ ~/binutils-dev/build-elf32-upstream/build-install/bin/riscv32-unknown-elf-objdump -d temp.o
>
> temp.o:     file format elf32-littleriscv
>
> Disassembly of section .text:
>
> 00000000 <.text>:
>    0:   00a50533                add     a0,a0,a0
>    4:   01                      .byte   0x01
>    5:   00                      .byte   0x00
>    6:   0001                    .2byte  0x1
>    8:   00000013                nop
>    c:   00000013                nop
>
> For the current objdump, we dump data to .byte/.short/.word/.dword, and
> dump the unknown or unsupported instructions to .2byte/.4byte/.8byte, which
> respectively are 2, 4 and 8 bytes instructions.  Therefore, we shouldn't
> dump the 0x0001 as a c.nop instruction in the above case, we should dump
> it to .2byte 0x1 as a unknown instruction, since the rvc is disabled.
>
> However, consider that some people may use the new objdump to dump the
> old objects, which don't have any elf attributes, we also have a
> default architecture string.  The default string can be set in the
> bfd/elfxx-riscv.c:riscv_set_default_arch.
>
> nelson@LAPTOP-QFSGI1F2:~/test$ cat temp.s
> .option rvc
> nop
> nop
> nelson@LAPTOP-QFSGI1F2:~/test$ ~/binutils-dev/build-elf32-upstream/build-install/bin/riscv32-unknown-elf-as -mno-arch-attr temp.s -o temp.o
> nelson@LAPTOP-QFSGI1F2:~/test$ ~/binutils-dev/build-elf32-upstream/build-install/bin/riscv32-unknown-elf-objdump -d temp.o
>
> temp.o:     file format elf32-littleriscv
>
> Disassembly of section .text:
>
> 00000000 <.text>:
>    0:   0001                    .2byte  0x1
>    2:   0001                    .2byte  0x1
>
> Since we are used to set default architecture string to rv64g without rvc,
> the nops are dumped to .2byte.  This is not the same as before.  So maybe
> we should set the default architecture string to rv64gc?
>
> This patch pass the riscv-gnu-toolchain gcc/binutils regressions for
> rv32emc-elf, rv32gc-linux, rv32i-elf, rv64gc-elf and rv64gc-linux
> toolchains.  Also, tested by --enable-targets=all and can build
> riscv-gdb successfully.
>
> bfd/
>         * elfnn-riscv.c (riscv_merge_arch_attr_info): Tidy the
>         codes for riscv_parse_subset_t setting.
>         * elfxx-riscv.c (riscv_get_default_ext_version): Updated.
>         (riscv_subset_supports): Moved from gas/config/tc-riscv.c.
>         (riscv_multi_subset_supports): Likewise.
>         * elfxx-riscv.h: Added extern for riscv_subset_supports and
>         riscv_multi_subset_supports.
> gas/
>         * config/tc-riscv.c (riscv_subset_supports): Moved to
>         bfd/elfxx-riscv.c.
>         (riscv_multi_subset_supports): Likewise.
>         (riscv_rps_as): Defined for architectrue parser.
>         (riscv_set_arch): Updated.
>         (riscv_set_abi_by_arch): Likewise.
>         (riscv_csr_address): Likewise.
>         (reg_lookup_internal): Likewise.
>         (riscv_ip): Likewise.
>         (s_riscv_option): Updated.
>         * testsuite/gas/riscv/mapping-04b.d: Updated.
>         * testsuite/gas/riscv/mapping-norelax-03b.d: Likewise.
>         * testsuite/gas/riscv/mapping-norelax-04b.d: Likewise.
> opcodes/
>         * riscv-dis.c: Include elfxx-riscv.h since we need the
>         architecture parser.  Also removed the cpu-riscv.h, it
>         is already included in elfxx-riscv.h.
>         (default_isa_spec): Defined since the parser need this
>         to set the default architecture string.
>         (xlen): Moved out from riscv_disassemble_insn as a global
>         variable, it is more convenient to initialize riscv_rps_dis.
>         (riscv_subsets): Defined to recoed the supported
>         extensions.
>         (riscv_rps_dis): Defined for architectrue parser.
>         (riscv_disassemble_insn): Call riscv_multi_subset_supports
>         to make sure if the instructions are valid or not.
>         (print_insn_riscv): Initialize the riscv_subsets by parsing
>         the elf architectrue attribute.  Otherwise, let
>         bfd/elfxx-riscv.c:riscv_set_default_arch to set the default
>         string.
> ---
>  bfd/elfnn-riscv.c                             |  27 ++-----
>  bfd/elfxx-riscv.c                             |  69 +++++++++++++++-
>  bfd/elfxx-riscv.h                             |   8 +-
>  gas/config/tc-riscv.c                         | 110 ++++++--------------------
>  gas/testsuite/gas/riscv/mapping-04b.d         |   4 +-
>  gas/testsuite/gas/riscv/mapping-norelax-03b.d |   2 +-
>  gas/testsuite/gas/riscv/mapping-norelax-04b.d |   4 +-
>  opcodes/riscv-dis.c                           |  32 ++++++--
>  8 files changed, 133 insertions(+), 123 deletions(-)
>
> diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
> index 2bae1e9..36cbf1e 100644
> --- a/bfd/elfnn-riscv.c
> +++ b/bfd/elfnn-riscv.c
> @@ -3574,37 +3574,22 @@ riscv_merge_arch_attr_info (bfd *ibfd, char *in_arch, char *out_arch)
>    merged_subsets.head = NULL;
>    merged_subsets.tail = NULL;
>
> -  riscv_parse_subset_t rpe_in;
> -  riscv_parse_subset_t rpe_out;
> -
> -  /* Only assembler needs to check the default version of ISA, so just set
> -     the rpe_in.get_default_version and rpe_out.get_default_version to NULL.  */
> -  rpe_in.subset_list = &in_subsets;
> -  rpe_in.error_handler = _bfd_error_handler;
> -  rpe_in.xlen = &xlen_in;
> -  rpe_in.isa_spec = ISA_SPEC_CLASS_NONE;
> -  rpe_in.check_unknown_prefixed_ext = false;
> -
> -  rpe_out.subset_list = &out_subsets;
> -  rpe_out.error_handler = _bfd_error_handler;
> -  rpe_out.xlen = &xlen_out;
> -  rpe_out.isa_spec = ISA_SPEC_CLASS_NONE;
> -  rpe_out.check_unknown_prefixed_ext = false;
> +  riscv_parse_subset_t riscv_rps_ld_in =
> +    {&in_subsets, _bfd_error_handler, &xlen_in, NULL, false};
> +  riscv_parse_subset_t riscv_rps_ld_out =
> +    {&out_subsets, _bfd_error_handler, &xlen_out, NULL, false};
>
>    if (in_arch == NULL && out_arch == NULL)
>      return NULL;
> -
>    if (in_arch == NULL && out_arch != NULL)
>      return out_arch;
> -
>    if (in_arch != NULL && out_arch == NULL)
>      return in_arch;
>
>    /* Parse subset from ISA string.  */
> -  if (!riscv_parse_subset (&rpe_in, in_arch))
> +  if (!riscv_parse_subset (&riscv_rps_ld_in, in_arch))
>      return NULL;
> -
> -  if (!riscv_parse_subset (&rpe_out, out_arch))
> +  if (!riscv_parse_subset (&riscv_rps_ld_out, out_arch))
>      return NULL;
>
>    /* Checking XLEN.  */
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index 65bb1ca..3ffbaad 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -1418,12 +1418,14 @@ riscv_add_subset (riscv_subset_list_t *subset_list,
>  /* Get the default versions from the riscv_supported_*ext tables.  */
>
>  static void
> -riscv_get_default_ext_version (enum riscv_spec_class default_isa_spec,
> +riscv_get_default_ext_version (enum riscv_spec_class *default_isa_spec,
>                                const char *name,
>                                int *major_version,
>                                int *minor_version)
>  {
> -  if (name == NULL || default_isa_spec == ISA_SPEC_CLASS_NONE)
> +  if (name == NULL
> +      || default_isa_spec == NULL
> +      || *default_isa_spec == ISA_SPEC_CLASS_NONE)
>      return;
>
>    struct riscv_supported_ext *table = NULL;
> @@ -1445,7 +1447,7 @@ riscv_get_default_ext_version (enum riscv_spec_class default_isa_spec,
>      {
>        if (strcmp (table[i].name, name) == 0
>           && (table[i].isa_spec_class == ISA_SPEC_CLASS_DRAFT
> -             || table[i].isa_spec_class == default_isa_spec))
> +             || table[i].isa_spec_class == *default_isa_spec))
>         {
>           *major_version = table[i].major_version;
>           *minor_version = table[i].minor_version;
> @@ -2095,3 +2097,64 @@ riscv_update_subset (riscv_parse_subset_t *rps,
>    riscv_parse_add_implicit_subsets (rps);
>    return riscv_parse_check_conflicts (rps);
>  }
> +
> +/* Check if the FEATURE subset is supported or not in the subset list.
> +   Return true if it is supported; Otherwise, return false.  */
> +
> +bool
> +riscv_subset_supports (riscv_parse_subset_t *rps,
> +                      const char *feature)
> +{
> +  struct riscv_subset_t *subset;
> +  return riscv_lookup_subset (rps->subset_list, feature, &subset);
> +}
> +
> +/* Each instuction is belonged to an instruction class INSN_CLASS_*.
> +   Call riscv_subset_supports to make sure if the instuction is valid.  */
> +
> +bool
> +riscv_multi_subset_supports (riscv_parse_subset_t *rps,
> +                            enum riscv_insn_class insn_class)
> +{
> +  switch (insn_class)
> +    {
> +    case INSN_CLASS_I:
> +      return riscv_subset_supports (rps, "i");
> +    case INSN_CLASS_ZICSR:
> +      return riscv_subset_supports (rps, "zicsr");
> +    case INSN_CLASS_ZIFENCEI:
> +      return riscv_subset_supports (rps, "zifencei");
> +    case INSN_CLASS_ZIHINTPAUSE:
> +      return riscv_subset_supports (rps, "zihintpause");
> +    case INSN_CLASS_M:
> +      return riscv_subset_supports (rps, "m");
> +    case INSN_CLASS_A:
> +      return riscv_subset_supports (rps, "a");
> +    case INSN_CLASS_F:
> +      return riscv_subset_supports (rps, "f");
> +    case INSN_CLASS_D:
> +      return riscv_subset_supports (rps, "d");
> +    case INSN_CLASS_Q:
> +      return riscv_subset_supports (rps, "q");
> +    case INSN_CLASS_C:
> +      return riscv_subset_supports (rps, "c");
> +    case INSN_CLASS_F_AND_C:
> +      return (riscv_subset_supports (rps, "f")
> +             && riscv_subset_supports (rps, "c"));
> +    case INSN_CLASS_D_AND_C:
> +      return (riscv_subset_supports (rps, "d")
> +             && riscv_subset_supports (rps, "c"));
> +    case INSN_CLASS_ZBA:
> +      return riscv_subset_supports (rps, "zba");
> +    case INSN_CLASS_ZBB:
> +      return riscv_subset_supports (rps, "zbb");
> +    case INSN_CLASS_ZBC:
> +      return riscv_subset_supports (rps, "zbc");
> +    case INSN_CLASS_ZBS:
> +      return riscv_subset_supports (rps, "zbs");
> +    default:
> +      rps->error_handler
> +        (_("internal: unreachable INSN_CLASS_*"));
> +      return false;
> +    }
> +}
> diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h
> index 17620fd..8de9adc 100644
> --- a/bfd/elfxx-riscv.h
> +++ b/bfd/elfxx-riscv.h
> @@ -72,7 +72,7 @@ typedef struct
>    void (*error_handler) (const char *,
>                          ...) ATTRIBUTE_PRINTF_1;
>    unsigned *xlen;
> -  enum riscv_spec_class isa_spec;
> +  enum riscv_spec_class *isa_spec;
>    bool check_unknown_prefixed_ext;
>  } riscv_parse_subset_t;
>
> @@ -95,6 +95,12 @@ riscv_compare_subsets (const char *, const char *);
>  extern bool
>  riscv_update_subset (riscv_parse_subset_t *, const char *, bool);
>
> +extern bool
> +riscv_subset_supports (riscv_parse_subset_t *, const char *);
> +
> +extern bool
> +riscv_multi_subset_supports (riscv_parse_subset_t *, enum riscv_insn_class);
> +
>  extern void
>  bfd_elf32_riscv_set_data_segment_info (struct bfd_link_info *, int *);
>  extern void
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index 90d960a..8cea72a 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -234,77 +234,20 @@ riscv_set_rvc (bool rvc_value)
>     -march option, the elf architecture attributes, and the --with-arch
>     configure option.  */
>  static riscv_subset_list_t riscv_subsets;
> -
> -/* Check if the FEATURE subset is supported or not in the subset list.
> -   Return true if it is supported; Otherwise, return false.  */
> -
> -static bool
> -riscv_subset_supports (const char *feature)
> -{
> -  struct riscv_subset_t *subset;
> -  return riscv_lookup_subset (&riscv_subsets, feature, &subset);
> -}
> -
> -/* Each instuction is belonged to an instruction class INSN_CLASS_*.
> -   Call riscv_subset_supports to make sure if the instuction is valid.  */
> -
> -static bool
> -riscv_multi_subset_supports (enum riscv_insn_class insn_class)
> +static riscv_parse_subset_t riscv_rps_as =
>  {
> -  switch (insn_class)
> -    {
> -    case INSN_CLASS_I:
> -      return riscv_subset_supports ("i");
> -    case INSN_CLASS_ZICSR:
> -      return riscv_subset_supports ("zicsr");
> -    case INSN_CLASS_ZIFENCEI:
> -      return riscv_subset_supports ("zifencei");
> -    case INSN_CLASS_ZIHINTPAUSE:
> -      return riscv_subset_supports ("zihintpause");
> -    case INSN_CLASS_M:
> -      return riscv_subset_supports ("m");
> -    case INSN_CLASS_A:
> -      return riscv_subset_supports ("a");
> -    case INSN_CLASS_F:
> -      return riscv_subset_supports ("f");
> -    case INSN_CLASS_D:
> -      return riscv_subset_supports ("d");
> -    case INSN_CLASS_Q:
> -      return riscv_subset_supports ("q");
> -    case INSN_CLASS_C:
> -      return riscv_subset_supports ("c");
> -    case INSN_CLASS_F_AND_C:
> -      return (riscv_subset_supports ("f")
> -             && riscv_subset_supports ("c"));
> -    case INSN_CLASS_D_AND_C:
> -      return (riscv_subset_supports ("d")
> -             && riscv_subset_supports ("c"));
> -    case INSN_CLASS_ZBA:
> -      return riscv_subset_supports ("zba");
> -    case INSN_CLASS_ZBB:
> -      return riscv_subset_supports ("zbb");
> -    case INSN_CLASS_ZBC:
> -      return riscv_subset_supports ("zbc");
> -    case INSN_CLASS_ZBS:
> -      return riscv_subset_supports ("zbs");
> -    default:
> -      as_fatal ("internal: unreachable");
> -      return false;
> -    }
> -}
> +  &riscv_subsets,      /* subset_list.  */
> +  as_bad,              /* error_handler.  */
> +  &xlen,               /* xlen.  */
> +  &default_isa_spec,   /* isa_spec.  */
> +  true,                        /* check_unknown_prefixed_ext.  */
> +};
>
>  /* Set which ISA and extensions are available.  */
>
>  static void
>  riscv_set_arch (const char *s)
>  {
> -  riscv_parse_subset_t rps;
> -  rps.subset_list = &riscv_subsets;
> -  rps.error_handler = as_bad;
> -  rps.xlen = &xlen;
> -  rps.isa_spec = default_isa_spec;
> -  rps.check_unknown_prefixed_ext = true;
> -
>    if (s != NULL && strcmp (s, "") == 0)
>      {
>        as_bad (_("the architecture string of -march and elf architecture "
> @@ -313,10 +256,10 @@ riscv_set_arch (const char *s)
>      }
>
>    riscv_release_subset_list (&riscv_subsets);
> -  riscv_parse_subset (&rps, s);
> +  riscv_parse_subset (&riscv_rps_as, s);
>
>    riscv_set_rvc (false);
> -  if (riscv_subset_supports ("c"))
> +  if (riscv_subset_supports (&riscv_rps_as, "c"))
>      riscv_set_rvc (true);
>  }
>
> @@ -341,11 +284,11 @@ riscv_set_abi_by_arch (void)
>  {
>    if (!explicit_mabi)
>      {
> -      if (riscv_subset_supports ("q"))
> +      if (riscv_subset_supports (&riscv_rps_as, "q"))
>         riscv_set_abi (xlen, FLOAT_ABI_QUAD, false);
> -      else if (riscv_subset_supports ("d"))
> +      else if (riscv_subset_supports (&riscv_rps_as, "d"))
>         riscv_set_abi (xlen, FLOAT_ABI_DOUBLE, false);
> -      else if (riscv_subset_supports ("e"))
> +      else if (riscv_subset_supports (&riscv_rps_as, "e"))
>         riscv_set_abi (xlen, FLOAT_ABI_SOFT, true);
>        else
>         riscv_set_abi (xlen, FLOAT_ABI_SOFT, false);
> @@ -358,19 +301,19 @@ riscv_set_abi_by_arch (void)
>        else if (abi_xlen < xlen)
>         as_bad ("%d-bit ABI not yet supported on %d-bit ISA", abi_xlen, xlen);
>
> -      if (riscv_subset_supports ("e") && !rve_abi)
> +      if (riscv_subset_supports (&riscv_rps_as, "e") && !rve_abi)
>         as_bad ("only the ilp32e ABI is supported for e extension");
>
>        if (float_abi == FLOAT_ABI_SINGLE
> -         && !riscv_subset_supports ("f"))
> +         && !riscv_subset_supports (&riscv_rps_as, "f"))
>         as_bad ("ilp32f/lp64f ABI can't be used when f extension "
>                 "isn't supported");
>        else if (float_abi == FLOAT_ABI_DOUBLE
> -              && !riscv_subset_supports ("d"))
> +              && !riscv_subset_supports (&riscv_rps_as, "d"))
>         as_bad ("ilp32d/lp64d ABI can't be used when d extension "
>                 "isn't supported");
>        else if (float_abi == FLOAT_ABI_QUAD
> -              && !riscv_subset_supports ("q"))
> +              && !riscv_subset_supports (&riscv_rps_as, "q"))
>         as_bad ("ilp32q/lp64q ABI can't be used when q extension "
>                 "isn't supported");
>      }
> @@ -923,13 +866,13 @@ riscv_csr_address (const char *csr_name,
>    switch (csr_class)
>      {
>      case CSR_CLASS_I:
> -      result = riscv_subset_supports ("i");
> +      result = riscv_subset_supports (&riscv_rps_as, "i");
>        break;
>      case CSR_CLASS_I_32:
> -      result = (xlen == 32 && riscv_subset_supports ("i"));
> +      result = (xlen == 32 && riscv_subset_supports (&riscv_rps_as, "i"));
>        break;
>      case CSR_CLASS_F:
> -      result = riscv_subset_supports ("f");
> +      result = riscv_subset_supports (&riscv_rps_as, "f");
>        need_check_version = false;
>        break;
>      case CSR_CLASS_DEBUG:
> @@ -995,7 +938,7 @@ reg_lookup_internal (const char *s, enum reg_class class)
>    if (r == NULL || DECODE_REG_CLASS (r) != class)
>      return -1;
>
> -  if (riscv_subset_supports ("e")
> +  if (riscv_subset_supports (&riscv_rps_as, "e")
>        && class == RCLASS_GPR
>        && DECODE_REG_NUM (r) > 15)
>      return -1;
> @@ -2061,7 +2004,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
>        if ((insn->xlen_requirement != 0) && (xlen != insn->xlen_requirement))
>         continue;
>
> -      if (!riscv_multi_subset_supports (insn->insn_class))
> +      if (!riscv_multi_subset_supports (&riscv_rps_as, insn->insn_class))
>         continue;
>
>        create_insn (ip, insn);
> @@ -3364,21 +3307,14 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
>    ch = *input_line_pointer;
>    *input_line_pointer = '\0';
>
> -  riscv_parse_subset_t rps;
> -  rps.subset_list = &riscv_subsets;
> -  rps.error_handler = as_bad;
> -  rps.xlen = &xlen;
> -  rps.isa_spec = default_isa_spec;
> -  rps.check_unknown_prefixed_ext = true;
> -
>    if (strcmp (name, "rvc") == 0)
>      {
> -      riscv_update_subset (&rps, "c", false);
> +      riscv_update_subset (&riscv_rps_as, "c", false);
>        riscv_set_rvc (true);
>      }
>    else if (strcmp (name, "norvc") == 0)
>      {
> -      riscv_update_subset (&rps, "c", true);
> +      riscv_update_subset (&riscv_rps_as, "c", true);
>        riscv_set_rvc (false);
>      }
>    else if (strcmp (name, "pic") == 0)
> diff --git a/gas/testsuite/gas/riscv/mapping-04b.d b/gas/testsuite/gas/riscv/mapping-04b.d
> index 9735498..54bd0af 100644
> --- a/gas/testsuite/gas/riscv/mapping-04b.d
> +++ b/gas/testsuite/gas/riscv/mapping-04b.d
> @@ -18,6 +18,6 @@ Disassembly of section .text:
>  [      ]+19:[  ]+20022002[     ]+.word[        ]+0x20022002
>  [      ]+1d:[  ]+2002[         ]+.short[       ]+0x2002
>  [      ]+1f:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
> -[      ]+23:[  ]+0000[         ]+unimp
> -[      ]+25:[  ]+0000[         ]+unimp
> +[      ]+23:[  ]+0000[         ]+.2byte[       ]+0x0
> +[      ]+25:[  ]+0000[         ]+.2byte[       ]+0x0
>  #...
> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03b.d b/gas/testsuite/gas/riscv/mapping-norelax-03b.d
> index ad88888..9e77735 100644
> --- a/gas/testsuite/gas/riscv/mapping-norelax-03b.d
> +++ b/gas/testsuite/gas/riscv/mapping-norelax-03b.d
> @@ -17,7 +17,7 @@ Disassembly of section .text:
>  [      ]+18:[  ]+00000302[     ]+.word[        ]+0x00000302
>  [      ]+1c:[  ]+00[   ]+.byte[        ]+0x00
>  [      ]+1d:[  ]+00[   ]+.byte[        ]+0x00
> -[      ]+1e:[  ]+0001[         ]+nop
> +[      ]+1e:[  ]+0001[         ]+.2byte[       ]+0x1
>  [      ]+20:[  ]+00000005[     ]+.word[        ]+0x00000005
>  [      ]+24:[  ]+00000013[     ]+nop
>  [      ]+28:[  ]+00000013[     ]+nop
> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04b.d b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
> index 824a898..be668f2 100644
> --- a/gas/testsuite/gas/riscv/mapping-norelax-04b.d
> +++ b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
> @@ -13,12 +13,12 @@ Disassembly of section .text:
>  [      ]+8:[   ]+00000001[     ]+.word[        ]+0x00000001
>  [      ]+c:[   ]+00[   ]+.byte[        ]+0x00
>  [      ]+d:[   ]+00[   ]+.byte[        ]+0x00
> -[      ]+e:[   ]+0001[         ]+nop
> +[      ]+e:[   ]+0001[         ]+.2byte[       ]+0x1
>  [      ]+10:[  ]+00a50533[     ]+add[  ]+a0,a0,a0
>  [      ]+14:[  ]+20022002[     ]+.word[        ]+0x20022002
>  [      ]+18:[  ]+20022002[     ]+.word[        ]+0x20022002
>  [      ]+1c:[  ]+2002[         ]+.short[       ]+0x2002
>  [      ]+1e:[  ]+00b585b3[     ]+add[  ]+a1,a1,a1
> -[      ]+22:[  ]+0001[         ]+nop
> +[      ]+22:[  ]+0001[         ]+.2byte[       ]+0x1
>  [      ]+24:[  ]+00000013[     ]+nop
>  #...
> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> index 1a09440..814c959 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -27,13 +27,26 @@
>  #include "opintl.h"
>  #include "elf-bfd.h"
>  #include "elf/riscv.h"
> -#include "cpu-riscv.h"
> +#include "elfxx-riscv.h"
>
>  #include <stdint.h>
>  #include <ctype.h>
>
> +static enum riscv_spec_class default_isa_spec = ISA_SPEC_CLASS_DRAFT - 1;
>  static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;
>
> +unsigned xlen = 0;
> +
> +static riscv_subset_list_t riscv_subsets;
> +static riscv_parse_subset_t riscv_rps_dis =
> +{
> +  &riscv_subsets,      /* subset_list.  */
> +  opcodes_error_handler,/* error_handler.  */
> +  &xlen,               /* xlen.  */
> +  &default_isa_spec,   /* isa_spec.  */
> +  false,               /* check_unknown_prefixed_ext.  */
> +};
> +
>  struct riscv_private_data
>  {
>    bfd_vma gp;
> @@ -502,8 +515,6 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
>    op = riscv_hash[OP_HASH_IDX (word)];
>    if (op != NULL)
>      {
> -      unsigned xlen = 0;
> -
>        /* If XLEN is not known, get its value from the ELF class.  */
>        if (info->mach == bfd_mach_riscv64)
>         xlen = 64;
> @@ -527,6 +538,9 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
>           if ((op->xlen_requirement != 0) && (op->xlen_requirement != xlen))
>             continue;
>
> +         if (!riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class))
> +           continue;
> +
>           /* It's a match.  */
>           (*info->fprintf_func) (info->stream, "%s", op->name);
>           print_insn_args (op->args, word, memaddr, info);
> @@ -852,11 +866,13 @@ print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
>  disassembler_ftype
>  riscv_get_disassembler (bfd *abfd)
>  {
> +  const char *default_arch = NULL;
> +
>    if (abfd)
>      {
>        const struct elf_backend_data *ebd = get_elf_backend_data (abfd);
>        if (ebd)
> -        {
> +       {
>           const char *sec_name = ebd->obj_attrs_section;
>           if (bfd_get_section_by_name (abfd, sec_name) != NULL)
>             {
> @@ -868,10 +884,14 @@ riscv_get_disassembler (bfd *abfd)
>                                                       attr[Tag_b].i,
>                                                       attr[Tag_c].i,
>                                                       &default_priv_spec);
> +             default_arch = attr[Tag_RISCV_arch].s;
>             }
> -        }
> +       }
>      }
> -   return print_insn_riscv;
> +
> +  riscv_release_subset_list (&riscv_subsets);
> +  riscv_parse_subset (&riscv_rps_dis, default_arch);
> +  return print_insn_riscv;
>  }
>
>  /* Prevent use of the fake labels that are generated as part of the DWARF
> --
> 2.7.4
>


More information about the Binutils mailing list