public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] RISC-V: Emit mapping symbol with ISA string if non-default arch is used
@ 2022-10-28 14:52 Tsukasa OI
  2022-10-28 15:02 ` Andreas Schwab
  2022-10-28 19:10 ` Nelson Chu
  0 siblings, 2 replies; 5+ messages in thread
From: Tsukasa OI @ 2022-10-28 14:52 UTC (permalink / raw)
  To: Tsukasa OI, Nelson Chu, Kito Cheng, Palmer Dabbelt; +Cc: binutils

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


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-10-28 19:17 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-28 14:52 [PATCH] RISC-V: Emit mapping symbol with ISA string if non-default arch is used Tsukasa OI
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

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).