From: Tsukasa OI <research_trasio@irq.a4lg.com>
To: Tsukasa OI <research_trasio@irq.a4lg.com>,
Nelson Chu <nelson@rivosinc.com>,
Kito Cheng <kito.cheng@sifive.com>,
Palmer Dabbelt <palmer@dabbelt.com>
Cc: binutils@sourceware.org
Subject: [PATCH] RISC-V: Emit mapping symbol with ISA string if non-default arch is used
Date: Fri, 28 Oct 2022 14:52:12 +0000 [thread overview]
Message-ID: <17f57574936af82be381a1451eac56b3709b60bb.1666968673.git.research_trasio@irq.a4lg.com> (raw)
GAS incorrectly emits instruction mapping symbols without ISA string if
no segments use two or more architectures simultaneously.
If no segments use two or more architectures (using .option directives),
need_arch_map_symbol is not set to true, making riscv_check_mapping_symbols
function to replace segment's mapping symbols ($x+arch) with $x.
This easily occurs when a segment (section) is surrounded by .option
push/pop. In this example, even when a non-default architecture is used by
the program, $x+arch mapping symbol emission is suppressed unless the
architecture is changed **during** a section so that two instructions in one
section use the different architecture.
This commit renames need_arch_map_symbol to arch_changed_in_seg to reflect
the actual role and suppresses $x+arch mapping symbol emission only if this
variable is false (as before) **and** the section's architecture is the
same as the default one (to be written as an ELF attribute).
gas/ChangeLog:
* config/tc-riscv.c
(arch_changed_in_seg): Rename from need_arch_map_symbol.
(riscv_mapping_state): Reflect variable name change.
(riscv_check_mapping_symbols): Suppress emission of $x+arch only
if the default architecture is used in that segment.
* testsuite/gas/riscv/mapping-onearch-in-seg.s: New test.
* testsuite/gas/riscv/mapping-onearch-in-seg-dis.d: Likewise.
* testsuite/gas/riscv/mapping-onearch-in-seg-attr.d: Likewise.
* testsuite/gas/riscv/mapping-onearch-in-seg-symbols.d: Likewise.
---
gas/config/tc-riscv.c | 26 ++++++-----
.../gas/riscv/mapping-onearch-in-seg-attr.d | 6 +++
.../gas/riscv/mapping-onearch-in-seg-dis.d | 30 +++++++++++++
.../riscv/mapping-onearch-in-seg-symbols.d | 23 ++++++++++
.../gas/riscv/mapping-onearch-in-seg.s | 44 +++++++++++++++++++
5 files changed, 119 insertions(+), 10 deletions(-)
create mode 100644 gas/testsuite/gas/riscv/mapping-onearch-in-seg-attr.d
create mode 100644 gas/testsuite/gas/riscv/mapping-onearch-in-seg-dis.d
create mode 100644 gas/testsuite/gas/riscv/mapping-onearch-in-seg-symbols.d
create mode 100644 gas/testsuite/gas/riscv/mapping-onearch-in-seg.s
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 01bfc01b0fc..6d6aa631106 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -470,10 +470,12 @@ static char *expr_end;
#define OPCODE_MATCHES(OPCODE, OP) \
(((OPCODE) & MASK_##OP) == MATCH_##OP)
-/* Indicate if .option directives do affect instructions. Set to true means
- we need to add $x+arch at somewhere; Otherwise just add $x for instructions
- should be enough. */
-static bool need_arch_map_symbol = false;
+/* Indicate if .option directives changed the architecture so that
+ two or more architectures are simultaneously used in one segment.
+ Set to true means we we need to add $x+arch at somewhere; Otherwise check
+ final architecture (to be written as an ELF attribute) and decide whether
+ we need to replace $x+arch with $x. */
+static bool arch_changed_in_seg = false;
/* Create a new mapping symbol for the transition to STATE. */
@@ -579,7 +581,7 @@ riscv_mapping_state (enum riscv_seg_mstate to_state,
S_GET_NAME (seg_arch_symbol) + 2) != 0)
{
reset_seg_arch_str = true;
- need_arch_map_symbol = true;
+ arch_changed_in_seg = true;
}
else if (from_state == to_state)
return;
@@ -634,11 +636,15 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
if (seginfo == NULL || seginfo->frchainP == NULL)
return;
- /* If we don't set any .option arch directive, then the arch_map_symbol
- in each segment must be the first instruction, and we don't need to
- add $x+arch for them. */
- if (!need_arch_map_symbol
- && seginfo->tc_segment_info_data.arch_map_symbol != 0)
+ /* If up to one architecture is used per segment, arch_map_symbol
+ (if exists) represents the architecture used in the segment.
+ Replace to $x if the architecture is the same as the final architecture
+ (to be written as an ELF attribute). */
+ if (!arch_changed_in_seg
+ && seginfo->tc_segment_info_data.arch_map_symbol != 0
+ && strcmp (riscv_rps_as.subset_list->arch_str,
+ S_GET_NAME (seginfo->tc_segment_info_data.arch_map_symbol) + 2)
+ == 0)
S_SET_NAME (seginfo->tc_segment_info_data.arch_map_symbol, "$x");
for (fragp = seginfo->frchainP->frch_root;
diff --git a/gas/testsuite/gas/riscv/mapping-onearch-in-seg-attr.d b/gas/testsuite/gas/riscv/mapping-onearch-in-seg-attr.d
new file mode 100644
index 00000000000..7bcf54766a3
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-onearch-in-seg-attr.d
@@ -0,0 +1,6 @@
+#as: -misa-spec=20191213 -march=rv32i2p1
+#source: mapping-onearch-in-seg.s
+#readelf: -A
+Attribute Section: riscv
+File Attributes
+ Tag_RISCV_arch: "rv32i2p1_zicsr2p0"
diff --git a/gas/testsuite/gas/riscv/mapping-onearch-in-seg-dis.d b/gas/testsuite/gas/riscv/mapping-onearch-in-seg-dis.d
new file mode 100644
index 00000000000..c086b92535c
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-onearch-in-seg-dis.d
@@ -0,0 +1,30 @@
+#as: -misa-spec=20191213 -march=rv32i2p1
+#source: mapping-onearch-in-seg.s
+#objdump: -d
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text.1.1:
+
+0+000 <fadd_1>:
+[ ]+[0-9a-f]+:[ ]+00b57553[ ]+fadd\.s[ ]+fa0,fa0,fa1
+[ ]+[0-9a-f]+:[ ]+00008067[ ]+ret
+
+Disassembly of section .text.1.2:
+
+0+000 <fadd_2>:
+[ ]+[0-9a-f]+:[ ]+02b57553[ ]+fadd\.d[ ]+fa0,fa0,fa1
+[ ]+[0-9a-f]+:[ ]+00008067[ ]+ret
+
+Disassembly of section .text.1.3:
+
+0+000 <fadd_3>:
+[ ]+[0-9a-f]+:[ ]+06b57553[ ]+fadd\.q[ ]+fa0,fa0,fa1
+[ ]+[0-9a-f]+:[ ]+00008067[ ]+ret
+
+Disassembly of section .text.2:
+
+0+000 <add_1>:
+[ ]+[0-9a-f]+:[ ]+00b50533[ ]+add[ ]+a0,a0,a1
+[ ]+[0-9a-f]+:[ ]+00008067[ ]+ret
diff --git a/gas/testsuite/gas/riscv/mapping-onearch-in-seg-symbols.d b/gas/testsuite/gas/riscv/mapping-onearch-in-seg-symbols.d
new file mode 100644
index 00000000000..3a476a373b7
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-onearch-in-seg-symbols.d
@@ -0,0 +1,23 @@
+#as: -misa-spec=20191213 -march=rv32i2p1
+#source: mapping-onearch-in-seg.s
+#objdump: --syms --special-syms
+
+.*file format.*riscv.*
+
+SYMBOL TABLE:
+0+00 l d .text 0+00 .text
+0+00 l d .data 0+00 .data
+0+00 l d .bss 0+00 .bss
+0+00 l d .text.1.1 0+00 .text.1.1
+0+00 l .text.1.1 0+00 fadd_1
+0+00 l .text.1.1 0+00 \$xrv32i2p1_f2p2_zicsr2p0
+0+00 l d .text.1.2 0+00 .text.1.2
+0+00 l .text.1.2 0+00 fadd_2
+0+00 l .text.1.2 0+00 \$xrv32i2p1_f2p2_d2p2_zicsr2p0
+0+00 l d .text.1.3 0+00 .text.1.3
+0+00 l .text.1.3 0+00 fadd_3
+0+00 l .text.1.3 0+00 \$xrv32i2p1_f2p2_d2p2_q2p2_zicsr2p0
+0+00 l d .text.2 0+00 .text.2
+0+00 l .text.2 0+00 add_1
+0+00 l .text.2 0+00 \$x
+0+00 l d .riscv.attributes 0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-onearch-in-seg.s b/gas/testsuite/gas/riscv/mapping-onearch-in-seg.s
new file mode 100644
index 00000000000..59b3f5dea98
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-onearch-in-seg.s
@@ -0,0 +1,44 @@
+# In following examples, we use the same architecture per section
+# (do not change the architecture *in* the section).
+
+
+ .section .text.1.1, "ax", %progbits
+fadd_1:
+ .option push
+ .option arch, rv32i2p1_f2p2_zicsr2p0
+ fadd.s fa0, fa0, fa1 # rv32if_zicsr
+ ret # rv32if_zicsr
+ .option pop
+ # rv32i
+
+
+ .section .text.1.2, "ax", %progbits
+fadd_2:
+ .option arch, rv32i2p1_f2p2_d2p2_zicsr2p0
+ fadd.d fa0, fa0, fa1 # rv32ifd_zicsr
+ .option arch, rv32i2p1_f2p2_d2p2_zicsr2p0
+ ret # rv32ifd_zicsr
+ # rv32ifd_zicsr
+
+
+ .section .text.1.3, "ax", %progbits
+fadd_3:
+ .option push
+ .option arch, +q
+ fadd.q fa0, fa0, fa1 # rv32ifdq_zicsr
+ .option pop
+ .option push
+ .option arch, rv32i2p1_f2p2_d2p2_q2p2_zicsr2p0
+ ret # rv32ifdq_zicsr
+ .option pop
+ # rv32ifd_zicsr (written in .text.1.2)
+
+
+ .option arch, rv32i2p1_zicsr2p0
+ .section .text.2, "ax", %progbits
+add_1:
+ add a0, a0, a1 # rv32i_zicsr
+ ret # rv32i_zicsr
+
+ # Final arch (for ELF attribute):
+ # rv32i_zicsr (set just before .section .text.2)
base-commit: 3190ebcbbf846617c0d5026995c26917f609a0f4
--
2.37.2
next reply other threads:[~2022-10-28 14:52 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-28 14:52 Tsukasa OI [this message]
2022-10-28 15:02 ` Andreas Schwab
2022-10-28 15:05 ` Tsukasa OI
2022-10-28 19:10 ` Nelson Chu
2022-10-28 19:17 ` Nelson Chu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=17f57574936af82be381a1451eac56b3709b60bb.1666968673.git.research_trasio@irq.a4lg.com \
--to=research_trasio@irq.a4lg.com \
--cc=binutils@sourceware.org \
--cc=kito.cheng@sifive.com \
--cc=nelson@rivosinc.com \
--cc=palmer@dabbelt.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).