aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorNelson Chu <nelson.chu@sifive.com>2021-11-08 16:35:25 +0800
committerNelson Chu <nelson.chu@sifive.com>2021-11-11 16:59:13 +0800
commitf786c359c1e3227fe8ecfcb2819bb3b80ed351ed (patch)
tree1127cc959b674da4128873b4bb4de8a3de84c2df /gas
parentefe113047d765b26869c3170c43678dd561027b4 (diff)
downloadgdb-f786c359c1e3227fe8ecfcb2819bb3b80ed351ed.zip
gdb-f786c359c1e3227fe8ecfcb2819bb3b80ed351ed.tar.gz
gdb-f786c359c1e3227fe8ecfcb2819bb3b80ed351ed.tar.bz2
RISC-V: Dump objects according to the elf architecture attribute.
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 usually set the default architecture string to rv64g by bfd/elfxx-riscv.c:riscv_set_default_arch. But this will cause rvc instructions to be unrecognized. Therefore, we set the default architecture string to rv64gc for disassembler, to keep the previous behavior. 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, set the default architectrue string to rv64gc.
Diffstat (limited to 'gas')
-rw-r--r--gas/config/tc-riscv.c110
-rw-r--r--gas/testsuite/gas/riscv/mapping-04b.d4
-rw-r--r--gas/testsuite/gas/riscv/mapping-norelax-03b.d2
-rw-r--r--gas/testsuite/gas/riscv/mapping-norelax-04b.d4
4 files changed, 28 insertions, 92 deletions
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
#...