public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 0/3]  RISC-V: The series to supporting mapping symbols
@ 2021-07-09  7:28 Nelson Chu
  2021-07-09  7:28 ` [PATCH v2 1/3] RISC-V: Enable elf attributes when default configure option isn't set Nelson Chu
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Nelson Chu @ 2021-07-09  7:28 UTC (permalink / raw)
  To: binutils, gdb-patches, jimw, andrew.burgess, kito.cheng, palmer, andrew

Hi Guys,

See in advance what are the difference with v1,
* Support data mapping symbols with the data size, if they are added
  by cons_worker, e.g. $d2, $d4.
* Support alignment mapping symbols, $a and $a1.  If the instructions
  are used for alignment, then we dump them with the prefix align.<insn>.
* Since the above two new features, we don't need to record all
  mapping symbols of the fragments.  Instead, only record the
  first and last mapping symbols should be enough.
* Extend .insn directive to support hardcode encoding.

These are all binutils changes, but not sure if the changes will break
the gdb disassembler.  Unfortunately I am not familiar with gdb, hope
gdb experts can give some suggestions, or warnings if something may be
broken.

Besides, the binutils readelf testcases in the second patch are affected
by the first patch, so I send them as the same series.  But in fact the
first patch can be regarded as an independent issue.  Therefore, I think
we can commit it separately first, if everything looks good.

The elf/linux toolchain regressions all passed, looks fine so far.

Thanks
Nelson



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

* [PATCH v2 1/3] RISC-V: Enable elf attributes when default configure option isn't set.
  2021-07-09  7:28 [PATCH v2 0/3] RISC-V: The series to supporting mapping symbols Nelson Chu
@ 2021-07-09  7:28 ` Nelson Chu
  2021-07-09  8:00   ` Kito Cheng
                     ` (2 more replies)
  2021-07-09  7:28 ` [PATCH v2 2/3] RISC-V: PR27916, Support mapping symbols Nelson Chu
  2021-07-09  7:28 ` [PATCH v2 3/3] RISC-V: PR27916, Extend .insn directive to support hardcode encoding Nelson Chu
  2 siblings, 3 replies; 13+ messages in thread
From: Nelson Chu @ 2021-07-09  7:28 UTC (permalink / raw)
  To: binutils, gdb-patches, jimw, andrew.burgess, kito.cheng, palmer, andrew

Since gcc commit, 3c70b3ca1ef58f302bf8c16d9e7c7bb8626408bf, we now enable
elf attributes for all riscv targets by default in gcc.  Therefore, I
think binutils should have the same behavior, in case users are writing
assembly files.

ChangLog:

binutils/

	* testsuite/binutils-all/readelf.s: Add comments for riscv.
	* testsuite/binutils-all/readelf.s-64: Likewise.
	* testsuite/binutils-all/readelf.s-64-unused: Likewise.
	* testsuite/binutils-all/readelf.ss: Likewise.
	* testsuite/binutils-all/readelf.ss-64: Likewise.
	* testsuite/binutils-all/readelf.ss-64-unused: Likewise.

gas/

	* configure.ac: If --enable-default-riscv-attribute isn't set,
	then we enable the elf attributes for all riscv targets by
	default.
	* configure: Regenerated.
---
 binutils/testsuite/binutils-all/readelf.s            | 3 ++-
 binutils/testsuite/binutils-all/readelf.s-64         | 2 ++
 binutils/testsuite/binutils-all/readelf.s-64-unused  | 2 ++
 binutils/testsuite/binutils-all/readelf.ss           | 1 +
 binutils/testsuite/binutils-all/readelf.ss-64        | 1 +
 binutils/testsuite/binutils-all/readelf.ss-64-unused | 1 +
 gas/configure                                        | 9 +--------
 gas/configure.ac                                     | 9 +--------
 8 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/binutils/testsuite/binutils-all/readelf.s b/binutils/testsuite/binutils-all/readelf.s
index 6ae4dc756b9..ff37acb4da8 100644
--- a/binutils/testsuite/binutils-all/readelf.s
+++ b/binutils/testsuite/binutils-all/readelf.s
@@ -11,9 +11,10 @@ Section Headers:
 #...
  +\[ .\] .* +PROGBITS +00000000 0000(3c|40|44|48|50) 0000(04|10) 00 +WA +0 +0 +(.|..)
  +\[ .\] .* +NOBITS +00000000 0000(40|44|48|4c|60) 000000 00 +WA +0 +0 +(.|..)
-# ARM targets put .ARM.attributes here
+# ARM targets put .ARM.attributes here.
 # MIPS targets put .reginfo, .mdebug, .MIPS.abiflags and .gnu.attributes here.
 # v850 targets put .call_table_data and .call_table_text here.
+# riscv targets put .riscv.attributes here.
 #...
  +\[..\] .symtab +SYMTAB +00000000 0+.* 0+.* 10 +.. +.+ +4
  +\[..\] .strtab +STRTAB +00000000 0+.* 0+.* 00 .* +0 +0 +1
diff --git a/binutils/testsuite/binutils-all/readelf.s-64 b/binutils/testsuite/binutils-all/readelf.s-64
index 92ec05f0376..4c957f7a938 100644
--- a/binutils/testsuite/binutils-all/readelf.s-64
+++ b/binutils/testsuite/binutils-all/readelf.s-64
@@ -14,10 +14,12 @@ Section Headers:
  +\[ 4\] .bss +NOBITS +0000000000000000 +000000(4c|50|54|58|68)
  +0000000000000000 +0000000000000000 +WA +0 +0 +.*
 # x86 targets may put .note.gnu.property here.
+# riscv targets put .riscv.attributes here.
 #...
  +\[ .\] .symtab +SYMTAB +0000000000000000 +0+.*
 # aarch64-elf targets have one more data symbol.
 # x86 targets may have .note.gnu.property.
+# riscv targets have .riscv.attributes.
  +0+.* +0000000000000018 +(6|7) +(3|4) +8
  +\[ .\] .strtab +STRTAB +0000000000000000 +0+.*
  +0+.* +0000000000000000 .* +0 +0 +1
diff --git a/binutils/testsuite/binutils-all/readelf.s-64-unused b/binutils/testsuite/binutils-all/readelf.s-64-unused
index a1e6cd1bbd8..771439411a0 100644
--- a/binutils/testsuite/binutils-all/readelf.s-64-unused
+++ b/binutils/testsuite/binutils-all/readelf.s-64-unused
@@ -14,10 +14,12 @@ Section Headers:
  +\[ 4\] .bss +NOBITS +0000000000000000 +000000(4c|50|54|58)
  +0000000000000000 +0000000000000000 +WA +0 +0 +.*
 # x86 targets may put .note.gnu.property here.
+# riscv targets put .riscv.attributes here.
 #...
  +\[ .\] .symtab +SYMTAB +0000000000000000 +0+.*
 # aarch64-elf targets have one more data symbol.
 # x86 targets may have .note.gnu.property.
+# riscv targets have .riscv.attributes.
  +0+.* +0000000000000018 +(6|7) +(6|7) +8
  +\[ .\] .strtab +STRTAB +0000000000000000 +0+.*
  +0+.* +0000000000000000 .* +0 +0 +1
diff --git a/binutils/testsuite/binutils-all/readelf.ss b/binutils/testsuite/binutils-all/readelf.ss
index 5fbb5d002e3..b81c016e9e7 100644
--- a/binutils/testsuite/binutils-all/readelf.ss
+++ b/binutils/testsuite/binutils-all/readelf.ss
@@ -9,6 +9,7 @@ Symbol table '.symtab' contains .* entries:
  +.: 00000000 +0 +NOTYPE +LOCAL +DEFAULT +[34] static_data_symbol
 # v850 targets include extra SECTION symbols here for the .call_table_data
 # and .call_table_text sections.
+# riscv targets add .riscv.attribute symbol here...
 #...
  +[0-9]+: 00000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
  +[0-9]+: 00000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
diff --git a/binutils/testsuite/binutils-all/readelf.ss-64 b/binutils/testsuite/binutils-all/readelf.ss-64
index 99a732f71f5..c6ffb0fc523 100644
--- a/binutils/testsuite/binutils-all/readelf.ss-64
+++ b/binutils/testsuite/binutils-all/readelf.ss-64
@@ -7,6 +7,7 @@ Symbol table '.symtab' contains .* entries:
 #...
  +.: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +3 static_data_symbol
 # ... or here ...
+# riscv targets add .riscv.attribute symbol here...
 #...
 .* +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
  +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
diff --git a/binutils/testsuite/binutils-all/readelf.ss-64-unused b/binutils/testsuite/binutils-all/readelf.ss-64-unused
index f48a4b2bbd2..cf515aa60d0 100644
--- a/binutils/testsuite/binutils-all/readelf.ss-64-unused
+++ b/binutils/testsuite/binutils-all/readelf.ss-64-unused
@@ -10,6 +10,7 @@ Symbol table '.symtab' contains .* entries:
 #...
  +.: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +3 static_data_symbol
 # ... or here ...
+# riscv targets add .riscv.attribute symbol here...
 #...
 .* +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
  +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
diff --git a/gas/configure b/gas/configure
index 110d707f079..7a528fd485e 100755
--- a/gas/configure
+++ b/gas/configure
@@ -12550,14 +12550,7 @@ _ACEOF
 
 
 if test ${ac_default_generate_riscv_attr} = unset; then
-    case ${target_os} in
-      elf)
-	ac_default_generate_riscv_attr=1
-	;;
-      *)
-	ac_default_generate_riscv_attr=0
-	;;
-  esac
+  ac_default_generate_riscv_attr=1
 fi
 
 
diff --git a/gas/configure.ac b/gas/configure.ac
index 78efba88e23..e2374268c56 100644
--- a/gas/configure.ac
+++ b/gas/configure.ac
@@ -727,14 +727,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_X86_USED_NOTE,
    properties by default.])
 
 if test ${ac_default_generate_riscv_attr} = unset; then
-    case ${target_os} in
-      elf)
-	ac_default_generate_riscv_attr=1
-	;;
-      *)
-	ac_default_generate_riscv_attr=0
-	;;
-  esac
+  ac_default_generate_riscv_attr=1
 fi
 
 AC_DEFINE_UNQUOTED(DEFAULT_RISCV_ATTR,
-- 
2.30.2


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

* [PATCH v2 2/3] RISC-V: PR27916, Support mapping symbols.
  2021-07-09  7:28 [PATCH v2 0/3] RISC-V: The series to supporting mapping symbols Nelson Chu
  2021-07-09  7:28 ` [PATCH v2 1/3] RISC-V: Enable elf attributes when default configure option isn't set Nelson Chu
@ 2021-07-09  7:28 ` Nelson Chu
  2021-07-15 15:16   ` Palmer Dabbelt
  2021-07-09  7:28 ` [PATCH v2 3/3] RISC-V: PR27916, Extend .insn directive to support hardcode encoding Nelson Chu
  2 siblings, 1 reply; 13+ messages in thread
From: Nelson Chu @ 2021-07-09  7:28 UTC (permalink / raw)
  To: binutils, gdb-patches, jimw, andrew.burgess, kito.cheng, palmer, andrew

Similar to ARM/AARCH64, we add mapping symbols in the symbol table,
to mark the start addresses of data and instructions.  The $d means
data, the $x means instruction, and the $a means code alignment.
Then the disassembler uses these symbols to decide whether we should
dump data or instruction.

For example,
$ cat tmp.s
  .text
  .option norelax
  .option norvc
  .fill 2, 4, 0x1001    # $d for 8 bytes fill data.
  .byte 1               # $d1
  .word 0               # $d4
  .align 3              # $a1 for align.byte, $a for align.nop.
  nop                   # $x
  .fill 5, 2, 0x2002    # $d for 10 bytes fill data.
  nop                   # $x
  .data
  .word 0x1             # No need to add mapping symbols.
  .word 0x2

$ riscv64-unknown-elf-as tmp.s -o tmp.o
$ riscv64-unknown-elf-objdump -D tmp.o

Disassembly of section .text:

0000000000000000 <.text>:
   0:   00001001                .word   0x00001001
   4:   00001001                .word   0x00001001
   8:   01                      .byte   0x01
   9:   00000000                .word   0x00000000
   d:   00                      align.byte
   e:   0001                    align.nop
  10:   00000013                nop
  14:   10001000                .word   0x20022002
  18:   10001000                .word   0x20022002
  1c:   1000                    .short  0x2002
  1e:   00000013                nop
  22:   0001                    align.nop
  24:   00000013                align.nop

Disassembly of section .data:

0000000000000000 <.data>:
   0:   00000001                .word   0x00000001
   4:   00000002                .word   0x00000002

Disassembly of section .riscv.attributes:

0000000000000000 <.riscv.attributes>:
   0:   00002d41                .word   0x00002d41
... skip ...

There are too many issues we can discuss from the above example,
so I just pick some of them that I think are important to mention.

* The documentation for -D says that on ARM platforms -D should
  disassemble instructions.  Therefore, they dump data by searching
  mapping symbols only when the DISASSEMBLE_DATA is set.  That causes
  the mapping symbols are useless for -D.  I am not sure if any riscv
  document had mentioned this, so I prefer to keep them useful, but
  only for text sections.  Otherwise, dump other sections as datas.

* If the data are written by cons_worker, then we add mapping symbols
  with the data size, to show more detials.  For example,

  .text
  .byte 1
  .word 0

  The $d1 is added for .byte, and $d4 is added for .word, so that
  we can show the code that is closer to the user's original code,
  rather than the data with 5 bytes size.

* Add the align.<insn> prefix if the instructions are used for
  alignment and marked with $a/$a1.  One of the benefits is that,
  we can distinguish c.nop and align.nop, when the rvc is disabled.
  The c.nop is illegal, but the align.nop is legal.

  Besides, we may dump .align.unimp at the end of sections when relax
  is enabled, this is expected.  Since the tail section alignments are
  not handled in the riscv_frag_align_code, and it cannot be filled with
  nops in the riscv_handle_align either.

The elf/linux toolchain regressions all passed.  Besides, I also
disable the mapping symbols internally, but use the new objudmp, the
regressions passed, too.  Therefore, the new objudmp should dump
the objects corretly, even if they don't have any mapping symbols.

ChangeLog:

bfd/

	pr 27916
	* cpu-riscv.c (riscv_elf_is_mapping_symbols): Define mapping symbols.
	* cpu-riscv.h: extern riscv_elf_is_mapping_symbols.
	* elfnn-riscv.c (riscv_maybe_function_sym): Do not choose mapping
	symbols as a function name.
	(riscv_elf_is_target_special_symbol): Add mapping symbols.

binutils/

	pr 27916
	* readelf (get_symbol_for_build_attribute): Filter data mapping
	symbols with size.
	* testsuite/binutils-all/readelf.s: Updated.
	* testsuite/binutils-all/readelf.s-64: Likewise.
	* testsuite/binutils-all/readelf.s-64-unused: Likewise.
	* testsuite/binutils-all/readelf.ss: Likewise.
	* testsuite/binutils-all/readelf.ss-64: Likewise.
	* testsuite/binutils-all/readelf.ss-64-unused: Likewise.

gas/

	pr 27916
	config/tc-riscv.c (make_mapping_symbol): Create a new mapping symbol.
	(riscv_mapping_state): Decide whether to create mapping symbol for
	frag_now.  Only add the mapping symbols to text sections.
	(riscv_add_odd_padding_symbol): Add the odd bytes of paddings for
	riscv_handle_align.
	(riscv_check_mapping_symbols): Remove any excess mapping symbols.
	(md_assemble): Marked as MAP_INSN.
	(riscv_frag_align_code): Marked as MAP_ALIGN.
	(riscv_init_frag): Add mapping symbols for frag, it usually called
	by frag_var.  Marked as MAP_DATA for rs_align and rs_fill, and
	marked as alignment MAP_ALIGN for rs_align_code.
	(s_riscv_insn): Marked as MAP_INSN.
	(riscv_adjust_symtab): Call riscv_check_mapping_symbols.
	* config/tc-riscv.h (md_cons_align): Defined to riscv_mapping_state
	with MAP_DATA_CONS[0|1|2|3].
	(TC_SEGMENT_INFO_TYPE): Record mapping state for each segment.
	(TC_FRAG_TYPE): Record the first and last mapping symbols for the
	fragments.  The first mapping symbol must be placed at the start
	of the fragment.
	(TC_FRAG_INIT): Defined to riscv_init_frag.
	* testsuite/gas/riscv/mapping-01.s: New testcase.
	* testsuite/gas/riscv/mapping-01a.d: Likewise.
	* testsuite/gas/riscv/mapping-01b.d: Likewise.
	* testsuite/gas/riscv/mapping-02.s: Likewise.
	* testsuite/gas/riscv/mapping-02a.d: Likewise.
	* testsuite/gas/riscv/mapping-02b.d: Likewise.
	* testsuite/gas/riscv/mapping-03.s: Likewise.
	* testsuite/gas/riscv/mapping-03a.d: Likewise.
	* testsuite/gas/riscv/mapping-03b.d: Likewise.
	* testsuite/gas/riscv/mapping-04.s: Likewise.
	* testsuite/gas/riscv/mapping-04a.d: Likewise.
	* testsuite/gas/riscv/mapping-04b.d: Likewise.
	* testsuite/gas/riscv/mapping-norelax-04a.d: Likewise.
	* testsuite/gas/riscv/mapping-norelax-04b.d: Likewise.
	* testsuite/gas/riscv/no-relax-align.d: Updated.
	* testsuite/gas/riscv/no-relax-align-2.d: Likewise.

include/

	pr 27916
	* opcode/riscv.h (enum riscv_seg_mstate): Added.

opcodes/

	pr 27916
	* riscv-dis.c (last_map_symbol, last_stop_offset, last_section,
	last_map_state): Added to dump sections with mapping symbols.
	(riscv_get_map_state): Get the mapping state from the symbol.
	(riscv_search_mapping_symbol): Check the sorted symbol table, and
	then find the suitable mapping symbol.
	(riscv_data_length): Decide which data size we should print.
	(riscv_disassemble_data): Dump the data contents.
	(riscv_disassemble_insn): Dump align.<insn> for MAP_ALIGN.
	(print_insn_riscv): Handle the mapping symbols.
	(riscv_symbol_is_valid): Marked mapping symbols as invalid.
---
 bfd/cpu-riscv.c                               |  10 +
 bfd/cpu-riscv.h                               |   3 +
 bfd/elfnn-riscv.c                             |  25 +-
 binutils/readelf.c                            |   8 +-
 binutils/testsuite/binutils-all/readelf.s-64  |   5 +-
 .../binutils-all/readelf.s-64-unused          |   5 +-
 binutils/testsuite/binutils-all/readelf.ss    |   2 +
 binutils/testsuite/binutils-all/readelf.ss-64 |   7 +-
 .../binutils-all/readelf.ss-64-unused         |   7 +-
 .../testsuite/binutils-all/readelf.ss-unused  |   2 +
 gas/config/tc-riscv.c                         | 223 ++++++++++++-
 gas/config/tc-riscv.h                         |  32 ++
 gas/testsuite/gas/riscv/mapping-01.s          |  18 +
 gas/testsuite/gas/riscv/mapping-01a.d         |  17 +
 gas/testsuite/gas/riscv/mapping-01b.d         |  21 ++
 gas/testsuite/gas/riscv/mapping-02.s          |  13 +
 gas/testsuite/gas/riscv/mapping-02a.d         |  15 +
 gas/testsuite/gas/riscv/mapping-02b.d         |  16 +
 gas/testsuite/gas/riscv/mapping-03.s          |  10 +
 gas/testsuite/gas/riscv/mapping-03a.d         |  16 +
 gas/testsuite/gas/riscv/mapping-03b.d         |  16 +
 gas/testsuite/gas/riscv/mapping-04.s          |  11 +
 gas/testsuite/gas/riscv/mapping-04a.d         |  21 ++
 gas/testsuite/gas/riscv/mapping-04b.d         |  24 ++
 gas/testsuite/gas/riscv/mapping-norelax-04a.d |  23 ++
 gas/testsuite/gas/riscv/mapping-norelax-04b.d |  25 ++
 gas/testsuite/gas/riscv/no-relax-align-2.d    |  19 +-
 gas/testsuite/gas/riscv/no-relax-align.d      |   4 +-
 include/opcode/riscv.h                        |  13 +
 opcodes/riscv-dis.c                           | 313 +++++++++++++++++-
 30 files changed, 885 insertions(+), 39 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/mapping-01.s
 create mode 100644 gas/testsuite/gas/riscv/mapping-01a.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-01b.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-02.s
 create mode 100644 gas/testsuite/gas/riscv/mapping-02a.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-02b.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-03.s
 create mode 100644 gas/testsuite/gas/riscv/mapping-03a.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-03b.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-04.s
 create mode 100644 gas/testsuite/gas/riscv/mapping-04a.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-04b.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04a.d
 create mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04b.d

diff --git a/bfd/cpu-riscv.c b/bfd/cpu-riscv.c
index 025e94afd34..dae76e7fdcc 100644
--- a/bfd/cpu-riscv.c
+++ b/bfd/cpu-riscv.c
@@ -140,3 +140,13 @@ riscv_get_priv_spec_class_from_numbers (unsigned int major,
   RISCV_GET_PRIV_SPEC_CLASS (buf, class_t);
   *class = class_t;
 }
+
+/* Define mapping symbols for riscv.  */
+
+bool
+riscv_elf_is_mapping_symbols (const char *name)
+{
+  return (!strncmp (name, "$d", 2)
+	  || !strncmp (name, "$x", 2)
+	  || !strncmp (name, "$a", 2));
+}
diff --git a/bfd/cpu-riscv.h b/bfd/cpu-riscv.h
index cafaca23be0..ed5ee7e60d5 100644
--- a/bfd/cpu-riscv.h
+++ b/bfd/cpu-riscv.h
@@ -79,3 +79,6 @@ riscv_get_priv_spec_class_from_numbers (unsigned int,
 					unsigned int,
 					unsigned int,
 					enum riscv_spec_class *);
+
+extern bool
+riscv_elf_is_mapping_symbols (const char *);
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 85a99f3d610..a10384cd4d3 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -5150,14 +5150,32 @@ riscv_elf_obj_attrs_arg_type (int tag)
   return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL;
 }
 
-/* PR27584, Omit local and empty symbols since they usually generated
-   for pcrel relocations.  */
+/* Do not choose mapping symbols as a function name.  */
+
+static bfd_size_type
+riscv_maybe_function_sym (const asymbol *sym,
+			  asection *sec,
+			  bfd_vma *code_off)
+{
+  if (sym->flags & BSF_LOCAL
+      && riscv_elf_is_mapping_symbols (sym->name))
+    return 0;
+
+  return _bfd_elf_maybe_function_sym (sym, sec, code_off);
+}
+
+/* Treat the following cases as target special symbols, they are
+   usually omitted.  */
 
 static bool
 riscv_elf_is_target_special_symbol (bfd *abfd, asymbol *sym)
 {
+  /* PR27584, local and empty symbols.  Since they are usually
+     generated for pcrel relocations.  */
   return (!strcmp (sym->name, "")
-	  || _bfd_elf_is_local_label_name (abfd, sym->name));
+	  || _bfd_elf_is_local_label_name (abfd, sym->name)
+	  /* PR27916, mapping symbols.  */
+	  || riscv_elf_is_mapping_symbols (sym->name));
 }
 
 static int
@@ -5245,6 +5263,7 @@ riscv_elf_modify_segment_map (bfd *abfd,
 #define elf_backend_grok_psinfo			riscv_elf_grok_psinfo
 #define elf_backend_object_p			riscv_elf_object_p
 #define elf_backend_write_core_note		riscv_write_core_note
+#define elf_backend_maybe_function_sym		riscv_maybe_function_sym
 #define elf_info_to_howto_rel			NULL
 #define elf_info_to_howto			riscv_info_to_howto_rela
 #define bfd_elfNN_bfd_relax_section		_bfd_riscv_relax_section
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 24ff069edf4..7560e0f6a51 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -20283,10 +20283,14 @@ get_symbol_for_build_attribute (Filedata *filedata,
 	  continue;
 
 	/* The AArch64 and ARM architectures define mapping symbols
-	   (eg $d, $x, $t) which we want to ignore.  */
+	   (eg $d, $x, $t) which we want to ignore.  Besides, riscv
+	   may defines data mapping symbols with size (eg $d1, $d2,
+	   $d4, $d8), which we also want to ignore.  */
 	if (ba_cache.strtab[sym->st_name] == '$'
 	    && ba_cache.strtab[sym->st_name + 1] != 0
-	    && ba_cache.strtab[sym->st_name + 2] == 0)
+	    && (ba_cache.strtab[sym->st_name + 2] == 0
+		|| (ba_cache.strtab[sym->st_name + 2] != 0
+		    && ba_cache.strtab[sym->st_name + 3] == 0)))
 	  continue;
 
 	if (is_open_attr)
diff --git a/binutils/testsuite/binutils-all/readelf.s-64 b/binutils/testsuite/binutils-all/readelf.s-64
index 4c957f7a938..0b1bafee537 100644
--- a/binutils/testsuite/binutils-all/readelf.s-64
+++ b/binutils/testsuite/binutils-all/readelf.s-64
@@ -19,8 +19,9 @@ Section Headers:
  +\[ .\] .symtab +SYMTAB +0000000000000000 +0+.*
 # aarch64-elf targets have one more data symbol.
 # x86 targets may have .note.gnu.property.
-# riscv targets have .riscv.attributes.
- +0+.* +0000000000000018 +(6|7) +(3|4) +8
+# riscv targets have five more symbols, one is .riscv.attributes,
+# others are mapping data symbols.
+ +0+.* +0000000000000018 +(6|7) +(3|4|8) +8
  +\[ .\] .strtab +STRTAB +0000000000000000 +0+.*
  +0+.* +0000000000000000 .* +0 +0 +1
  +\[ .\] .shstrtab +STRTAB +0000000000000000 +[0-9a-f]+
diff --git a/binutils/testsuite/binutils-all/readelf.s-64-unused b/binutils/testsuite/binutils-all/readelf.s-64-unused
index 771439411a0..542bbb70064 100644
--- a/binutils/testsuite/binutils-all/readelf.s-64-unused
+++ b/binutils/testsuite/binutils-all/readelf.s-64-unused
@@ -19,8 +19,9 @@ Section Headers:
  +\[ .\] .symtab +SYMTAB +0000000000000000 +0+.*
 # aarch64-elf targets have one more data symbol.
 # x86 targets may have .note.gnu.property.
-# riscv targets have .riscv.attributes.
- +0+.* +0000000000000018 +(6|7) +(6|7) +8
+# riscv targets have five more symbols, one is .riscv.attributes,
+# others are mapping data symbols.
+ +0+.* +0000000000000018 +(6|7) +(6|7|11) +8
  +\[ .\] .strtab +STRTAB +0000000000000000 +0+.*
  +0+.* +0000000000000000 .* +0 +0 +1
  +\[ .\] .shstrtab +STRTAB +0000000000000000 +[0-9a-f]+
diff --git a/binutils/testsuite/binutils-all/readelf.ss b/binutils/testsuite/binutils-all/readelf.ss
index b81c016e9e7..5d96649c2a0 100644
--- a/binutils/testsuite/binutils-all/readelf.ss
+++ b/binutils/testsuite/binutils-all/readelf.ss
@@ -5,8 +5,10 @@ Symbol table '.symtab' contains .* entries:
  +1: 00000000 +0 +NOTYPE +LOCAL +DEFAULT +1 static_text_symbol
 # ARM targets add the $d mapping symbol here...
 # NDS32 targets add the $d2 mapping symbol here...
+# riscv targets add the $d4 mapping symbols here...
 #...
  +.: 00000000 +0 +NOTYPE +LOCAL +DEFAULT +[34] static_data_symbol
+# ... or here ...
 # v850 targets include extra SECTION symbols here for the .call_table_data
 # and .call_table_text sections.
 # riscv targets add .riscv.attribute symbol here...
diff --git a/binutils/testsuite/binutils-all/readelf.ss-64 b/binutils/testsuite/binutils-all/readelf.ss-64
index c6ffb0fc523..105f1b88361 100644
--- a/binutils/testsuite/binutils-all/readelf.ss-64
+++ b/binutils/testsuite/binutils-all/readelf.ss-64
@@ -4,13 +4,14 @@ Symbol table '.symtab' contains .* entries:
  +0: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +UND 
  +1: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +1 static_text_symbol
 # aarch64-elf targets add the $d mapping symbol here...
+# riscv targets add the $d4 mapping symbols here...
 #...
  +.: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +3 static_data_symbol
 # ... or here ...
 # riscv targets add .riscv.attribute symbol here...
 #...
-.* +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
- +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
- +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +3 data_symbol
+.* +[0-9]+: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
+ +[0-9]+: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
+ +[0-9]+: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +3 data_symbol
  +[0-9]+: 0000000000000004 +4 +(COMMON|OBJECT) +GLOBAL +DEFAULT +COM common_symbol
 #pass
diff --git a/binutils/testsuite/binutils-all/readelf.ss-64-unused b/binutils/testsuite/binutils-all/readelf.ss-64-unused
index cf515aa60d0..50fca025b31 100644
--- a/binutils/testsuite/binutils-all/readelf.ss-64-unused
+++ b/binutils/testsuite/binutils-all/readelf.ss-64-unused
@@ -7,13 +7,14 @@ Symbol table '.symtab' contains .* entries:
  +3: 0000000000000000 +0 +SECTION +LOCAL +DEFAULT +4.*
  +4: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +1 static_text_symbol
 # aarch64-elf targets add the $d mapping symbol here...
+# riscv targets add the $d4 mapping symbols here...
 #...
  +.: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +3 static_data_symbol
 # ... or here ...
 # riscv targets add .riscv.attribute symbol here...
 #...
-.* +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
- +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
- +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +3 data_symbol
+.* +[0-9]+: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
+ +[0-9]+: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
+ +[0-9]+: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +3 data_symbol
  +[0-9]+: 0000000000000004 +4 +(COMMON|OBJECT) +GLOBAL +DEFAULT +COM common_symbol
 #pass
diff --git a/binutils/testsuite/binutils-all/readelf.ss-unused b/binutils/testsuite/binutils-all/readelf.ss-unused
index 3107af930eb..944ab45cc46 100644
--- a/binutils/testsuite/binutils-all/readelf.ss-unused
+++ b/binutils/testsuite/binutils-all/readelf.ss-unused
@@ -8,8 +8,10 @@ Symbol table '.symtab' contains .* entries:
  +4: 00000000 +0 +NOTYPE +LOCAL +DEFAULT +1 static_text_symbol
 # ARM targets add the $d mapping symbol here...
 # NDS32 targets add the $d2 mapping symbol here...
+# riscv targets add the $d4 mapping symbols here...
 #...
  +.: 00000000 +0 +NOTYPE +LOCAL +DEFAULT +[34] static_data_symbol
+# ... or here ...
 # v850 targets include extra SECTION symbols here for the .call_table_data
 # and .call_table_text sections.
 #...
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index df37579c843..55c49471825 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -561,6 +561,179 @@ static bool explicit_priv_attr = false;
 
 static char *expr_end;
 
+/* Create a new mapping symbol for the transition to STATE.  */
+
+static void
+make_mapping_symbol (enum riscv_seg_mstate state,
+		     valueT value,
+		     fragS *frag)
+{
+  const char *name;
+  switch (state)
+    {
+    case MAP_DATA:
+      name = "$d";
+      break;
+    case MAP_DATA_CONS0:
+      name = "$d1";
+      break;
+    case MAP_DATA_CONS1:
+      name = "$d2";
+      break;
+    case MAP_DATA_CONS2:
+      name = "$d4";
+      break;
+    case MAP_DATA_CONS3:
+      name = "$d8";
+      break;
+    case MAP_INSN:
+      name = "$x";
+      break;
+    case MAP_ALIGN:
+      name = "$a";
+      break;
+    case MAP_ALIGN_ODD:
+      name = "$a1";
+      break;
+    default:
+      abort ();
+    }
+
+  symbolS *symbol = symbol_new (name, now_seg, frag, value);
+  symbol_get_bfdsym (symbol)->flags |= (BSF_NO_FLAGS | BSF_LOCAL);
+
+  /* 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.  */
+  if (value == 0)
+    {
+       if (frag->tc_frag_data.first_map_symbol != NULL)
+	{
+	  know (S_GET_VALUE (frag->tc_frag_data.first_map_symbol)
+		== S_GET_VALUE (symbol));
+	  /* Remove the old one.  */
+	  symbol_remove (frag->tc_frag_data.first_map_symbol,
+			 &symbol_rootP, &symbol_lastP);
+	}
+      frag->tc_frag_data.first_map_symbol = symbol;
+    }
+  if (frag->tc_frag_data.last_map_symbol != 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));
+      /* 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);
+    }
+  frag->tc_frag_data.last_map_symbol = symbol;
+}
+
+/* Set the mapping state for frag_now.  */
+
+void
+riscv_mapping_state (enum riscv_seg_mstate to_state,
+		     int max_chars)
+{
+  enum riscv_seg_mstate from_state =
+	seg_info (now_seg)->tc_segment_info_data.map_state;
+
+  if (!SEG_NORMAL (now_seg)
+      /* For now I 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.  */
+      || !subseg_text_p (now_seg))
+    return;
+
+  /* Keep inserting the MAP_DATA_CONS in text.  Otherwise, the mapping
+     symbol should be emitted.  */
+  if (from_state == to_state
+      && from_state != MAP_DATA_CONS0
+      && from_state != MAP_DATA_CONS1
+      && from_state != MAP_DATA_CONS2
+      && from_state != MAP_DATA_CONS3)
+    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);
+}
+
+/* Add the odd bytes of paddings for riscv_handle_align.  */
+
+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_ALIGN_ODD, frag->fr_fix, frag);
+  make_mapping_symbol (MAP_ALIGN, frag->fr_fix + 1, frag);
+}
+
+/* Remove any excess mapping symbols generated for alignment frags in
+   SEC.  We may have created a mapping symbol before a zero byte
+   alignment; remove it if there's a mapping symbol after the
+   alignment.  */
+
+static void
+riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
+			     asection *sec,
+			     void *dummy ATTRIBUTE_UNUSED)
+{
+  segment_info_type *seginfo = seg_info (sec);
+  fragS *fragp;
+
+  if (seginfo == NULL || seginfo->frchainP == NULL)
+    return;
+
+  for (fragp = seginfo->frchainP->frch_root;
+       fragp != NULL;
+       fragp = fragp->fr_next)
+    {
+      symbolS *last = fragp->tc_frag_data.last_map_symbol;
+      fragS *next = fragp->fr_next;
+
+      if (last == NULL || next == NULL)
+	continue;
+
+      /* Check the last mapping symbol if it is at the boundary of
+	 fragmnet.  */
+      if (S_GET_VALUE (last) < next->fr_address)
+	continue;
+      know (S_GET_VALUE (last) == next->fr_address);
+
+      do
+	{
+	  if (next->tc_frag_data.first_map_symbol != NULL)
+	    {
+	      /* The last mapping symbol overlaps with another one
+		 which at the start of the next frag.  */
+	      symbol_remove (last, &symbol_rootP, &symbol_lastP);
+	      break;
+	    }
+
+	  if (next->fr_next == NULL)
+	    {
+	      /* The last mapping symbol is at the end of the section.  */
+	      know (next->fr_fix == 0 && next->fr_var == 0);
+	      symbol_remove (last, &symbol_rootP, &symbol_lastP);
+	      break;
+	    }
+
+	  /* Since we may have empty frags without any mapping symbols,
+	     keep looking until the non-empty frag.  */
+	  if (next->fr_address != next->fr_next->fr_address)
+	    break;
+
+	  next = next->fr_next;
+	}
+      while (next != NULL);
+    }
+}
+
 /* The default target format to use.  */
 
 const char *
@@ -2767,6 +2940,8 @@ md_assemble (char *str)
        return;
     }
 
+  riscv_mapping_state (MAP_INSN, 0);
+
   const char *error = riscv_ip (str, &insn, &imm_expr, &imm_reloc, op_hash);
 
   if (error)
@@ -3422,6 +3597,8 @@ 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_ALIGN, worst_case_bytes);
+
   return true;
 }
 
@@ -3441,6 +3618,7 @@ riscv_handle_align (fragS *fragP)
 	  /* We have 4 byte uncompressed nops.  */
 	  bfd_signed_vma size = 4;
 	  bfd_signed_vma excess = bytes % size;
+	  bfd_boolean odd_padding = (excess % 2 == 1);
 	  char *p = fragP->fr_literal + fragP->fr_fix;
 
 	  if (bytes <= 0)
@@ -3449,12 +3627,20 @@ riscv_handle_align (fragS *fragP)
 	  /* Insert zeros or compressed nops to get 4 byte alignment.  */
 	  if (excess)
 	    {
+	      if (odd_padding)
+		riscv_add_odd_padding_symbol (fragP);
 	      riscv_make_nops (p, excess);
 	      fragP->fr_fix += excess;
 	      p += excess;
 	    }
 
-	  /* Insert variable number of 4 byte uncompressed nops.  */
+	  /* The frag will be changed to `rs_fill` later.  The function
+	     `write_contents` will try to fill the remaining spaces
+	     according to the patterns we give.  In this case, we give
+	     a 4 byte uncompressed nop as the pattern, and set the size
+	     of the pattern into `fr_var`.  The nop will be output to the
+	     file `fr_offset` times.  However, `fr_offset` could be zero
+	     if we don't need to pad the boundary finally.  */
 	  riscv_make_nops (p, size);
 	  fragP->fr_var = size;
 	}
@@ -3465,6 +3651,30 @@ riscv_handle_align (fragS *fragP)
     }
 }
 
+/* This usually called from frag_var.  */
+
+void
+riscv_init_frag (fragS * fragP, int max_chars)
+{
+  /* Do not add mapping symbol to debug sections.  */
+  if (bfd_section_flags (now_seg) & SEC_DEBUGGING)
+    return;
+
+  switch (fragP->fr_type)
+    {
+    case rs_fill:
+    case rs_align:
+    case rs_align_test:
+      riscv_mapping_state (MAP_DATA, max_chars);
+      break;
+    case rs_align_code:
+      riscv_mapping_state (MAP_ALIGN, max_chars);
+      break;
+    default:
+      break;
+    }
+}
+
 int
 md_estimate_size_before_relax (fragS *fragp, asection *segtype)
 {
@@ -3721,6 +3931,8 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
   save_c = *input_line_pointer;
   *input_line_pointer = '\0';
 
+  riscv_mapping_state (MAP_INSN, 0);
+
   const char *error = riscv_ip (str, &insn, &imm_expr,
 				&imm_reloc, insn_type_hash);
 
@@ -3811,6 +4023,15 @@ riscv_md_end (void)
   riscv_set_public_attributes ();
 }
 
+/* Adjust the symbol table.  */
+
+void
+riscv_adjust_symtab (void)
+{
+  bfd_map_over_sections (stdoutput, riscv_check_mapping_symbols, (char *) 0);
+  elf_adjust_symtab ();
+}
+
 /* Given a symbolic attribute NAME, return the proper integer value.
    Returns -1 if the attribute is not known.  */
 
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index 1de138458d8..1702b25bc51 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -128,4 +128,36 @@ extern void riscv_elf_final_processing (void);
 extern void riscv_md_end (void);
 extern int riscv_convert_symbolic_attribute (const char *);
 
+/* Set mapping symbol states.  */
+#define md_cons_align(nbytes)					\
+  switch (nbytes)						\
+    {								\
+    default: riscv_mapping_state (MAP_DATA, 0); break;		\
+    case 1:  riscv_mapping_state (MAP_DATA_CONS0, 0); break;	\
+    case 2:  riscv_mapping_state (MAP_DATA_CONS1, 0); break;	\
+    case 4:  riscv_mapping_state (MAP_DATA_CONS2, 0); break;	\
+    case 8:  riscv_mapping_state (MAP_DATA_CONS3, 0); break;	\
+    }
+void riscv_mapping_state (enum riscv_seg_mstate, int);
+
+/* 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;
+};
+
+/* Define target fragment type.  */
+#define TC_FRAG_TYPE struct riscv_frag_type
+struct riscv_frag_type
+{
+  symbolS *first_map_symbol, *last_map_symbol;
+};
+
+#define TC_FRAG_INIT(fragp, max_bytes) riscv_init_frag (fragp, max_bytes)
+extern void riscv_init_frag (struct frag *, int);
+
+#define obj_adjust_symtab() riscv_adjust_symtab ()
+extern void riscv_adjust_symtab (void);
+
 #endif /* TC_RISCV */
diff --git a/gas/testsuite/gas/riscv/mapping-01.s b/gas/testsuite/gas/riscv/mapping-01.s
new file mode 100644
index 00000000000..0a270454b1b
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-01.s
@@ -0,0 +1,18 @@
+	.option norvc
+	.text
+	.global	funcA
+funcA:
+	nop
+	j	funcB
+
+	.global	funcB
+funcB:
+	nop
+	bne	a0, a1, funcB
+
+	.data
+	.word 0x123456
+
+	.section	.foo, "ax"
+foo:
+	nop
diff --git a/gas/testsuite/gas/riscv/mapping-01a.d b/gas/testsuite/gas/riscv/mapping-01a.d
new file mode 100644
index 00000000000..32e0027a13d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-01a.d
@@ -0,0 +1,17 @@
+#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
new file mode 100644
index 00000000000..723bd5951cb
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-01b.d
@@ -0,0 +1,21 @@
+#as:
+#source: mapping-01.s
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <funcA>:
+[ 	]+0:[ 	]+00000013[ 	]+nop
+[ 	]+4:[ 	]+0040006f[ 	]+j[ 	]+8 <funcB>
+
+0+008 <funcB>:
+[ 	]+8:[ 	]+00000013[ 	]+nop
+[ 	]+c:[ 	]+feb51ee3[ 	]+bne[ 	]+a0,a1,8 <funcB>
+
+Disassembly of section .foo:
+
+0+000 <foo>:
+[ 	]+0:[ 	]+00000013[ 	]+nop
diff --git a/gas/testsuite/gas/riscv/mapping-02.s b/gas/testsuite/gas/riscv/mapping-02.s
new file mode 100644
index 00000000000..d3de6dedac8
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-02.s
@@ -0,0 +1,13 @@
+	.option norvc
+	.text
+	.global main
+	.type   main, %function
+main:
+	nop
+foo:
+	nop
+	nop
+	.size   main, .-main
+	.ident  ""
+
+	nop
diff --git a/gas/testsuite/gas/riscv/mapping-02a.d b/gas/testsuite/gas/riscv/mapping-02a.d
new file mode 100644
index 00000000000..d0cb460e08e
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-02a.d
@@ -0,0 +1,15 @@
+#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 \$x
+0+04 l       .text	0+00 foo
+0+00 l    d  .comment	0+00 .comment
+0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
+0+00 g     F .text	0+0c main
diff --git a/gas/testsuite/gas/riscv/mapping-02b.d b/gas/testsuite/gas/riscv/mapping-02b.d
new file mode 100644
index 00000000000..3e875600a9c
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-02b.d
@@ -0,0 +1,16 @@
+#as:
+#source: mapping-02.s
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <main>:
+[ 	]+0:[ 	]+00000013[ 	]+nop
+
+0+004 <foo>:
+[ 	]+4:[ 	]+00000013[ 	]+nop
+[ 	]+8:[ 	]+00000013[ 	]+nop
+[ 	]+c:[ 	]+00000013[ 	]+nop
diff --git a/gas/testsuite/gas/riscv/mapping-03.s b/gas/testsuite/gas/riscv/mapping-03.s
new file mode 100644
index 00000000000..49964f20288
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-03.s
@@ -0,0 +1,10 @@
+	.option norvc
+	.text
+	.word 0
+	nop
+	.data
+	.word 0
+	.text
+	nop
+	.short 0
+	nop
diff --git a/gas/testsuite/gas/riscv/mapping-03a.d b/gas/testsuite/gas/riscv/mapping-03a.d
new file mode 100644
index 00000000000..8567820b941
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-03a.d
@@ -0,0 +1,16 @@
+#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 \$d4
+0+04 l       .text	0+00 \$x
+0+0c l       .text	0+00 \$d2
+0+0e l       .text	0+00 \$x
+0+12 l       .text	0+00 \$a
+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
new file mode 100644
index 00000000000..ed87fcf33d2
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-03b.d
@@ -0,0 +1,16 @@
+#as:
+#source: mapping-03.s
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ 	]+0:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
+[ 	]+4:[ 	]+00000013[ 	]+nop
+[ 	]+8:[ 	]+00000013[ 	]+nop
+[ 	]+c:[ 	]+0000[ 	]+.short[ 	]+0x0000
+[ 	]+e:[ 	]+00000013[ 	]+nop
+#...
diff --git a/gas/testsuite/gas/riscv/mapping-04.s b/gas/testsuite/gas/riscv/mapping-04.s
new file mode 100644
index 00000000000..36bfac11050
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-04.s
@@ -0,0 +1,11 @@
+	.option norvc
+	.text
+	nop
+	.long	0
+	.align	4
+	.word	0x12345678
+	nop
+	.byte	1
+	.long	0
+	.align	4
+	.word	0x12345678
diff --git a/gas/testsuite/gas/riscv/mapping-04a.d b/gas/testsuite/gas/riscv/mapping-04a.d
new file mode 100644
index 00000000000..a3bb31a98b4
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-04a.d
@@ -0,0 +1,21 @@
+#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 \$x
+0+04 l       .text	0+00 \$d4
+0+08 l       .text	0+00 \$a
+0+14 l       .text	0+00 \$d4
+0+18 l       .text	0+00 \$x
+0+1c l       .text	0+00 \$d1
+0+1d l       .text	0+00 \$d4
+0+21 l       .text	0+00 \$a
+0+2d l       .text	0+00 \$d4
+0+31 l       .text	0+00 \$a
+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
new file mode 100644
index 00000000000..d27b98db2ae
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-04b.d
@@ -0,0 +1,24 @@
+#as:
+#source: mapping-04.s
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ 	]+0:[ 	]+00000013[ 	]+nop
+[ 	]+4:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
+[ 	]+8:[ 	]+00000013[ 	]+align.nop
+[ 	]+c:[ 	]+00000013[ 	]+align.nop
+[ 	]+10:[ 	]+00000013[ 	]+align.nop
+[ 	]+14:[ 	]+12345678[ 	]+.word[ 	]+0x12345678
+[ 	]+18:[ 	]+00000013[ 	]+nop
+[ 	]+1c:[ 	]+01[ 	]+.byte[ 	]+0x01
+[ 	]+1d:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
+[ 	]+21:[ 	]+00000013[ 	]+align.nop
+[ 	]+25:[ 	]+00000013[ 	]+align.nop
+[ 	]+29:[ 	]+00000013[ 	]+align.nop
+[ 	]+2d:[ 	]+12345678[ 	]+.word[ 	]+0x12345678
+#...
diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04a.d b/gas/testsuite/gas/riscv/mapping-norelax-04a.d
new file mode 100644
index 00000000000..785b9d9f922
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-norelax-04a.d
@@ -0,0 +1,23 @@
+#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 \$x
+0+04 l       .text	0+00 \$d4
+0+08 l       .text	0+00 \$a
+0+10 l       .text	0+00 \$d4
+0+14 l       .text	0+00 \$x
+0+18 l       .text	0+00 \$d1
+0+19 l       .text	0+00 \$d4
+0+20 l       .text	0+00 \$d4
+0+24 l       .text	0+00 \$a
+0+1d l       .text	0+00 \$a1
+0+1e l       .text	0+00 \$a
+# Maybe section symbol for .riscv.attributes
+#...
diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04b.d b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
new file mode 100644
index 00000000000..8765c6cd129
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
@@ -0,0 +1,25 @@
+#as: -mno-relax
+#source: mapping-04.s
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ 	]+0:[ 	]+00000013[ 	]+nop
+[ 	]+4:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
+[ 	]+8:[ 	]+00000013[ 	]+align.nop
+[ 	]+c:[ 	]+00000013[ 	]+align.nop
+[ 	]+10:[ 	]+12345678[ 	]+.word[ 	]+0x12345678
+[ 	]+14:[ 	]+00000013[ 	]+nop
+[ 	]+18:[ 	]+01[ 	]+.byte[ 	]+0x01
+[ 	]+19:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
+[ 	]+1d:[ 	]+00[ 	]+align.byte
+[ 	]+1e:[ 	]+0001[ 	]+align.nop
+[ 	]+20:[ 	]+12345678[ 	]+.word[ 	]+0x12345678
+[ 	]+24:[ 	]+00000013[ 	]+align.nop
+[ 	]+28:[ 	]+00000013[ 	]+align.nop
+[ 	]+2c:[ 	]+00000013[ 	]+align.nop
+#...
diff --git a/gas/testsuite/gas/riscv/no-relax-align-2.d b/gas/testsuite/gas/riscv/no-relax-align-2.d
index 7407b495a8f..3c4323cc186 100644
--- a/gas/testsuite/gas/riscv/no-relax-align-2.d
+++ b/gas/testsuite/gas/riscv/no-relax-align-2.d
@@ -7,13 +7,14 @@
 Disassembly of section .text:
 
 0+000 <.text>:
-[ 	]+0:[ 	]+0000[ 	]+unimp
-[ 	]+2:[ 	]+0001[ 	]+nop
-[ 	]+4:[ 	]+00000013[ 	]+nop
-[ 	]+8:[ 	]+00000013[ 	]+nop
-[ 	]+c:[ 	]+00000013[ 	]+nop
+[ 	]+0:[ 	]+00[ 	]+.byte[ 	]+0x00
+[ 	]+1:[ 	]+00[ 	]+align.byte
+[ 	]+2:[ 	]+0001[ 	]+align.nop
+[ 	]+4:[ 	]+00000013[ 	]+align.nop
+[ 	]+8:[ 	]+00000013[ 	]+align.nop
+[ 	]+c:[ 	]+00000013[ 	]+align.nop
 [ 	]+10:[ 	]+0001[ 	]+nop
-[ 	]+12:[ 	]+0001[ 	]+nop
-[ 	]+14:[ 	]+00000013[ 	]+nop
-[ 	]+18:[ 	]+00000013[ 	]+nop
-[ 	]+1c:[ 	]+00000013[ 	]+nop
+[ 	]+12:[ 	]+0001[ 	]+align.nop
+[ 	]+14:[ 	]+00000013[ 	]+align.nop
+[ 	]+18:[ 	]+00000013[ 	]+align.nop
+[ 	]+1c:[ 	]+00000013[ 	]+align.nop
diff --git a/gas/testsuite/gas/riscv/no-relax-align.d b/gas/testsuite/gas/riscv/no-relax-align.d
index ced07d3c830..960db2a58bc 100644
--- a/gas/testsuite/gas/riscv/no-relax-align.d
+++ b/gas/testsuite/gas/riscv/no-relax-align.d
@@ -9,5 +9,5 @@ Disassembly of section .text:
 0+000 <.text>:
 [ 	]+0:[ 	]+00000013[ 	]+nop
 [ 	]+4:[ 	]+00000013[ 	]+nop
-[ 	]+8:[ 	]+00000013[ 	]+nop
-[ 	]+c:[ 	]+00000013[ 	]+nop
+[ 	]+8:[ 	]+00000013[ 	]+align.nop
+[ 	]+c:[ 	]+00000013[ 	]+align.nop
diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
index fdf3df4f5c1..3cea9e93c96 100644
--- a/include/opcode/riscv.h
+++ b/include/opcode/riscv.h
@@ -425,6 +425,19 @@ enum
   M_NUM_MACROS
 };
 
+/* The mapping symbol states.  */
+enum riscv_seg_mstate
+{
+  MAP_NONE = 0,		/* Must be zero, for seginfo in new sections.  */
+  MAP_DATA,		/* The rs_fill and rs_align.  */
+  MAP_DATA_CONS0,	/* Added for cons_worker, with the data size.  */
+  MAP_DATA_CONS1,
+  MAP_DATA_CONS2,
+  MAP_DATA_CONS3,
+  MAP_INSN,		/* Instructions.  */
+  MAP_ALIGN,		/* The rs_align_code, added nops.  */
+  MAP_ALIGN_ODD,	/* The rs_align_code, added odd byte.  */
+};
 
 extern const char * const riscv_gpr_names_numeric[NGPR];
 extern const char * const riscv_gpr_names_abi[NGPR];
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index fe8dfb88d90..b41cad8f4aa 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -41,6 +41,12 @@ struct riscv_private_data
   bfd_vma hi_addr[OP_MASK_RD + 1];
 };
 
+/* Used for mapping symbols.  */
+static int last_map_symbol = -1;
+static bfd_vma last_stop_offset = 0;
+static asection *last_section = NULL;
+enum riscv_seg_mstate last_map_state;
+
 static const char * const *riscv_gpr_names;
 static const char * const *riscv_fpr_names;
 
@@ -507,6 +513,27 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
 	  if ((op->xlen_requirement != 0) && (op->xlen_requirement != xlen))
 	    continue;
 
+	  /* Add the "align." prefix if it is used for alignment.
+
+	     Consider the following case,
+	     .text
+	     .byte 0
+	     nop
+
+	     0000000000000000 <.text>:
+	     0:	00		.byte   0x00
+	     1:	00000013	nop
+	     5:	0000		align.unimp
+		...
+
+	     The tail section alignments are not handled in the
+	     riscv_frag_align_code, and since the relax is enable,
+	     it cannot be filled with nops in the riscv_handle_align
+	     either.  Therefore, we may get align.unimp at the end
+	     of the sections, I think this is expected.  */
+	  if (last_map_state == MAP_ALIGN)
+	    (*info->fprintf_func) (info->stream, "align.");
+
 	  /* It's a match.  */
 	  (*info->fprintf_func) (info->stream, "%s", op->name);
 	  print_insn_args (op->args, word, memaddr, info);
@@ -556,13 +583,238 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
   return insnlen;
 }
 
+/* Return true if we find the suitable mapping symbol,
+   and also update the STATE.  Otherwise, return false.  */
+
+static bool
+riscv_get_map_state (int n,
+		     enum riscv_seg_mstate *state,
+		     struct disassemble_info *info)
+{
+  const char *name;
+
+  /* If the symbol is in a different section, ignore it.  */
+  if (info->section != NULL
+      && info->section != info->symtab[n]->section)
+    return false;
+
+  name = bfd_asymbol_name(info->symtab[n]);
+  if (strcmp (name, "$x") == 0)
+    *state = MAP_INSN;
+  else if (strcmp (name, "$d") == 0)
+    *state = MAP_DATA;
+  else if (strcmp (name, "$d1") == 0)
+    *state = MAP_DATA_CONS0;
+  else if (strcmp (name, "$d2") == 0)
+    *state = MAP_DATA_CONS1;
+  else if (strcmp (name, "$d4") == 0)
+    *state = MAP_DATA_CONS2;
+  else if (strcmp (name, "$d8") == 0)
+    *state = MAP_DATA_CONS3;
+  else if (strcmp (name, "$a") == 0)
+    *state = MAP_ALIGN;
+  else if (strcmp (name, "$a1") == 0)
+    *state = MAP_ALIGN_ODD;
+  else
+    return false;
+
+  return true;
+}
+
+/* Check the sorted symbol table (sorted by the symbol value), find the
+   suitable mapping symbols.  */
+
+static enum riscv_seg_mstate
+riscv_search_mapping_symbol (bfd_vma memaddr,
+			     struct disassemble_info *info)
+{
+  enum riscv_seg_mstate mstate;
+  bool from_last_map_symbol;
+  bool found = false;
+  int symbol = -1;
+  int n;
+
+  /* Decide whether to print the data or instruction by default, in case
+     we can not find the corresponding mapping symbols.  */
+  mstate = MAP_DATA;
+  if ((info->section
+       && info->section->flags & SEC_CODE)
+      || !info->section)
+    mstate = MAP_INSN;
+
+  if (info->symtab_size == 0
+      || bfd_asymbol_flavour (*info->symtab) != bfd_target_elf_flavour)
+    return mstate;
+
+  /* Reset the last_map_symbol if we start to dump a new section.  */
+  if (memaddr <= 0)
+    last_map_symbol = -1;
+
+  /* If the last stop offset is different from the current one, then
+     don't use the last_map_symbol to search.  We usually reset the
+     info->stop_offset when handling a new section.  */
+  from_last_map_symbol = (last_map_symbol >= 0
+			  && info->stop_offset == last_stop_offset);
+
+  /* Start scanning at the start of the function, or wherever
+     we finished last time.  */
+  n = info->symtab_pos + 1;
+  if (from_last_map_symbol && n >= last_map_symbol)
+    n = last_map_symbol;
+
+  /* Find the suitable mapping symbol to dump.  */
+  for (; n < info->symtab_size; n++)
+    {
+      bfd_vma addr = bfd_asymbol_value (info->symtab[n]);
+      /* We have searched all possible symbols in the range.  */
+      if (addr > memaddr)
+	break;
+      if (riscv_get_map_state (n, &mstate, info))
+	{
+	  symbol = n;
+	  found = true;
+	  /* Do not stop searching, in case there are some mapping
+	     symbols have the same value, but have different names.
+	     Use the last one.  */
+	}
+    }
+
+  /* We can not find the suitable mapping symbol above.  Therefore, we
+     look forwards and try to find it again, but don't go pass the start
+     of the section.  Otherwise a data section without mapping symbols
+     can pick up a text mapping symbol of a preceeding section.  */
+  if (!found)
+    {
+      n = info->symtab_pos;
+      if (from_last_map_symbol && n >= last_map_symbol)
+	n = last_map_symbol;
+
+      for (; n >= 0; n--)
+	{
+	  bfd_vma addr = bfd_asymbol_value (info->symtab[n]);
+	  /* We have searched all possible symbols in the range.  */
+	  if (addr < (info->section ? info->section->vma : 0))
+	    break;
+	  /* Stop searching once we find the closed mapping symbol.  */
+	  if (riscv_get_map_state (n, &mstate, info))
+	    {
+	      symbol = n;
+	      found = true;
+	      break;
+	    }
+	}
+    }
+
+  /* Save the information for next use.  */
+  last_map_symbol = symbol;
+  last_stop_offset = info->stop_offset;
+  last_section = info->section;
+
+  return mstate;
+}
+
+/* Decide which data size we should print.  */
+
+static bfd_vma
+riscv_data_length (bfd_vma memaddr,
+		   enum riscv_seg_mstate mstate,
+		   disassemble_info *info)
+{
+  bfd_vma length;
+  bool found = false;
+
+  switch (mstate)
+    {
+    case MAP_DATA:	 length = 0; break;
+    case MAP_DATA_CONS0: length = 1; break;
+    case MAP_DATA_CONS1: length = 2; break;
+    case MAP_DATA_CONS2: length = 4; break;
+    case MAP_DATA_CONS3: length = 8; break;
+    default: abort ();
+    }
+  if (length > 0)
+    return length;
+
+  length = 4;
+  if (info->symtab_size != 0
+      && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour
+      && last_map_symbol >= 0)
+    {
+      int n;
+      enum riscv_seg_mstate m = MAP_NONE;
+      for (n = last_map_symbol + 1; n < info->symtab_size; n++)
+	{
+	  bfd_vma addr = bfd_asymbol_value (info->symtab[n]);
+	  if (addr > memaddr
+	      && riscv_get_map_state (n, &m, info))
+	    {
+	      if (addr - memaddr < length)
+		length = addr - memaddr;
+	      found = true;
+	      break;
+	    }
+	}
+    }
+  if (!found)
+    {
+      /* Do not set the length which exceeds the section size.  */
+      bfd_vma offset = info->section->vma + info->section->size;
+      offset -= memaddr;
+      length = (offset < length) ? offset : length;
+    }
+  length = length == 3 ? 2 : length;
+  return length;
+}
+
+/* Dump the data contents.  */
+
+static int
+riscv_disassemble_data (bfd_vma memaddr ATTRIBUTE_UNUSED,
+			insn_t data,
+			disassemble_info *info)
+{
+  info->display_endian = info->endian;
+
+  switch (info->bytes_per_chunk)
+    {
+    case 1:
+      info->bytes_per_line = 6;
+      if (last_map_state == MAP_ALIGN_ODD)
+	(*info->fprintf_func) (info->stream, "align.byte");
+      else
+	(*info->fprintf_func) (info->stream, ".byte\t0x%02llx",
+			       (unsigned long long) data);
+      break;
+    case 2:
+      info->bytes_per_line = 8;
+      (*info->fprintf_func) (info->stream, ".short\t0x%04llx",
+			     (unsigned long long) data);
+      break;
+    case 4:
+      info->bytes_per_line = 8;
+      (*info->fprintf_func) (info->stream, ".word\t0x%08llx",
+			     (unsigned long long) data);
+      break;
+    case 8:
+      info->bytes_per_line = 8;
+      (*info->fprintf_func) (info->stream, ".dword\t0x%016llx",
+			     (unsigned long long) data);
+      break;
+    default:
+      abort ();
+    }
+  return info->bytes_per_chunk;
+}
+
 int
 print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
 {
-  bfd_byte packet[2];
+  bfd_byte packet[8];
   insn_t insn = 0;
-  bfd_vma n;
+  bfd_vma dump_size;
   int status;
+  enum riscv_seg_mstate mstate;
+  int (*riscv_disassembler) (bfd_vma, insn_t, struct disassemble_info *);
 
   if (info->disassembler_options != NULL)
     {
@@ -573,23 +825,59 @@ print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
   else if (riscv_gpr_names == NULL)
     set_default_riscv_dis_options ();
 
-  /* Instructions are a sequence of 2-byte packets in little-endian order.  */
-  for (n = 0; n < sizeof (insn) && n < riscv_insn_length (insn); n += 2)
+  mstate = riscv_search_mapping_symbol (memaddr, info);
+  /* Save the last mapping state.  */
+  last_map_state = mstate;
+
+  /* Set the size to dump.  */
+  if (mstate == MAP_DATA
+      || mstate == MAP_DATA_CONS0
+      || mstate == MAP_DATA_CONS1
+      || mstate == MAP_DATA_CONS2
+      || mstate == MAP_DATA_CONS3)
     {
-      status = (*info->read_memory_func) (memaddr + n, packet, 2, info);
+      /* The documentation for -D says that on Arm platforms -D should
+	 disassemble instructions.  Therefore, they dump data by searching
+	 mapping symbols only when the DISASSEMBLE_DATA is set.  That causes
+	 the mapping symbols are useless for -D.  I am not sure if any riscv
+	 document had mentioned this, so I prefer to keep them useful, but
+	 only for text sections.  If we decide not only to support mapping
+	 symbols for text sections, then the riscv_mapping_state in the
+	 gas/config/tc-riscv.c should be updated.  */
+      dump_size = riscv_data_length (memaddr, mstate, info);
+      info->bytes_per_chunk = dump_size;
+      riscv_disassembler = riscv_disassemble_data;
+    }
+  else if (mstate == MAP_ALIGN_ODD)
+    {
+      dump_size = 1;
+      info->bytes_per_chunk = dump_size;
+      riscv_disassembler = riscv_disassemble_data;
+    }
+  else
+    {
+      /* Get the first 2-bytes to check the lenghth of instruction.  */
+      status = (*info->read_memory_func) (memaddr, packet, 2, info);
       if (status != 0)
 	{
-	  /* Don't fail just because we fell off the end.  */
-	  if (n > 0)
-	    break;
 	  (*info->memory_error_func) (status, memaddr, info);
-	  return status;
+	  return 1;
 	}
+      insn = (insn_t) bfd_getl16 (packet);
+      dump_size = riscv_insn_length (insn);
+      riscv_disassembler = riscv_disassemble_insn;
+    }
 
-      insn |= ((insn_t) bfd_getl16 (packet)) << (8 * n);
+  /* Fetch the instruction to dump.  */
+  status = (*info->read_memory_func) (memaddr, packet, dump_size, info);
+  if (status != 0)
+    {
+      (*info->memory_error_func) (status, memaddr, info);
+      return 1;
     }
+  insn = (insn_t) bfd_get_bits (packet, dump_size * 8, false);
 
-  return riscv_disassemble_insn (memaddr, insn, info);
+  return (*riscv_disassembler) (memaddr, insn, info);
 }
 
 disassembler_ftype
@@ -631,7 +919,8 @@ riscv_symbol_is_valid (asymbol * sym,
 
   name = bfd_asymbol_name (sym);
 
-  return (strcmp (name, RISCV_FAKE_LABEL_NAME) != 0);
+  return (strcmp (name, RISCV_FAKE_LABEL_NAME) != 0
+	  && !riscv_elf_is_mapping_symbols (name));
 }
 
 void
-- 
2.30.2


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

* [PATCH v2 3/3] RISC-V: PR27916, Extend .insn directive to support hardcode encoding.
  2021-07-09  7:28 [PATCH v2 0/3] RISC-V: The series to supporting mapping symbols Nelson Chu
  2021-07-09  7:28 ` [PATCH v2 1/3] RISC-V: Enable elf attributes when default configure option isn't set Nelson Chu
  2021-07-09  7:28 ` [PATCH v2 2/3] RISC-V: PR27916, Support mapping symbols Nelson Chu
@ 2021-07-09  7:28 ` Nelson Chu
  2021-07-09  8:01   ` Kito Cheng
  2 siblings, 1 reply; 13+ messages in thread
From: Nelson Chu @ 2021-07-09  7:28 UTC (permalink / raw)
  To: binutils, gdb-patches, jimw, andrew.burgess, kito.cheng, palmer, andrew

The .insn directive can let users use their own instructions, or
some new instruction, which haven't supported in the old binutils.
For example, if users want to use sifive cache instruction, they
cannot just write "cflush.d1.l1" in the assembly code, they should
use ".insn i SYSTEM, 0, x0, x10, -0x40".  But the .insn directive
may not easy to use for some cases, and not so friendly to users.
Therefore, I believe most of the users will use ".word 0xfc050073",
to encode the instructions directly, rather than use .insn.  But
once we have supported the mapping symbols, the .word directives
are marked as data, so disassembler won't dump them as instructions
as usual.  I have discussed this with Kito many times, we all think
extend the .insn direcitve to support the hardcode encoding, is the
easiest way to resolve the problem.  Therefore, there are two more
.insn formats are proposed as follows,

(original) .insn <type>, <operand1>, <operand2>, ...
           .insn <insn-length>, <value>
           .insn <value>

The <type> is string, and the <insn-length> and <value> are constants.

ChangeLog:

gas/

	pr 27916
	* config/tc-riscv.c (riscv_ip_hardcode): Similar to riscv_ip,
	but assembles an instruction according to the hardcode values
	of .insn directive.
	* testsuite/gas/riscv/insn-fail.d: New testcases.
	* testsuite/gas/riscv/insn-fail.l: Likewise.
	* testsuite/gas/riscv/insn-fail.s: Likewise.
	* testsuite/gas/riscv/insn.d: Updated.
	* testsuite/gas/riscv/insn.s: Likewise.
---
 gas/config/tc-riscv.c               | 57 +++++++++++++++++++++++++++--
 gas/testsuite/gas/riscv/insn-fail.d |  3 ++
 gas/testsuite/gas/riscv/insn-fail.l |  7 ++++
 gas/testsuite/gas/riscv/insn-fail.s |  6 +++
 gas/testsuite/gas/riscv/insn.d      |  6 +++
 gas/testsuite/gas/riscv/insn.s      |  7 ++++
 6 files changed, 83 insertions(+), 3 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/insn-fail.d
 create mode 100644 gas/testsuite/gas/riscv/insn-fail.l
 create mode 100644 gas/testsuite/gas/riscv/insn-fail.s

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 55c49471825..e9be17f56d1 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -2922,6 +2922,50 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
   return error;
 }
 
+/* Similar to riscv_ip, but assembles an instruction according to the
+   hardcode values of .insn directive.  */
+
+static const char *
+riscv_ip_hardcode (char *str,
+		   struct riscv_cl_insn *ip,
+		   expressionS *imm_expr,
+		   const char *error)
+{
+  struct riscv_opcode *insn;
+  insn_t values[2] = {0, 0};
+  unsigned int num = 0;
+
+  input_line_pointer = str;
+  do
+    {
+      expression (imm_expr);
+      if (imm_expr->X_op != O_constant)
+	{
+	  /* The first value isn't constant, so it should be
+	     .insn <type> <operands>.  Call riscv_ip to parse it.  */
+	  if (num == 0)
+	    return error;
+	  return _("values must be constant");
+	}
+      values[num++] = (insn_t) imm_expr->X_add_number;
+    }
+  while (*input_line_pointer++ == ',' && num < 2);
+
+  input_line_pointer--;
+  if (*input_line_pointer != '\0')
+    return _("unrecognized values");
+
+  insn = XNEW (struct riscv_opcode);
+  insn->match = values[num - 1];
+  create_insn (ip, insn);
+  unsigned int bytes = riscv_insn_length (insn->match);
+  if (values[num - 1] >> (8 * bytes) != 0
+      || (num == 2 && values[0] != bytes))
+    return _("value conflicts with instruction length");
+
+  return NULL;
+}
+
 void
 md_assemble (char *str)
 {
@@ -3914,7 +3958,10 @@ s_riscv_leb128 (int sign)
   return s_leb128 (sign);
 }
 
-/* Parse the .insn directive.  */
+/* Parse the .insn directive.  There are three formats,
+   Format 1: .insn <type> <operand1>, <operand2>, ...
+   Format 2: .insn <length>, <value>
+   Format 3: .insn <value>.  */
 
 static void
 s_riscv_insn (int x ATTRIBUTE_UNUSED)
@@ -3935,11 +3982,15 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
 
   const char *error = riscv_ip (str, &insn, &imm_expr,
 				&imm_reloc, insn_type_hash);
-
   if (error)
     {
-      as_bad ("%s `%s'", error, str);
+      char *save_in = input_line_pointer;
+      error = riscv_ip_hardcode (str, &insn, &imm_expr, error);
+      input_line_pointer = save_in;
     }
+
+  if (error)
+    as_bad ("%s `%s'", error, str);
   else
     {
       gas_assert (insn.insn_mo->pinfo != INSN_MACRO);
diff --git a/gas/testsuite/gas/riscv/insn-fail.d b/gas/testsuite/gas/riscv/insn-fail.d
new file mode 100644
index 00000000000..3548e85415a
--- /dev/null
+++ b/gas/testsuite/gas/riscv/insn-fail.d
@@ -0,0 +1,3 @@
+#as:
+#source: insn-fail.s
+#error_output: insn-fail.l
diff --git a/gas/testsuite/gas/riscv/insn-fail.l b/gas/testsuite/gas/riscv/insn-fail.l
new file mode 100644
index 00000000000..e47d106b39b
--- /dev/null
+++ b/gas/testsuite/gas/riscv/insn-fail.l
@@ -0,0 +1,7 @@
+.*Assembler messages:
+.*Error: unrecognized opcode `r,0x00000013'
+.*Error: values must be constant `0x4,rs1'
+.*Error: unrecognized values `0x4 0x5'
+.*Error: unrecognized values `0x4,0x5,0x6'
+.*Error: value conflicts with instruction length `0x4,0x0001'
+.*Error: value conflicts with instruction length `0x2,0x00000013'
diff --git a/gas/testsuite/gas/riscv/insn-fail.s b/gas/testsuite/gas/riscv/insn-fail.s
new file mode 100644
index 00000000000..064211d985d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/insn-fail.s
@@ -0,0 +1,6 @@
+	.insn	r, 0x00000013
+	.insn	0x4, rs1
+	.insn	0x4 0x5
+	.insn	0x4, 0x5, 0x6
+	.insn	0x4, 0x0001
+	.insn	0x2, 0x00000013
diff --git a/gas/testsuite/gas/riscv/insn.d b/gas/testsuite/gas/riscv/insn.d
index 8cb3d64b1a5..4edacc63368 100644
--- a/gas/testsuite/gas/riscv/insn.d
+++ b/gas/testsuite/gas/riscv/insn.d
@@ -69,3 +69,9 @@ Disassembly of section .text:
 [^:]+:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
 [^:]+:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
 [^:]+:[ 	]+00c58533[ 	]+add[ 	]+a0,a1,a2
+[^:]+:[ 	]+0001[ 	]+nop
+[^:]+:[ 	]+00000013[ 	]+nop
+[^:]+:[ 	]+00000057[ 	]+0x57
+[^:]+:[ 	]+0001[ 	]+nop
+[^:]+:[ 	]+00000013[ 	]+nop
+[^:]+:[ 	]+00000057[ 	]+0x57
diff --git a/gas/testsuite/gas/riscv/insn.s b/gas/testsuite/gas/riscv/insn.s
index 937ad119ff2..84739056b1a 100644
--- a/gas/testsuite/gas/riscv/insn.s
+++ b/gas/testsuite/gas/riscv/insn.s
@@ -53,3 +53,10 @@ target:
 	.insn r  0x33,  0,  0, fa0, a1, fa2
 	.insn r  0x33,  0,  0, a0, fa1, fa2
 	.insn r  0x33,  0,  0, fa0, fa1, fa2
+
+	.insn 0x0001
+	.insn 0x00000013
+	.insn 0x00000057
+	.insn 0x2, 0x0001
+	.insn 0x4, 0x00000013
+	.insn 0x4, 0x00000057
-- 
2.30.2


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

* Re: [PATCH v2 1/3] RISC-V: Enable elf attributes when default configure option isn't set.
  2021-07-09  7:28 ` [PATCH v2 1/3] RISC-V: Enable elf attributes when default configure option isn't set Nelson Chu
@ 2021-07-09  8:00   ` Kito Cheng
  2021-07-13  7:07     ` Nelson Chu
  2021-07-13 20:38   ` Palmer Dabbelt
  2022-02-25 13:57   ` Sebastian Huber
  2 siblings, 1 reply; 13+ messages in thread
From: Kito Cheng @ 2021-07-09  8:00 UTC (permalink / raw)
  To: Nelson Chu
  Cc: Binutils, gdb-patches, Jim Wilson, andrew.burgess,
	Palmer Dabbelt, Andrew Waterman

 I would suggest this patch could be a standalone patch from the
mapping symbol patch set.

On Fri, Jul 9, 2021 at 3:28 PM Nelson Chu <nelson.chu@sifive.com> wrote:
>
> Since gcc commit, 3c70b3ca1ef58f302bf8c16d9e7c7bb8626408bf, we now enable
> elf attributes for all riscv targets by default in gcc.  Therefore, I
> think binutils should have the same behavior, in case users are writing
> assembly files.
>
> ChangLog:
>
> binutils/
>
>         * testsuite/binutils-all/readelf.s: Add comments for riscv.
>         * testsuite/binutils-all/readelf.s-64: Likewise.
>         * testsuite/binutils-all/readelf.s-64-unused: Likewise.
>         * testsuite/binutils-all/readelf.ss: Likewise.
>         * testsuite/binutils-all/readelf.ss-64: Likewise.
>         * testsuite/binutils-all/readelf.ss-64-unused: Likewise.
>
> gas/
>
>         * configure.ac: If --enable-default-riscv-attribute isn't set,
>         then we enable the elf attributes for all riscv targets by
>         default.
>         * configure: Regenerated.
> ---
>  binutils/testsuite/binutils-all/readelf.s            | 3 ++-
>  binutils/testsuite/binutils-all/readelf.s-64         | 2 ++
>  binutils/testsuite/binutils-all/readelf.s-64-unused  | 2 ++
>  binutils/testsuite/binutils-all/readelf.ss           | 1 +
>  binutils/testsuite/binutils-all/readelf.ss-64        | 1 +
>  binutils/testsuite/binutils-all/readelf.ss-64-unused | 1 +
>  gas/configure                                        | 9 +--------
>  gas/configure.ac                                     | 9 +--------
>  8 files changed, 11 insertions(+), 17 deletions(-)
>
> diff --git a/binutils/testsuite/binutils-all/readelf.s b/binutils/testsuite/binutils-all/readelf.s
> index 6ae4dc756b9..ff37acb4da8 100644
> --- a/binutils/testsuite/binutils-all/readelf.s
> +++ b/binutils/testsuite/binutils-all/readelf.s
> @@ -11,9 +11,10 @@ Section Headers:
>  #...
>   +\[ .\] .* +PROGBITS +00000000 0000(3c|40|44|48|50) 0000(04|10) 00 +WA +0 +0 +(.|..)
>   +\[ .\] .* +NOBITS +00000000 0000(40|44|48|4c|60) 000000 00 +WA +0 +0 +(.|..)
> -# ARM targets put .ARM.attributes here
> +# ARM targets put .ARM.attributes here.
>  # MIPS targets put .reginfo, .mdebug, .MIPS.abiflags and .gnu.attributes here.
>  # v850 targets put .call_table_data and .call_table_text here.
> +# riscv targets put .riscv.attributes here.
>  #...
>   +\[..\] .symtab +SYMTAB +00000000 0+.* 0+.* 10 +.. +.+ +4
>   +\[..\] .strtab +STRTAB +00000000 0+.* 0+.* 00 .* +0 +0 +1
> diff --git a/binutils/testsuite/binutils-all/readelf.s-64 b/binutils/testsuite/binutils-all/readelf.s-64
> index 92ec05f0376..4c957f7a938 100644
> --- a/binutils/testsuite/binutils-all/readelf.s-64
> +++ b/binutils/testsuite/binutils-all/readelf.s-64
> @@ -14,10 +14,12 @@ Section Headers:
>   +\[ 4\] .bss +NOBITS +0000000000000000 +000000(4c|50|54|58|68)
>   +0000000000000000 +0000000000000000 +WA +0 +0 +.*
>  # x86 targets may put .note.gnu.property here.
> +# riscv targets put .riscv.attributes here.
>  #...
>   +\[ .\] .symtab +SYMTAB +0000000000000000 +0+.*
>  # aarch64-elf targets have one more data symbol.
>  # x86 targets may have .note.gnu.property.
> +# riscv targets have .riscv.attributes.
>   +0+.* +0000000000000018 +(6|7) +(3|4) +8
>   +\[ .\] .strtab +STRTAB +0000000000000000 +0+.*
>   +0+.* +0000000000000000 .* +0 +0 +1
> diff --git a/binutils/testsuite/binutils-all/readelf.s-64-unused b/binutils/testsuite/binutils-all/readelf.s-64-unused
> index a1e6cd1bbd8..771439411a0 100644
> --- a/binutils/testsuite/binutils-all/readelf.s-64-unused
> +++ b/binutils/testsuite/binutils-all/readelf.s-64-unused
> @@ -14,10 +14,12 @@ Section Headers:
>   +\[ 4\] .bss +NOBITS +0000000000000000 +000000(4c|50|54|58)
>   +0000000000000000 +0000000000000000 +WA +0 +0 +.*
>  # x86 targets may put .note.gnu.property here.
> +# riscv targets put .riscv.attributes here.
>  #...
>   +\[ .\] .symtab +SYMTAB +0000000000000000 +0+.*
>  # aarch64-elf targets have one more data symbol.
>  # x86 targets may have .note.gnu.property.
> +# riscv targets have .riscv.attributes.
>   +0+.* +0000000000000018 +(6|7) +(6|7) +8
>   +\[ .\] .strtab +STRTAB +0000000000000000 +0+.*
>   +0+.* +0000000000000000 .* +0 +0 +1
> diff --git a/binutils/testsuite/binutils-all/readelf.ss b/binutils/testsuite/binutils-all/readelf.ss
> index 5fbb5d002e3..b81c016e9e7 100644
> --- a/binutils/testsuite/binutils-all/readelf.ss
> +++ b/binutils/testsuite/binutils-all/readelf.ss
> @@ -9,6 +9,7 @@ Symbol table '.symtab' contains .* entries:
>   +.: 00000000 +0 +NOTYPE +LOCAL +DEFAULT +[34] static_data_symbol
>  # v850 targets include extra SECTION symbols here for the .call_table_data
>  # and .call_table_text sections.
> +# riscv targets add .riscv.attribute symbol here...
>  #...
>   +[0-9]+: 00000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
>   +[0-9]+: 00000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
> diff --git a/binutils/testsuite/binutils-all/readelf.ss-64 b/binutils/testsuite/binutils-all/readelf.ss-64
> index 99a732f71f5..c6ffb0fc523 100644
> --- a/binutils/testsuite/binutils-all/readelf.ss-64
> +++ b/binutils/testsuite/binutils-all/readelf.ss-64
> @@ -7,6 +7,7 @@ Symbol table '.symtab' contains .* entries:
>  #...
>   +.: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +3 static_data_symbol
>  # ... or here ...
> +# riscv targets add .riscv.attribute symbol here...
>  #...
>  .* +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
>   +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
> diff --git a/binutils/testsuite/binutils-all/readelf.ss-64-unused b/binutils/testsuite/binutils-all/readelf.ss-64-unused
> index f48a4b2bbd2..cf515aa60d0 100644
> --- a/binutils/testsuite/binutils-all/readelf.ss-64-unused
> +++ b/binutils/testsuite/binutils-all/readelf.ss-64-unused
> @@ -10,6 +10,7 @@ Symbol table '.symtab' contains .* entries:
>  #...
>   +.: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +3 static_data_symbol
>  # ... or here ...
> +# riscv targets add .riscv.attribute symbol here...
>  #...
>  .* +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
>   +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
> diff --git a/gas/configure b/gas/configure
> index 110d707f079..7a528fd485e 100755
> --- a/gas/configure
> +++ b/gas/configure
> @@ -12550,14 +12550,7 @@ _ACEOF
>
>
>  if test ${ac_default_generate_riscv_attr} = unset; then
> -    case ${target_os} in
> -      elf)
> -       ac_default_generate_riscv_attr=1
> -       ;;
> -      *)
> -       ac_default_generate_riscv_attr=0
> -       ;;
> -  esac
> +  ac_default_generate_riscv_attr=1
>  fi
>
>
> diff --git a/gas/configure.ac b/gas/configure.ac
> index 78efba88e23..e2374268c56 100644
> --- a/gas/configure.ac
> +++ b/gas/configure.ac
> @@ -727,14 +727,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_X86_USED_NOTE,
>     properties by default.])
>
>  if test ${ac_default_generate_riscv_attr} = unset; then
> -    case ${target_os} in
> -      elf)
> -       ac_default_generate_riscv_attr=1
> -       ;;
> -      *)
> -       ac_default_generate_riscv_attr=0
> -       ;;
> -  esac
> +  ac_default_generate_riscv_attr=1
>  fi
>
>  AC_DEFINE_UNQUOTED(DEFAULT_RISCV_ATTR,
> --
> 2.30.2
>

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

* Re: [PATCH v2 3/3] RISC-V: PR27916, Extend .insn directive to support hardcode encoding.
  2021-07-09  7:28 ` [PATCH v2 3/3] RISC-V: PR27916, Extend .insn directive to support hardcode encoding Nelson Chu
@ 2021-07-09  8:01   ` Kito Cheng
  2021-07-14 20:38     ` Palmer Dabbelt
  0 siblings, 1 reply; 13+ messages in thread
From: Kito Cheng @ 2021-07-09  8:01 UTC (permalink / raw)
  To: Nelson Chu
  Cc: Binutils, gdb-patches, Jim Wilson, andrew.burgess,
	Palmer Dabbelt, Andrew Waterman

This patch is extending new formats of .insn, so I suggest this should
be a standalone patch.

On Fri, Jul 9, 2021 at 3:28 PM Nelson Chu <nelson.chu@sifive.com> wrote:
>
> The .insn directive can let users use their own instructions, or
> some new instruction, which haven't supported in the old binutils.
> For example, if users want to use sifive cache instruction, they
> cannot just write "cflush.d1.l1" in the assembly code, they should
> use ".insn i SYSTEM, 0, x0, x10, -0x40".  But the .insn directive
> may not easy to use for some cases, and not so friendly to users.
> Therefore, I believe most of the users will use ".word 0xfc050073",
> to encode the instructions directly, rather than use .insn.  But
> once we have supported the mapping symbols, the .word directives
> are marked as data, so disassembler won't dump them as instructions
> as usual.  I have discussed this with Kito many times, we all think
> extend the .insn direcitve to support the hardcode encoding, is the
> easiest way to resolve the problem.  Therefore, there are two more
> .insn formats are proposed as follows,
>
> (original) .insn <type>, <operand1>, <operand2>, ...
>            .insn <insn-length>, <value>
>            .insn <value>
>
> The <type> is string, and the <insn-length> and <value> are constants.
>
> ChangeLog:
>
> gas/
>
>         pr 27916
>         * config/tc-riscv.c (riscv_ip_hardcode): Similar to riscv_ip,
>         but assembles an instruction according to the hardcode values
>         of .insn directive.
>         * testsuite/gas/riscv/insn-fail.d: New testcases.
>         * testsuite/gas/riscv/insn-fail.l: Likewise.
>         * testsuite/gas/riscv/insn-fail.s: Likewise.
>         * testsuite/gas/riscv/insn.d: Updated.
>         * testsuite/gas/riscv/insn.s: Likewise.
> ---
>  gas/config/tc-riscv.c               | 57 +++++++++++++++++++++++++++--
>  gas/testsuite/gas/riscv/insn-fail.d |  3 ++
>  gas/testsuite/gas/riscv/insn-fail.l |  7 ++++
>  gas/testsuite/gas/riscv/insn-fail.s |  6 +++
>  gas/testsuite/gas/riscv/insn.d      |  6 +++
>  gas/testsuite/gas/riscv/insn.s      |  7 ++++
>  6 files changed, 83 insertions(+), 3 deletions(-)
>  create mode 100644 gas/testsuite/gas/riscv/insn-fail.d
>  create mode 100644 gas/testsuite/gas/riscv/insn-fail.l
>  create mode 100644 gas/testsuite/gas/riscv/insn-fail.s
>
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index 55c49471825..e9be17f56d1 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -2922,6 +2922,50 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
>    return error;
>  }
>
> +/* Similar to riscv_ip, but assembles an instruction according to the
> +   hardcode values of .insn directive.  */
> +
> +static const char *
> +riscv_ip_hardcode (char *str,
> +                  struct riscv_cl_insn *ip,
> +                  expressionS *imm_expr,
> +                  const char *error)
> +{
> +  struct riscv_opcode *insn;
> +  insn_t values[2] = {0, 0};
> +  unsigned int num = 0;
> +
> +  input_line_pointer = str;
> +  do
> +    {
> +      expression (imm_expr);
> +      if (imm_expr->X_op != O_constant)
> +       {
> +         /* The first value isn't constant, so it should be
> +            .insn <type> <operands>.  Call riscv_ip to parse it.  */
> +         if (num == 0)
> +           return error;
> +         return _("values must be constant");
> +       }
> +      values[num++] = (insn_t) imm_expr->X_add_number;
> +    }
> +  while (*input_line_pointer++ == ',' && num < 2);
> +
> +  input_line_pointer--;
> +  if (*input_line_pointer != '\0')
> +    return _("unrecognized values");
> +
> +  insn = XNEW (struct riscv_opcode);
> +  insn->match = values[num - 1];
> +  create_insn (ip, insn);
> +  unsigned int bytes = riscv_insn_length (insn->match);
> +  if (values[num - 1] >> (8 * bytes) != 0
> +      || (num == 2 && values[0] != bytes))
> +    return _("value conflicts with instruction length");
> +
> +  return NULL;
> +}
> +
>  void
>  md_assemble (char *str)
>  {
> @@ -3914,7 +3958,10 @@ s_riscv_leb128 (int sign)
>    return s_leb128 (sign);
>  }
>
> -/* Parse the .insn directive.  */
> +/* Parse the .insn directive.  There are three formats,
> +   Format 1: .insn <type> <operand1>, <operand2>, ...
> +   Format 2: .insn <length>, <value>
> +   Format 3: .insn <value>.  */
>
>  static void
>  s_riscv_insn (int x ATTRIBUTE_UNUSED)
> @@ -3935,11 +3982,15 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
>
>    const char *error = riscv_ip (str, &insn, &imm_expr,
>                                 &imm_reloc, insn_type_hash);
> -
>    if (error)
>      {
> -      as_bad ("%s `%s'", error, str);
> +      char *save_in = input_line_pointer;
> +      error = riscv_ip_hardcode (str, &insn, &imm_expr, error);
> +      input_line_pointer = save_in;
>      }
> +
> +  if (error)
> +    as_bad ("%s `%s'", error, str);
>    else
>      {
>        gas_assert (insn.insn_mo->pinfo != INSN_MACRO);
> diff --git a/gas/testsuite/gas/riscv/insn-fail.d b/gas/testsuite/gas/riscv/insn-fail.d
> new file mode 100644
> index 00000000000..3548e85415a
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/insn-fail.d
> @@ -0,0 +1,3 @@
> +#as:
> +#source: insn-fail.s
> +#error_output: insn-fail.l
> diff --git a/gas/testsuite/gas/riscv/insn-fail.l b/gas/testsuite/gas/riscv/insn-fail.l
> new file mode 100644
> index 00000000000..e47d106b39b
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/insn-fail.l
> @@ -0,0 +1,7 @@
> +.*Assembler messages:
> +.*Error: unrecognized opcode `r,0x00000013'
> +.*Error: values must be constant `0x4,rs1'
> +.*Error: unrecognized values `0x4 0x5'
> +.*Error: unrecognized values `0x4,0x5,0x6'
> +.*Error: value conflicts with instruction length `0x4,0x0001'
> +.*Error: value conflicts with instruction length `0x2,0x00000013'
> diff --git a/gas/testsuite/gas/riscv/insn-fail.s b/gas/testsuite/gas/riscv/insn-fail.s
> new file mode 100644
> index 00000000000..064211d985d
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/insn-fail.s
> @@ -0,0 +1,6 @@
> +       .insn   r, 0x00000013
> +       .insn   0x4, rs1
> +       .insn   0x4 0x5
> +       .insn   0x4, 0x5, 0x6
> +       .insn   0x4, 0x0001
> +       .insn   0x2, 0x00000013
> diff --git a/gas/testsuite/gas/riscv/insn.d b/gas/testsuite/gas/riscv/insn.d
> index 8cb3d64b1a5..4edacc63368 100644
> --- a/gas/testsuite/gas/riscv/insn.d
> +++ b/gas/testsuite/gas/riscv/insn.d
> @@ -69,3 +69,9 @@ Disassembly of section .text:
>  [^:]+:[        ]+00c58533[     ]+add[  ]+a0,a1,a2
>  [^:]+:[        ]+00c58533[     ]+add[  ]+a0,a1,a2
>  [^:]+:[        ]+00c58533[     ]+add[  ]+a0,a1,a2
> +[^:]+:[        ]+0001[         ]+nop
> +[^:]+:[        ]+00000013[     ]+nop
> +[^:]+:[        ]+00000057[     ]+0x57
> +[^:]+:[        ]+0001[         ]+nop
> +[^:]+:[        ]+00000013[     ]+nop
> +[^:]+:[        ]+00000057[     ]+0x57
> diff --git a/gas/testsuite/gas/riscv/insn.s b/gas/testsuite/gas/riscv/insn.s
> index 937ad119ff2..84739056b1a 100644
> --- a/gas/testsuite/gas/riscv/insn.s
> +++ b/gas/testsuite/gas/riscv/insn.s
> @@ -53,3 +53,10 @@ target:
>         .insn r  0x33,  0,  0, fa0, a1, fa2
>         .insn r  0x33,  0,  0, a0, fa1, fa2
>         .insn r  0x33,  0,  0, fa0, fa1, fa2
> +
> +       .insn 0x0001
> +       .insn 0x00000013
> +       .insn 0x00000057
> +       .insn 0x2, 0x0001
> +       .insn 0x4, 0x00000013
> +       .insn 0x4, 0x00000057
> --
> 2.30.2
>

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

* Re: [PATCH v2 1/3] RISC-V: Enable elf attributes when default configure option isn't set.
  2021-07-09  8:00   ` Kito Cheng
@ 2021-07-13  7:07     ` Nelson Chu
  0 siblings, 0 replies; 13+ messages in thread
From: Nelson Chu @ 2021-07-13  7:07 UTC (permalink / raw)
  To: Kito Cheng
  Cc: Binutils, gdb-patches, Jim Wilson, Andrew Burgess,
	Palmer Dabbelt, Andrew Waterman

Thanks for the suggestion.  Committed this one first.

Nelson

On Fri, Jul 9, 2021 at 4:00 PM Kito Cheng <kito.cheng@sifive.com> wrote:
>
>  I would suggest this patch could be a standalone patch from the
> mapping symbol patch set.
>
> On Fri, Jul 9, 2021 at 3:28 PM Nelson Chu <nelson.chu@sifive.com> wrote:
> >
> > Since gcc commit, 3c70b3ca1ef58f302bf8c16d9e7c7bb8626408bf, we now enable
> > elf attributes for all riscv targets by default in gcc.  Therefore, I
> > think binutils should have the same behavior, in case users are writing
> > assembly files.
> >
> > ChangLog:
> >
> > binutils/
> >
> >         * testsuite/binutils-all/readelf.s: Add comments for riscv.
> >         * testsuite/binutils-all/readelf.s-64: Likewise.
> >         * testsuite/binutils-all/readelf.s-64-unused: Likewise.
> >         * testsuite/binutils-all/readelf.ss: Likewise.
> >         * testsuite/binutils-all/readelf.ss-64: Likewise.
> >         * testsuite/binutils-all/readelf.ss-64-unused: Likewise.
> >
> > gas/
> >
> >         * configure.ac: If --enable-default-riscv-attribute isn't set,
> >         then we enable the elf attributes for all riscv targets by
> >         default.
> >         * configure: Regenerated.
> > ---
> >  binutils/testsuite/binutils-all/readelf.s            | 3 ++-
> >  binutils/testsuite/binutils-all/readelf.s-64         | 2 ++
> >  binutils/testsuite/binutils-all/readelf.s-64-unused  | 2 ++
> >  binutils/testsuite/binutils-all/readelf.ss           | 1 +
> >  binutils/testsuite/binutils-all/readelf.ss-64        | 1 +
> >  binutils/testsuite/binutils-all/readelf.ss-64-unused | 1 +
> >  gas/configure                                        | 9 +--------
> >  gas/configure.ac                                     | 9 +--------
> >  8 files changed, 11 insertions(+), 17 deletions(-)
> >
> > diff --git a/binutils/testsuite/binutils-all/readelf.s b/binutils/testsuite/binutils-all/readelf.s
> > index 6ae4dc756b9..ff37acb4da8 100644
> > --- a/binutils/testsuite/binutils-all/readelf.s
> > +++ b/binutils/testsuite/binutils-all/readelf.s
> > @@ -11,9 +11,10 @@ Section Headers:
> >  #...
> >   +\[ .\] .* +PROGBITS +00000000 0000(3c|40|44|48|50) 0000(04|10) 00 +WA +0 +0 +(.|..)
> >   +\[ .\] .* +NOBITS +00000000 0000(40|44|48|4c|60) 000000 00 +WA +0 +0 +(.|..)
> > -# ARM targets put .ARM.attributes here
> > +# ARM targets put .ARM.attributes here.
> >  # MIPS targets put .reginfo, .mdebug, .MIPS.abiflags and .gnu.attributes here.
> >  # v850 targets put .call_table_data and .call_table_text here.
> > +# riscv targets put .riscv.attributes here.
> >  #...
> >   +\[..\] .symtab +SYMTAB +00000000 0+.* 0+.* 10 +.. +.+ +4
> >   +\[..\] .strtab +STRTAB +00000000 0+.* 0+.* 00 .* +0 +0 +1
> > diff --git a/binutils/testsuite/binutils-all/readelf.s-64 b/binutils/testsuite/binutils-all/readelf.s-64
> > index 92ec05f0376..4c957f7a938 100644
> > --- a/binutils/testsuite/binutils-all/readelf.s-64
> > +++ b/binutils/testsuite/binutils-all/readelf.s-64
> > @@ -14,10 +14,12 @@ Section Headers:
> >   +\[ 4\] .bss +NOBITS +0000000000000000 +000000(4c|50|54|58|68)
> >   +0000000000000000 +0000000000000000 +WA +0 +0 +.*
> >  # x86 targets may put .note.gnu.property here.
> > +# riscv targets put .riscv.attributes here.
> >  #...
> >   +\[ .\] .symtab +SYMTAB +0000000000000000 +0+.*
> >  # aarch64-elf targets have one more data symbol.
> >  # x86 targets may have .note.gnu.property.
> > +# riscv targets have .riscv.attributes.
> >   +0+.* +0000000000000018 +(6|7) +(3|4) +8
> >   +\[ .\] .strtab +STRTAB +0000000000000000 +0+.*
> >   +0+.* +0000000000000000 .* +0 +0 +1
> > diff --git a/binutils/testsuite/binutils-all/readelf.s-64-unused b/binutils/testsuite/binutils-all/readelf.s-64-unused
> > index a1e6cd1bbd8..771439411a0 100644
> > --- a/binutils/testsuite/binutils-all/readelf.s-64-unused
> > +++ b/binutils/testsuite/binutils-all/readelf.s-64-unused
> > @@ -14,10 +14,12 @@ Section Headers:
> >   +\[ 4\] .bss +NOBITS +0000000000000000 +000000(4c|50|54|58)
> >   +0000000000000000 +0000000000000000 +WA +0 +0 +.*
> >  # x86 targets may put .note.gnu.property here.
> > +# riscv targets put .riscv.attributes here.
> >  #...
> >   +\[ .\] .symtab +SYMTAB +0000000000000000 +0+.*
> >  # aarch64-elf targets have one more data symbol.
> >  # x86 targets may have .note.gnu.property.
> > +# riscv targets have .riscv.attributes.
> >   +0+.* +0000000000000018 +(6|7) +(6|7) +8
> >   +\[ .\] .strtab +STRTAB +0000000000000000 +0+.*
> >   +0+.* +0000000000000000 .* +0 +0 +1
> > diff --git a/binutils/testsuite/binutils-all/readelf.ss b/binutils/testsuite/binutils-all/readelf.ss
> > index 5fbb5d002e3..b81c016e9e7 100644
> > --- a/binutils/testsuite/binutils-all/readelf.ss
> > +++ b/binutils/testsuite/binutils-all/readelf.ss
> > @@ -9,6 +9,7 @@ Symbol table '.symtab' contains .* entries:
> >   +.: 00000000 +0 +NOTYPE +LOCAL +DEFAULT +[34] static_data_symbol
> >  # v850 targets include extra SECTION symbols here for the .call_table_data
> >  # and .call_table_text sections.
> > +# riscv targets add .riscv.attribute symbol here...
> >  #...
> >   +[0-9]+: 00000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
> >   +[0-9]+: 00000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
> > diff --git a/binutils/testsuite/binutils-all/readelf.ss-64 b/binutils/testsuite/binutils-all/readelf.ss-64
> > index 99a732f71f5..c6ffb0fc523 100644
> > --- a/binutils/testsuite/binutils-all/readelf.ss-64
> > +++ b/binutils/testsuite/binutils-all/readelf.ss-64
> > @@ -7,6 +7,7 @@ Symbol table '.symtab' contains .* entries:
> >  #...
> >   +.: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +3 static_data_symbol
> >  # ... or here ...
> > +# riscv targets add .riscv.attribute symbol here...
> >  #...
> >  .* +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
> >   +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
> > diff --git a/binutils/testsuite/binutils-all/readelf.ss-64-unused b/binutils/testsuite/binutils-all/readelf.ss-64-unused
> > index f48a4b2bbd2..cf515aa60d0 100644
> > --- a/binutils/testsuite/binutils-all/readelf.ss-64-unused
> > +++ b/binutils/testsuite/binutils-all/readelf.ss-64-unused
> > @@ -10,6 +10,7 @@ Symbol table '.symtab' contains .* entries:
> >  #...
> >   +.: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +3 static_data_symbol
> >  # ... or here ...
> > +# riscv targets add .riscv.attribute symbol here...
> >  #...
> >  .* +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
> >   +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
> > diff --git a/gas/configure b/gas/configure
> > index 110d707f079..7a528fd485e 100755
> > --- a/gas/configure
> > +++ b/gas/configure
> > @@ -12550,14 +12550,7 @@ _ACEOF
> >
> >
> >  if test ${ac_default_generate_riscv_attr} = unset; then
> > -    case ${target_os} in
> > -      elf)
> > -       ac_default_generate_riscv_attr=1
> > -       ;;
> > -      *)
> > -       ac_default_generate_riscv_attr=0
> > -       ;;
> > -  esac
> > +  ac_default_generate_riscv_attr=1
> >  fi
> >
> >
> > diff --git a/gas/configure.ac b/gas/configure.ac
> > index 78efba88e23..e2374268c56 100644
> > --- a/gas/configure.ac
> > +++ b/gas/configure.ac
> > @@ -727,14 +727,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_X86_USED_NOTE,
> >     properties by default.])
> >
> >  if test ${ac_default_generate_riscv_attr} = unset; then
> > -    case ${target_os} in
> > -      elf)
> > -       ac_default_generate_riscv_attr=1
> > -       ;;
> > -      *)
> > -       ac_default_generate_riscv_attr=0
> > -       ;;
> > -  esac
> > +  ac_default_generate_riscv_attr=1
> >  fi
> >
> >  AC_DEFINE_UNQUOTED(DEFAULT_RISCV_ATTR,
> > --
> > 2.30.2
> >

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

* Re: [PATCH v2 1/3] RISC-V: Enable elf attributes when default configure option isn't set.
  2021-07-09  7:28 ` [PATCH v2 1/3] RISC-V: Enable elf attributes when default configure option isn't set Nelson Chu
  2021-07-09  8:00   ` Kito Cheng
@ 2021-07-13 20:38   ` Palmer Dabbelt
  2021-07-15  1:47     ` Nelson Chu
  2022-02-25 13:57   ` Sebastian Huber
  2 siblings, 1 reply; 13+ messages in thread
From: Palmer Dabbelt @ 2021-07-13 20:38 UTC (permalink / raw)
  To: nelson.chu
  Cc: binutils, gdb-patches, Jim Wilson, andrew.burgess, kito.cheng,
	Andrew Waterman, nelson.chu

On Fri, 09 Jul 2021 00:28:23 PDT (-0700), nelson.chu@sifive.com wrote:
> Since gcc commit, 3c70b3ca1ef58f302bf8c16d9e7c7bb8626408bf, we now enable
> elf attributes for all riscv targets by default in gcc.  Therefore, I
> think binutils should have the same behavior, in case users are writing
> assembly files.
>
> ChangLog:
>
> binutils/
>
> 	* testsuite/binutils-all/readelf.s: Add comments for riscv.
> 	* testsuite/binutils-all/readelf.s-64: Likewise.
> 	* testsuite/binutils-all/readelf.s-64-unused: Likewise.
> 	* testsuite/binutils-all/readelf.ss: Likewise.
> 	* testsuite/binutils-all/readelf.ss-64: Likewise.
> 	* testsuite/binutils-all/readelf.ss-64-unused: Likewise.
>
> gas/
>
> 	* configure.ac: If --enable-default-riscv-attribute isn't set,
> 	then we enable the elf attributes for all riscv targets by
> 	default.
> 	* configure: Regenerated.
> ---
>  binutils/testsuite/binutils-all/readelf.s            | 3 ++-
>  binutils/testsuite/binutils-all/readelf.s-64         | 2 ++
>  binutils/testsuite/binutils-all/readelf.s-64-unused  | 2 ++
>  binutils/testsuite/binutils-all/readelf.ss           | 1 +
>  binutils/testsuite/binutils-all/readelf.ss-64        | 1 +
>  binutils/testsuite/binutils-all/readelf.ss-64-unused | 1 +
>  gas/configure                                        | 9 +--------
>  gas/configure.ac                                     | 9 +--------
>  8 files changed, 11 insertions(+), 17 deletions(-)
>
> diff --git a/binutils/testsuite/binutils-all/readelf.s b/binutils/testsuite/binutils-all/readelf.s
> index 6ae4dc756b9..ff37acb4da8 100644
> --- a/binutils/testsuite/binutils-all/readelf.s
> +++ b/binutils/testsuite/binutils-all/readelf.s
> @@ -11,9 +11,10 @@ Section Headers:
>  #...
>   +\[ .\] .* +PROGBITS +00000000 0000(3c|40|44|48|50) 0000(04|10) 00 +WA +0 +0 +(.|..)
>   +\[ .\] .* +NOBITS +00000000 0000(40|44|48|4c|60) 000000 00 +WA +0 +0 +(.|..)
> -# ARM targets put .ARM.attributes here
> +# ARM targets put .ARM.attributes here.
>  # MIPS targets put .reginfo, .mdebug, .MIPS.abiflags and .gnu.attributes here.
>  # v850 targets put .call_table_data and .call_table_text here.
> +# riscv targets put .riscv.attributes here.
>  #...
>   +\[..\] .symtab +SYMTAB +00000000 0+.* 0+.* 10 +.. +.+ +4
>   +\[..\] .strtab +STRTAB +00000000 0+.* 0+.* 00 .* +0 +0 +1
> diff --git a/binutils/testsuite/binutils-all/readelf.s-64 b/binutils/testsuite/binutils-all/readelf.s-64
> index 92ec05f0376..4c957f7a938 100644
> --- a/binutils/testsuite/binutils-all/readelf.s-64
> +++ b/binutils/testsuite/binutils-all/readelf.s-64
> @@ -14,10 +14,12 @@ Section Headers:
>   +\[ 4\] .bss +NOBITS +0000000000000000 +000000(4c|50|54|58|68)
>   +0000000000000000 +0000000000000000 +WA +0 +0 +.*
>  # x86 targets may put .note.gnu.property here.
> +# riscv targets put .riscv.attributes here.
>  #...
>   +\[ .\] .symtab +SYMTAB +0000000000000000 +0+.*
>  # aarch64-elf targets have one more data symbol.
>  # x86 targets may have .note.gnu.property.
> +# riscv targets have .riscv.attributes.
>   +0+.* +0000000000000018 +(6|7) +(3|4) +8
>   +\[ .\] .strtab +STRTAB +0000000000000000 +0+.*
>   +0+.* +0000000000000000 .* +0 +0 +1
> diff --git a/binutils/testsuite/binutils-all/readelf.s-64-unused b/binutils/testsuite/binutils-all/readelf.s-64-unused
> index a1e6cd1bbd8..771439411a0 100644
> --- a/binutils/testsuite/binutils-all/readelf.s-64-unused
> +++ b/binutils/testsuite/binutils-all/readelf.s-64-unused
> @@ -14,10 +14,12 @@ Section Headers:
>   +\[ 4\] .bss +NOBITS +0000000000000000 +000000(4c|50|54|58)
>   +0000000000000000 +0000000000000000 +WA +0 +0 +.*
>  # x86 targets may put .note.gnu.property here.
> +# riscv targets put .riscv.attributes here.
>  #...
>   +\[ .\] .symtab +SYMTAB +0000000000000000 +0+.*
>  # aarch64-elf targets have one more data symbol.
>  # x86 targets may have .note.gnu.property.
> +# riscv targets have .riscv.attributes.
>   +0+.* +0000000000000018 +(6|7) +(6|7) +8
>   +\[ .\] .strtab +STRTAB +0000000000000000 +0+.*
>   +0+.* +0000000000000000 .* +0 +0 +1
> diff --git a/binutils/testsuite/binutils-all/readelf.ss b/binutils/testsuite/binutils-all/readelf.ss
> index 5fbb5d002e3..b81c016e9e7 100644
> --- a/binutils/testsuite/binutils-all/readelf.ss
> +++ b/binutils/testsuite/binutils-all/readelf.ss
> @@ -9,6 +9,7 @@ Symbol table '.symtab' contains .* entries:
>   +.: 00000000 +0 +NOTYPE +LOCAL +DEFAULT +[34] static_data_symbol
>  # v850 targets include extra SECTION symbols here for the .call_table_data
>  # and .call_table_text sections.
> +# riscv targets add .riscv.attribute symbol here...
>  #...
>   +[0-9]+: 00000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
>   +[0-9]+: 00000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
> diff --git a/binutils/testsuite/binutils-all/readelf.ss-64 b/binutils/testsuite/binutils-all/readelf.ss-64
> index 99a732f71f5..c6ffb0fc523 100644
> --- a/binutils/testsuite/binutils-all/readelf.ss-64
> +++ b/binutils/testsuite/binutils-all/readelf.ss-64
> @@ -7,6 +7,7 @@ Symbol table '.symtab' contains .* entries:
>  #...
>   +.: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +3 static_data_symbol
>  # ... or here ...
> +# riscv targets add .riscv.attribute symbol here...
>  #...
>  .* +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
>   +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
> diff --git a/binutils/testsuite/binutils-all/readelf.ss-64-unused b/binutils/testsuite/binutils-all/readelf.ss-64-unused
> index f48a4b2bbd2..cf515aa60d0 100644
> --- a/binutils/testsuite/binutils-all/readelf.ss-64-unused
> +++ b/binutils/testsuite/binutils-all/readelf.ss-64-unused
> @@ -10,6 +10,7 @@ Symbol table '.symtab' contains .* entries:
>  #...
>   +.: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +3 static_data_symbol
>  # ... or here ...
> +# riscv targets add .riscv.attribute symbol here...
>  #...
>  .* +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
>   +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
> diff --git a/gas/configure b/gas/configure
> index 110d707f079..7a528fd485e 100755
> --- a/gas/configure
> +++ b/gas/configure
> @@ -12550,14 +12550,7 @@ _ACEOF
>
>
>  if test ${ac_default_generate_riscv_attr} = unset; then
> -    case ${target_os} in
> -      elf)
> -	ac_default_generate_riscv_attr=1
> -	;;
> -      *)
> -	ac_default_generate_riscv_attr=0
> -	;;
> -  esac
> +  ac_default_generate_riscv_attr=1
>  fi
>
>
> diff --git a/gas/configure.ac b/gas/configure.ac
> index 78efba88e23..e2374268c56 100644
> --- a/gas/configure.ac
> +++ b/gas/configure.ac
> @@ -727,14 +727,7 @@ AC_DEFINE_UNQUOTED(DEFAULT_X86_USED_NOTE,
>     properties by default.])
>
>  if test ${ac_default_generate_riscv_attr} = unset; then
> -    case ${target_os} in
> -      elf)
> -	ac_default_generate_riscv_attr=1
> -	;;
> -      *)
> -	ac_default_generate_riscv_attr=0
> -	;;
> -  esac
> +  ac_default_generate_riscv_attr=1
>  fi
>
>  AC_DEFINE_UNQUOTED(DEFAULT_RISCV_ATTR,

Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
Acked-by: Palmer Dabbelt <palmerdabbelt@google.com>

I'm assuming you have gotten commit access working?

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

* Re: [PATCH v2 3/3] RISC-V: PR27916, Extend .insn directive to support hardcode encoding.
  2021-07-09  8:01   ` Kito Cheng
@ 2021-07-14 20:38     ` Palmer Dabbelt
  0 siblings, 0 replies; 13+ messages in thread
From: Palmer Dabbelt @ 2021-07-14 20:38 UTC (permalink / raw)
  To: nelson.chu, kito.cheng
  Cc: nelson.chu, binutils, gdb-patches, Jim Wilson, andrew.burgess,
	Andrew Waterman

On Fri, 09 Jul 2021 01:01:36 PDT (-0700), kito.cheng@sifive.com wrote:
> This patch is extending new formats of .insn, so I suggest this should
> be a standalone patch.

Ya, that's probably best.  In practice it doesn't matter all that much, 
as it's not like we pull these in via branches or anything.

> On Fri, Jul 9, 2021 at 3:28 PM Nelson Chu <nelson.chu@sifive.com> wrote:
>>
>> The .insn directive can let users use their own instructions, or
>> some new instruction, which haven't supported in the old binutils.
>> For example, if users want to use sifive cache instruction, they
>> cannot just write "cflush.d1.l1" in the assembly code, they should
>> use ".insn i SYSTEM, 0, x0, x10, -0x40".  But the .insn directive
>> may not easy to use for some cases, and not so friendly to users.
>> Therefore, I believe most of the users will use ".word 0xfc050073",
>> to encode the instructions directly, rather than use .insn.  But
>> once we have supported the mapping symbols, the .word directives
>> are marked as data, so disassembler won't dump them as instructions
>> as usual.  I have discussed this with Kito many times, we all think
>> extend the .insn direcitve to support the hardcode encoding, is the
>> easiest way to resolve the problem.  Therefore, there are two more
>> .insn formats are proposed as follows,
>>
>> (original) .insn <type>, <operand1>, <operand2>, ...
>>            .insn <insn-length>, <value>
>>            .insn <value>
>>
>> The <type> is string, and the <insn-length> and <value> are constants.

IMO we'd be way better off just having the actual instructions in tree 
than relying on users to know about the bits driectly.  I'm still fine 
with .insn, as it's essentially necessary to make the mapping symbols 
work and it's better than what users are currently doing.

>> ChangeLog:
>>
>> gas/
>>
>>         pr 27916
>>         * config/tc-riscv.c (riscv_ip_hardcode): Similar to riscv_ip,
>>         but assembles an instruction according to the hardcode values
>>         of .insn directive.
>>         * testsuite/gas/riscv/insn-fail.d: New testcases.
>>         * testsuite/gas/riscv/insn-fail.l: Likewise.
>>         * testsuite/gas/riscv/insn-fail.s: Likewise.
>>         * testsuite/gas/riscv/insn.d: Updated.
>>         * testsuite/gas/riscv/insn.s: Likewise.
>> ---
>>  gas/config/tc-riscv.c               | 57 +++++++++++++++++++++++++++--
>>  gas/testsuite/gas/riscv/insn-fail.d |  3 ++
>>  gas/testsuite/gas/riscv/insn-fail.l |  7 ++++
>>  gas/testsuite/gas/riscv/insn-fail.s |  6 +++
>>  gas/testsuite/gas/riscv/insn.d      |  6 +++
>>  gas/testsuite/gas/riscv/insn.s      |  7 ++++
>>  6 files changed, 83 insertions(+), 3 deletions(-)
>>  create mode 100644 gas/testsuite/gas/riscv/insn-fail.d
>>  create mode 100644 gas/testsuite/gas/riscv/insn-fail.l
>>  create mode 100644 gas/testsuite/gas/riscv/insn-fail.s
>>
>> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
>> index 55c49471825..e9be17f56d1 100644
>> --- a/gas/config/tc-riscv.c
>> +++ b/gas/config/tc-riscv.c
>> @@ -2922,6 +2922,50 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
>>    return error;
>>  }
>>
>> +/* Similar to riscv_ip, but assembles an instruction according to the
>> +   hardcode values of .insn directive.  */
>> +
>> +static const char *
>> +riscv_ip_hardcode (char *str,
>> +                  struct riscv_cl_insn *ip,
>> +                  expressionS *imm_expr,
>> +                  const char *error)
>> +{
>> +  struct riscv_opcode *insn;
>> +  insn_t values[2] = {0, 0};
>> +  unsigned int num = 0;
>> +
>> +  input_line_pointer = str;
>> +  do
>> +    {
>> +      expression (imm_expr);
>> +      if (imm_expr->X_op != O_constant)
>> +       {
>> +         /* The first value isn't constant, so it should be
>> +            .insn <type> <operands>.  Call riscv_ip to parse it.  */
>> +         if (num == 0)
>> +           return error;
>> +         return _("values must be constant");
>> +       }
>> +      values[num++] = (insn_t) imm_expr->X_add_number;
>> +    }
>> +  while (*input_line_pointer++ == ',' && num < 2);
>> +
>> +  input_line_pointer--;
>> +  if (*input_line_pointer != '\0')
>> +    return _("unrecognized values");
>> +
>> +  insn = XNEW (struct riscv_opcode);
>> +  insn->match = values[num - 1];
>> +  create_insn (ip, insn);
>> +  unsigned int bytes = riscv_insn_length (insn->match);
>> +  if (values[num - 1] >> (8 * bytes) != 0
>> +      || (num == 2 && values[0] != bytes))
>> +    return _("value conflicts with instruction length");
>> +
>> +  return NULL;
>> +}
>> +
>>  void
>>  md_assemble (char *str)
>>  {
>> @@ -3914,7 +3958,10 @@ s_riscv_leb128 (int sign)
>>    return s_leb128 (sign);
>>  }
>>
>> -/* Parse the .insn directive.  */
>> +/* Parse the .insn directive.  There are three formats,
>> +   Format 1: .insn <type> <operand1>, <operand2>, ...
>> +   Format 2: .insn <length>, <value>
>> +   Format 3: .insn <value>.  */
>>
>>  static void
>>  s_riscv_insn (int x ATTRIBUTE_UNUSED)
>> @@ -3935,11 +3982,15 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
>>
>>    const char *error = riscv_ip (str, &insn, &imm_expr,
>>                                 &imm_reloc, insn_type_hash);
>> -
>>    if (error)
>>      {
>> -      as_bad ("%s `%s'", error, str);
>> +      char *save_in = input_line_pointer;
>> +      error = riscv_ip_hardcode (str, &insn, &imm_expr, error);
>> +      input_line_pointer = save_in;
>>      }
>> +
>> +  if (error)
>> +    as_bad ("%s `%s'", error, str);
>>    else
>>      {
>>        gas_assert (insn.insn_mo->pinfo != INSN_MACRO);
>> diff --git a/gas/testsuite/gas/riscv/insn-fail.d b/gas/testsuite/gas/riscv/insn-fail.d
>> new file mode 100644
>> index 00000000000..3548e85415a
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/insn-fail.d
>> @@ -0,0 +1,3 @@
>> +#as:
>> +#source: insn-fail.s
>> +#error_output: insn-fail.l
>> diff --git a/gas/testsuite/gas/riscv/insn-fail.l b/gas/testsuite/gas/riscv/insn-fail.l
>> new file mode 100644
>> index 00000000000..e47d106b39b
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/insn-fail.l
>> @@ -0,0 +1,7 @@
>> +.*Assembler messages:
>> +.*Error: unrecognized opcode `r,0x00000013'
>> +.*Error: values must be constant `0x4,rs1'
>> +.*Error: unrecognized values `0x4 0x5'
>> +.*Error: unrecognized values `0x4,0x5,0x6'
>> +.*Error: value conflicts with instruction length `0x4,0x0001'
>> +.*Error: value conflicts with instruction length `0x2,0x00000013'
>> diff --git a/gas/testsuite/gas/riscv/insn-fail.s b/gas/testsuite/gas/riscv/insn-fail.s
>> new file mode 100644
>> index 00000000000..064211d985d
>> --- /dev/null
>> +++ b/gas/testsuite/gas/riscv/insn-fail.s
>> @@ -0,0 +1,6 @@
>> +       .insn   r, 0x00000013
>> +       .insn   0x4, rs1
>> +       .insn   0x4 0x5
>> +       .insn   0x4, 0x5, 0x6
>> +       .insn   0x4, 0x0001
>> +       .insn   0x2, 0x00000013
>> diff --git a/gas/testsuite/gas/riscv/insn.d b/gas/testsuite/gas/riscv/insn.d
>> index 8cb3d64b1a5..4edacc63368 100644
>> --- a/gas/testsuite/gas/riscv/insn.d
>> +++ b/gas/testsuite/gas/riscv/insn.d
>> @@ -69,3 +69,9 @@ Disassembly of section .text:
>>  [^:]+:[        ]+00c58533[     ]+add[  ]+a0,a1,a2
>>  [^:]+:[        ]+00c58533[     ]+add[  ]+a0,a1,a2
>>  [^:]+:[        ]+00c58533[     ]+add[  ]+a0,a1,a2
>> +[^:]+:[        ]+0001[         ]+nop
>> +[^:]+:[        ]+00000013[     ]+nop
>> +[^:]+:[        ]+00000057[     ]+0x57
>> +[^:]+:[        ]+0001[         ]+nop
>> +[^:]+:[        ]+00000013[     ]+nop
>> +[^:]+:[        ]+00000057[     ]+0x57
>> diff --git a/gas/testsuite/gas/riscv/insn.s b/gas/testsuite/gas/riscv/insn.s
>> index 937ad119ff2..84739056b1a 100644
>> --- a/gas/testsuite/gas/riscv/insn.s
>> +++ b/gas/testsuite/gas/riscv/insn.s
>> @@ -53,3 +53,10 @@ target:
>>         .insn r  0x33,  0,  0, fa0, a1, fa2
>>         .insn r  0x33,  0,  0, a0, fa1, fa2
>>         .insn r  0x33,  0,  0, fa0, fa1, fa2
>> +
>> +       .insn 0x0001
>> +       .insn 0x00000013
>> +       .insn 0x00000057
>> +       .insn 0x2, 0x0001
>> +       .insn 0x4, 0x00000013
>> +       .insn 0x4, 0x00000057
>> --
>> 2.30.2
>>

Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>

Thanks!

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

* Re: [PATCH v2 1/3] RISC-V: Enable elf attributes when default configure option isn't set.
  2021-07-13 20:38   ` Palmer Dabbelt
@ 2021-07-15  1:47     ` Nelson Chu
  0 siblings, 0 replies; 13+ messages in thread
From: Nelson Chu @ 2021-07-15  1:47 UTC (permalink / raw)
  To: Palmer Dabbelt
  Cc: Binutils, gdb-patches, Jim Wilson, Andrew Burgess, Kito Cheng,
	Andrew Waterman

> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
> Acked-by: Palmer Dabbelt <palmerdabbelt@google.com>
>
> I'm assuming you have gotten commit access working?

Yeah I have gotten the write access.  Thanks, committed.

Nelson

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

* Re: [PATCH v2 2/3] RISC-V: PR27916, Support mapping symbols.
  2021-07-09  7:28 ` [PATCH v2 2/3] RISC-V: PR27916, Support mapping symbols Nelson Chu
@ 2021-07-15 15:16   ` Palmer Dabbelt
  2021-07-16  2:58     ` Nelson Chu
  0 siblings, 1 reply; 13+ messages in thread
From: Palmer Dabbelt @ 2021-07-15 15:16 UTC (permalink / raw)
  To: nelson.chu
  Cc: binutils, gdb-patches, Jim Wilson, andrew.burgess, kito.cheng,
	Andrew Waterman, nelson.chu

On Fri, 09 Jul 2021 00:28:24 PDT (-0700), nelson.chu@sifive.com wrote:
> Similar to ARM/AARCH64, we add mapping symbols in the symbol table,
> to mark the start addresses of data and instructions.  The $d means
> data, the $x means instruction, and the $a means code alignment.
> Then the disassembler uses these symbols to decide whether we should
> dump data or instruction.
>
> For example,
> $ cat tmp.s
>   .text
>   .option norelax
>   .option norvc
>   .fill 2, 4, 0x1001    # $d for 8 bytes fill data.
>   .byte 1               # $d1
>   .word 0               # $d4
>   .align 3              # $a1 for align.byte, $a for align.nop.
>   nop                   # $x
>   .fill 5, 2, 0x2002    # $d for 10 bytes fill data.
>   nop                   # $x
>   .data
>   .word 0x1             # No need to add mapping symbols.
>   .word 0x2
>
> $ riscv64-unknown-elf-as tmp.s -o tmp.o
> $ riscv64-unknown-elf-objdump -D tmp.o
>
> Disassembly of section .text:
>
> 0000000000000000 <.text>:
>    0:   00001001                .word   0x00001001
>    4:   00001001                .word   0x00001001
>    8:   01                      .byte   0x01
>    9:   00000000                .word   0x00000000
>    d:   00                      align.byte
>    e:   0001                    align.nop
>   10:   00000013                nop
>   14:   10001000                .word   0x20022002
>   18:   10001000                .word   0x20022002
>   1c:   1000                    .short  0x2002
>   1e:   00000013                nop
>   22:   0001                    align.nop
>   24:   00000013                align.nop
>
> Disassembly of section .data:
>
> 0000000000000000 <.data>:
>    0:   00000001                .word   0x00000001
>    4:   00000002                .word   0x00000002
>
> Disassembly of section .riscv.attributes:
>
> 0000000000000000 <.riscv.attributes>:
>    0:   00002d41                .word   0x00002d41
> ... skip ...
>
> There are too many issues we can discuss from the above example,
> so I just pick some of them that I think are important to mention.
>
> * The documentation for -D says that on ARM platforms -D should
>   disassemble instructions.  Therefore, they dump data by searching
>   mapping symbols only when the DISASSEMBLE_DATA is set.  That causes
>   the mapping symbols are useless for -D.  I am not sure if any riscv
>   document had mentioned this, so I prefer to keep them useful, but
>   only for text sections.  Otherwise, dump other sections as datas.
>
> * If the data are written by cons_worker, then we add mapping symbols
>   with the data size, to show more detials.  For example,
>
>   .text
>   .byte 1
>   .word 0
>
>   The $d1 is added for .byte, and $d4 is added for .word, so that
>   we can show the code that is closer to the user's original code,
>   rather than the data with 5 bytes size.
>
> * Add the align.<insn> prefix if the instructions are used for
>   alignment and marked with $a/$a1.  One of the benefits is that,
>   we can distinguish c.nop and align.nop, when the rvc is disabled.
>   The c.nop is illegal, but the align.nop is legal.
>
>   Besides, we may dump .align.unimp at the end of sections when relax
>   is enabled, this is expected.  Since the tail section alignments are
>   not handled in the riscv_frag_align_code, and it cannot be filled with
>   nops in the riscv_handle_align either.
>
> The elf/linux toolchain regressions all passed.  Besides, I also
> disable the mapping symbols internally, but use the new objudmp, the
> regressions passed, too.  Therefore, the new objudmp should dump
> the objects corretly, even if they don't have any mapping symbols.
>
> ChangeLog:
>
> bfd/
>
> 	pr 27916
> 	* cpu-riscv.c (riscv_elf_is_mapping_symbols): Define mapping symbols.
> 	* cpu-riscv.h: extern riscv_elf_is_mapping_symbols.
> 	* elfnn-riscv.c (riscv_maybe_function_sym): Do not choose mapping
> 	symbols as a function name.
> 	(riscv_elf_is_target_special_symbol): Add mapping symbols.
>
> binutils/
>
> 	pr 27916
> 	* readelf (get_symbol_for_build_attribute): Filter data mapping
> 	symbols with size.
> 	* testsuite/binutils-all/readelf.s: Updated.
> 	* testsuite/binutils-all/readelf.s-64: Likewise.
> 	* testsuite/binutils-all/readelf.s-64-unused: Likewise.
> 	* testsuite/binutils-all/readelf.ss: Likewise.
> 	* testsuite/binutils-all/readelf.ss-64: Likewise.
> 	* testsuite/binutils-all/readelf.ss-64-unused: Likewise.
>
> gas/
>
> 	pr 27916
> 	config/tc-riscv.c (make_mapping_symbol): Create a new mapping symbol.
> 	(riscv_mapping_state): Decide whether to create mapping symbol for
> 	frag_now.  Only add the mapping symbols to text sections.
> 	(riscv_add_odd_padding_symbol): Add the odd bytes of paddings for
> 	riscv_handle_align.
> 	(riscv_check_mapping_symbols): Remove any excess mapping symbols.
> 	(md_assemble): Marked as MAP_INSN.
> 	(riscv_frag_align_code): Marked as MAP_ALIGN.
> 	(riscv_init_frag): Add mapping symbols for frag, it usually called
> 	by frag_var.  Marked as MAP_DATA for rs_align and rs_fill, and
> 	marked as alignment MAP_ALIGN for rs_align_code.
> 	(s_riscv_insn): Marked as MAP_INSN.
> 	(riscv_adjust_symtab): Call riscv_check_mapping_symbols.
> 	* config/tc-riscv.h (md_cons_align): Defined to riscv_mapping_state
> 	with MAP_DATA_CONS[0|1|2|3].
> 	(TC_SEGMENT_INFO_TYPE): Record mapping state for each segment.
> 	(TC_FRAG_TYPE): Record the first and last mapping symbols for the
> 	fragments.  The first mapping symbol must be placed at the start
> 	of the fragment.
> 	(TC_FRAG_INIT): Defined to riscv_init_frag.
> 	* testsuite/gas/riscv/mapping-01.s: New testcase.
> 	* testsuite/gas/riscv/mapping-01a.d: Likewise.
> 	* testsuite/gas/riscv/mapping-01b.d: Likewise.
> 	* testsuite/gas/riscv/mapping-02.s: Likewise.
> 	* testsuite/gas/riscv/mapping-02a.d: Likewise.
> 	* testsuite/gas/riscv/mapping-02b.d: Likewise.
> 	* testsuite/gas/riscv/mapping-03.s: Likewise.
> 	* testsuite/gas/riscv/mapping-03a.d: Likewise.
> 	* testsuite/gas/riscv/mapping-03b.d: Likewise.
> 	* testsuite/gas/riscv/mapping-04.s: Likewise.
> 	* testsuite/gas/riscv/mapping-04a.d: Likewise.
> 	* testsuite/gas/riscv/mapping-04b.d: Likewise.
> 	* testsuite/gas/riscv/mapping-norelax-04a.d: Likewise.
> 	* testsuite/gas/riscv/mapping-norelax-04b.d: Likewise.
> 	* testsuite/gas/riscv/no-relax-align.d: Updated.
> 	* testsuite/gas/riscv/no-relax-align-2.d: Likewise.
>
> include/
>
> 	pr 27916
> 	* opcode/riscv.h (enum riscv_seg_mstate): Added.
>
> opcodes/
>
> 	pr 27916
> 	* riscv-dis.c (last_map_symbol, last_stop_offset, last_section,
> 	last_map_state): Added to dump sections with mapping symbols.
> 	(riscv_get_map_state): Get the mapping state from the symbol.
> 	(riscv_search_mapping_symbol): Check the sorted symbol table, and
> 	then find the suitable mapping symbol.
> 	(riscv_data_length): Decide which data size we should print.
> 	(riscv_disassemble_data): Dump the data contents.
> 	(riscv_disassemble_insn): Dump align.<insn> for MAP_ALIGN.
> 	(print_insn_riscv): Handle the mapping symbols.
> 	(riscv_symbol_is_valid): Marked mapping symbols as invalid.
> ---
>  bfd/cpu-riscv.c                               |  10 +
>  bfd/cpu-riscv.h                               |   3 +
>  bfd/elfnn-riscv.c                             |  25 +-
>  binutils/readelf.c                            |   8 +-
>  binutils/testsuite/binutils-all/readelf.s-64  |   5 +-
>  .../binutils-all/readelf.s-64-unused          |   5 +-
>  binutils/testsuite/binutils-all/readelf.ss    |   2 +
>  binutils/testsuite/binutils-all/readelf.ss-64 |   7 +-
>  .../binutils-all/readelf.ss-64-unused         |   7 +-
>  .../testsuite/binutils-all/readelf.ss-unused  |   2 +
>  gas/config/tc-riscv.c                         | 223 ++++++++++++-
>  gas/config/tc-riscv.h                         |  32 ++
>  gas/testsuite/gas/riscv/mapping-01.s          |  18 +
>  gas/testsuite/gas/riscv/mapping-01a.d         |  17 +
>  gas/testsuite/gas/riscv/mapping-01b.d         |  21 ++
>  gas/testsuite/gas/riscv/mapping-02.s          |  13 +
>  gas/testsuite/gas/riscv/mapping-02a.d         |  15 +
>  gas/testsuite/gas/riscv/mapping-02b.d         |  16 +
>  gas/testsuite/gas/riscv/mapping-03.s          |  10 +
>  gas/testsuite/gas/riscv/mapping-03a.d         |  16 +
>  gas/testsuite/gas/riscv/mapping-03b.d         |  16 +
>  gas/testsuite/gas/riscv/mapping-04.s          |  11 +
>  gas/testsuite/gas/riscv/mapping-04a.d         |  21 ++
>  gas/testsuite/gas/riscv/mapping-04b.d         |  24 ++
>  gas/testsuite/gas/riscv/mapping-norelax-04a.d |  23 ++
>  gas/testsuite/gas/riscv/mapping-norelax-04b.d |  25 ++
>  gas/testsuite/gas/riscv/no-relax-align-2.d    |  19 +-
>  gas/testsuite/gas/riscv/no-relax-align.d      |   4 +-
>  include/opcode/riscv.h                        |  13 +
>  opcodes/riscv-dis.c                           | 313 +++++++++++++++++-
>  30 files changed, 885 insertions(+), 39 deletions(-)
>  create mode 100644 gas/testsuite/gas/riscv/mapping-01.s
>  create mode 100644 gas/testsuite/gas/riscv/mapping-01a.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-01b.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-02.s
>  create mode 100644 gas/testsuite/gas/riscv/mapping-02a.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-02b.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-03.s
>  create mode 100644 gas/testsuite/gas/riscv/mapping-03a.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-03b.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-04.s
>  create mode 100644 gas/testsuite/gas/riscv/mapping-04a.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-04b.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04a.d
>  create mode 100644 gas/testsuite/gas/riscv/mapping-norelax-04b.d
>
> diff --git a/bfd/cpu-riscv.c b/bfd/cpu-riscv.c
> index 025e94afd34..dae76e7fdcc 100644
> --- a/bfd/cpu-riscv.c
> +++ b/bfd/cpu-riscv.c
> @@ -140,3 +140,13 @@ riscv_get_priv_spec_class_from_numbers (unsigned int major,
>    RISCV_GET_PRIV_SPEC_CLASS (buf, class_t);
>    *class = class_t;
>  }
> +
> +/* Define mapping symbols for riscv.  */
> +
> +bool
> +riscv_elf_is_mapping_symbols (const char *name)
> +{
> +  return (!strncmp (name, "$d", 2)
> +	  || !strncmp (name, "$x", 2)
> +	  || !strncmp (name, "$a", 2));
> +}

I can't quite figure this one out: this will treat something like 
"$aWHATEVER" as a mapping symbol, does that cause binutils to crash 
somewhere?  All I'm seeing it do is mark these as hidden symbols, which 
I guess is OK (we've kind of set the "anything with $ is inernal 
precedent").

Either way,

Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>

> diff --git a/bfd/cpu-riscv.h b/bfd/cpu-riscv.h
> index cafaca23be0..ed5ee7e60d5 100644
> --- a/bfd/cpu-riscv.h
> +++ b/bfd/cpu-riscv.h
> @@ -79,3 +79,6 @@ riscv_get_priv_spec_class_from_numbers (unsigned int,
>  					unsigned int,
>  					unsigned int,
>  					enum riscv_spec_class *);
> +
> +extern bool
> +riscv_elf_is_mapping_symbols (const char *);
> diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
> index 85a99f3d610..a10384cd4d3 100644
> --- a/bfd/elfnn-riscv.c
> +++ b/bfd/elfnn-riscv.c
> @@ -5150,14 +5150,32 @@ riscv_elf_obj_attrs_arg_type (int tag)
>    return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL;
>  }
>
> -/* PR27584, Omit local and empty symbols since they usually generated
> -   for pcrel relocations.  */
> +/* Do not choose mapping symbols as a function name.  */
> +
> +static bfd_size_type
> +riscv_maybe_function_sym (const asymbol *sym,
> +			  asection *sec,
> +			  bfd_vma *code_off)
> +{
> +  if (sym->flags & BSF_LOCAL
> +      && riscv_elf_is_mapping_symbols (sym->name))
> +    return 0;
> +
> +  return _bfd_elf_maybe_function_sym (sym, sec, code_off);
> +}
> +
> +/* Treat the following cases as target special symbols, they are
> +   usually omitted.  */
>
>  static bool
>  riscv_elf_is_target_special_symbol (bfd *abfd, asymbol *sym)
>  {
> +  /* PR27584, local and empty symbols.  Since they are usually
> +     generated for pcrel relocations.  */
>    return (!strcmp (sym->name, "")
> -	  || _bfd_elf_is_local_label_name (abfd, sym->name));
> +	  || _bfd_elf_is_local_label_name (abfd, sym->name)
> +	  /* PR27916, mapping symbols.  */
> +	  || riscv_elf_is_mapping_symbols (sym->name));
>  }
>
>  static int
> @@ -5245,6 +5263,7 @@ riscv_elf_modify_segment_map (bfd *abfd,
>  #define elf_backend_grok_psinfo			riscv_elf_grok_psinfo
>  #define elf_backend_object_p			riscv_elf_object_p
>  #define elf_backend_write_core_note		riscv_write_core_note
> +#define elf_backend_maybe_function_sym		riscv_maybe_function_sym
>  #define elf_info_to_howto_rel			NULL
>  #define elf_info_to_howto			riscv_info_to_howto_rela
>  #define bfd_elfNN_bfd_relax_section		_bfd_riscv_relax_section
> diff --git a/binutils/readelf.c b/binutils/readelf.c
> index 24ff069edf4..7560e0f6a51 100644
> --- a/binutils/readelf.c
> +++ b/binutils/readelf.c
> @@ -20283,10 +20283,14 @@ get_symbol_for_build_attribute (Filedata *filedata,
>  	  continue;
>
>  	/* The AArch64 and ARM architectures define mapping symbols
> -	   (eg $d, $x, $t) which we want to ignore.  */
> +	   (eg $d, $x, $t) which we want to ignore.  Besides, riscv
> +	   may defines data mapping symbols with size (eg $d1, $d2,
> +	   $d4, $d8), which we also want to ignore.  */
>  	if (ba_cache.strtab[sym->st_name] == '$'
>  	    && ba_cache.strtab[sym->st_name + 1] != 0
> -	    && ba_cache.strtab[sym->st_name + 2] == 0)
> +	    && (ba_cache.strtab[sym->st_name + 2] == 0
> +		|| (ba_cache.strtab[sym->st_name + 2] != 0
> +		    && ba_cache.strtab[sym->st_name + 3] == 0)))
>  	  continue;
>
>  	if (is_open_attr)
> diff --git a/binutils/testsuite/binutils-all/readelf.s-64 b/binutils/testsuite/binutils-all/readelf.s-64
> index 4c957f7a938..0b1bafee537 100644
> --- a/binutils/testsuite/binutils-all/readelf.s-64
> +++ b/binutils/testsuite/binutils-all/readelf.s-64
> @@ -19,8 +19,9 @@ Section Headers:
>   +\[ .\] .symtab +SYMTAB +0000000000000000 +0+.*
>  # aarch64-elf targets have one more data symbol.
>  # x86 targets may have .note.gnu.property.
> -# riscv targets have .riscv.attributes.
> - +0+.* +0000000000000018 +(6|7) +(3|4) +8
> +# riscv targets have five more symbols, one is .riscv.attributes,
> +# others are mapping data symbols.
> + +0+.* +0000000000000018 +(6|7) +(3|4|8) +8
>   +\[ .\] .strtab +STRTAB +0000000000000000 +0+.*
>   +0+.* +0000000000000000 .* +0 +0 +1
>   +\[ .\] .shstrtab +STRTAB +0000000000000000 +[0-9a-f]+
> diff --git a/binutils/testsuite/binutils-all/readelf.s-64-unused b/binutils/testsuite/binutils-all/readelf.s-64-unused
> index 771439411a0..542bbb70064 100644
> --- a/binutils/testsuite/binutils-all/readelf.s-64-unused
> +++ b/binutils/testsuite/binutils-all/readelf.s-64-unused
> @@ -19,8 +19,9 @@ Section Headers:
>   +\[ .\] .symtab +SYMTAB +0000000000000000 +0+.*
>  # aarch64-elf targets have one more data symbol.
>  # x86 targets may have .note.gnu.property.
> -# riscv targets have .riscv.attributes.
> - +0+.* +0000000000000018 +(6|7) +(6|7) +8
> +# riscv targets have five more symbols, one is .riscv.attributes,
> +# others are mapping data symbols.
> + +0+.* +0000000000000018 +(6|7) +(6|7|11) +8
>   +\[ .\] .strtab +STRTAB +0000000000000000 +0+.*
>   +0+.* +0000000000000000 .* +0 +0 +1
>   +\[ .\] .shstrtab +STRTAB +0000000000000000 +[0-9a-f]+
> diff --git a/binutils/testsuite/binutils-all/readelf.ss b/binutils/testsuite/binutils-all/readelf.ss
> index b81c016e9e7..5d96649c2a0 100644
> --- a/binutils/testsuite/binutils-all/readelf.ss
> +++ b/binutils/testsuite/binutils-all/readelf.ss
> @@ -5,8 +5,10 @@ Symbol table '.symtab' contains .* entries:
>   +1: 00000000 +0 +NOTYPE +LOCAL +DEFAULT +1 static_text_symbol
>  # ARM targets add the $d mapping symbol here...
>  # NDS32 targets add the $d2 mapping symbol here...
> +# riscv targets add the $d4 mapping symbols here...
>  #...
>   +.: 00000000 +0 +NOTYPE +LOCAL +DEFAULT +[34] static_data_symbol
> +# ... or here ...
>  # v850 targets include extra SECTION symbols here for the .call_table_data
>  # and .call_table_text sections.
>  # riscv targets add .riscv.attribute symbol here...
> diff --git a/binutils/testsuite/binutils-all/readelf.ss-64 b/binutils/testsuite/binutils-all/readelf.ss-64
> index c6ffb0fc523..105f1b88361 100644
> --- a/binutils/testsuite/binutils-all/readelf.ss-64
> +++ b/binutils/testsuite/binutils-all/readelf.ss-64
> @@ -4,13 +4,14 @@ Symbol table '.symtab' contains .* entries:
>   +0: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +UND
>   +1: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +1 static_text_symbol
>  # aarch64-elf targets add the $d mapping symbol here...
> +# riscv targets add the $d4 mapping symbols here...
>  #...
>   +.: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +3 static_data_symbol
>  # ... or here ...
>  # riscv targets add .riscv.attribute symbol here...
>  #...
> -.* +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
> - +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
> - +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +3 data_symbol
> +.* +[0-9]+: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
> + +[0-9]+: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
> + +[0-9]+: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +3 data_symbol
>   +[0-9]+: 0000000000000004 +4 +(COMMON|OBJECT) +GLOBAL +DEFAULT +COM common_symbol
>  #pass
> diff --git a/binutils/testsuite/binutils-all/readelf.ss-64-unused b/binutils/testsuite/binutils-all/readelf.ss-64-unused
> index cf515aa60d0..50fca025b31 100644
> --- a/binutils/testsuite/binutils-all/readelf.ss-64-unused
> +++ b/binutils/testsuite/binutils-all/readelf.ss-64-unused
> @@ -7,13 +7,14 @@ Symbol table '.symtab' contains .* entries:
>   +3: 0000000000000000 +0 +SECTION +LOCAL +DEFAULT +4.*
>   +4: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +1 static_text_symbol
>  # aarch64-elf targets add the $d mapping symbol here...
> +# riscv targets add the $d4 mapping symbols here...
>  #...
>   +.: 0000000000000000 +0 +NOTYPE +LOCAL +DEFAULT +3 static_data_symbol
>  # ... or here ...
>  # riscv targets add .riscv.attribute symbol here...
>  #...
> -.* +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
> - +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
> - +.: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +3 data_symbol
> +.* +[0-9]+: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +1 text_symbol
> + +[0-9]+: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +UND external_symbol
> + +[0-9]+: 0000000000000000 +0 +NOTYPE +GLOBAL +DEFAULT +3 data_symbol
>   +[0-9]+: 0000000000000004 +4 +(COMMON|OBJECT) +GLOBAL +DEFAULT +COM common_symbol
>  #pass
> diff --git a/binutils/testsuite/binutils-all/readelf.ss-unused b/binutils/testsuite/binutils-all/readelf.ss-unused
> index 3107af930eb..944ab45cc46 100644
> --- a/binutils/testsuite/binutils-all/readelf.ss-unused
> +++ b/binutils/testsuite/binutils-all/readelf.ss-unused
> @@ -8,8 +8,10 @@ Symbol table '.symtab' contains .* entries:
>   +4: 00000000 +0 +NOTYPE +LOCAL +DEFAULT +1 static_text_symbol
>  # ARM targets add the $d mapping symbol here...
>  # NDS32 targets add the $d2 mapping symbol here...
> +# riscv targets add the $d4 mapping symbols here...
>  #...
>   +.: 00000000 +0 +NOTYPE +LOCAL +DEFAULT +[34] static_data_symbol
> +# ... or here ...
>  # v850 targets include extra SECTION symbols here for the .call_table_data
>  # and .call_table_text sections.
>  #...
> diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
> index df37579c843..55c49471825 100644
> --- a/gas/config/tc-riscv.c
> +++ b/gas/config/tc-riscv.c
> @@ -561,6 +561,179 @@ static bool explicit_priv_attr = false;
>
>  static char *expr_end;
>
> +/* Create a new mapping symbol for the transition to STATE.  */
> +
> +static void
> +make_mapping_symbol (enum riscv_seg_mstate state,
> +		     valueT value,
> +		     fragS *frag)
> +{
> +  const char *name;
> +  switch (state)
> +    {
> +    case MAP_DATA:
> +      name = "$d";
> +      break;
> +    case MAP_DATA_CONS0:
> +      name = "$d1";
> +      break;
> +    case MAP_DATA_CONS1:
> +      name = "$d2";
> +      break;
> +    case MAP_DATA_CONS2:
> +      name = "$d4";
> +      break;
> +    case MAP_DATA_CONS3:
> +      name = "$d8";
> +      break;
> +    case MAP_INSN:
> +      name = "$x";
> +      break;
> +    case MAP_ALIGN:
> +      name = "$a";
> +      break;
> +    case MAP_ALIGN_ODD:
> +      name = "$a1";
> +      break;
> +    default:
> +      abort ();
> +    }
> +
> +  symbolS *symbol = symbol_new (name, now_seg, frag, value);
> +  symbol_get_bfdsym (symbol)->flags |= (BSF_NO_FLAGS | BSF_LOCAL);
> +
> +  /* 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.  */
> +  if (value == 0)
> +    {
> +       if (frag->tc_frag_data.first_map_symbol != NULL)
> +	{
> +	  know (S_GET_VALUE (frag->tc_frag_data.first_map_symbol)
> +		== S_GET_VALUE (symbol));
> +	  /* Remove the old one.  */
> +	  symbol_remove (frag->tc_frag_data.first_map_symbol,
> +			 &symbol_rootP, &symbol_lastP);
> +	}
> +      frag->tc_frag_data.first_map_symbol = symbol;
> +    }
> +  if (frag->tc_frag_data.last_map_symbol != 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));
> +      /* 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);
> +    }
> +  frag->tc_frag_data.last_map_symbol = symbol;
> +}
> +
> +/* Set the mapping state for frag_now.  */
> +
> +void
> +riscv_mapping_state (enum riscv_seg_mstate to_state,
> +		     int max_chars)
> +{
> +  enum riscv_seg_mstate from_state =
> +	seg_info (now_seg)->tc_segment_info_data.map_state;
> +
> +  if (!SEG_NORMAL (now_seg)
> +      /* For now I 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.  */
> +      || !subseg_text_p (now_seg))
> +    return;
> +
> +  /* Keep inserting the MAP_DATA_CONS in text.  Otherwise, the mapping
> +     symbol should be emitted.  */
> +  if (from_state == to_state
> +      && from_state != MAP_DATA_CONS0
> +      && from_state != MAP_DATA_CONS1
> +      && from_state != MAP_DATA_CONS2
> +      && from_state != MAP_DATA_CONS3)
> +    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);
> +}
> +
> +/* Add the odd bytes of paddings for riscv_handle_align.  */
> +
> +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_ALIGN_ODD, frag->fr_fix, frag);
> +  make_mapping_symbol (MAP_ALIGN, frag->fr_fix + 1, frag);
> +}
> +
> +/* Remove any excess mapping symbols generated for alignment frags in
> +   SEC.  We may have created a mapping symbol before a zero byte
> +   alignment; remove it if there's a mapping symbol after the
> +   alignment.  */
> +
> +static void
> +riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
> +			     asection *sec,
> +			     void *dummy ATTRIBUTE_UNUSED)
> +{
> +  segment_info_type *seginfo = seg_info (sec);
> +  fragS *fragp;
> +
> +  if (seginfo == NULL || seginfo->frchainP == NULL)
> +    return;
> +
> +  for (fragp = seginfo->frchainP->frch_root;
> +       fragp != NULL;
> +       fragp = fragp->fr_next)
> +    {
> +      symbolS *last = fragp->tc_frag_data.last_map_symbol;
> +      fragS *next = fragp->fr_next;
> +
> +      if (last == NULL || next == NULL)
> +	continue;
> +
> +      /* Check the last mapping symbol if it is at the boundary of
> +	 fragmnet.  */
> +      if (S_GET_VALUE (last) < next->fr_address)
> +	continue;
> +      know (S_GET_VALUE (last) == next->fr_address);
> +
> +      do
> +	{
> +	  if (next->tc_frag_data.first_map_symbol != NULL)
> +	    {
> +	      /* The last mapping symbol overlaps with another one
> +		 which at the start of the next frag.  */
> +	      symbol_remove (last, &symbol_rootP, &symbol_lastP);
> +	      break;
> +	    }
> +
> +	  if (next->fr_next == NULL)
> +	    {
> +	      /* The last mapping symbol is at the end of the section.  */
> +	      know (next->fr_fix == 0 && next->fr_var == 0);
> +	      symbol_remove (last, &symbol_rootP, &symbol_lastP);
> +	      break;
> +	    }
> +
> +	  /* Since we may have empty frags without any mapping symbols,
> +	     keep looking until the non-empty frag.  */
> +	  if (next->fr_address != next->fr_next->fr_address)
> +	    break;
> +
> +	  next = next->fr_next;
> +	}
> +      while (next != NULL);
> +    }
> +}
> +
>  /* The default target format to use.  */
>
>  const char *
> @@ -2767,6 +2940,8 @@ md_assemble (char *str)
>         return;
>      }
>
> +  riscv_mapping_state (MAP_INSN, 0);
> +
>    const char *error = riscv_ip (str, &insn, &imm_expr, &imm_reloc, op_hash);
>
>    if (error)
> @@ -3422,6 +3597,8 @@ 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_ALIGN, worst_case_bytes);
> +
>    return true;
>  }
>
> @@ -3441,6 +3618,7 @@ riscv_handle_align (fragS *fragP)
>  	  /* We have 4 byte uncompressed nops.  */
>  	  bfd_signed_vma size = 4;
>  	  bfd_signed_vma excess = bytes % size;
> +	  bfd_boolean odd_padding = (excess % 2 == 1);
>  	  char *p = fragP->fr_literal + fragP->fr_fix;
>
>  	  if (bytes <= 0)
> @@ -3449,12 +3627,20 @@ riscv_handle_align (fragS *fragP)
>  	  /* Insert zeros or compressed nops to get 4 byte alignment.  */
>  	  if (excess)
>  	    {
> +	      if (odd_padding)
> +		riscv_add_odd_padding_symbol (fragP);
>  	      riscv_make_nops (p, excess);
>  	      fragP->fr_fix += excess;
>  	      p += excess;
>  	    }
>
> -	  /* Insert variable number of 4 byte uncompressed nops.  */
> +	  /* The frag will be changed to `rs_fill` later.  The function
> +	     `write_contents` will try to fill the remaining spaces
> +	     according to the patterns we give.  In this case, we give
> +	     a 4 byte uncompressed nop as the pattern, and set the size
> +	     of the pattern into `fr_var`.  The nop will be output to the
> +	     file `fr_offset` times.  However, `fr_offset` could be zero
> +	     if we don't need to pad the boundary finally.  */
>  	  riscv_make_nops (p, size);
>  	  fragP->fr_var = size;
>  	}
> @@ -3465,6 +3651,30 @@ riscv_handle_align (fragS *fragP)
>      }
>  }
>
> +/* This usually called from frag_var.  */
> +
> +void
> +riscv_init_frag (fragS * fragP, int max_chars)
> +{
> +  /* Do not add mapping symbol to debug sections.  */
> +  if (bfd_section_flags (now_seg) & SEC_DEBUGGING)
> +    return;
> +
> +  switch (fragP->fr_type)
> +    {
> +    case rs_fill:
> +    case rs_align:
> +    case rs_align_test:
> +      riscv_mapping_state (MAP_DATA, max_chars);
> +      break;
> +    case rs_align_code:
> +      riscv_mapping_state (MAP_ALIGN, max_chars);
> +      break;
> +    default:
> +      break;
> +    }
> +}
> +
>  int
>  md_estimate_size_before_relax (fragS *fragp, asection *segtype)
>  {
> @@ -3721,6 +3931,8 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
>    save_c = *input_line_pointer;
>    *input_line_pointer = '\0';
>
> +  riscv_mapping_state (MAP_INSN, 0);
> +
>    const char *error = riscv_ip (str, &insn, &imm_expr,
>  				&imm_reloc, insn_type_hash);
>
> @@ -3811,6 +4023,15 @@ riscv_md_end (void)
>    riscv_set_public_attributes ();
>  }
>
> +/* Adjust the symbol table.  */
> +
> +void
> +riscv_adjust_symtab (void)
> +{
> +  bfd_map_over_sections (stdoutput, riscv_check_mapping_symbols, (char *) 0);
> +  elf_adjust_symtab ();
> +}
> +
>  /* Given a symbolic attribute NAME, return the proper integer value.
>     Returns -1 if the attribute is not known.  */
>
> diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
> index 1de138458d8..1702b25bc51 100644
> --- a/gas/config/tc-riscv.h
> +++ b/gas/config/tc-riscv.h
> @@ -128,4 +128,36 @@ extern void riscv_elf_final_processing (void);
>  extern void riscv_md_end (void);
>  extern int riscv_convert_symbolic_attribute (const char *);
>
> +/* Set mapping symbol states.  */
> +#define md_cons_align(nbytes)					\
> +  switch (nbytes)						\
> +    {								\
> +    default: riscv_mapping_state (MAP_DATA, 0); break;		\
> +    case 1:  riscv_mapping_state (MAP_DATA_CONS0, 0); break;	\
> +    case 2:  riscv_mapping_state (MAP_DATA_CONS1, 0); break;	\
> +    case 4:  riscv_mapping_state (MAP_DATA_CONS2, 0); break;	\
> +    case 8:  riscv_mapping_state (MAP_DATA_CONS3, 0); break;	\
> +    }
> +void riscv_mapping_state (enum riscv_seg_mstate, int);
> +
> +/* 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;
> +};
> +
> +/* Define target fragment type.  */
> +#define TC_FRAG_TYPE struct riscv_frag_type
> +struct riscv_frag_type
> +{
> +  symbolS *first_map_symbol, *last_map_symbol;
> +};
> +
> +#define TC_FRAG_INIT(fragp, max_bytes) riscv_init_frag (fragp, max_bytes)
> +extern void riscv_init_frag (struct frag *, int);
> +
> +#define obj_adjust_symtab() riscv_adjust_symtab ()
> +extern void riscv_adjust_symtab (void);
> +
>  #endif /* TC_RISCV */
> diff --git a/gas/testsuite/gas/riscv/mapping-01.s b/gas/testsuite/gas/riscv/mapping-01.s
> new file mode 100644
> index 00000000000..0a270454b1b
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-01.s
> @@ -0,0 +1,18 @@
> +	.option norvc
> +	.text
> +	.global	funcA
> +funcA:
> +	nop
> +	j	funcB
> +
> +	.global	funcB
> +funcB:
> +	nop
> +	bne	a0, a1, funcB
> +
> +	.data
> +	.word 0x123456
> +
> +	.section	.foo, "ax"
> +foo:
> +	nop
> diff --git a/gas/testsuite/gas/riscv/mapping-01a.d b/gas/testsuite/gas/riscv/mapping-01a.d
> new file mode 100644
> index 00000000000..32e0027a13d
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-01a.d
> @@ -0,0 +1,17 @@
> +#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
> new file mode 100644
> index 00000000000..723bd5951cb
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-01b.d
> @@ -0,0 +1,21 @@
> +#as:
> +#source: mapping-01.s
> +#objdump: -d
> +
> +.*:[ 	]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+000 <funcA>:
> +[ 	]+0:[ 	]+00000013[ 	]+nop
> +[ 	]+4:[ 	]+0040006f[ 	]+j[ 	]+8 <funcB>
> +
> +0+008 <funcB>:
> +[ 	]+8:[ 	]+00000013[ 	]+nop
> +[ 	]+c:[ 	]+feb51ee3[ 	]+bne[ 	]+a0,a1,8 <funcB>
> +
> +Disassembly of section .foo:
> +
> +0+000 <foo>:
> +[ 	]+0:[ 	]+00000013[ 	]+nop
> diff --git a/gas/testsuite/gas/riscv/mapping-02.s b/gas/testsuite/gas/riscv/mapping-02.s
> new file mode 100644
> index 00000000000..d3de6dedac8
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-02.s
> @@ -0,0 +1,13 @@
> +	.option norvc
> +	.text
> +	.global main
> +	.type   main, %function
> +main:
> +	nop
> +foo:
> +	nop
> +	nop
> +	.size   main, .-main
> +	.ident  ""
> +
> +	nop
> diff --git a/gas/testsuite/gas/riscv/mapping-02a.d b/gas/testsuite/gas/riscv/mapping-02a.d
> new file mode 100644
> index 00000000000..d0cb460e08e
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-02a.d
> @@ -0,0 +1,15 @@
> +#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 \$x
> +0+04 l       .text	0+00 foo
> +0+00 l    d  .comment	0+00 .comment
> +0+00 l    d  .riscv.attributes	0+00 .riscv.attributes
> +0+00 g     F .text	0+0c main
> diff --git a/gas/testsuite/gas/riscv/mapping-02b.d b/gas/testsuite/gas/riscv/mapping-02b.d
> new file mode 100644
> index 00000000000..3e875600a9c
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-02b.d
> @@ -0,0 +1,16 @@
> +#as:
> +#source: mapping-02.s
> +#objdump: -d
> +
> +.*:[ 	]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+000 <main>:
> +[ 	]+0:[ 	]+00000013[ 	]+nop
> +
> +0+004 <foo>:
> +[ 	]+4:[ 	]+00000013[ 	]+nop
> +[ 	]+8:[ 	]+00000013[ 	]+nop
> +[ 	]+c:[ 	]+00000013[ 	]+nop
> diff --git a/gas/testsuite/gas/riscv/mapping-03.s b/gas/testsuite/gas/riscv/mapping-03.s
> new file mode 100644
> index 00000000000..49964f20288
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-03.s
> @@ -0,0 +1,10 @@
> +	.option norvc
> +	.text
> +	.word 0
> +	nop
> +	.data
> +	.word 0
> +	.text
> +	nop
> +	.short 0
> +	nop
> diff --git a/gas/testsuite/gas/riscv/mapping-03a.d b/gas/testsuite/gas/riscv/mapping-03a.d
> new file mode 100644
> index 00000000000..8567820b941
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-03a.d
> @@ -0,0 +1,16 @@
> +#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 \$d4
> +0+04 l       .text	0+00 \$x
> +0+0c l       .text	0+00 \$d2
> +0+0e l       .text	0+00 \$x
> +0+12 l       .text	0+00 \$a
> +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
> new file mode 100644
> index 00000000000..ed87fcf33d2
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-03b.d
> @@ -0,0 +1,16 @@
> +#as:
> +#source: mapping-03.s
> +#objdump: -d
> +
> +.*:[ 	]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+000 <.text>:
> +[ 	]+0:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
> +[ 	]+4:[ 	]+00000013[ 	]+nop
> +[ 	]+8:[ 	]+00000013[ 	]+nop
> +[ 	]+c:[ 	]+0000[ 	]+.short[ 	]+0x0000
> +[ 	]+e:[ 	]+00000013[ 	]+nop
> +#...
> diff --git a/gas/testsuite/gas/riscv/mapping-04.s b/gas/testsuite/gas/riscv/mapping-04.s
> new file mode 100644
> index 00000000000..36bfac11050
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-04.s
> @@ -0,0 +1,11 @@
> +	.option norvc
> +	.text
> +	nop
> +	.long	0
> +	.align	4
> +	.word	0x12345678
> +	nop
> +	.byte	1
> +	.long	0
> +	.align	4
> +	.word	0x12345678
> diff --git a/gas/testsuite/gas/riscv/mapping-04a.d b/gas/testsuite/gas/riscv/mapping-04a.d
> new file mode 100644
> index 00000000000..a3bb31a98b4
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-04a.d
> @@ -0,0 +1,21 @@
> +#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 \$x
> +0+04 l       .text	0+00 \$d4
> +0+08 l       .text	0+00 \$a
> +0+14 l       .text	0+00 \$d4
> +0+18 l       .text	0+00 \$x
> +0+1c l       .text	0+00 \$d1
> +0+1d l       .text	0+00 \$d4
> +0+21 l       .text	0+00 \$a
> +0+2d l       .text	0+00 \$d4
> +0+31 l       .text	0+00 \$a
> +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
> new file mode 100644
> index 00000000000..d27b98db2ae
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-04b.d
> @@ -0,0 +1,24 @@
> +#as:
> +#source: mapping-04.s
> +#objdump: -d
> +
> +.*:[ 	]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+000 <.text>:
> +[ 	]+0:[ 	]+00000013[ 	]+nop
> +[ 	]+4:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
> +[ 	]+8:[ 	]+00000013[ 	]+align.nop
> +[ 	]+c:[ 	]+00000013[ 	]+align.nop
> +[ 	]+10:[ 	]+00000013[ 	]+align.nop
> +[ 	]+14:[ 	]+12345678[ 	]+.word[ 	]+0x12345678
> +[ 	]+18:[ 	]+00000013[ 	]+nop
> +[ 	]+1c:[ 	]+01[ 	]+.byte[ 	]+0x01
> +[ 	]+1d:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
> +[ 	]+21:[ 	]+00000013[ 	]+align.nop
> +[ 	]+25:[ 	]+00000013[ 	]+align.nop
> +[ 	]+29:[ 	]+00000013[ 	]+align.nop
> +[ 	]+2d:[ 	]+12345678[ 	]+.word[ 	]+0x12345678
> +#...
> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04a.d b/gas/testsuite/gas/riscv/mapping-norelax-04a.d
> new file mode 100644
> index 00000000000..785b9d9f922
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-norelax-04a.d
> @@ -0,0 +1,23 @@
> +#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 \$x
> +0+04 l       .text	0+00 \$d4
> +0+08 l       .text	0+00 \$a
> +0+10 l       .text	0+00 \$d4
> +0+14 l       .text	0+00 \$x
> +0+18 l       .text	0+00 \$d1
> +0+19 l       .text	0+00 \$d4
> +0+20 l       .text	0+00 \$d4
> +0+24 l       .text	0+00 \$a
> +0+1d l       .text	0+00 \$a1
> +0+1e l       .text	0+00 \$a
> +# Maybe section symbol for .riscv.attributes
> +#...
> diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04b.d b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
> new file mode 100644
> index 00000000000..8765c6cd129
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
> @@ -0,0 +1,25 @@
> +#as: -mno-relax
> +#source: mapping-04.s
> +#objdump: -d
> +
> +.*:[ 	]+file format .*
> +
> +
> +Disassembly of section .text:
> +
> +0+000 <.text>:
> +[ 	]+0:[ 	]+00000013[ 	]+nop
> +[ 	]+4:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
> +[ 	]+8:[ 	]+00000013[ 	]+align.nop
> +[ 	]+c:[ 	]+00000013[ 	]+align.nop
> +[ 	]+10:[ 	]+12345678[ 	]+.word[ 	]+0x12345678
> +[ 	]+14:[ 	]+00000013[ 	]+nop
> +[ 	]+18:[ 	]+01[ 	]+.byte[ 	]+0x01
> +[ 	]+19:[ 	]+00000000[ 	]+.word[ 	]+0x00000000
> +[ 	]+1d:[ 	]+00[ 	]+align.byte
> +[ 	]+1e:[ 	]+0001[ 	]+align.nop
> +[ 	]+20:[ 	]+12345678[ 	]+.word[ 	]+0x12345678
> +[ 	]+24:[ 	]+00000013[ 	]+align.nop
> +[ 	]+28:[ 	]+00000013[ 	]+align.nop
> +[ 	]+2c:[ 	]+00000013[ 	]+align.nop
> +#...
> diff --git a/gas/testsuite/gas/riscv/no-relax-align-2.d b/gas/testsuite/gas/riscv/no-relax-align-2.d
> index 7407b495a8f..3c4323cc186 100644
> --- a/gas/testsuite/gas/riscv/no-relax-align-2.d
> +++ b/gas/testsuite/gas/riscv/no-relax-align-2.d
> @@ -7,13 +7,14 @@
>  Disassembly of section .text:
>
>  0+000 <.text>:
> -[ 	]+0:[ 	]+0000[ 	]+unimp
> -[ 	]+2:[ 	]+0001[ 	]+nop
> -[ 	]+4:[ 	]+00000013[ 	]+nop
> -[ 	]+8:[ 	]+00000013[ 	]+nop
> -[ 	]+c:[ 	]+00000013[ 	]+nop
> +[ 	]+0:[ 	]+00[ 	]+.byte[ 	]+0x00
> +[ 	]+1:[ 	]+00[ 	]+align.byte
> +[ 	]+2:[ 	]+0001[ 	]+align.nop
> +[ 	]+4:[ 	]+00000013[ 	]+align.nop
> +[ 	]+8:[ 	]+00000013[ 	]+align.nop
> +[ 	]+c:[ 	]+00000013[ 	]+align.nop
>  [ 	]+10:[ 	]+0001[ 	]+nop
> -[ 	]+12:[ 	]+0001[ 	]+nop
> -[ 	]+14:[ 	]+00000013[ 	]+nop
> -[ 	]+18:[ 	]+00000013[ 	]+nop
> -[ 	]+1c:[ 	]+00000013[ 	]+nop
> +[ 	]+12:[ 	]+0001[ 	]+align.nop
> +[ 	]+14:[ 	]+00000013[ 	]+align.nop
> +[ 	]+18:[ 	]+00000013[ 	]+align.nop
> +[ 	]+1c:[ 	]+00000013[ 	]+align.nop
> diff --git a/gas/testsuite/gas/riscv/no-relax-align.d b/gas/testsuite/gas/riscv/no-relax-align.d
> index ced07d3c830..960db2a58bc 100644
> --- a/gas/testsuite/gas/riscv/no-relax-align.d
> +++ b/gas/testsuite/gas/riscv/no-relax-align.d
> @@ -9,5 +9,5 @@ Disassembly of section .text:
>  0+000 <.text>:
>  [ 	]+0:[ 	]+00000013[ 	]+nop
>  [ 	]+4:[ 	]+00000013[ 	]+nop
> -[ 	]+8:[ 	]+00000013[ 	]+nop
> -[ 	]+c:[ 	]+00000013[ 	]+nop
> +[ 	]+8:[ 	]+00000013[ 	]+align.nop
> +[ 	]+c:[ 	]+00000013[ 	]+align.nop
> diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h
> index fdf3df4f5c1..3cea9e93c96 100644
> --- a/include/opcode/riscv.h
> +++ b/include/opcode/riscv.h
> @@ -425,6 +425,19 @@ enum
>    M_NUM_MACROS
>  };
>
> +/* The mapping symbol states.  */
> +enum riscv_seg_mstate
> +{
> +  MAP_NONE = 0,		/* Must be zero, for seginfo in new sections.  */
> +  MAP_DATA,		/* The rs_fill and rs_align.  */
> +  MAP_DATA_CONS0,	/* Added for cons_worker, with the data size.  */
> +  MAP_DATA_CONS1,
> +  MAP_DATA_CONS2,
> +  MAP_DATA_CONS3,
> +  MAP_INSN,		/* Instructions.  */
> +  MAP_ALIGN,		/* The rs_align_code, added nops.  */
> +  MAP_ALIGN_ODD,	/* The rs_align_code, added odd byte.  */
> +};
>
>  extern const char * const riscv_gpr_names_numeric[NGPR];
>  extern const char * const riscv_gpr_names_abi[NGPR];
> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> index fe8dfb88d90..b41cad8f4aa 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -41,6 +41,12 @@ struct riscv_private_data
>    bfd_vma hi_addr[OP_MASK_RD + 1];
>  };
>
> +/* Used for mapping symbols.  */
> +static int last_map_symbol = -1;
> +static bfd_vma last_stop_offset = 0;
> +static asection *last_section = NULL;
> +enum riscv_seg_mstate last_map_state;
> +
>  static const char * const *riscv_gpr_names;
>  static const char * const *riscv_fpr_names;
>
> @@ -507,6 +513,27 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
>  	  if ((op->xlen_requirement != 0) && (op->xlen_requirement != xlen))
>  	    continue;
>
> +	  /* Add the "align." prefix if it is used for alignment.
> +
> +	     Consider the following case,
> +	     .text
> +	     .byte 0
> +	     nop
> +
> +	     0000000000000000 <.text>:
> +	     0:	00		.byte   0x00
> +	     1:	00000013	nop
> +	     5:	0000		align.unimp
> +		...
> +
> +	     The tail section alignments are not handled in the
> +	     riscv_frag_align_code, and since the relax is enable,
> +	     it cannot be filled with nops in the riscv_handle_align
> +	     either.  Therefore, we may get align.unimp at the end
> +	     of the sections, I think this is expected.  */
> +	  if (last_map_state == MAP_ALIGN)
> +	    (*info->fprintf_func) (info->stream, "align.");
> +
>  	  /* It's a match.  */
>  	  (*info->fprintf_func) (info->stream, "%s", op->name);
>  	  print_insn_args (op->args, word, memaddr, info);
> @@ -556,13 +583,238 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
>    return insnlen;
>  }
>
> +/* Return true if we find the suitable mapping symbol,
> +   and also update the STATE.  Otherwise, return false.  */
> +
> +static bool
> +riscv_get_map_state (int n,
> +		     enum riscv_seg_mstate *state,
> +		     struct disassemble_info *info)
> +{
> +  const char *name;
> +
> +  /* If the symbol is in a different section, ignore it.  */
> +  if (info->section != NULL
> +      && info->section != info->symtab[n]->section)
> +    return false;
> +
> +  name = bfd_asymbol_name(info->symtab[n]);
> +  if (strcmp (name, "$x") == 0)
> +    *state = MAP_INSN;
> +  else if (strcmp (name, "$d") == 0)
> +    *state = MAP_DATA;
> +  else if (strcmp (name, "$d1") == 0)
> +    *state = MAP_DATA_CONS0;
> +  else if (strcmp (name, "$d2") == 0)
> +    *state = MAP_DATA_CONS1;
> +  else if (strcmp (name, "$d4") == 0)
> +    *state = MAP_DATA_CONS2;
> +  else if (strcmp (name, "$d8") == 0)
> +    *state = MAP_DATA_CONS3;
> +  else if (strcmp (name, "$a") == 0)
> +    *state = MAP_ALIGN;
> +  else if (strcmp (name, "$a1") == 0)
> +    *state = MAP_ALIGN_ODD;
> +  else
> +    return false;
> +
> +  return true;
> +}
> +
> +/* Check the sorted symbol table (sorted by the symbol value), find the
> +   suitable mapping symbols.  */
> +
> +static enum riscv_seg_mstate
> +riscv_search_mapping_symbol (bfd_vma memaddr,
> +			     struct disassemble_info *info)
> +{
> +  enum riscv_seg_mstate mstate;
> +  bool from_last_map_symbol;
> +  bool found = false;
> +  int symbol = -1;
> +  int n;
> +
> +  /* Decide whether to print the data or instruction by default, in case
> +     we can not find the corresponding mapping symbols.  */
> +  mstate = MAP_DATA;
> +  if ((info->section
> +       && info->section->flags & SEC_CODE)
> +      || !info->section)
> +    mstate = MAP_INSN;
> +
> +  if (info->symtab_size == 0
> +      || bfd_asymbol_flavour (*info->symtab) != bfd_target_elf_flavour)
> +    return mstate;
> +
> +  /* Reset the last_map_symbol if we start to dump a new section.  */
> +  if (memaddr <= 0)
> +    last_map_symbol = -1;
> +
> +  /* If the last stop offset is different from the current one, then
> +     don't use the last_map_symbol to search.  We usually reset the
> +     info->stop_offset when handling a new section.  */
> +  from_last_map_symbol = (last_map_symbol >= 0
> +			  && info->stop_offset == last_stop_offset);
> +
> +  /* Start scanning at the start of the function, or wherever
> +     we finished last time.  */
> +  n = info->symtab_pos + 1;
> +  if (from_last_map_symbol && n >= last_map_symbol)
> +    n = last_map_symbol;
> +
> +  /* Find the suitable mapping symbol to dump.  */
> +  for (; n < info->symtab_size; n++)
> +    {
> +      bfd_vma addr = bfd_asymbol_value (info->symtab[n]);
> +      /* We have searched all possible symbols in the range.  */
> +      if (addr > memaddr)
> +	break;
> +      if (riscv_get_map_state (n, &mstate, info))
> +	{
> +	  symbol = n;
> +	  found = true;
> +	  /* Do not stop searching, in case there are some mapping
> +	     symbols have the same value, but have different names.
> +	     Use the last one.  */
> +	}
> +    }
> +
> +  /* We can not find the suitable mapping symbol above.  Therefore, we
> +     look forwards and try to find it again, but don't go pass the start
> +     of the section.  Otherwise a data section without mapping symbols
> +     can pick up a text mapping symbol of a preceeding section.  */
> +  if (!found)
> +    {
> +      n = info->symtab_pos;
> +      if (from_last_map_symbol && n >= last_map_symbol)
> +	n = last_map_symbol;
> +
> +      for (; n >= 0; n--)
> +	{
> +	  bfd_vma addr = bfd_asymbol_value (info->symtab[n]);
> +	  /* We have searched all possible symbols in the range.  */
> +	  if (addr < (info->section ? info->section->vma : 0))
> +	    break;
> +	  /* Stop searching once we find the closed mapping symbol.  */
> +	  if (riscv_get_map_state (n, &mstate, info))
> +	    {
> +	      symbol = n;
> +	      found = true;
> +	      break;
> +	    }
> +	}
> +    }
> +
> +  /* Save the information for next use.  */
> +  last_map_symbol = symbol;
> +  last_stop_offset = info->stop_offset;
> +  last_section = info->section;
> +
> +  return mstate;
> +}
> +
> +/* Decide which data size we should print.  */
> +
> +static bfd_vma
> +riscv_data_length (bfd_vma memaddr,
> +		   enum riscv_seg_mstate mstate,
> +		   disassemble_info *info)
> +{
> +  bfd_vma length;
> +  bool found = false;
> +
> +  switch (mstate)
> +    {
> +    case MAP_DATA:	 length = 0; break;
> +    case MAP_DATA_CONS0: length = 1; break;
> +    case MAP_DATA_CONS1: length = 2; break;
> +    case MAP_DATA_CONS2: length = 4; break;
> +    case MAP_DATA_CONS3: length = 8; break;
> +    default: abort ();
> +    }
> +  if (length > 0)
> +    return length;
> +
> +  length = 4;
> +  if (info->symtab_size != 0
> +      && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour
> +      && last_map_symbol >= 0)
> +    {
> +      int n;
> +      enum riscv_seg_mstate m = MAP_NONE;
> +      for (n = last_map_symbol + 1; n < info->symtab_size; n++)
> +	{
> +	  bfd_vma addr = bfd_asymbol_value (info->symtab[n]);
> +	  if (addr > memaddr
> +	      && riscv_get_map_state (n, &m, info))
> +	    {
> +	      if (addr - memaddr < length)
> +		length = addr - memaddr;
> +	      found = true;
> +	      break;
> +	    }
> +	}
> +    }
> +  if (!found)
> +    {
> +      /* Do not set the length which exceeds the section size.  */
> +      bfd_vma offset = info->section->vma + info->section->size;
> +      offset -= memaddr;
> +      length = (offset < length) ? offset : length;
> +    }
> +  length = length == 3 ? 2 : length;
> +  return length;
> +}
> +
> +/* Dump the data contents.  */
> +
> +static int
> +riscv_disassemble_data (bfd_vma memaddr ATTRIBUTE_UNUSED,
> +			insn_t data,
> +			disassemble_info *info)
> +{
> +  info->display_endian = info->endian;
> +
> +  switch (info->bytes_per_chunk)
> +    {
> +    case 1:
> +      info->bytes_per_line = 6;
> +      if (last_map_state == MAP_ALIGN_ODD)
> +	(*info->fprintf_func) (info->stream, "align.byte");
> +      else
> +	(*info->fprintf_func) (info->stream, ".byte\t0x%02llx",
> +			       (unsigned long long) data);
> +      break;
> +    case 2:
> +      info->bytes_per_line = 8;
> +      (*info->fprintf_func) (info->stream, ".short\t0x%04llx",
> +			     (unsigned long long) data);
> +      break;
> +    case 4:
> +      info->bytes_per_line = 8;
> +      (*info->fprintf_func) (info->stream, ".word\t0x%08llx",
> +			     (unsigned long long) data);
> +      break;
> +    case 8:
> +      info->bytes_per_line = 8;
> +      (*info->fprintf_func) (info->stream, ".dword\t0x%016llx",
> +			     (unsigned long long) data);
> +      break;
> +    default:
> +      abort ();
> +    }
> +  return info->bytes_per_chunk;
> +}
> +
>  int
>  print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
>  {
> -  bfd_byte packet[2];
> +  bfd_byte packet[8];
>    insn_t insn = 0;
> -  bfd_vma n;
> +  bfd_vma dump_size;
>    int status;
> +  enum riscv_seg_mstate mstate;
> +  int (*riscv_disassembler) (bfd_vma, insn_t, struct disassemble_info *);
>
>    if (info->disassembler_options != NULL)
>      {
> @@ -573,23 +825,59 @@ print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
>    else if (riscv_gpr_names == NULL)
>      set_default_riscv_dis_options ();
>
> -  /* Instructions are a sequence of 2-byte packets in little-endian order.  */
> -  for (n = 0; n < sizeof (insn) && n < riscv_insn_length (insn); n += 2)
> +  mstate = riscv_search_mapping_symbol (memaddr, info);
> +  /* Save the last mapping state.  */
> +  last_map_state = mstate;
> +
> +  /* Set the size to dump.  */
> +  if (mstate == MAP_DATA
> +      || mstate == MAP_DATA_CONS0
> +      || mstate == MAP_DATA_CONS1
> +      || mstate == MAP_DATA_CONS2
> +      || mstate == MAP_DATA_CONS3)
>      {
> -      status = (*info->read_memory_func) (memaddr + n, packet, 2, info);
> +      /* The documentation for -D says that on Arm platforms -D should
> +	 disassemble instructions.  Therefore, they dump data by searching
> +	 mapping symbols only when the DISASSEMBLE_DATA is set.  That causes
> +	 the mapping symbols are useless for -D.  I am not sure if any riscv
> +	 document had mentioned this, so I prefer to keep them useful, but
> +	 only for text sections.  If we decide not only to support mapping
> +	 symbols for text sections, then the riscv_mapping_state in the
> +	 gas/config/tc-riscv.c should be updated.  */
> +      dump_size = riscv_data_length (memaddr, mstate, info);
> +      info->bytes_per_chunk = dump_size;
> +      riscv_disassembler = riscv_disassemble_data;
> +    }
> +  else if (mstate == MAP_ALIGN_ODD)
> +    {
> +      dump_size = 1;
> +      info->bytes_per_chunk = dump_size;
> +      riscv_disassembler = riscv_disassemble_data;
> +    }
> +  else
> +    {
> +      /* Get the first 2-bytes to check the lenghth of instruction.  */
> +      status = (*info->read_memory_func) (memaddr, packet, 2, info);
>        if (status != 0)
>  	{
> -	  /* Don't fail just because we fell off the end.  */
> -	  if (n > 0)
> -	    break;
>  	  (*info->memory_error_func) (status, memaddr, info);
> -	  return status;
> +	  return 1;
>  	}
> +      insn = (insn_t) bfd_getl16 (packet);
> +      dump_size = riscv_insn_length (insn);
> +      riscv_disassembler = riscv_disassemble_insn;
> +    }
>
> -      insn |= ((insn_t) bfd_getl16 (packet)) << (8 * n);
> +  /* Fetch the instruction to dump.  */
> +  status = (*info->read_memory_func) (memaddr, packet, dump_size, info);
> +  if (status != 0)
> +    {
> +      (*info->memory_error_func) (status, memaddr, info);
> +      return 1;
>      }
> +  insn = (insn_t) bfd_get_bits (packet, dump_size * 8, false);
>
> -  return riscv_disassemble_insn (memaddr, insn, info);
> +  return (*riscv_disassembler) (memaddr, insn, info);
>  }
>
>  disassembler_ftype
> @@ -631,7 +919,8 @@ riscv_symbol_is_valid (asymbol * sym,
>
>    name = bfd_asymbol_name (sym);
>
> -  return (strcmp (name, RISCV_FAKE_LABEL_NAME) != 0);
> +  return (strcmp (name, RISCV_FAKE_LABEL_NAME) != 0
> +	  && !riscv_elf_is_mapping_symbols (name));
>  }
>
>  void

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

* Re: [PATCH v2 2/3] RISC-V: PR27916, Support mapping symbols.
  2021-07-15 15:16   ` Palmer Dabbelt
@ 2021-07-16  2:58     ` Nelson Chu
  0 siblings, 0 replies; 13+ messages in thread
From: Nelson Chu @ 2021-07-16  2:58 UTC (permalink / raw)
  To: Palmer Dabbelt
  Cc: Binutils, gdb-patches, Jim Wilson, Andrew Burgess, Kito Cheng,
	Andrew Waterman

On Thu, Jul 15, 2021 at 11:16 PM Palmer Dabbelt <palmer@dabbelt.com> wrote:
> > +/* Define mapping symbols for riscv.  */
> > +
> > +bool
> > +riscv_elf_is_mapping_symbols (const char *name)
> > +{
> > +  return (!strncmp (name, "$d", 2)
> > +       || !strncmp (name, "$x", 2)
> > +       || !strncmp (name, "$a", 2));
> > +}
>
> I can't quite figure this one out: this will treat something like
> "$aWHATEVER" as a mapping symbol, does that cause binutils to crash
> somewhere?  All I'm seeing it do is mark these as hidden symbols, which
> I guess is OK (we've kind of set the "anything with $ is inernal
> precedent").
>
> Either way,
> Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
Just filtering the mapping symbols in the
bfd/elfnn-riscv.c/riscv_elf_is_target_special_symbol isn't enough.  I
notice that we also need to filter them in
bfd/elfnn-riscv.c/riscv_maybe_function_sym and
opcode/riscv-dis.c/riscv_symbol_is_valid, otherwise, something may be
broken.  For example, objudmp/nm/addr2line calls bfd_find_nearest_line
to dump something, including the GNU note sections, and it will call
_bfd_elf_find_function to get the function name.  If we don't filter
the mapping symbols here, then they may be regarded as function names,
which is not the expected result.

BTW, since the discussion from psabi,
https://github.com/riscv/riscv-elf-psabi-doc/pull/196
The $a and $d+size are abandoned for now.  So the v3 patch is a little
bit different from this one.


Thanks
Nelson

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

* Re: [PATCH v2 1/3] RISC-V: Enable elf attributes when default configure option isn't set.
  2021-07-09  7:28 ` [PATCH v2 1/3] RISC-V: Enable elf attributes when default configure option isn't set Nelson Chu
  2021-07-09  8:00   ` Kito Cheng
  2021-07-13 20:38   ` Palmer Dabbelt
@ 2022-02-25 13:57   ` Sebastian Huber
  2 siblings, 0 replies; 13+ messages in thread
From: Sebastian Huber @ 2022-02-25 13:57 UTC (permalink / raw)
  To: Nelson Chu, binutils

Hello,

On 09/07/2021 09:28, Nelson Chu wrote:
> Since gcc commit, 3c70b3ca1ef58f302bf8c16d9e7c7bb8626408bf, we now enable
> elf attributes for all riscv targets by default in gcc.  Therefore, I
> think binutils should have the same behavior, in case users are writing
> assembly files.

this is probably not directly related to this patch, however, the 
riscv.attributes are not covered by the default linker command file:

riscv-rtems6-ld --verbose | grep attrib
   .gnu.build.attributes : { *(.gnu.build.attributes 
.gnu.build.attributes.*) }
   .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }

Compared to for example:

arm-rtems6-ld --verbose | grep attrib
   .gnu.build.attributes : { *(.gnu.build.attributes 
.gnu.build.attributes.*) }
   .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP 
(*(.gnu.attributes)) }

-- 
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.huber@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/

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

end of thread, other threads:[~2022-02-25 13:57 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-09  7:28 [PATCH v2 0/3] RISC-V: The series to supporting mapping symbols Nelson Chu
2021-07-09  7:28 ` [PATCH v2 1/3] RISC-V: Enable elf attributes when default configure option isn't set Nelson Chu
2021-07-09  8:00   ` Kito Cheng
2021-07-13  7:07     ` Nelson Chu
2021-07-13 20:38   ` Palmer Dabbelt
2021-07-15  1:47     ` Nelson Chu
2022-02-25 13:57   ` Sebastian Huber
2021-07-09  7:28 ` [PATCH v2 2/3] RISC-V: PR27916, Support mapping symbols Nelson Chu
2021-07-15 15:16   ` Palmer Dabbelt
2021-07-16  2:58     ` Nelson Chu
2021-07-09  7:28 ` [PATCH v2 3/3] RISC-V: PR27916, Extend .insn directive to support hardcode encoding Nelson Chu
2021-07-09  8:01   ` Kito Cheng
2021-07-14 20:38     ` Palmer Dabbelt

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