aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorNelson Chu <nelson.chu@sifive.com>2021-07-13 03:09:38 -0700
committerNelson Chu <nelson.chu@sifive.com>2021-08-30 17:36:11 +0800
commit9b9b1092f0a8e6b7d240ea05a74968a883b8a05c (patch)
treedc5a9df30faf6439ec510b2462fc98e04beb1e3a /gas
parent590d3faada8a12bf0937bbf68413956dc6a339a9 (diff)
downloadbinutils-9b9b1092f0a8e6b7d240ea05a74968a883b8a05c.zip
binutils-9b9b1092f0a8e6b7d240ea05a74968a883b8a05c.tar.gz
binutils-9b9b1092f0a8e6b7d240ea05a74968a883b8a05c.tar.bz2
RISC-V: PR27916, Support mapping symbols.
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, and the $x means instruction. Then the disassembler uses these symbols to decide whether we should dump data or instruction. Consider the mapping-04 test case, $ cat tmp.s .text .option norelax .option norvc .fill 2, 4, 0x1001 .byte 1 .word 0 .balign 8 add a0, a0, a0 .fill 5, 2, 0x2002 add a1, a1, a1 .data .word 0x1 # 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 # Marked $d, .fill directive. 4: 00001001 .word 0x00001001 8: 00000001 .word 0x00000001 # .byte + part of .word. c: 00 .byte 0x00 # remaining .word. d: 00 .byte 0x00 # Marked $d, odd byte of alignment. e: 0001 nop # Marked $x, nops for alignment. 10: 00a50533 add a0,a0,a0 14: 20022002 .word 0x20022002 # Marked $d, .fill directive. 18: 20022002 .word 0x20022002 1c: 2002 .short 0x2002 1e: 00b585b3 add a1,a1,a1 # Marked $x. 22: 0001 nop # Section tail alignment. 24: 00000013 nop * Use $d and $x to mark the distribution of data and instructions. Alignments of code are recognized as instructions, since we usually fill nops for them. * If the alignment have odd bytes, then we cannot just fill the nops into the spaces. We always fill an odd byte 0x00 at the start of the spaces. Therefore, add a $d mapping symbol for the odd byte, to tell disassembler that it isn't an instruction. The behavior is same as Arm and Aarch64. 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. 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 * 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 mapping symbols for the riscv_handle_align, which have odd bytes spaces. (riscv_check_mapping_symbols): Remove any excess mapping symbols. (md_assemble): Marked as MAP_INSN. (riscv_frag_align_code): Marked as MAP_INSN. (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 MAP_INSN 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. (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_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. (print_insn_riscv): Handle the mapping symbols. (riscv_symbol_is_valid): Marked mapping symbols as invalid.
Diffstat (limited to 'gas')
-rw-r--r--gas/config/tc-riscv.c201
-rw-r--r--gas/config/tc-riscv.h24
-rw-r--r--gas/testsuite/gas/riscv/mapping-01.s17
-rw-r--r--gas/testsuite/gas/riscv/mapping-01a.d17
-rw-r--r--gas/testsuite/gas/riscv/mapping-01b.d21
-rw-r--r--gas/testsuite/gas/riscv/mapping-02.s12
-rw-r--r--gas/testsuite/gas/riscv/mapping-02a.d15
-rw-r--r--gas/testsuite/gas/riscv/mapping-02b.d16
-rw-r--r--gas/testsuite/gas/riscv/mapping-03.s11
-rw-r--r--gas/testsuite/gas/riscv/mapping-03a.d20
-rw-r--r--gas/testsuite/gas/riscv/mapping-03b.d24
-rw-r--r--gas/testsuite/gas/riscv/mapping-04.s13
-rw-r--r--gas/testsuite/gas/riscv/mapping-04a.d15
-rw-r--r--gas/testsuite/gas/riscv/mapping-04b.d23
-rw-r--r--gas/testsuite/gas/riscv/mapping-norelax-03a.d21
-rw-r--r--gas/testsuite/gas/riscv/mapping-norelax-03b.d25
-rw-r--r--gas/testsuite/gas/riscv/mapping-norelax-04a.d16
-rw-r--r--gas/testsuite/gas/riscv/mapping-norelax-04b.d24
-rw-r--r--gas/testsuite/gas/riscv/no-relax-align-2.d3
19 files changed, 516 insertions, 2 deletions
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 460667e..bb6b063 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -561,6 +561,157 @@ 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_INSN:
+ name = "$x";
+ 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;
+
+ /* The mapping symbol should be emitted if not in the right
+ mapping state */
+ if (from_state == to_state)
+ return;
+
+ valueT value = (valueT) (frag_now_fix () - max_chars);
+ seg_info (now_seg)->tc_segment_info_data.map_state = to_state;
+ make_mapping_symbol (to_state, value, frag_now);
+}
+
+/* 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_DATA, frag->fr_fix, frag);
+ make_mapping_symbol (MAP_INSN, 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
+ fragment. */
+ 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 +2918,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)
@@ -3421,6 +3574,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_INSN, worst_case_bytes);
+
return true;
}
@@ -3440,6 +3595,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)
@@ -3448,12 +3604,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;
}
@@ -3464,6 +3628,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_INSN, max_chars);
+ break;
+ default:
+ break;
+ }
+}
+
int
md_estimate_size_before_relax (fragS *fragp, asection *segtype)
{
@@ -3720,6 +3908,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);
@@ -3810,6 +4000,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 1de1384..d035eed 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -128,4 +128,28 @@ 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) riscv_mapping_state (MAP_DATA, 0)
+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 0000000..0002098
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-01.s
@@ -0,0 +1,17 @@
+ .option norvc
+ .text
+ .global funcA
+funcA:
+ add a0, a0, a0
+ j funcB
+ .global funcB
+funcB:
+ add a1, a1, a1
+ bne a0, a1, funcB
+
+ .data
+ .word 0x123456
+
+ .section .foo, "ax"
+foo:
+ add a2, a2, a2
diff --git a/gas/testsuite/gas/riscv/mapping-01a.d b/gas/testsuite/gas/riscv/mapping-01a.d
new file mode 100644
index 0000000..32e0027
--- /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 0000000..e84b3d6
--- /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:[ ]+00a50533[ ]+add[ ]+a0,a0,a0
+[ ]+4:[ ]+0040006f[ ]+j[ ]+8 <funcB>
+
+0+008 <funcB>:
+[ ]+8:[ ]+00b585b3[ ]+add[ ]+a1,a1,a1
+[ ]+c:[ ]+feb51ee3[ ]+bne[ ]+a0,a1,8 <funcB>
+
+Disassembly of section .foo:
+
+0+000 <foo>:
+[ ]+0:[ ]+00c60633[ ]+add[ ]+a2,a2,a2
diff --git a/gas/testsuite/gas/riscv/mapping-02.s b/gas/testsuite/gas/riscv/mapping-02.s
new file mode 100644
index 0000000..f8306d0
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-02.s
@@ -0,0 +1,12 @@
+ .option norvc
+ .text
+ .word 1
+ add a0, a0, a0
+
+ .data
+ .word 2
+
+ .text
+ add a1, a1, a1
+ .short 3
+ add a2, a2, a2
diff --git a/gas/testsuite/gas/riscv/mapping-02a.d b/gas/testsuite/gas/riscv/mapping-02a.d
new file mode 100644
index 0000000..333f12c
--- /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 \$d
+0+04 l .text 0+00 \$x
+0+0c l .text 0+00 \$d
+0+0e l .text 0+00 \$x
+0+00 l d .riscv.attributes 0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-02b.d b/gas/testsuite/gas/riscv/mapping-02b.d
new file mode 100644
index 0000000..1ed6c08
--- /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 <.text>:
+[ ]+0:[ ]+00000001[ ]+.word[ ]+0x00000001
+[ ]+4:[ ]+00a50533[ ]+add[ ]+a0,a0,a0
+[ ]+8:[ ]+00b585b3[ ]+add[ ]+a1,a1,a1
+[ ]+c:[ ]+0003[ ]+.short[ ]+0x0003
+[ ]+e:[ ]+00c60633[ ]+add[ ]+a2,a2,a2
+#...
diff --git a/gas/testsuite/gas/riscv/mapping-03.s b/gas/testsuite/gas/riscv/mapping-03.s
new file mode 100644
index 0000000..a099eac
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-03.s
@@ -0,0 +1,11 @@
+ .option norvc
+ .text
+ add a0, a0, a0
+ .long 0
+ .balign 16
+ .word 1
+ add a1, a1, a1
+ .byte 2
+ .long 3
+ .balign 16
+ .word 5
diff --git a/gas/testsuite/gas/riscv/mapping-03a.d b/gas/testsuite/gas/riscv/mapping-03a.d
new file mode 100644
index 0000000..d3663b6
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-03a.d
@@ -0,0 +1,20 @@
+#as:
+#source: mapping-03.s
+#objdump: --syms --special-syms
+
+.*file format.*riscv.*
+
+SYMBOL TABLE:
+0+00 l d .text 0+00 .text
+0+00 l d .data 0+00 .data
+0+00 l d .bss 0+00 .bss
+0+00 l .text 0+00 \$x
+0+04 l .text 0+00 \$d
+0+08 l .text 0+00 \$x
+0+14 l .text 0+00 \$d
+0+18 l .text 0+00 \$x
+0+1c l .text 0+00 \$d
+0+21 l .text 0+00 \$x
+0+2d l .text 0+00 \$d
+0+31 l .text 0+00 \$x
+0+00 l d .riscv.attributes 0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-03b.d b/gas/testsuite/gas/riscv/mapping-03b.d
new file mode 100644
index 0000000..f4f6726
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-03b.d
@@ -0,0 +1,24 @@
+#as:
+#source: mapping-03.s
+#objdump: -d
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ ]+0:[ ]+00a50533[ ]+add[ ]+a0,a0,a0
+[ ]+4:[ ]+00000000[ ]+.word[ ]+0x00000000
+[ ]+8:[ ]+00000013[ ]+nop
+[ ]+c:[ ]+00000013[ ]+nop
+[ ]+10:[ ]+00000013[ ]+nop
+[ ]+14:[ ]+00000001[ ]+.word[ ]+0x00000001
+[ ]+18:[ ]+00b585b3[ ]+add[ ]+a1,a1,a1
+[ ]+1c:[ ]+00000302[ ]+.word[ ]+0x00000302
+[ ]+20:[ ]+00[ ]+.byte[ ]+0x00
+[ ]+21:[ ]+00000013[ ]+nop
+[ ]+25:[ ]+00000013[ ]+nop
+[ ]+29:[ ]+00000013[ ]+nop
+[ ]+2d:[ ]+00000005[ ]+.word[ ]+0x00000005
+#...
diff --git a/gas/testsuite/gas/riscv/mapping-04.s b/gas/testsuite/gas/riscv/mapping-04.s
new file mode 100644
index 0000000..c597495
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-04.s
@@ -0,0 +1,13 @@
+ .text
+ .option norvc
+ .fill 2, 4, 0x1001
+ .byte 1
+ .word 0
+ .balign 8
+ add a0, a0, a0
+ .fill 5, 2, 0x2002
+ add a1, a1, a1
+
+ .data
+ .word 0x1
+ .word 0x2
diff --git a/gas/testsuite/gas/riscv/mapping-04a.d b/gas/testsuite/gas/riscv/mapping-04a.d
new file mode 100644
index 0000000..1ae9653
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-04a.d
@@ -0,0 +1,15 @@
+#as:
+#source: mapping-04.s
+#objdump: --syms --special-syms
+
+.*file format.*riscv.*
+
+SYMBOL TABLE:
+0+00 l d .text 0+00 .text
+0+00 l d .data 0+00 .data
+0+00 l d .bss 0+00 .bss
+0+00 l .text 0+00 \$d
+0+0d l .text 0+00 \$x
+0+15 l .text 0+00 \$d
+0+1f l .text 0+00 \$x
+0+00 l d .riscv.attributes 0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-04b.d b/gas/testsuite/gas/riscv/mapping-04b.d
new file mode 100644
index 0000000..9735498
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-04b.d
@@ -0,0 +1,23 @@
+#as:
+#source: mapping-04.s
+#objdump: -d
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ ]+0:[ ]+00001001[ ]+.word[ ]+0x00001001
+[ ]+4:[ ]+00001001[ ]+.word[ ]+0x00001001
+[ ]+8:[ ]+00000001[ ]+.word[ ]+0x00000001
+[ ]+c:[ ]+00[ ]+.byte[ ]+0x00
+[ ]+d:[ ]+00000013[ ]+nop
+[ ]+11:[ ]+00a50533[ ]+add[ ]+a0,a0,a0
+[ ]+15:[ ]+20022002[ ]+.word[ ]+0x20022002
+[ ]+19:[ ]+20022002[ ]+.word[ ]+0x20022002
+[ ]+1d:[ ]+2002[ ]+.short[ ]+0x2002
+[ ]+1f:[ ]+00b585b3[ ]+add[ ]+a1,a1,a1
+[ ]+23:[ ]+0000[ ]+unimp
+[ ]+25:[ ]+0000[ ]+unimp
+#...
diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03a.d b/gas/testsuite/gas/riscv/mapping-norelax-03a.d
new file mode 100644
index 0000000..916f732
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-norelax-03a.d
@@ -0,0 +1,21 @@
+#as: -mno-relax
+#source: mapping-03.s
+#objdump: --syms --special-syms
+
+.*file format.*riscv.*
+
+SYMBOL TABLE:
+0+00 l d .text 0+00 .text
+0+00 l d .data 0+00 .data
+0+00 l d .bss 0+00 .bss
+0+00 l .text 0+00 \$x
+0+04 l .text 0+00 \$d
+0+08 l .text 0+00 \$x
+0+10 l .text 0+00 \$d
+0+14 l .text 0+00 \$x
+0+18 l .text 0+00 \$d
+0+20 l .text 0+00 \$d
+0+24 l .text 0+00 \$x
+0+1d l .text 0+00 \$d
+0+1e l .text 0+00 \$x
+0+00 l d .riscv.attributes 0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-norelax-03b.d b/gas/testsuite/gas/riscv/mapping-norelax-03b.d
new file mode 100644
index 0000000..ad88888
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-norelax-03b.d
@@ -0,0 +1,25 @@
+#as: -mno-relax
+#source: mapping-03.s
+#objdump: -d
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ ]+0:[ ]+00a50533[ ]+add[ ]+a0,a0,a0
+[ ]+4:[ ]+00000000[ ]+.word[ ]+0x00000000
+[ ]+8:[ ]+00000013[ ]+nop
+[ ]+c:[ ]+00000013[ ]+nop
+[ ]+10:[ ]+00000001[ ]+.word[ ]+0x00000001
+[ ]+14:[ ]+00b585b3[ ]+add[ ]+a1,a1,a1
+[ ]+18:[ ]+00000302[ ]+.word[ ]+0x00000302
+[ ]+1c:[ ]+00[ ]+.byte[ ]+0x00
+[ ]+1d:[ ]+00[ ]+.byte[ ]+0x00
+[ ]+1e:[ ]+0001[ ]+nop
+[ ]+20:[ ]+00000005[ ]+.word[ ]+0x00000005
+[ ]+24:[ ]+00000013[ ]+nop
+[ ]+28:[ ]+00000013[ ]+nop
+[ ]+2c:[ ]+00000013[ ]+nop
+#...
diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04a.d b/gas/testsuite/gas/riscv/mapping-norelax-04a.d
new file mode 100644
index 0000000..d552a7f
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-norelax-04a.d
@@ -0,0 +1,16 @@
+#as: -mno-relax
+#source: mapping-04.s
+#objdump: --syms --special-syms
+
+.*file format.*riscv.*
+
+SYMBOL TABLE:
+0+00 l d .text 0+00 .text
+0+00 l d .data 0+00 .data
+0+00 l d .bss 0+00 .bss
+0+00 l .text 0+00 \$d
+0+14 l .text 0+00 \$d
+0+1e l .text 0+00 \$x
+0+0d l .text 0+00 \$d
+0+0e l .text 0+00 \$x
+0+00 l d .riscv.attributes 0+00 .riscv.attributes
diff --git a/gas/testsuite/gas/riscv/mapping-norelax-04b.d b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
new file mode 100644
index 0000000..824a898
--- /dev/null
+++ b/gas/testsuite/gas/riscv/mapping-norelax-04b.d
@@ -0,0 +1,24 @@
+#as: -mno-relax
+#source: mapping-04.s
+#objdump: -d
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[ ]+0:[ ]+00001001[ ]+.word[ ]+0x00001001
+[ ]+4:[ ]+00001001[ ]+.word[ ]+0x00001001
+[ ]+8:[ ]+00000001[ ]+.word[ ]+0x00000001
+[ ]+c:[ ]+00[ ]+.byte[ ]+0x00
+[ ]+d:[ ]+00[ ]+.byte[ ]+0x00
+[ ]+e:[ ]+0001[ ]+nop
+[ ]+10:[ ]+00a50533[ ]+add[ ]+a0,a0,a0
+[ ]+14:[ ]+20022002[ ]+.word[ ]+0x20022002
+[ ]+18:[ ]+20022002[ ]+.word[ ]+0x20022002
+[ ]+1c:[ ]+2002[ ]+.short[ ]+0x2002
+[ ]+1e:[ ]+00b585b3[ ]+add[ ]+a1,a1,a1
+[ ]+22:[ ]+0001[ ]+nop
+[ ]+24:[ ]+00000013[ ]+nop
+#...
diff --git a/gas/testsuite/gas/riscv/no-relax-align-2.d b/gas/testsuite/gas/riscv/no-relax-align-2.d
index 7407b49..19edf13 100644
--- a/gas/testsuite/gas/riscv/no-relax-align-2.d
+++ b/gas/testsuite/gas/riscv/no-relax-align-2.d
@@ -7,7 +7,8 @@
Disassembly of section .text:
0+000 <.text>:
-[ ]+0:[ ]+0000[ ]+unimp
+[ ]+0:[ ]+00[ ]+.byte[ ]+0x00
+[ ]+1:[ ]+00[ ]+.byte[ ]+0x00
[ ]+2:[ ]+0001[ ]+nop
[ ]+4:[ ]+00000013[ ]+nop
[ ]+8:[ ]+00000013[ ]+nop