RISC-V: Output mapping symbols with ISA string.

RISC-V Psabi pr196,
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/196

bfd/
    * elfxx-riscv.c (riscv_release_subset_list): Free arch_str if needed.
    (riscv_copy_subset_list): Copy arch_str as well.
    * elfxx-riscv.h (riscv_subset_list_t): Store arch_str for each subset list.
gas/
    * config/tc-riscv.c (riscv_reset_subsets_list_arch_str): Update the
    architecture string in the subset_list.
    (riscv_set_arch): Call riscv_reset_subsets_list_arch_str after parsing new
    architecture string.
    (s_riscv_option): Likewise.
    (need_arch_map_symbol): New boolean, used to indicate if .option
    directives do affect instructions.
    (make_mapping_symbol): New boolean parameter reset_seg_arch_str.  Need to
    generate $x+arch for MAP_INSN, and then store it into tc_segment_info_data
    if reset_seg_arch_str is true.
    (riscv_mapping_state): Decide if we need to add $x+arch for MAP_INSN.  For
    now, only add $x+arch if the architecture strings in subset list and segment
    are different.  Besides, always add $x+arch at the start of section, and do
    not add $x+arch for code alignment, since rvc for alignment can be judged
    from addend of R_RISCV_ALIGN.
    (riscv_remove_mapping_symbol): If current and previous mapping symbol have
    same value, then remove the current $x only if the previous is $x+arch;
    Otherwise, always remove previous.
    (riscv_add_odd_padding_symbol): Updated.
    (riscv_check_mapping_symbols): Don't need to add any $x+arch if
    need_arch_map_symbol is false, so changed them to $x.
    (riscv_frag_align_code): Updated since riscv_mapping_state is changed.
    (riscv_init_frag): Likewise.
    (s_riscv_insn): Likewise.
    (riscv_elf_final_processing): Call riscv_release_subset_list to release
    subset_list of riscv_rps_as, rather than only release arch_str in the
    riscv_write_out_attrs.
    (riscv_write_out_attrs): No need to call riscv_arch_str, just get arch_str
    from subset_list of riscv_rps_as.
    * config/tc-riscv.h (riscv_segment_info_type): Record current $x+arch mapping
    symbol of each segment.
    * testsuite/gas/riscv/mapping-0*: Merged and replaced by mapping.s.
    * testsuite/gas/riscv/mapping.s: New testcase, to test most of the cases in
    one file.
    * testsuite/gas/riscv/mapping-symbols.d: Likewise.
    * testsuite/gas/riscv/mapping-dis.d: Likewise.
    * testsuite/gas/riscv/mapping-non-arch.s: New testcase for the case that
    does need any $x+arch.
    * testsuite/gas/riscv/mapping-non-arch.d: Likewise.
    * testsuite/gas/riscv/option-arch-01a.d: Updated.
opcodes/
    * riscv-dis.c (riscv_disassemble_insn): Set riscv_fpr_names back to
    riscv_fpr_names_abi or riscv_fpr_names_numeric when zfinx is disabled
    for some specfic code region.
    (riscv_get_map_state): Recognized mapping symbols $x+arch, and then reset
    the architecture string once the ISA is different.
This commit is contained in:
Nelson Chu 2022-09-29 19:07:46 +08:00
parent 58b2ba6d88
commit 40f1a1a456
27 changed files with 421 additions and 328 deletions

View file

@ -1583,6 +1583,12 @@ riscv_release_subset_list (riscv_subset_list_t *subset_list)
} }
subset_list->tail = NULL; subset_list->tail = NULL;
if (subset_list->arch_str != NULL)
{
free ((void*) subset_list->arch_str);
subset_list->arch_str = NULL;
}
} }
/* Parsing extension version. /* Parsing extension version.
@ -2138,6 +2144,7 @@ riscv_copy_subset_list (riscv_subset_list_t *subset_list)
{ {
riscv_subset_list_t *new = xmalloc (sizeof *new); riscv_subset_list_t *new = xmalloc (sizeof *new);
new->head = riscv_copy_subset (new, subset_list->head); new->head = riscv_copy_subset (new, subset_list->head);
new->arch_str = strdup (subset_list->arch_str);
return new; return new;
} }

View file

@ -51,6 +51,7 @@ typedef struct
{ {
riscv_subset_t *head; riscv_subset_t *head;
riscv_subset_t *tail; riscv_subset_t *tail;
const char *arch_str;
} riscv_subset_list_t; } riscv_subset_list_t;
extern void extern void

View file

@ -279,6 +279,17 @@ static riscv_parse_subset_t riscv_rps_as =
true, /* check_unknown_prefixed_ext. */ true, /* check_unknown_prefixed_ext. */
}; };
/* Update the architecture string in the subset_list. */
static void
riscv_reset_subsets_list_arch_str (void)
{
riscv_subset_list_t *subsets = riscv_rps_as.subset_list;
if (subsets->arch_str != NULL)
free ((void *) subsets->arch_str);
subsets->arch_str = riscv_arch_str (xlen, subsets);
}
/* This structure is used to hold a stack of .option values. */ /* This structure is used to hold a stack of .option values. */
struct riscv_option_stack struct riscv_option_stack
{ {
@ -306,9 +317,11 @@ riscv_set_arch (const char *s)
riscv_rps_as.subset_list = XNEW (riscv_subset_list_t); riscv_rps_as.subset_list = XNEW (riscv_subset_list_t);
riscv_rps_as.subset_list->head = NULL; riscv_rps_as.subset_list->head = NULL;
riscv_rps_as.subset_list->tail = NULL; riscv_rps_as.subset_list->tail = NULL;
riscv_rps_as.subset_list->arch_str = NULL;
} }
riscv_release_subset_list (riscv_rps_as.subset_list); riscv_release_subset_list (riscv_rps_as.subset_list);
riscv_parse_subset (&riscv_rps_as, s); riscv_parse_subset (&riscv_rps_as, s);
riscv_reset_subsets_list_arch_str ();
riscv_set_rvc (false); riscv_set_rvc (false);
if (riscv_subset_supports (&riscv_rps_as, "c")) if (riscv_subset_supports (&riscv_rps_as, "c"))
@ -457,20 +470,36 @@ static char *expr_end;
#define OPCODE_MATCHES(OPCODE, OP) \ #define OPCODE_MATCHES(OPCODE, OP) \
(((OPCODE) & MASK_##OP) == MATCH_##OP) (((OPCODE) & MASK_##OP) == MATCH_##OP)
/* Indicate if .option directives do affect instructions. Set to true means
we need to add $x+arch at somewhere; Otherwise just add $x for instructions
should be enough. */
static bool need_arch_map_symbol = false;
/* Create a new mapping symbol for the transition to STATE. */ /* Create a new mapping symbol for the transition to STATE. */
static void static void
make_mapping_symbol (enum riscv_seg_mstate state, make_mapping_symbol (enum riscv_seg_mstate state,
valueT value, valueT value,
fragS *frag) fragS *frag,
bool reset_seg_arch_str)
{ {
const char *name; const char *name;
char *buff;
switch (state) switch (state)
{ {
case MAP_DATA: case MAP_DATA:
name = "$d"; name = "$d";
break; break;
case MAP_INSN: case MAP_INSN:
if (reset_seg_arch_str)
{
const char *isa = riscv_rps_as.subset_list->arch_str;
size_t size = strlen (isa) + 3; /* "rv" + '\0' */
buff = xmalloc (size);
snprintf (buff, size, "$x%s", isa);
name = buff;
}
else
name = "$x"; name = "$x";
break; break;
default: default:
@ -479,32 +508,38 @@ make_mapping_symbol (enum riscv_seg_mstate state,
symbolS *symbol = symbol_new (name, now_seg, frag, value); symbolS *symbol = symbol_new (name, now_seg, frag, value);
symbol_get_bfdsym (symbol)->flags |= (BSF_NO_FLAGS | BSF_LOCAL); symbol_get_bfdsym (symbol)->flags |= (BSF_NO_FLAGS | BSF_LOCAL);
if (reset_seg_arch_str)
{
/* Store current $x+arch into tc_segment_info. */
seg_info (now_seg)->tc_segment_info_data.arch_map_symbol = symbol;
xfree ((void *) buff);
}
/* If .fill or other data filling directive generates zero sized data, /* If .fill or other data filling directive generates zero sized data,
or we are adding odd alignemnts, then the mapping symbol for the then mapping symbol for the following code will have the same value.
following code will have the same value. */
Please see gas/testsuite/gas/riscv/mapping.s: .text.zero.fill.first
and .text.zero.fill.last. */
symbolS *first = frag->tc_frag_data.first_map_symbol;
symbolS *last = frag->tc_frag_data.last_map_symbol;
if (value == 0) if (value == 0)
{ {
if (frag->tc_frag_data.first_map_symbol != NULL) if (first != NULL)
{ {
know (S_GET_VALUE (frag->tc_frag_data.first_map_symbol) know (S_GET_VALUE (first) == S_GET_VALUE (symbol)
== S_GET_VALUE (symbol)); && first == last);
/* Remove the old one. */ /* Remove the old one. */
symbol_remove (frag->tc_frag_data.first_map_symbol, symbol_remove (first, &symbol_rootP, &symbol_lastP);
&symbol_rootP, &symbol_lastP);
} }
frag->tc_frag_data.first_map_symbol = symbol; frag->tc_frag_data.first_map_symbol = symbol;
} }
if (frag->tc_frag_data.last_map_symbol != NULL) else if (last != NULL)
{ {
/* The mapping symbols should be added in offset order. */ /* The mapping symbols should be added in offset order. */
know (S_GET_VALUE (frag->tc_frag_data.last_map_symbol) know (S_GET_VALUE (last) <= S_GET_VALUE (symbol));
<= S_GET_VALUE (symbol));
/* Remove the old one. */ /* Remove the old one. */
if (S_GET_VALUE (frag->tc_frag_data.last_map_symbol) if (S_GET_VALUE (last) == S_GET_VALUE (symbol))
== S_GET_VALUE (symbol)) symbol_remove (last, &symbol_rootP, &symbol_lastP);
symbol_remove (frag->tc_frag_data.last_map_symbol,
&symbol_rootP, &symbol_lastP);
} }
frag->tc_frag_data.last_map_symbol = symbol; frag->tc_frag_data.last_map_symbol = symbol;
} }
@ -513,13 +548,15 @@ make_mapping_symbol (enum riscv_seg_mstate state,
void void
riscv_mapping_state (enum riscv_seg_mstate to_state, riscv_mapping_state (enum riscv_seg_mstate to_state,
int max_chars) int max_chars,
bool frag_align_code)
{ {
enum riscv_seg_mstate from_state = enum riscv_seg_mstate from_state =
seg_info (now_seg)->tc_segment_info_data.map_state; seg_info (now_seg)->tc_segment_info_data.map_state;
bool reset_seg_arch_str = false;
if (!SEG_NORMAL (now_seg) if (!SEG_NORMAL (now_seg)
/* For now I only add the mapping symbols to text sections. /* For now we only add the mapping symbols to text sections.
Therefore, the dis-assembler only show the actual contents Therefore, the dis-assembler only show the actual contents
distribution for text. Other sections will be shown as distribution for text. Other sections will be shown as
data without the details. */ data without the details. */
@ -527,13 +564,29 @@ riscv_mapping_state (enum riscv_seg_mstate to_state,
return; return;
/* The mapping symbol should be emitted if not in the right /* The mapping symbol should be emitted if not in the right
mapping state */ mapping state. */
if (from_state == to_state) symbolS *seg_arch_symbol =
seg_info (now_seg)->tc_segment_info_data.arch_map_symbol;
if (to_state == MAP_INSN && seg_arch_symbol == 0)
{
/* Always add $x+arch at the first instruction of section. */
reset_seg_arch_str = true;
}
else if (seg_arch_symbol != 0
&& to_state == MAP_INSN
&& !frag_align_code
&& strcmp (riscv_rps_as.subset_list->arch_str,
S_GET_NAME (seg_arch_symbol) + 2) != 0)
{
reset_seg_arch_str = true;
need_arch_map_symbol = true;
}
else if (from_state == to_state)
return; return;
valueT value = (valueT) (frag_now_fix () - max_chars); valueT value = (valueT) (frag_now_fix () - max_chars);
seg_info (now_seg)->tc_segment_info_data.map_state = to_state; seg_info (now_seg)->tc_segment_info_data.map_state = to_state;
make_mapping_symbol (to_state, value, frag_now); make_mapping_symbol (to_state, value, frag_now, reset_seg_arch_str);
} }
/* Add the odd bytes of paddings for riscv_handle_align. */ /* Add the odd bytes of paddings for riscv_handle_align. */
@ -542,9 +595,27 @@ static void
riscv_add_odd_padding_symbol (fragS *frag) riscv_add_odd_padding_symbol (fragS *frag)
{ {
/* If there was already a mapping symbol, it should be /* If there was already a mapping symbol, it should be
removed in the make_mapping_symbol. */ 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); Please see gas/testsuite/gas/riscv/mapping.s: .text.odd.align. */
make_mapping_symbol (MAP_DATA, frag->fr_fix, frag, false);
make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag, false);
}
/* If previous and current mapping symbol have same value, then remove the
current $x only if the previous is $x+arch; Otherwise, always remove the
previous. */
static void
riscv_remove_mapping_symbol (symbolS *pre, symbolS *cur)
{
know (pre != NULL && cur != NULL
&& S_GET_VALUE (pre) == S_GET_VALUE (cur));
symbolS *removed = pre;
if (strncmp (S_GET_NAME (pre), "$xrv", 4) == 0
&& strcmp (S_GET_NAME (cur), "$x") == 0)
removed = cur;
symbol_remove (removed, &symbol_rootP, &symbol_lastP);
} }
/* Remove any excess mapping symbols generated for alignment frags in /* Remove any excess mapping symbols generated for alignment frags in
@ -563,6 +634,13 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
if (seginfo == NULL || seginfo->frchainP == NULL) if (seginfo == NULL || seginfo->frchainP == NULL)
return; return;
/* If we don't set any .option arch directive, then the arch_map_symbol
in each segment must be the first instruction, and we don't need to
add $x+arch for them. */
if (!need_arch_map_symbol
&& seginfo->tc_segment_info_data.arch_map_symbol != 0)
S_SET_NAME (seginfo->tc_segment_info_data.arch_map_symbol, "$x");
for (fragp = seginfo->frchainP->frch_root; for (fragp = seginfo->frchainP->frch_root;
fragp != NULL; fragp != NULL;
fragp = fragp->fr_next) fragp = fragp->fr_next)
@ -581,17 +659,24 @@ riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
do do
{ {
if (next->tc_frag_data.first_map_symbol != NULL) symbolS *next_first = next->tc_frag_data.first_map_symbol;
if (next_first != NULL)
{ {
/* The last mapping symbol overlaps with another one /* The last mapping symbol overlaps with another one
which at the start of the next frag. */ which at the start of the next frag.
symbol_remove (last, &symbol_rootP, &symbol_lastP);
Please see the gas/testsuite/gas/riscv/mapping.s:
.text.zero.fill.align.A and .text.zero.fill.align.B. */
riscv_remove_mapping_symbol (last, next_first);
break; break;
} }
if (next->fr_next == NULL) if (next->fr_next == NULL)
{ {
/* The last mapping symbol is at the end of the section. */ /* The last mapping symbol is at the end of the section.
Please see the gas/testsuite/gas/riscv/mapping.s:
.text.last.section. */
know (next->fr_fix == 0 && next->fr_var == 0); know (next->fr_fix == 0 && next->fr_var == 0);
symbol_remove (last, &symbol_rootP, &symbol_lastP); symbol_remove (last, &symbol_rootP, &symbol_lastP);
break; break;
@ -3455,7 +3540,7 @@ md_assemble (char *str)
return; return;
} }
riscv_mapping_state (MAP_INSN, 0); riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
const struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr, const struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
&imm_reloc, op_hash); &imm_reloc, op_hash);
@ -3963,11 +4048,13 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
if (strcmp (name, "rvc") == 0) if (strcmp (name, "rvc") == 0)
{ {
riscv_update_subset (&riscv_rps_as, "+c"); riscv_update_subset (&riscv_rps_as, "+c");
riscv_reset_subsets_list_arch_str ();
riscv_set_rvc (true); riscv_set_rvc (true);
} }
else if (strcmp (name, "norvc") == 0) else if (strcmp (name, "norvc") == 0)
{ {
riscv_update_subset (&riscv_rps_as, "-c"); riscv_update_subset (&riscv_rps_as, "-c");
riscv_reset_subsets_list_arch_str ();
riscv_set_rvc (false); riscv_set_rvc (false);
} }
else if (strcmp (name, "pic") == 0) else if (strcmp (name, "pic") == 0)
@ -3988,6 +4075,7 @@ s_riscv_option (int x ATTRIBUTE_UNUSED)
if (ISSPACE (*name) && *name != '\0') if (ISSPACE (*name) && *name != '\0')
name++; name++;
riscv_update_subset (&riscv_rps_as, name); riscv_update_subset (&riscv_rps_as, name);
riscv_reset_subsets_list_arch_str ();
riscv_set_rvc (false); riscv_set_rvc (false);
if (riscv_subset_supports (&riscv_rps_as, "c")) if (riscv_subset_supports (&riscv_rps_as, "c"))
@ -4117,6 +4205,10 @@ riscv_frag_align_code (int n)
if (!riscv_opts.relax) if (!riscv_opts.relax)
return false; return false;
/* Maybe we should use frag_var to create a new rs_align_code fragment,
rather than just use frag_more to handle an alignment here? So that we
don't need to call riscv_mapping_state again later, and then only need
to check frag->fr_type to see if it is frag_align_code. */
nops = frag_more (worst_case_bytes); nops = frag_more (worst_case_bytes);
ex.X_op = O_constant; ex.X_op = O_constant;
@ -4127,7 +4219,7 @@ riscv_frag_align_code (int n)
fix_new_exp (frag_now, nops - frag_now->fr_literal, 0, fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
&ex, false, BFD_RELOC_RISCV_ALIGN); &ex, false, BFD_RELOC_RISCV_ALIGN);
riscv_mapping_state (MAP_INSN, worst_case_bytes); riscv_mapping_state (MAP_INSN, worst_case_bytes, 1/* frag_align_code */);
/* We need to start a new frag after the alignment which may be removed by /* We need to start a new frag after the alignment which may be removed by
the linker, to prevent the assembler from computing static offsets. the linker, to prevent the assembler from computing static offsets.
@ -4201,10 +4293,10 @@ riscv_init_frag (fragS * fragP, int max_chars)
case rs_fill: case rs_fill:
case rs_align: case rs_align:
case rs_align_test: case rs_align_test:
riscv_mapping_state (MAP_DATA, max_chars); riscv_mapping_state (MAP_DATA, max_chars, 0/* frag_align_code */);
break; break;
case rs_align_code: case rs_align_code:
riscv_mapping_state (MAP_INSN, max_chars); riscv_mapping_state (MAP_INSN, max_chars, 1/* frag_align_code */);
break; break;
default: default:
break; break;
@ -4436,6 +4528,7 @@ void
riscv_elf_final_processing (void) riscv_elf_final_processing (void)
{ {
riscv_set_abi_by_arch (); riscv_set_abi_by_arch ();
riscv_release_subset_list (riscv_rps_as.subset_list);
elf_elfheader (stdoutput)->e_flags |= elf_flags; elf_elfheader (stdoutput)->e_flags |= elf_flags;
} }
@ -4477,7 +4570,7 @@ s_riscv_insn (int x ATTRIBUTE_UNUSED)
save_c = *input_line_pointer; save_c = *input_line_pointer;
*input_line_pointer = '\0'; *input_line_pointer = '\0';
riscv_mapping_state (MAP_INSN, 0); riscv_mapping_state (MAP_INSN, 0, 0/* frag_align_code */);
struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr, struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
&imm_reloc, insn_type_hash); &imm_reloc, insn_type_hash);
@ -4520,9 +4613,8 @@ riscv_write_out_attrs (void)
unsigned int i; unsigned int i;
/* Re-write architecture elf attribute. */ /* Re-write architecture elf attribute. */
arch_str = riscv_arch_str (xlen, riscv_rps_as.subset_list); arch_str = riscv_rps_as.subset_list->arch_str;
bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, arch_str); bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, arch_str);
xfree ((void *) arch_str);
/* For the file without any instruction, we don't set the default_priv_spec /* For the file without any instruction, we don't set the default_priv_spec
according to the privileged elf attributes since the md_assemble isn't according to the privileged elf attributes since the md_assemble isn't

View file

@ -130,14 +130,16 @@ extern void riscv_md_finish (void);
extern int riscv_convert_symbolic_attribute (const char *); extern int riscv_convert_symbolic_attribute (const char *);
/* Set mapping symbol states. */ /* Set mapping symbol states. */
#define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0) #define md_cons_align(nbytes) riscv_mapping_state (MAP_DATA, 0, 0)
void riscv_mapping_state (enum riscv_seg_mstate, int); void riscv_mapping_state (enum riscv_seg_mstate, int, bool);
/* Define target segment type. */ /* Define target segment type. */
#define TC_SEGMENT_INFO_TYPE struct riscv_segment_info_type #define TC_SEGMENT_INFO_TYPE struct riscv_segment_info_type
struct riscv_segment_info_type struct riscv_segment_info_type
{ {
enum riscv_seg_mstate map_state; enum riscv_seg_mstate map_state;
/* The current mapping symbol with architecture string. */
symbolS *arch_map_symbol;
}; };
/* Define target fragment type. */ /* Define target fragment type. */

View file

@ -1,17 +0,0 @@
.option arch, -c
.text
.global funcA
funcA:
add a0, a0, a0
j funcB
.global funcB
funcB:
add a1, a1, a1
bne a0, a1, funcB
.data
.word 0x123456
.section .foo, "ax"
foo:
add a2, a2, a2

View file

@ -1,17 +0,0 @@
#as:
#source: mapping-01.s
#objdump: --syms --special-syms
.*file format.*riscv.*
SYMBOL TABLE:
0+00 l d .text 0+00 .text
0+00 l d .data 0+00 .data
0+00 l d .bss 0+00 .bss
0+00 l .text 0+00 \$x
0+00 l d .foo 0+00 .foo
0+00 l .foo 0+00 foo
0+00 l .foo 0+00 \$x
0+00 l d .riscv.attributes 0+00 .riscv.attributes
0+00 g .text 0+00 funcA
0+08 g .text 0+00 funcB

View file

@ -1,21 +0,0 @@
#as:
#source: mapping-01.s
#objdump: -d
.*:[ ]+file format .*
Disassembly of section .text:
0+000 <funcA>:
[ ]+0:[ ]+00a50533[ ]+add[ ]+a0,a0,a0
[ ]+4:[ ]+0040006f[ ]+j[ ]+8 <funcB>
0+008 <funcB>:
[ ]+8:[ ]+00b585b3[ ]+add[ ]+a1,a1,a1
[ ]+c:[ ]+feb51ee3[ ]+bne[ ]+a0,a1,8 <funcB>
Disassembly of section .foo:
0+000 <foo>:
[ ]+0:[ ]+00c60633[ ]+add[ ]+a2,a2,a2

View file

@ -1,12 +0,0 @@
.option arch, -c
.text
.word 1
add a0, a0, a0
.data
.word 2
.text
add a1, a1, a1
.short 3
add a2, a2, a2

View file

@ -1,15 +0,0 @@
#as:
#source: mapping-02.s
#objdump: --syms --special-syms
.*file format.*riscv.*
SYMBOL TABLE:
0+00 l d .text 0+00 .text
0+00 l d .data 0+00 .data
0+00 l d .bss 0+00 .bss
0+00 l .text 0+00 \$d
0+04 l .text 0+00 \$x
0+0c l .text 0+00 \$d
0+0e l .text 0+00 \$x
0+00 l d .riscv.attributes 0+00 .riscv.attributes

View file

@ -1,16 +0,0 @@
#as:
#source: mapping-02.s
#objdump: -d
.*:[ ]+file format .*
Disassembly of section .text:
0+000 <.text>:
[ ]+0:[ ]+00000001[ ]+.word[ ]+0x00000001
[ ]+4:[ ]+00a50533[ ]+add[ ]+a0,a0,a0
[ ]+8:[ ]+00b585b3[ ]+add[ ]+a1,a1,a1
[ ]+c:[ ]+0003[ ]+.short[ ]+0x0003
[ ]+e:[ ]+00c60633[ ]+add[ ]+a2,a2,a2
#...

View file

@ -1,11 +0,0 @@
.option arch, -c
.text
add a0, a0, a0
.long 0
.balign 16
.word 1
add a1, a1, a1
.byte 2
.long 3
.balign 16
.word 5

View file

@ -1,20 +0,0 @@
#as:
#source: mapping-03.s
#objdump: --syms --special-syms
.*file format.*riscv.*
SYMBOL TABLE:
0+00 l d .text 0+00 .text
0+00 l d .data 0+00 .data
0+00 l d .bss 0+00 .bss
0+00 l .text 0+00 \$x
0+04 l .text 0+00 \$d
0+08 l .text 0+00 \$x
0+14 l .text 0+00 \$d
0+18 l .text 0+00 \$x
0+1c l .text 0+00 \$d
0+21 l .text 0+00 \$x
0+2d l .text 0+00 \$d
0+31 l .text 0+00 \$x
0+00 l d .riscv.attributes 0+00 .riscv.attributes

View file

@ -1,24 +0,0 @@
#as:
#source: mapping-03.s
#objdump: -d
.*:[ ]+file format .*
Disassembly of section .text:
0+000 <.text>:
[ ]+0:[ ]+00a50533[ ]+add[ ]+a0,a0,a0
[ ]+4:[ ]+00000000[ ]+.word[ ]+0x00000000
[ ]+8:[ ]+00000013[ ]+nop
[ ]+c:[ ]+00000013[ ]+nop
[ ]+10:[ ]+00000013[ ]+nop
[ ]+14:[ ]+00000001[ ]+.word[ ]+0x00000001
[ ]+18:[ ]+00b585b3[ ]+add[ ]+a1,a1,a1
[ ]+1c:[ ]+00000302[ ]+.word[ ]+0x00000302
[ ]+20:[ ]+00[ ]+.byte[ ]+0x00
[ ]+21:[ ]+00000013[ ]+nop
[ ]+25:[ ]+00000013[ ]+nop
[ ]+29:[ ]+00000013[ ]+nop
[ ]+2d:[ ]+00000005[ ]+.word[ ]+0x00000005
#...

View file

@ -1,13 +0,0 @@
.text
.option arch, -c
.fill 2, 4, 0x1001
.byte 1
.word 0
.balign 8
add a0, a0, a0
.fill 5, 2, 0x2002
add a1, a1, a1
.data
.word 0x1
.word 0x2

View file

@ -1,15 +0,0 @@
#as:
#source: mapping-04.s
#objdump: --syms --special-syms
.*file format.*riscv.*
SYMBOL TABLE:
0+00 l d .text 0+00 .text
0+00 l d .data 0+00 .data
0+00 l d .bss 0+00 .bss
0+00 l .text 0+00 \$d
0+0d l .text 0+00 \$x
0+15 l .text 0+00 \$d
0+1f l .text 0+00 \$x
0+00 l d .riscv.attributes 0+00 .riscv.attributes

View file

@ -1,23 +0,0 @@
#as:
#source: mapping-04.s
#objdump: -d
.*:[ ]+file format .*
Disassembly of section .text:
0+000 <.text>:
[ ]+0:[ ]+00001001[ ]+.word[ ]+0x00001001
[ ]+4:[ ]+00001001[ ]+.word[ ]+0x00001001
[ ]+8:[ ]+00000001[ ]+.word[ ]+0x00000001
[ ]+c:[ ]+00[ ]+.byte[ ]+0x00
[ ]+d:[ ]+00000013[ ]+nop
[ ]+11:[ ]+00a50533[ ]+add[ ]+a0,a0,a0
[ ]+15:[ ]+20022002[ ]+.word[ ]+0x20022002
[ ]+19:[ ]+20022002[ ]+.word[ ]+0x20022002
[ ]+1d:[ ]+2002[ ]+.short[ ]+0x2002
[ ]+1f:[ ]+00b585b3[ ]+add[ ]+a1,a1,a1
[ ]+23:[ ]+0000[ ]+.2byte[ ]+0x0
[ ]+25:[ ]+0000[ ]+.2byte[ ]+0x0
#...

View file

@ -0,0 +1,84 @@
#as:
#source: mapping.s
#objdump: -d
.*:[ ]+file format .*
Disassembly of section .text.cross.section.A:
0+000 <funcA>:
[ ]+[0-9a-f]+:[ ]+4505[ ]+li[ ]+a0,1
[ ]+[0-9a-f]+:[ ]+bffd[ ]+j[ ]+0 <funcA>
Disassembly of section .text.corss.section.B:
0+000 <funcB>:
[ ]+[0-9a-f]+:[ ]+4509[ ]+li[ ]+a0,2
[ ]+[0-9a-f]+:[ ]+fffff06f[ ]+j[ ]+0 <funcB>
Disassembly of section .text.data:
0+000 <.text.data>:
[ ]+[0-9a-f]+:[ ]+00000000[ ]+.word[ ]+0x00000000
[ ]+[0-9a-f]+:[ ]+00000001[ ]+.word[ ]+0x00000001
[ ]+[0-9a-f]+:[ ]+4505[ ]+li[ ]+a0,1
[ ]+[0-9a-f]+:[ ]+4509[ ]+li[ ]+a0,2
[ ]+[0-9a-f]+:[ ]+05000302[ ]+.word[ ]+0x05000302
Disassembly of section .text.odd.align:
0+000 <.text.odd.align>:
[ ]+[0-9a-f]+:[ ]+4505[ ]+li[ ]+a0,1
[ ]+[0-9a-f]+:[ ]+01[ ]+.byte[ ]+0x01
[ ]+[0-9a-f]+:[ ]+00[ ]+.byte[ ]+0x00
[ ]+[0-9a-f]+:[ ]+00000013[ ]+nop
[ ]+[0-9a-f]+:[ ]+00200513[ ]+li[ ]+a0,2
[ ]+[0-9a-f]+:[ ]+00000013[ ]+nop
Disassembly of section .text.zero.fill.first:
0+000 <.text.zero.fill.first>:
[ ]+[0-9a-f]+:[ ]+4505[ ]+li[ ]+a0,1
Disassembly of section .text.zero.fill.last:
0+000 <.text.zero.fill.last>:
[ ]+[0-9a-f]+:[ ]+4505[ ]+li[ ]+a0,1
[ ]+[0-9a-f]+:[ ]+4509[ ]+li[ ]+a0,2
Disassembly of section .text.zero.fill.align.A:
0+000 <.text.zero.fill.align.A>:
[ ]+[0-9a-f]+:[ ]+4505[ ]+li[ ]+a0,1
[ ]+[0-9a-f]+:[ ]+4509[ ]+li[ ]+a0,2
Disassembly of section .text.zero.fill.align.B:
0+000 <.text.zero.fill.align.B>:
[ ]+[0-9a-f]+:[ ]+00100513[ ]+li[ ]+a0,1
[ ]+[0-9a-f]+:[ ]+00200513[ ]+li[ ]+a0,2
Disassembly of section .text.last.section:
0+000 <.text.last.section>:
[ ]+[0-9a-f]+:[ ]+00100513[ ]+li[ ]+a0,1
[ ]+[0-9a-f]+:[ ]+00000001[ ]+.word[ ]+0x00000001
Disassembly of section .text.section.padding:
0+000 <.text.section.padding>:
[ ]+[0-9a-f]+:[ ]+4505[ ]+li[ ]+a0,1
[ ]+[0-9a-f]+:[ ]+0001[ ]+nop
[ ]+[0-9a-f]+:[ ]+4509[ ]+li[ ]+a0,2
[ ]+[0-9a-f]+:[ ]+00000001[ ]+.word[ ]+0x00000001
[ ]+[0-9a-f]+:[ ]+0001[ ]+nop
Disassembly of section .text.relax.align:
0+000 <.text.relax.align>:
[ ]+[0-9a-f]+:[ ]+0001[ ]+nop
[ ]+[0-9a-f]+:[ ]+4505[ ]+li[ ]+a0,1
[ ]+[0-9a-f]+:[ ]+00000013[ ]+nop
[ ]+[0-9a-f]+:[ ]+00200513[ ]+li[ ]+a0,2
[ ]+[0-9a-f]+:[ ]+00000013[ ]+nop

View file

@ -0,0 +1,17 @@
#as:
#source: mapping-non-arch.s
#objdump: --syms --special-syms
.*file format.*riscv.*
SYMBOL TABLE:
00+00 l d .text 00+00 .text
00+00 l d .data 00+00 .data
00+00 l d .bss 00+00 .bss
00+00 l .text 00+00 \$x
00+08 l .text 00+00 \$d
00+0c l .text 00+00 \$x
00+00 l d text.A 00+00 text.A
00+00 l text.A 00+00 \$x
00+02 l text.A 00+00 \$d
00+00 l d .riscv.attributes 00+00 .riscv.attributes

View file

@ -0,0 +1,11 @@
.attribute arch, "rv32i"
.option arch, +c
.text
addi a0, zero, 1
.align 3
.word 0x1
addi a0, zero, 2
.section text.A, "ax"
addi a0, zero, 3
.word 0x2

View file

@ -1,21 +0,0 @@
#as: -mno-relax
#source: mapping-03.s
#objdump: --syms --special-syms
.*file format.*riscv.*
SYMBOL TABLE:
0+00 l d .text 0+00 .text
0+00 l d .data 0+00 .data
0+00 l d .bss 0+00 .bss
0+00 l .text 0+00 \$x
0+04 l .text 0+00 \$d
0+08 l .text 0+00 \$x
0+10 l .text 0+00 \$d
0+14 l .text 0+00 \$x
0+18 l .text 0+00 \$d
0+20 l .text 0+00 \$d
0+24 l .text 0+00 \$x
0+1d l .text 0+00 \$d
0+1e l .text 0+00 \$x
0+00 l d .riscv.attributes 0+00 .riscv.attributes

View file

@ -1,25 +0,0 @@
#as: -mno-relax
#source: mapping-03.s
#objdump: -d
.*:[ ]+file format .*
Disassembly of section .text:
0+000 <.text>:
[ ]+0:[ ]+00a50533[ ]+add[ ]+a0,a0,a0
[ ]+4:[ ]+00000000[ ]+.word[ ]+0x00000000
[ ]+8:[ ]+00000013[ ]+nop
[ ]+c:[ ]+00000013[ ]+nop
[ ]+10:[ ]+00000001[ ]+.word[ ]+0x00000001
[ ]+14:[ ]+00b585b3[ ]+add[ ]+a1,a1,a1
[ ]+18:[ ]+00000302[ ]+.word[ ]+0x00000302
[ ]+1c:[ ]+00[ ]+.byte[ ]+0x00
[ ]+1d:[ ]+00[ ]+.byte[ ]+0x00
[ ]+1e:[ ]+0001[ ]+.2byte[ ]+0x1
[ ]+20:[ ]+00000005[ ]+.word[ ]+0x00000005
[ ]+24:[ ]+00000013[ ]+nop
[ ]+28:[ ]+00000013[ ]+nop
[ ]+2c:[ ]+00000013[ ]+nop
#...

View file

@ -1,16 +0,0 @@
#as: -mno-relax
#source: mapping-04.s
#objdump: --syms --special-syms
.*file format.*riscv.*
SYMBOL TABLE:
0+00 l d .text 0+00 .text
0+00 l d .data 0+00 .data
0+00 l d .bss 0+00 .bss
0+00 l .text 0+00 \$d
0+14 l .text 0+00 \$d
0+1e l .text 0+00 \$x
0+0d l .text 0+00 \$d
0+0e l .text 0+00 \$x
0+00 l d .riscv.attributes 0+00 .riscv.attributes

View file

@ -1,24 +0,0 @@
#as: -mno-relax
#source: mapping-04.s
#objdump: -d
.*:[ ]+file format .*
Disassembly of section .text:
0+000 <.text>:
[ ]+0:[ ]+00001001[ ]+.word[ ]+0x00001001
[ ]+4:[ ]+00001001[ ]+.word[ ]+0x00001001
[ ]+8:[ ]+00000001[ ]+.word[ ]+0x00000001
[ ]+c:[ ]+00[ ]+.byte[ ]+0x00
[ ]+d:[ ]+00[ ]+.byte[ ]+0x00
[ ]+e:[ ]+0001[ ]+.2byte[ ]+0x1
[ ]+10:[ ]+00a50533[ ]+add[ ]+a0,a0,a0
[ ]+14:[ ]+20022002[ ]+.word[ ]+0x20022002
[ ]+18:[ ]+20022002[ ]+.word[ ]+0x20022002
[ ]+1c:[ ]+2002[ ]+.short[ ]+0x2002
[ ]+1e:[ ]+00b585b3[ ]+add[ ]+a1,a1,a1
[ ]+22:[ ]+0001[ ]+.2byte[ ]+0x1
[ ]+24:[ ]+00000013[ ]+nop
#...

View file

@ -0,0 +1,48 @@
#as: -misa-spec=20191213
#source: mapping.s
#objdump: --syms --special-syms
.*file format.*riscv.*
SYMBOL TABLE:
0+00 l d .text 0+00 .text
0+00 l d .data 0+00 .data
0+00 l d .bss 0+00 .bss
0+00 l d .text.cross.section.A 0+00 .text.cross.section.A
0+00 l .text.cross.section.A 0+00 \$xrv32i2p1_c2p0
0+00 l d .text.corss.section.B 0+00 .text.corss.section.B
0+00 l .text.corss.section.B 0+00 \$xrv32i2p1_c2p0
0+02 l .text.corss.section.B 0+00 \$xrv32i2p1
0+00 l d .text.data 0+00 .text.data
0+00 l .text.data 0+00 \$d
0+08 l .text.data 0+00 \$xrv32i2p1_c2p0
0+0c l .text.data 0+00 \$d
0+00 l d .text.odd.align 0+00 .text.odd.align
0+00 l .text.odd.align 0+00 \$xrv32i2p1_c2p0
0+02 l .text.odd.align 0+00 \$d
0+08 l .text.odd.align 0+00 \$xrv32i2p1
0+00 l d .text.zero.fill.first 0+00 .text.zero.fill.first
0+00 l .text.zero.fill.first 0+00 \$xrv32i2p1_c2p0
0+00 l d .text.zero.fill.last 0+00 .text.zero.fill.last
0+00 l .text.zero.fill.last 0+00 \$xrv32i2p1_c2p0
0+02 l .text.zero.fill.last 0+00 \$x
0+00 l d .text.zero.fill.align.A 0+00 .text.zero.fill.align.A
0+00 l .text.zero.fill.align.A 0+00 \$xrv32i2p1_c2p0
0+00 l d .text.zero.fill.align.B 0+00 .text.zero.fill.align.B
0+00 l .text.zero.fill.align.B 0+00 \$xrv32i2p1
0+00 l d .text.last.section 0+00 .text.last.section
0+00 l .text.last.section 0+00 \$xrv32i2p1
0+04 l .text.last.section 0+00 \$d
0+00 l d .text.section.padding 0+00 .text.section.padding
0+00 l .text.section.padding 0+00 \$xrv32i2p1_c2p0
0+04 l .text.section.padding 0+00 \$xrv32i2p1_a2p1_c2p0
0+06 l .text.section.padding 0+00 \$d
0+00 l d .text.relax.align 0+00 .text.relax.align
0+00 l .text.relax.align 0+00 \$xrv32i2p1_c2p0
0+08 l .text.relax.align 0+00 \$xrv32i2p1
0+0a l .text.section.padding 0+00 \$x
0+03 l .text.odd.align 0+00 \$d
0+04 l .text.odd.align 0+00 \$x
0+00 l d .riscv.attributes 0+00 .riscv.attributes
0+00 g .text.cross.section.A 0+00 funcA
0+00 g .text.corss.section.B 0+00 funcB

View file

@ -0,0 +1,112 @@
.attribute arch, "rv32ic"
.option norelax # FIXME: assembler fill the paddings after parsing everything,
# so we probably won't fill anything for the norelax region when
# the riscv_opts.relax is enabled at somewhere.
.section .text.cross.section.A, "ax"
.option push
.global funcA
funcA:
addi a0, zero, 1 # rv32i
.option arch, +c
j funcA # rv32ic
.section .text.corss.section.B, "ax"
.globl funcB
funcB:
addi a0, zero, 2 # rv32ic, need to be added since start of section
.option arch, -c
j funcB # rv32i
.option pop
.section .text.data, "ax"
.option push
.word 0 # $d
.long 1
addi a0, zero, 1 # rv32ic
.data
.word 2 # don't add mapping symbols for non-text section
.section .text.data
addi a0, zero, 2 # $x, but same as previous addi, so removed
.byte 2 # $d, dumped as .word
.short 3
.byte 5
.option pop
.section .text.odd.align, "ax"
.option push
.option norelax
.option arch, +c
addi a0, zero, 1 # $xrv32ic
.byte 1 # $d
.option arch, -c
.align 3 # odd alignment, $x replaced by $d + $x
addi a0, zero, 2 # $xrv32i
.option pop
.section .text.zero.fill.first, "ax"
.option push
.option norelax
.fill 1, 0, 0 # $d with zero size, removed in make_mapping_symbol
addi a0, zero, 1 # $xrv32ic
.option pop
.section .text.zero.fill.last, "ax"
.option push
.option norelax
addi a0, zero, 1 # $xrv32ic
.fill 1, 0, 0 # $d with zero size, removed in make_mapping_symbol
addi a0, zero, 2 # $x, FIXME: need find a way to remove?
.option pop
# last overlap next first
.section .text.zero.fill.align.A, "ax"
.option push
.option norelax
.align 2 # $xrv32ic, .align and .fill are in the different frag, so neither be removed
.fill 1, 0, 0 # $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
addi a0, zero, 1 # $x, should be removed in riscv_check_mapping_symbols
addi a0, zero, 2
.option pop
# last overlap next first
.section .text.zero.fill.align.B, "ax"
.option push
.option norelax
.align 2 # $xrv32ic, .align and .fill are in the different frag, so neither be removed,
# but will be removed in riscv_check_mapping_symbols
.fill 1, 0, 0 # $d with zero size, removed in make_mapping_symbol when adding $xrv32ic
.option arch, -c
addi a0, zero, 1 # $xrv32i
addi a0, zero, 2
.option pop
.section .text.last.section, "ax"
.option push
.option norelax
.option arch, -c
addi a0, zero, 1 # $xrv32i
.word 1 # $d
.align 2 # zero section padding, $x at the end of section, removed in riscv_check_mapping_symbols
.option pop
.section .text.section.padding, "ax"
.option push
.option norelax
.align 2
addi a0, zero, 1 # $rv32ic
.option arch, +a
.align 2 # 2-byte padding, $x, removed
addi a0, zero, 2 # $xrv32iac
.word 1 # $d
.option pop # 2-byte padding, $x
.section .text.relax.align, "ax"
.option push
.option relax
.option arch, rv32ic
.balign 4 # $xrv32ic, add at the start of section
addi a0, zero, 1 # $x, won't added
.option arch, -c
.align 3 # $x, won't added
addi a0, zero, 2 # $xrv32i
.option pop

View file

@ -10,5 +10,5 @@ Disassembly of section .text:
0+000 <.text>: 0+000 <.text>:
[ ]+[0-9a-f]+:[ ]+952e[ ]+add[ ]+a0,a0,a1 [ ]+[0-9a-f]+:[ ]+952e[ ]+add[ ]+a0,a0,a1
[ ]+[0-9a-f]+:[ ]+00b50533[ ]+add[ ]+a0,a0,a1 [ ]+[0-9a-f]+:[ ]+00b50533[ ]+add[ ]+a0,a0,a1
[ ]+[0-9a-f]+:[ ]+00302573[ ]+csrr[ ]+a0,fcsr [ ]+[0-9a-f]+:[ ]+00302573[ ]+frcsr[ ]+a0
#... #...

View file

@ -716,6 +716,9 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
/* If arch has the Zfinx extension, replace FPR with GPR. */ /* If arch has the Zfinx extension, replace FPR with GPR. */
if (riscv_subset_supports (&riscv_rps_dis, "zfinx")) if (riscv_subset_supports (&riscv_rps_dis, "zfinx"))
riscv_fpr_names = riscv_gpr_names; riscv_fpr_names = riscv_gpr_names;
else
riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi ?
riscv_fpr_names_abi : riscv_fpr_names_numeric;
for (; op->name; op++) for (; op->name; op++)
{ {
@ -832,6 +835,12 @@ riscv_get_map_state (int n,
*state = MAP_INSN; *state = MAP_INSN;
else if (strcmp (name, "$d") == 0) else if (strcmp (name, "$d") == 0)
*state = MAP_DATA; *state = MAP_DATA;
else if (strncmp (name, "$xrv", 4) == 0)
{
*state = MAP_INSN;
riscv_release_subset_list (&riscv_subsets);
riscv_parse_subset (&riscv_rps_dis, name + 2);
}
else else
return false; return false;