public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
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:10:28 +0800	[thread overview]
Message-ID: <CAPpQWtCLzkBRJZMgpEQ2QGA3Jg=HuiWitqbD-ELm9xn=S7DStg@mail.gmail.com> (raw)
In-Reply-To: <17f57574936af82be381a1451eac56b3709b60bb.1666968673.git.research_trasio@irq.a4lg.com>

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
>

  parent reply	other threads:[~2022-10-28 19:10 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 [this message]
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='CAPpQWtCLzkBRJZMgpEQ2QGA3Jg=HuiWitqbD-ELm9xn=S7DStg@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).