From: Nelson Chu <nelson@rivosinc.com>
To: Tsukasa OI <research_trasio@irq.a4lg.com>
Cc: Kito Cheng <kito.cheng@sifive.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
binutils@sourceware.org
Subject: Re: [PATCH] RISC-V: Emit mapping symbol with ISA string if non-default arch is used
Date: Sat, 29 Oct 2022 03:17:47 +0800 [thread overview]
Message-ID: <CAPpQWtB-oN_eqviuceTm3vjgWaU4=vUMFa+o0gx0eHOiB+hPtg@mail.gmail.com> (raw)
In-Reply-To: <CAPpQWtCLzkBRJZMgpEQ2QGA3Jg=HuiWitqbD-ELm9xn=S7DStg@mail.gmail.com>
Forgot to say, if you want to suppress the mapping symbol to $x for
the section when it has the same arch with elf attribute, then you may
also need to update the riscv_get_map_state in the
opcodes/riscv-dis.c, to see if the $x is the first mapping symbol of
the section. Since the first mapping symbol of the section is $x
means it is the same as elf arch attribute; Otherwise, $x means the
same as the previous arch mapping symbol.
Nelson
On Sat, Oct 29, 2022 at 3:10 AM Nelson Chu <nelson@rivosinc.com> wrote:
>
> On Fri, Oct 28, 2022 at 10:52 PM Tsukasa OI
> <research_trasio@irq.a4lg.com> wrote:
> >
> > GAS incorrectly emits instruction mapping symbols without ISA string if
> > no segments use two or more architectures simultaneously.
>
> First of all, thanks for pointing this out so quickly :)
>
> > 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;
>
> Add a new int flag in struct riscv_segment_info_type to replace the
> need_arch_map_symbol.
>
> struct riscv_segment_info_type
> {
> enum riscv_seg_mstate map_state;
> /* The current mapping symbol with architecture string. */
> symbolS *arch_map_symbol;
> + int arch_changed : 0;
> };
>
> and then set the flag to 1 here,
> seg_info (now_seg)->tc_segment_info_data.arch_changed = 1;
>
> > }
> > 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. */
>
> I prefer the comment here as,
>
> /* If the section only has a mapping symbol at the first instruction,
> and it is the same as
> the elf architecture attribute, then no need to add $x+arch for it.
>
> Please see gas/testsuite/gas/riscv/mapping.s: <your testcase
> section name>. */
>
> > - if (!need_arch_map_symbol
> > - && seginfo->tc_segment_info_data.arch_map_symbol != 0)
> > + if (!arch_changed_in_seg
>
> if (!seg_info (now_seg)->tc_segment_info_data.arch_changed
>
> > + && seginfo->tc_segment_info_data.arch_map_symbol != 0
> > + && strcmp (riscv_rps_as.subset_list->arch_str,
>
> There is a TODO that I had discussed with Kito a long time ago - the
> elf arch attribute should be affected by the .option arch directives,
> though the current implementation doesn't do that. That means, the
> mapping symbol here isn't necessarily the same as the elf arch
> attribute. So in this place, we should compare the saved elf arch
> attribute, rather than the arch mapping symbol in each segment.
> However, according to the current implementation, the final elf
> attribute is the same as riscv_rps_as.subset_list->arch_str, so the
> change is reasonable for now.
>
> > + 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
>
> Don't need this test case.
>
> > 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)
>
> For me, fadd_3 is redundant, fadd_2 and fadd_1 should be the same
> thing, so just keep one of them. Generally, the more test cases the
> better, but short and precise test cases are what we really need. I
> appreciate you always spending lots of time to make risc-v better, but
> sometimes you are adding lots of test cases, which might all just be
> testing the similar thing.
>
> > +
> > + .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)
>
> Please try to add the test cases into the mapping-symbol.s.
>
> Thanks
> Nelson
>
> > base-commit: 3190ebcbbf846617c0d5026995c26917f609a0f4
> > --
> > 2.37.2
> >
prev parent reply other threads:[~2022-10-28 19:17 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-28 14:52 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 message]
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='CAPpQWtB-oN_eqviuceTm3vjgWaU4=vUMFa+o0gx0eHOiB+hPtg@mail.gmail.com' \
--to=nelson@rivosinc.com \
--cc=binutils@sourceware.org \
--cc=kito.cheng@sifive.com \
--cc=palmer@dabbelt.com \
--cc=research_trasio@irq.a4lg.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).