From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-sender-0.a4lg.com (mail-sender-0.a4lg.com [IPv6:2401:2500:203:30b:4000:6bfe:4757:0]) by sourceware.org (Postfix) with ESMTPS id 9DD073854163 for ; Thu, 11 Aug 2022 07:01:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9DD073854163 Received: from [127.0.0.1] (localhost [127.0.0.1]) by mail-sender-0.a4lg.com (Postfix) with ESMTPSA id F02D8300089; Thu, 11 Aug 2022 07:01:46 +0000 (UTC) From: Tsukasa OI To: Tsukasa OI , Nelson Chu , Kito Cheng , Palmer Dabbelt Cc: binutils@sourceware.org Subject: [RFC PATCH 4/5] RISC-V: Mapping symbols with ISA string on disassembler Date: Thu, 11 Aug 2022 16:00:52 +0900 Message-Id: <4ab83d9c6682c8834dd04fbe608aee40e4bc61c8.1660201178.git.research_trasio@irq.a4lg.com> In-Reply-To: References: <1659692183-5682-1-git-send-email-nelson.chu@sifive.com> Mime-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, T_FILL_THIS_FORM_SHORT, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 11 Aug 2022 07:01:50 -0000 The mapping symbols with ISA string is proposed to deal with so called "ifunc issue". It enables disassembling a certain range of the code with a different architecture than the rest, even if conflicting. This is useful when there's "optimized" implementation is available but dynamically switched only if a certain extension is available. This commit implements the disassembler support to parse mapping symbols with ISA string. [1] Proposal: Extend .option directive for control enabled extensions on specific code region, https://github.com/riscv-non-isa/riscv-asm-manual/pull/67 [2] Proposal: Add mapping symbol, https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/196 This commit is based on Nelson Chu's proposal "RISC-V: Output mapping symbols with ISA string once .option arch is used." but heavily modified to reflect the intent of Kito's original proposal. It is also made smarter so that it no longer requires MAP_INSN_ARCH. gas/ChangeLog: * testsuite/gas/riscv/option-arch-01a.d: Reflect the disassembler support of mapping symbols with ISA string. opcodes/ChangeLog: * riscv-dis.c (initial_default_arch) Default architecture string if no ELF attributes are available. (default_arch): A copy of the default architecture string. (is_arch_mapping): New variable to keep track of whether the current architecture is deviced from a mapping symbol. (riscv_disassemble_insn): Update FPR names when a mapping symbol with ISA string is encountered. (riscv_get_map_state): Support mapping symbols with ISA string. Use `is_arch_mapping' to stop repeatedly parsing the default architecture. (riscv_get_disassembler): Safer architecture string handling. Copy the string to switch to the default while disassembling. --- gas/testsuite/gas/riscv/option-arch-01a.d | 2 +- opcodes/riscv-dis.c | 44 ++++++++++++++++++++--- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/gas/testsuite/gas/riscv/option-arch-01a.d b/gas/testsuite/gas/riscv/option-arch-01a.d index aed4ca8e4d9..b9c260c9949 100644 --- a/gas/testsuite/gas/riscv/option-arch-01a.d +++ b/gas/testsuite/gas/riscv/option-arch-01a.d @@ -10,5 +10,5 @@ Disassembly of section .text: 0+000 <.text>: [ ]+[0-9a-f]+:[ ]+952e[ ]+add[ ]+a0,a0,a1 [ ]+[0-9a-f]+:[ ]+00b50533[ ]+add[ ]+a0,a0,a1 -[ ]+[0-9a-f]+:[ ]+00302573[ ]+csrr[ ]+a0,fcsr +[ ]+[0-9a-f]+:[ ]+00302573[ ]+frcsr[ ]+a0 #... diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index 4b7b17235ee..c029c65827c 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -32,6 +32,16 @@ #include #include +/* Default architecture string (if not available). */ +static const char *initial_default_arch = "rv64gc"; + +/* Default architecture string + (as specified by the ELF attributes or `initial_default_arch'). */ +static const char *default_arch = NULL; + +/* True if the architecture is set from a mapping symbol. */ +static bool is_arch_mapping = false; + static enum riscv_spec_class default_isa_spec = ISA_SPEC_CLASS_DRAFT - 1; static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE; @@ -638,8 +648,12 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info) } /* If arch has ZFINX flags, use gpr for disassemble. */ - if(riscv_subset_supports (&riscv_rps_dis, "zfinx")) + if (riscv_subset_supports (&riscv_rps_dis, "zfinx")) riscv_fpr_names = riscv_gpr_names; + else + riscv_fpr_names = riscv_gpr_names == riscv_gpr_names_abi + ? riscv_fpr_names_abi + : riscv_fpr_names_numeric; for (; op->name; op++) { @@ -750,8 +764,23 @@ riscv_get_map_state (int n, return false; name = bfd_asymbol_name(info->symtab[n]); - if (strncmp (name, "$x", 2) == 0) + if (strncmp (name, "$xrv", 4) == 0) + { *state = MAP_INSN; + riscv_release_subset_list (&riscv_subsets); + riscv_parse_subset (&riscv_rps_dis, name + 2); + is_arch_mapping = true; + } + else if (strcmp (name, "$x") == 0) + { + *state = MAP_INSN; + if (is_arch_mapping) + { + riscv_release_subset_list (&riscv_subsets); + riscv_parse_subset (&riscv_rps_dis, default_arch); + is_arch_mapping = false; + } + } else if (strcmp (name, "$d") == 0) *state = MAP_DATA; else @@ -1000,7 +1029,7 @@ print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info) disassembler_ftype riscv_get_disassembler (bfd *abfd) { - const char *default_arch = "rv64gc"; + const char *default_arch_next = initial_default_arch; if (abfd && bfd_get_flavour (abfd) == bfd_target_elf_flavour) { @@ -1015,12 +1044,19 @@ riscv_get_disassembler (bfd *abfd) attr[Tag_b].i, attr[Tag_c].i, &default_priv_spec); - default_arch = attr[Tag_RISCV_arch].s; + default_arch_next = attr[Tag_RISCV_arch].s; + /* For ELF files with (somehow) no architecture string + in the attributes, use the default value. */ + if (!default_arch_next) + default_arch_next = initial_default_arch; } } + free ((void *) default_arch); + default_arch = xstrdup (default_arch_next); riscv_release_subset_list (&riscv_subsets); riscv_parse_subset (&riscv_rps_dis, default_arch); + is_arch_mapping = false; return print_insn_riscv; } -- 2.34.1