public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Tsukasa OI <research_trasio@irq.a4lg.com>
To: Nelson Chu <nelson@rivosinc.com>, binutils@sourceware.org
Subject: Re: [PATCH 1/2] RISC-V: Output mapping symbols with ISA string.
Date: Mon, 3 Oct 2022 20:17:50 +0900	[thread overview]
Message-ID: <3a3040fe-c9ce-85f9-d256-c6d35f6a14df@irq.a4lg.com> (raw)
In-Reply-To: <20220930092058.71286-1-nelson@rivosinc.com>

Hi Nelson,

Some minor behaviors were different than I assumed but they make sense.

This time, I could not find any easy examples to "break" or "confuse"
the assembler.  So, LGTM.

...except one line I describe below (I don't think this is your fault
but needs to be fixed).

Thanks,
Tsukasa

On 2022/09/30 18:20, Nelson Chu wrote:
> RISC-V Psabi pr196,
> https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/196
> 
> bfd/
>     * elfxx-riscv.c (riscv_release_subset_list): Free arch_str if needed.
>     (riscv_copy_subset_list): Copy arch_str as well.
>     * elfxx-riscv.h (riscv_subset_list_t): Store arch_str for each subset list.
> gas/
>     * config/tc-riscv.c (riscv_reset_subsets_list_arch_str): Update the
>     architecture string in the subset_list.
>     (riscv_set_arch): Call riscv_reset_subsets_list_arch_str after parsing new
>     architecture string.
>     (s_riscv_option): Likewise.
>     (need_arch_map_symbol): New boolean, used to indicate if .option
>     directives do affect instructions.
>     (make_mapping_symbol): New boolean parameter reset_seg_arch_str.  Need to
>     generate $x+arch for MAP_INSN, and then store it into tc_segment_info_data
>     if reset_seg_arch_str is true.
>     (riscv_mapping_state): Decide if we need to add $x+arch for MAP_INSN.  For
>     now, only add $x+arch if the architecture strings in subset list and segment
>     are different.  Besides, always add $x+arch at the start of section, and do
>     not add $x+arch for code alignment, since rvc for alignment can be judged
>     from addend of R_RISCV_ALIGN.
>     (riscv_remove_mapping_symbol): If current and previous mapping symbol have
>     same value, then remove the current $x only if the previous is $x+arch;
>     Otherwise, always remove previous.
>     (riscv_add_odd_padding_symbol): Updated.
>     (riscv_check_mapping_symbols): Don't need to add any $x+arch if
>     need_arch_map_symbol is false, so changed them to $x.
>     (riscv_frag_align_code): Updated since riscv_mapping_state is changed.
>     (riscv_init_frag): Likewise.
>     (s_riscv_insn): Likewise.
>     (riscv_elf_final_processing): Call riscv_release_subset_list to release
>     riscv_subsets, rather than only release arch_str in the riscv_write_out_attrs.
>     (riscv_write_out_attrs): No need to call riscv_arch_str, just get arch_str
>     from riscv_subsets.
>     * config/tc-riscv.h (riscv_segment_info_type): Record current $x+arch mapping
>     symbol of each segment.
> 
>     * testsuite/gas/riscv/mapping-0*: Merged and replaced by mapping.s.
>     * testsuite/gas/riscv/mapping.s: New testcase, to test most of the cases in
>     one file.
>     * testsuite/gas/riscv/mapping-symbols.d: Likewise.
>     * testsuite/gas/riscv/mapping-dis.d: Likewise.
>     * testsuite/gas/riscv/mapping-non-arch.s: New testcase for the case that
>     does need any $x+arch.
>     * testsuite/gas/riscv/mapping-non-arch.d: Likewise.
>     * testsuite/gas/riscv/option-arch-01a.d: Updated.
> opcodes/
>     * riscv-dis.c (riscv_disassemble_insn): Set riscv_fpr_names back to
>     riscv_fpr_names_abi or riscv_fpr_names_numeric when zfinx is disabled
>     for some specfic code region.
>     (riscv_get_map_state): Recognized mapping symbols $x+arch, and then reset
>     the architecture string once the ISA is different.
> ---
>  bfd/elfxx-riscv.c                             |   7 +
>  bfd/elfxx-riscv.h                             |   1 +
>  gas/config/tc-riscv.c                         | 161 ++++++++++++++----
>  gas/config/tc-riscv.h                         |   6 +-
>  gas/testsuite/gas/riscv/mapping-01.s          |  17 --
>  gas/testsuite/gas/riscv/mapping-01a.d         |  17 --
>  gas/testsuite/gas/riscv/mapping-01b.d         |  21 ---
>  gas/testsuite/gas/riscv/mapping-02.s          |  12 --
>  gas/testsuite/gas/riscv/mapping-02a.d         |  15 --
>  gas/testsuite/gas/riscv/mapping-02b.d         |  16 --
>  gas/testsuite/gas/riscv/mapping-03.s          |  11 --
>  gas/testsuite/gas/riscv/mapping-03a.d         |  20 ---
>  gas/testsuite/gas/riscv/mapping-03b.d         |  24 ---
>  gas/testsuite/gas/riscv/mapping-04.s          |  13 --
>  gas/testsuite/gas/riscv/mapping-04a.d         |  15 --
>  gas/testsuite/gas/riscv/mapping-04b.d         |  23 ---
>  gas/testsuite/gas/riscv/mapping-dis.d         |  84 +++++++++
>  gas/testsuite/gas/riscv/mapping-non-arch.d    |  17 ++
>  gas/testsuite/gas/riscv/mapping-non-arch.s    |  11 ++
>  gas/testsuite/gas/riscv/mapping-norelax-03a.d |  21 ---
>  gas/testsuite/gas/riscv/mapping-norelax-03b.d |  25 ---
>  gas/testsuite/gas/riscv/mapping-norelax-04a.d |  16 --
>  gas/testsuite/gas/riscv/mapping-norelax-04b.d |  24 ---
>  gas/testsuite/gas/riscv/mapping-symbols.d     |  48 ++++++
>  gas/testsuite/gas/riscv/mapping.s             | 112 ++++++++++++
>  gas/testsuite/gas/riscv/option-arch-01a.d     |   2 +-
>  opcodes/riscv-dis.c                           |   9 +
>  27 files changed, 420 insertions(+), 328 deletions(-)
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01.s
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-01b.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02.s
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-02b.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03.s
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-03b.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04.s
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-04b.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-dis.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-non-arch.s
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-03b.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04a.d
>  delete mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04b.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-symbols.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping.s
> 
> diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
> index c67d4167232..9247350c2c2 100644
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -1578,6 +1578,12 @@ riscv_release_subset_list (riscv_subset_list_t *subset_list)
>      }
>  
>    subset_list->tail = NULL;
> +
> +  if (subset_list->arch_str != NULL)
> +    {
> +      free ((void*) subset_list->arch_str);
> +      subset_list->arch_str = NULL;
> +    }
>  }
>  
>  /* Parsing extension version.
> @@ -2133,6 +2139,7 @@ riscv_copy_subset_list (riscv_subset_list_t *subset_list)
>  {
>    riscv_subset_list_t *new = xmalloc (sizeof *new);
>    new->head = riscv_copy_subset (new, subset_list->head);
> +  new->arch_str = strdup (subset_list->arch_str);
>    return new;
>  }
>  
> diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h
> index ea7126bdb4d..e2c1e3c1618 100644
> --- a/bfd/elfxx-riscv.h
> +++ b/bfd/elfxx-riscv.h
> @@ -51,6 +51,7 @@ typedef struct
>  {
>    riscv_subset_t *head;
>    riscv_subset_t *tail;
> +  const char *arch_str;
>  } riscv_subset_list_t;
>  
>  extern void
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index d9f63b11398..99bd0a06d97 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -280,6 +280,16 @@ static riscv_parse_subset_t riscv_rps_as =
>    true,			/* check_unknown_prefixed_ext.  */
>  };
>  
> +/* Update the architecture string in the subset_list.  */
> +
> +static void
> +riscv_reset_subsets_list_arch_str (void)
> +{
> +  if (riscv_subsets->arch_str != NULL)
> +    free ((void *) riscv_subsets->arch_str);
> +  riscv_subsets->arch_str = riscv_arch_str (xlen, riscv_subsets);
> +}
> +
>  /* This structure is used to hold a stack of .option values.  */
>  struct riscv_option_stack
>  {
> @@ -307,10 +317,12 @@ riscv_set_arch (const char *s)
>        riscv_subsets = XNEW (riscv_subset_list_t);
>        riscv_subsets->head = NULL;
>        riscv_subsets->tail = NULL;
> +      riscv_subsets->arch_str = NULL;
>        riscv_rps_as.subset_list = riscv_subsets;
>      }
>    riscv_release_subset_list (riscv_subsets);
>    riscv_parse_subset (&riscv_rps_as, s);
> +  riscv_reset_subsets_list_arch_str ();
>  
>    riscv_set_rvc (false);
>    if (riscv_subset_supports (&riscv_rps_as, "c"))
> @@ -459,21 +471,37 @@ 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;
> +
>  /* Create a new mapping symbol for the transition to STATE.  */
>  
>  static void
>  make_mapping_symbol (enum riscv_seg_mstate state,
>  		     valueT value,
> -		     fragS *frag)
> +		     fragS *frag,
> +		     bool reset_seg_arch_str)
>  {
>    const char *name;
> +  char *buff;

Change here to:
char *buff = NULL;

Yes, I know that.  But GCC 12 (on my Ubuntu 22.04 LTS) complains about
"maybe uninitialized" variable.  This is definitely a false positive but
"fails to build by default" is what I don't want to see.

>    switch (state)
>      {
>      case MAP_DATA:
>        name = "$d";
>        break;
>      case MAP_INSN:
> -      name = "$x";
> +      if (reset_seg_arch_str)
> +	{
> +	  const char *isa = riscv_subsets->arch_str;
> +	  size_t size = strlen (isa) + 3; /* "rv" + '\0'  */
> +	  buff = xmalloc (size);
> +	  snprintf (buff, size, "$x%s", isa);
> +	  name = buff;
> +	}
> +      else
> +	name = "$x";
>        break;
>      default:
>        abort ();
> @@ -481,32 +509,38 @@ make_mapping_symbol (enum riscv_seg_mstate state,
>  
>    symbolS *symbol = symbol_new (name, now_seg, frag, value);
>    symbol_get_bfdsym (symbol)->flags |= (BSF_NO_FLAGS | BSF_LOCAL);
> +  if (reset_seg_arch_str)
> +    {
> +      /* Store current $x+arch into tc_segment_info.  */
> +      seg_info (now_seg)->tc_segment_info_data.arch_map_symbol = symbol;
> +      xfree ((void *) buff);
> +    }
>  
>    /* If .fill or other data filling directive generates zero sized data,
> -     or we are adding odd alignemnts, then the mapping symbol for the
> -     following code will have the same value.  */
> +     then mapping symbol for the following code will have the same value.
> +
> +     Please see gas/testsuite/gas/riscv/mapping.s: .text.zero.fill.first
> +     and .text.zero.fill.last.  */
> +  symbolS *first = frag->tc_frag_data.first_map_symbol;
> +  symbolS *last = frag->tc_frag_data.last_map_symbol;
>    if (value == 0)
>      {
> -       if (frag->tc_frag_data.first_map_symbol != NULL)
> +      if (first != NULL)
>  	{
> -	  know (S_GET_VALUE (frag->tc_frag_data.first_map_symbol)
> -		== S_GET_VALUE (symbol));
> +	  know (S_GET_VALUE (first) == S_GET_VALUE (symbol)
> +		&& first == last);
>  	  /* Remove the old one.  */
> -	  symbol_remove (frag->tc_frag_data.first_map_symbol,
> -			 &symbol_rootP, &symbol_lastP);
> +	  symbol_remove (first, &symbol_rootP, &symbol_lastP);
>  	}
>        frag->tc_frag_data.first_map_symbol = symbol;
>      }
> -  if (frag->tc_frag_data.last_map_symbol != NULL)
> +  else if (last != NULL)
>      {
>        /* The mapping symbols should be added in offset order.  */
> -      know (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
> -			 <= S_GET_VALUE (symbol));
> +      know (S_GET_VALUE (last) <= S_GET_VALUE (symbol));
>        /* Remove the old one.  */
> -      if (S_GET_VALUE (frag->tc_frag_data.last_map_symbol)
> -	  == S_GET_VALUE (symbol))
> -	symbol_remove (frag->tc_frag_data.last_map_symbol,
> -		       &symbol_rootP, &symbol_lastP);
> +      if (S_GET_VALUE (last) == S_GET_VALUE (symbol))
> +	symbol_remove (last, &symbol_rootP, &symbol_lastP);
>      }
>    frag->tc_frag_data.last_map_symbol = symbol;
>  }
> @@ -515,13 +549,15 @@ make_mapping_symbol (enum riscv_seg_mstate state,
>  
>  void
>  riscv_mapping_state (enum riscv_seg_mstate to_state,
> -		     int max_chars)
> +		     int max_chars,
> +		     bool frag_align_code)
>  {
>    enum riscv_seg_mstate from_state =
>  	seg_info (now_seg)->tc_segment_info_data.map_state;
> +  bool reset_seg_arch_str = false;
>  
>    if (!SEG_NORMAL (now_seg)
> -      /* For now I only add the mapping symbols to text sections.
> +      /* For now we only add the mapping symbols to text sections.
>  	 Therefore, the dis-assembler only show the actual contents
>  	 distribution for text.  Other sections will be shown as
>  	 data without the details.  */
> @@ -529,13 +565,29 @@ riscv_mapping_state (enum riscv_seg_mstate to_state,
>      return;
>  
>    /* The mapping symbol should be emitted if not in the right
> -     mapping state  */
> -  if (from_state == to_state)
> +     mapping state.  */
> +  symbolS *seg_arch_symbol =
> +	seg_info (now_seg)->tc_segment_info_data.arch_map_symbol;
> +  if (to_state == MAP_INSN && seg_arch_symbol == 0)
> +    {
> +      /* Always add $x+arch at the first instruction of section.  */
> +      reset_seg_arch_str = true;
> +    }
> +  else if (seg_arch_symbol != 0
> +	   && to_state == MAP_INSN
> +	   && !frag_align_code
> +	   && strcmp (riscv_subsets->arch_str,
> +		      S_GET_NAME (seg_arch_symbol) + 2) != 0)
> +    {
> +      reset_seg_arch_str = true;
> +      need_arch_map_symbol = true;
> +    }
> +  else if (from_state == to_state)
>      return;
>  
>    valueT value = (valueT) (frag_now_fix () - max_chars);
>    seg_info (now_seg)->tc_segment_info_data.map_state = to_state;
> -  make_mapping_symbol (to_state, value, frag_now);
> +  make_mapping_symbol (to_state, value, frag_now, reset_seg_arch_str);
>  }
>  
>  /* Add the odd bytes of paddings for riscv_handle_align.  */
> @@ -544,9 +596,27 @@ static void
>  riscv_add_odd_padding_symbol (fragS *frag)
>  {
>    /* If there was already a mapping symbol, it should be
> -     removed in the make_mapping_symbol.  */
> -  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag);
> -  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag);
> +     removed in the make_mapping_symbol.
> +
> +     Please see gas/testsuite/gas/riscv/mapping.s: .text.odd.align.  */
> +  make_mapping_symbol (MAP_DATA, frag->fr_fix, frag, false);
> +  make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag, false);
> +}
> +
> +/* If previous and current mapping symbol have same value, then remove the
> +   current $x only if the previous is $x+arch; Otherwise, always remove the
> +   previous.  */
> +
> +static void
> +riscv_remove_mapping_symbol (symbolS *pre, symbolS *cur)
> +{
> +  know (pre != NULL && cur != NULL
> +	&& S_GET_VALUE (pre) == S_GET_VALUE (cur));
> +  symbolS *removed = pre;
> +  if (strncmp (S_GET_NAME (pre), "$xrv", 4) == 0
> +      && strcmp (S_GET_NAME (cur), "$x") == 0)
> +    removed = cur;
> +  symbol_remove (removed, &symbol_rootP, &symbol_lastP);
>  }
>  
>  /* Remove any excess mapping symbols generated for alignment frags in
> @@ -565,6 +635,13 @@ 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)
> +    S_SET_NAME (seginfo->tc_segment_info_data.arch_map_symbol, "$x");
> +
>    for (fragp = seginfo->frchainP->frch_root;
>         fragp != NULL;
>         fragp = fragp->fr_next)
> @@ -583,17 +660,24 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
>  
>        do
>  	{
> -	  if (next->tc_frag_data.first_map_symbol != NULL)
> +	  symbolS *next_first = next->tc_frag_data.first_map_symbol;
> +	  if (next_first != NULL)
>  	    {
>  	      /* The last mapping symbol overlaps with another one
> -		 which at the start of the next frag.  */
> -	      symbol_remove (last, &symbol_rootP, &symbol_lastP);
> +		 which at the start of the next frag.
> +
> +		 Please see the gas/testsuite/gas/riscv/mapping.s:
> +		 .text.zero.fill.align.A and .text.zero.fill.align.B.  */
> +	      riscv_remove_mapping_symbol (last, next_first);
>  	      break;
>  	    }
>  
>  	  if (next->fr_next == NULL)
>  	    {
> -	      /* The last mapping symbol is at the end of the section.  */
> +	      /* The last mapping symbol is at the end of the section.
> +
> +		 Please see the gas/testsuite/gas/riscv/mapping.s:
> +		 .text.last.section.  */
>  	      know (next->fr_fix == 0 && next->fr_var == 0);
>  	      symbol_remove (last, &symbol_rootP, &symbol_lastP);
>  	      break;
> @@ -3438,7 +3522,7 @@ md_assemble (char *str)
>         return;
>      }
>  
> -  riscv_mapping_state (MAP_INSN, 0);
> +  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
>  
>    const struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
>  						&imm_reloc, op_hash);
> @@ -3946,11 +4030,13 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
>    if (strcmp (name, "rvc") == 0)
>      {
>        riscv_update_subset (&riscv_rps_as, "+c");
> +      riscv_reset_subsets_list_arch_str ();
>        riscv_set_rvc (true);
>      }
>    else if (strcmp (name, "norvc") == 0)
>      {
>        riscv_update_subset (&riscv_rps_as, "-c");
> +      riscv_reset_subsets_list_arch_str ();
>        riscv_set_rvc (false);
>      }
>    else if (strcmp (name, "pic") == 0)
> @@ -3971,6 +4057,7 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
>        if (ISSPACE (*name) && *name != '\0')
>  	name++;
>        riscv_update_subset (&riscv_rps_as, name);
> +      riscv_reset_subsets_list_arch_str ();
>  
>        riscv_set_rvc (false);
>        if (riscv_subset_supports (&riscv_rps_as, "c"))
> @@ -4102,6 +4189,10 @@ riscv_frag_align_code (int n)
>    if (!riscv_opts.relax)
>      return false;
>  
> +  /* Maybe we should use frag_var to create a new rs_align_code fragment,
> +     rather than just use frag_more to handle an alignment here?  So that we
> +     don't need to call riscv_mapping_state again later, and then only need
> +     to check frag->fr_type to see if it is frag_align_code.  */
>    nops = frag_more (worst_case_bytes);
>  
>    ex.X_op = O_constant;
> @@ -4112,7 +4203,7 @@ riscv_frag_align_code (int n)
>    fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
>  	       &ex, false, BFD_RELOC_RISCV_ALIGN);
>  
> -  riscv_mapping_state (MAP_INSN, worst_case_bytes);
> +  riscv_mapping_state (MAP_INSN, worst_case_bytes, 1/* frag_align_code */);
>  
>    /* We need to start a new frag after the alignment which may be removed by
>       the linker, to prevent the assembler from computing static offsets.
> @@ -4186,10 +4277,10 @@ riscv_init_frag (fragS * fragP, int max_chars)
>      case rs_fill:
>      case rs_align:
>      case rs_align_test:
> -      riscv_mapping_state (MAP_DATA, max_chars);
> +      riscv_mapping_state (MAP_DATA, max_chars, 0/* frag_align_code */);
>        break;
>      case rs_align_code:
> -      riscv_mapping_state (MAP_INSN, max_chars);
> +      riscv_mapping_state (MAP_INSN, max_chars, 1/* frag_align_code */);
>        break;
>      default:
>        break;
> @@ -4418,6 +4509,7 @@ void
>  riscv_elf_final_processing (void)
>  {
>    riscv_set_abi_by_arch ();
> +  riscv_release_subset_list (riscv_subsets);
>    elf_elfheader (stdoutput)->e_flags |= elf_flags;
>  }
>  
> @@ -4459,7 +4551,7 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
>    save_c = *input_line_pointer;
>    *input_line_pointer = '\0';
>  
> -  riscv_mapping_state (MAP_INSN, 0);
> +  riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
>  
>    struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
>  				&imm_reloc, insn_type_hash);
> @@ -4502,9 +4594,8 @@ riscv_write_out_attrs (void)
>    unsigned int i;
>  
>    /* Re-write architecture elf attribute.  */
> -  arch_str = riscv_arch_str (xlen, riscv_subsets);
> +  arch_str = riscv_subsets->arch_str;
>    bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, arch_str);
> -  xfree ((void *) arch_str);
>  
>    /* For the file without any instruction, we don't set the default_priv_spec
>       according to the privileged elf attributes since the md_assemble isn't
> diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
> index 802e7afe670..19c45ba2d12 100644
> --- a/gas/config/tc-riscv.h
> +++ b/gas/config/tc-riscv.h
> @@ -130,14 +130,16 @@ extern void riscv_md_finish (void);
>  extern int riscv_convert_symbolic_attribute (const char *);
>  
>  /* Set mapping symbol states.  */
> -#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0)
> -void riscv_mapping_state (enum riscv_seg_mstate, int);
> +#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0, 0)
> +void riscv_mapping_state (enum riscv_seg_mstate, int, bool);
>  
>  /* Define target segment type.  */
>  #define TC_SEGMENT_INFO_TYPE struct riscv_segment_info_type
>  struct riscv_segment_info_type
>  {
>    enum riscv_seg_mstate map_state;
> +  /* The current mapping symbol with architecture string.  */
> +  symbolS *arch_map_symbol;
>  };
>  
>  /* Define target fragment type.  */
> diff --git a/gas/testsuite/gas/riscv/mapping-01.s b/gas/testsuite/gas/riscv/mapping-01.s
> deleted file mode 100644
> index 989463f91ee..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-01.s
> +++ /dev/null
> @@ -1,17 +0,0 @@
> -	.option arch, -c
> -	.text
> -	.global	funcA
> -funcA:
> -	add	a0, a0, a0
> -	j	funcB
> -	.global	funcB
> -funcB:
> -	add	a1, a1, a1
> -	bne	a0, a1, funcB
> -
> -	.data
> -	.word 0x123456
> -
> -	.section	.foo, "ax"
> -foo:
> -	add	a2, a2, a2
> diff --git a/gas/testsuite/gas/riscv/mapping-01a.d b/gas/testsuite/gas/riscv/mapping-01a.d
> deleted file mode 100644
> index 32e0027a13d..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-01a.d
> +++ /dev/null
> @@ -1,17 +0,0 @@
> -#as:
> -#source: mapping-01.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       .text	0+00 \$x
> -0+00 l    d  .foo	0+00 .foo
> -0+00 l       .foo	0+00 foo
> -0+00 l       .foo	0+00 \$x
> -0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
> -0+00 g       .text	0+00 funcA
> -0+08 g       .text	0+00 funcB
> diff --git a/gas/testsuite/gas/riscv/mapping-01b.d b/gas/testsuite/gas/riscv/mapping-01b.d
> deleted file mode 100644
> index e84b3d608f5..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-01b.d
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -#as:
> -#source: mapping-01.s
> -#objdump: -d
> -
> -.*:[ 	]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <funcA>:
> -[ 	]+0:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
> -[ 	]+4:[ 	]+0040006f[ 	]+j[ 	]+8 <funcB>
> -
> -0+008 <funcB>:
> -[ 	]+8:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
> -[ 	]+c:[ 	]+feb51ee3[ 	]+bne[ 	]+a0,a1,8 <funcB>
> -
> -Disassembly of section .foo:
> -
> -0+000 <foo>:
> -[ 	]+0:[ 	]+00c60633[ 	]+add[ 	]+a2,a2,a2
> diff --git a/gas/testsuite/gas/riscv/mapping-02.s b/gas/testsuite/gas/riscv/mapping-02.s
> deleted file mode 100644
> index 79468c0d14f..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-02.s
> +++ /dev/null
> @@ -1,12 +0,0 @@
> -	.option arch, -c
> -	.text
> -	.word	1
> -	add	a0, a0, a0
> -
> -	.data
> -	.word	2
> -
> -	.text
> -	add	a1, a1, a1
> -	.short	3
> -	add	a2, a2, a2
> diff --git a/gas/testsuite/gas/riscv/mapping-02a.d b/gas/testsuite/gas/riscv/mapping-02a.d
> deleted file mode 100644
> index 333f12cd343..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-02a.d
> +++ /dev/null
> @@ -1,15 +0,0 @@
> -#as:
> -#source: mapping-02.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       .text	0+00 \$d
> -0+04 l       .text	0+00 \$x
> -0+0c l       .text	0+00 \$d
> -0+0e l       .text	0+00 \$x
> -0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-02b.d b/gas/testsuite/gas/riscv/mapping-02b.d
> deleted file mode 100644
> index 1ed6c081cf7..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-02b.d
> +++ /dev/null
> @@ -1,16 +0,0 @@
> -#as:
> -#source: mapping-02.s
> -#objdump: -d
> -
> -.*:[ 	]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <.text>:
> -[ 	]+0:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
> -[ 	]+4:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
> -[ 	]+8:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
> -[ 	]+c:[ 	]+0003[ 	]+.short[ 	]+0x0003
> -[ 	]+e:[ 	]+00c60633[ 	]+add[ 	]+a2,a2,a2
> -#...
> diff --git a/gas/testsuite/gas/riscv/mapping-03.s b/gas/testsuite/gas/riscv/mapping-03.s
> deleted file mode 100644
> index 88f2601568d..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-03.s
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -	.option arch, -c
> -	.text
> -	add	a0, a0, a0
> -	.long	0
> -	.balign	16
> -	.word	1
> -	add	a1, a1, a1
> -	.byte	2
> -	.long	3
> -	.balign	16
> -	.word	5
> diff --git a/gas/testsuite/gas/riscv/mapping-03a.d b/gas/testsuite/gas/riscv/mapping-03a.d
> deleted file mode 100644
> index d3663b663aa..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-03a.d
> +++ /dev/null
> @@ -1,20 +0,0 @@
> -#as:
> -#source: mapping-03.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       .text	0+00 \$x
> -0+04 l       .text	0+00 \$d
> -0+08 l       .text	0+00 \$x
> -0+14 l       .text	0+00 \$d
> -0+18 l       .text	0+00 \$x
> -0+1c l       .text	0+00 \$d
> -0+21 l       .text	0+00 \$x
> -0+2d l       .text	0+00 \$d
> -0+31 l       .text	0+00 \$x
> -0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-03b.d b/gas/testsuite/gas/riscv/mapping-03b.d
> deleted file mode 100644
> index f4f67269981..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-03b.d
> +++ /dev/null
> @@ -1,24 +0,0 @@
> -#as:
> -#source: mapping-03.s
> -#objdump: -d
> -
> -.*:[ 	]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <.text>:
> -[ 	]+0:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
> -[ 	]+4:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
> -[ 	]+8:[ 	]+00000013[ 	]+nop
> -[ 	]+c:[ 	]+00000013[ 	]+nop
> -[ 	]+10:[ 	]+00000013[ 	]+nop
> -[ 	]+14:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
> -[ 	]+18:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
> -[ 	]+1c:[ 	]+00000302[ 	]+.word[ 	]+0x00000302
> -[ 	]+20:[ 	]+00[ 	]+.byte[ 	]+0x00
> -[ 	]+21:[ 	]+00000013[ 	]+nop
> -[ 	]+25:[ 	]+00000013[ 	]+nop
> -[ 	]+29:[ 	]+00000013[ 	]+nop
> -[ 	]+2d:[ 	]+00000005[ 	]+.word[ 	]+0x00000005
> -#...
> diff --git a/gas/testsuite/gas/riscv/mapping-04.s b/gas/testsuite/gas/riscv/mapping-04.s
> deleted file mode 100644
> index 804b0397737..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-04.s
> +++ /dev/null
> @@ -1,13 +0,0 @@
> -	.text
> -	.option	arch, -c
> -	.fill	2, 4, 0x1001
> -	.byte	1
> -	.word	0
> -	.balign	8
> -	add	a0, a0, a0
> -	.fill	5, 2, 0x2002
> -	add	a1, a1, a1
> -
> -	.data
> -	.word	0x1
> -	.word	0x2
> diff --git a/gas/testsuite/gas/riscv/mapping-04a.d b/gas/testsuite/gas/riscv/mapping-04a.d
> deleted file mode 100644
> index 1ae9653212b..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-04a.d
> +++ /dev/null
> @@ -1,15 +0,0 @@
> -#as:
> -#source: mapping-04.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       .text	0+00 \$d
> -0+0d l       .text	0+00 \$x
> -0+15 l       .text	0+00 \$d
> -0+1f l       .text	0+00 \$x
> -0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-04b.d b/gas/testsuite/gas/riscv/mapping-04b.d
> deleted file mode 100644
> index 54bd0afb6c4..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-04b.d
> +++ /dev/null
> @@ -1,23 +0,0 @@
> -#as:
> -#source: mapping-04.s
> -#objdump: -d
> -
> -.*:[ 	]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <.text>:
> -[ 	]+0:[ 	]+00001001[ 	]+.word[ 	]+0x00001001
> -[ 	]+4:[ 	]+00001001[ 	]+.word[ 	]+0x00001001
> -[ 	]+8:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
> -[ 	]+c:[ 	]+00[ 	]+.byte[ 	]+0x00
> -[ 	]+d:[ 	]+00000013[ 	]+nop
> -[ 	]+11:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
> -[ 	]+15:[ 	]+20022002[ 	]+.word[ 	]+0x20022002
> -[ 	]+19:[ 	]+20022002[ 	]+.word[ 	]+0x20022002
> -[ 	]+1d:[ 	]+2002[ 	]+.short[ 	]+0x2002
> -[ 	]+1f:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
> -[ 	]+23:[ 	]+0000[ 	]+.2byte[ 	]+0x0
> -[ 	]+25:[ 	]+0000[ 	]+.2byte[ 	]+0x0
> -#...
> diff --git a/gas/testsuite/gas/riscv/mapping-dis.d b/gas/testsuite/gas/riscv/mapping-dis.d
> new file mode 100644
> index 00000000000..246f3672ade
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-dis.d
> @@ -0,0 +1,84 @@
> +#as:
> +#source: mapping.s
> +#objdump: -d
> +
> +.*:[ 	]+file format .*
> +
> +
> +Disassembly of section .text.cross.section.A:
> +
> +0+000 <funcA>:
> +[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+bffd[ 	]+j[ 	]+0 <funcA>
> +
> +Disassembly of section .text.corss.section.B:
> +
> +0+000 <funcB>:
> +[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
> +[ 	]+[0-9a-f]+:[ 	]+fffff06f[ 	]+j[ 	]+0 <funcB>
> +
> +Disassembly of section .text.data:
> +
> +0+000 <.text.data>:
> +[ 	]+[0-9a-f]+:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
> +[ 	]+[0-9a-f]+:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
> +[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
> +[ 	]+[0-9a-f]+:[ 	]+05000302[ 	]+.word[ 	]+0x05000302
> +
> +Disassembly of section .text.odd.align:
> +
> +0+000 <.text.odd.align>:
> +[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+01[ 	]+.byte[ 	]+0x01
> +[ 	]+[0-9a-f]+:[ 	]+00[ 	]+.byte[ 	]+0x00
> +[ 	]+[0-9a-f]+:[ 	]+00000013[ 	]+nop
> +[ 	]+[0-9a-f]+:[ 	]+00200513[ 	]+li[ 	]+a0,2
> +[ 	]+[0-9a-f]+:[ 	]+00000013[ 	]+nop
> +
> +Disassembly of section .text.zero.fill.first:
> +
> +0+000 <.text.zero.fill.first>:
> +[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
> +
> +Disassembly of section .text.zero.fill.last:
> +
> +0+000 <.text.zero.fill.last>:
> +[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
> +
> +Disassembly of section .text.zero.fill.align.A:
> +
> +0+000 <.text.zero.fill.align.A>:
> +[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
> +
> +Disassembly of section .text.zero.fill.align.B:
> +
> +0+000 <.text.zero.fill.align.B>:
> +[ 	]+[0-9a-f]+:[ 	]+00100513[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+00200513[ 	]+li[ 	]+a0,2
> +
> +Disassembly of section .text.last.section:
> +
> +0+000 <.text.last.section>:
> +[ 	]+[0-9a-f]+:[ 	]+00100513[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
> +
> +Disassembly of section .text.section.padding:
> +
> +0+000 <.text.section.padding>:
> +[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+0001[ 	]+nop
> +[ 	]+[0-9a-f]+:[ 	]+4509[ 	]+li[ 	]+a0,2
> +[ 	]+[0-9a-f]+:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
> +[ 	]+[0-9a-f]+:[ 	]+0001[ 	]+nop
> +
> +Disassembly of section .text.relax.align:
> +
> +0+000 <.text.relax.align>:
> +[ 	]+[0-9a-f]+:[ 	]+0001[ 	]+nop
> +[ 	]+[0-9a-f]+:[ 	]+4505[ 	]+li[ 	]+a0,1
> +[ 	]+[0-9a-f]+:[ 	]+00000013[ 	]+nop
> +[ 	]+[0-9a-f]+:[ 	]+00200513[ 	]+li[ 	]+a0,2
> +[ 	]+[0-9a-f]+:[ 	]+00000013[ 	]+nop
> diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.d b/gas/testsuite/gas/riscv/mapping-non-arch.d
> new file mode 100644
> index 00000000000..f69e719ff30
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-non-arch.d
> @@ -0,0 +1,17 @@
> +#as:
> +#source: mapping-non-arch.s
> +#objdump: --syms --special-syms
> +
> +.*file format.*riscv.*
> +
> +SYMBOL TABLE:
> +00+00 l    d  .text	00+00 .text
> +00+00 l    d  .data	00+00 .data
> +00+00 l    d  .bss	00+00 .bss
> +00+00 l       .text	00+00 \$x
> +00+08 l       .text	00+00 \$d
> +00+0c l       .text	00+00 \$x
> +00+00 l    d  text.A	00+00 text.A
> +00+00 l       text.A	00+00 \$x
> +00+02 l       text.A	00+00 \$d
> +00+00 l    d  .riscv.attributes	00+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-non-arch.s b/gas/testsuite/gas/riscv/mapping-non-arch.s
> new file mode 100644
> index 00000000000..03b2d75a5dd
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-non-arch.s
> @@ -0,0 +1,11 @@
> +.attribute arch, "rv32i"
> +.option arch, +c
> +.text
> +addi	a0, zero, 1
> +.align 3
> +.word 0x1
> +addi	a0, zero, 2
> +
> +.section text.A, "ax"
> +addi	a0, zero, 3
> +.word 0x2
> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03a.d b/gas/testsuite/gas/riscv/mapping-norelax-03a.d
> deleted file mode 100644
> index 916f732b7f7..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-norelax-03a.d
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -#as: -mno-relax
> -#source: mapping-03.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       .text	0+00 \$x
> -0+04 l       .text	0+00 \$d
> -0+08 l       .text	0+00 \$x
> -0+10 l       .text	0+00 \$d
> -0+14 l       .text	0+00 \$x
> -0+18 l       .text	0+00 \$d
> -0+20 l       .text	0+00 \$d
> -0+24 l       .text	0+00 \$x
> -0+1d l       .text	0+00 \$d
> -0+1e l       .text	0+00 \$x
> -0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03b.d b/gas/testsuite/gas/riscv/mapping-norelax-03b.d
> deleted file mode 100644
> index 9e777351d1d..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-norelax-03b.d
> +++ /dev/null
> @@ -1,25 +0,0 @@
> -#as: -mno-relax
> -#source: mapping-03.s
> -#objdump: -d
> -
> -.*:[ 	]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <.text>:
> -[ 	]+0:[ 	]+00a50533[ 	]+add[ 	]+a0,a0,a0
> -[ 	]+4:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
> -[ 	]+8:[ 	]+00000013[ 	]+nop
> -[ 	]+c:[ 	]+00000013[ 	]+nop
> -[ 	]+10:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
> -[ 	]+14:[ 	]+00b585b3[ 	]+add[ 	]+a1,a1,a1
> -[ 	]+18:[ 	]+00000302[ 	]+.word[ 	]+0x00000302
> -[ 	]+1c:[ 	]+00[ 	]+.byte[ 	]+0x00
> -[ 	]+1d:[ 	]+00[ 	]+.byte[ 	]+0x00
> -[ 	]+1e:[ 	]+0001[ 	]+.2byte[ 	]+0x1
> -[ 	]+20:[ 	]+00000005[ 	]+.word[ 	]+0x00000005
> -[ 	]+24:[ 	]+00000013[ 	]+nop
> -[ 	]+28:[ 	]+00000013[ 	]+nop
> -[ 	]+2c:[ 	]+00000013[ 	]+nop
> -#...
> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04a.d b/gas/testsuite/gas/riscv/mapping-norelax-04a.d
> deleted file mode 100644
> index d552a7f632a..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-norelax-04a.d
> +++ /dev/null
> @@ -1,16 +0,0 @@
> -#as: -mno-relax
> -#source: mapping-04.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       .text	0+00 \$d
> -0+14 l       .text	0+00 \$d
> -0+1e l       .text	0+00 \$x
> -0+0d l       .text	0+00 \$d
> -0+0e l       .text	0+00 \$x
> -0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04b.d b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
> deleted file mode 100644
> index be668f29220..00000000000
> --- a/gas/testsuite/gas/riscv/mapping-norelax-04b.d
> +++ /dev/null
> @@ -1,24 +0,0 @@
> -#as: -mno-relax
> -#source: mapping-04.s
> -#objdump: -d
> -
> -.*:[ 	]+file format .*
> -
> -
> -Disassembly of section .text:
> -
> -0+000 <.text>:
> -[ 	]+0:[ 	]+00001001[ 	]+.word[ 	]+0x00001001
> -[ 	]+4:[ 	]+00001001[ 	]+.word[ 	]+0x00001001
> -[ 	]+8:[ 	]+00000001[ 	]+.word[ 	]+0x00000001
> -[ 	]+c:[ 	]+00[ 	]+.byte[ 	]+0x00
> -[ 	]+d:[ 	]+00[ 	]+.byte[ 	]+0x00
> -[ 	]+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[ 	]+.2byte[ 	]+0x1
> -[ 	]+24:[ 	]+00000013[ 	]+nop
> -#...
> diff --git a/gas/testsuite/gas/riscv/mapping-symbols.d b/gas/testsuite/gas/riscv/mapping-symbols.d
> new file mode 100644
> index 00000000000..83ee6528b79
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-symbols.d
> @@ -0,0 +1,48 @@
> +#as:
> +#source: mapping.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.cross.section.A	0+00 .text.cross.section.A
> +0+00 l       .text.cross.section.A	0+00 \$xrv32i2p1_c2p0
> +0+00 l    d  .text.corss.section.B	0+00 .text.corss.section.B
> +0+00 l       .text.corss.section.B	0+00 \$xrv32i2p1_c2p0
> +0+02 l       .text.corss.section.B	0+00 \$xrv32i2p1
> +0+00 l    d  .text.data	0+00 .text.data
> +0+00 l       .text.data	0+00 \$d
> +0+08 l       .text.data	0+00 \$xrv32i2p1_c2p0
> +0+0c l       .text.data	0+00 \$d
> +0+00 l    d  .text.odd.align	0+00 .text.odd.align
> +0+00 l       .text.odd.align	0+00 \$xrv32i2p1_c2p0
> +0+02 l       .text.odd.align	0+00 \$d
> +0+08 l       .text.odd.align	0+00 \$xrv32i2p1
> +0+00 l    d  .text.zero.fill.first	0+00 .text.zero.fill.first
> +0+00 l       .text.zero.fill.first	0+00 \$xrv32i2p1_c2p0
> +0+00 l    d  .text.zero.fill.last	0+00 .text.zero.fill.last
> +0+00 l       .text.zero.fill.last	0+00 \$xrv32i2p1_c2p0
> +0+02 l       .text.zero.fill.last	0+00 \$x
> +0+00 l    d  .text.zero.fill.align.A	0+00 .text.zero.fill.align.A
> +0+00 l       .text.zero.fill.align.A	0+00 \$xrv32i2p1_c2p0
> +0+00 l    d  .text.zero.fill.align.B	0+00 .text.zero.fill.align.B
> +0+00 l       .text.zero.fill.align.B	0+00 \$xrv32i2p1
> +0+00 l    d  .text.last.section	0+00 .text.last.section
> +0+00 l       .text.last.section	0+00 \$xrv32i2p1
> +0+04 l       .text.last.section	0+00 \$d
> +0+00 l    d  .text.section.padding	0+00 .text.section.padding
> +0+00 l       .text.section.padding	0+00 \$xrv32i2p1_c2p0
> +0+04 l       .text.section.padding	0+00 \$xrv32i2p1_a2p1_c2p0
> +0+06 l       .text.section.padding	0+00 \$d
> +0+00 l    d  .text.relax.align	0+00 .text.relax.align
> +0+00 l       .text.relax.align	0+00 \$xrv32i2p1_c2p0
> +0+08 l       .text.relax.align	0+00 \$xrv32i2p1
> +0+0a l       .text.section.padding	0+00 \$x
> +0+03 l       .text.odd.align	0+00 \$d
> +0+04 l       .text.odd.align	0+00 \$x
> +0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
> +0+00 g       .text.cross.section.A	0+00 funcA
> +0+00 g       .text.corss.section.B	0+00 funcB
> diff --git a/gas/testsuite/gas/riscv/mapping.s b/gas/testsuite/gas/riscv/mapping.s
> new file mode 100644
> index 00000000000..a0e6c744107
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping.s
> @@ -0,0 +1,112 @@
> +.attribute arch, "rv32ic"
> +.option norelax			# FIXME: assembler fill the paddings after parsing everything,
> +				# so we probably won't fill anything for the norelax region when
> +				# the riscv_opts.relax is enabled at somewhere.
> +
> +.section .text.cross.section.A, "ax"
> +.option push
> +.global funcA
> +funcA:
> +addi	a0, zero, 1		# rv32i
> +.option arch, +c
> +j	funcA			# rv32ic
> +.section .text.corss.section.B, "ax"
> +.globl funcB
> +funcB:
> +addi	a0, zero, 2		# rv32ic, need to be added since start of section
> +.option arch, -c
> +j	funcB			# rv32i
> +.option pop
> +
> +.section .text.data, "ax"
> +.option push
> +.word	0			# $d
> +.long	1
> +addi	a0, zero, 1		# rv32ic
> +.data
> +.word	2			# don't add mapping symbols for non-text section
> +.section .text.data
> +addi	a0, zero, 2		# $x, but same as previous addi, so removed
> +.byte	2			# $d, dumped as .word
> +.short	3
> +.byte	5
> +.option pop
> +
> +.section .text.odd.align, "ax"
> +.option push
> +.option norelax
> +.option arch, +c
> +addi	a0, zero, 1		# $xrv32ic
> +.byte	1			# $d
> +.option arch, -c
> +.align	3			# odd alignment, $x replaced by $d + $x
> +addi	a0, zero, 2		# $xrv32i
> +.option pop
> +
> +.section .text.zero.fill.first, "ax"
> +.option push
> +.option norelax
> +.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol
> +addi	a0, zero, 1		# $xrv32ic
> +.option pop
> +
> +.section .text.zero.fill.last, "ax"
> +.option push
> +.option norelax
> +addi	a0, zero, 1		# $xrv32ic
> +.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol
> +addi	a0, zero, 2		# $x, FIXME: need find a way to remove?
> +.option pop
> +
> +# last overlap next first
> +.section .text.zero.fill.align.A, "ax"
> +.option push
> +.option norelax
> +.align	2			# $xrv32ic, .align and .fill are in the different frag, so neither be removed
> +.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
> +addi	a0, zero, 1		# $x, should be removed in riscv_check_mapping_symbols
> +addi	a0, zero, 2
> +.option pop
> +
> +# last overlap next first
> +.section .text.zero.fill.align.B, "ax"
> +.option push
> +.option norelax
> +.align	2			# $xrv32ic, .align and .fill are in the different frag, so neither be removed,
> +				# but will be removed in riscv_check_mapping_symbols
> +.fill	1, 0, 0			# $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
> +.option arch, -c
> +addi	a0, zero, 1		# $xrv32i
> +addi	a0, zero, 2
> +.option pop
> +
> +.section .text.last.section, "ax"
> +.option push
> +.option norelax
> +.option arch, -c
> +addi	a0, zero, 1		# $xrv32i
> +.word	1			# $d
> +.align	2			# zero section padding, $x at the end of section, removed in riscv_check_mapping_symbols
> +.option pop
> +
> +.section .text.section.padding, "ax"
> +.option push
> +.option norelax
> +.align	2
> +addi	a0, zero, 1		# $rv32ic
> +.option arch, +a
> +.align	2			# 2-byte padding, $x, removed
> +addi	a0, zero, 2		# $xrv32iac
> +.word	1			# $d
> +.option pop			# 2-byte padding, $x
> +
> +.section .text.relax.align, "ax"
> +.option push
> +.option relax
> +.option arch, rv32ic
> +.balign	4			# $xrv32ic, add at the start of section
> +addi	a0, zero, 1		# $x, won't added
> +.option arch, -c
> +.align	3			# $x, won't added
> +addi	a0, zero, 2		# $xrv32i
> +.option pop
> diff --git a/gas/testsuite/gas/riscv/option-arch-01a.d b/gas/testsuite/gas/riscv/option-arch-01a.d
> index aed4ca8e4d9..1d14c604dec 100644
> --- a/gas/testsuite/gas/riscv/option-arch-01a.d
> +++ b/gas/testsuite/gas/riscv/option-arch-01a.d
> @@ -10,5 +10,5 @@ Disassembly of section .text:
>  0+000 <.text>:
>  [ 	]+[0-9a-f]+:[  	]+952e[    	]+add[        	]+a0,a0,a1
>  [ 	]+[0-9a-f]+:[  	]+00b50533[    	]+add[        	]+a0,a0,a1
> -[ 	]+[0-9a-f]+:[  	]+00302573[    	]+csrr[        	]+a0,fcsr
> +[ 	]+[0-9a-f]+:[  	]+00302573[    	]+frcsr[        	]+a0
>  #...
> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> index f2d399260c1..eb88c81c0f1 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -696,6 +696,9 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
>        /* If arch has ZFINX flags, use gpr for disassemble.  */
>        if(riscv_subset_supports (&riscv_rps_dis, "zfinx"))
>  	riscv_fpr_names = riscv_gpr_names;
> +      else
> +	riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi ?
> +			  riscv_fpr_names_abi : riscv_fpr_names_numeric;
>  
>        for (; op->name; op++)
>  	{
> @@ -810,6 +813,12 @@ riscv_get_map_state (int n,
>      *state = MAP_INSN;
>    else if (strcmp (name, "$d") == 0)
>      *state = MAP_DATA;
> +  else if (strncmp (name, "$xrv", 4) == 0)
> +    {
> +      *state = MAP_INSN;
> +      riscv_release_subset_list (&riscv_subsets);
> +      riscv_parse_subset (&riscv_rps_dis, name + 2);
> +    }
>    else
>      return false;
>  

  parent reply	other threads:[~2022-10-03 11:17 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-30  9:20 Nelson Chu
2022-09-30  9:20 ` [PATCH 2/2] RISC-V: Refer mapping symbol to R_RISCV_RELAX for rvc relaxations Nelson Chu
2022-10-03 11:17 ` Tsukasa OI [this message]
2022-10-28  3:16 ` [PATCH 1/2] RISC-V: Output mapping symbols with ISA string Nelson Chu
2022-10-28  7:01   ` Tsukasa OI
2022-10-28  7:10     ` Kito Cheng
2022-10-28  9:23       ` Nelson Chu
2022-10-28 14:43         ` Tsukasa OI
  -- strict thread matches above, loose matches on Subject: below --
2022-09-30  8:58 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=3a3040fe-c9ce-85f9-d256-c6d35f6a14df@irq.a4lg.com \
    --to=research_trasio@irq.a4lg.com \
    --cc=binutils@sourceware.org \
    --cc=nelson@rivosinc.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).