[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