From patchwork Fri Sep 30 09:20:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nelson Chu X-Patchwork-Id: 1580 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp388923wrs; Fri, 30 Sep 2022 02:21:12 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5AcXRTy5AMkNiXLIxGLtnpWWT1LLefXXPG+U4oySey37utLOVOjqeimwwHzECpozANoBzu X-Received: by 2002:a17:907:7eaa:b0:782:3d2b:20b0 with SMTP id qb42-20020a1709077eaa00b007823d2b20b0mr5853752ejc.746.1664529672802; Fri, 30 Sep 2022 02:21:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1664529672; cv=none; d=google.com; s=arc-20160816; b=DvGL8T4if+VCR7BPIoPoywo6i5G1dsJP5IVHUXM0kTz4sP9cGEsByTob3hUs5nNENA y2dsgYq/vjZSc3HapFdOOrnpFkr3GxHuNEyEWORXzenp+cxhk74ltluCS8myzEUihjdL dseOkiKHASxGRnlLg3V52TxeWla4wZ4raRfoOQsnoyMQmWVSFZ9WlbGRmX3w5qnnviLQ UngSMWQf1EYKnEWYC1abkEO9ejxf76YU1NuXTkK2n/Vg0pkVhmo/98K0vgTWUgPKSb8v AzAHnHm04597vfbE55ImfLNZPKTnCxKvfburdj2udqt4irfK61PNkeSRwhMVnI1+dKtC 1sNA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dmarc-filter:delivered-to; bh=a4A03+hsGG72hsElTbFR5/ly+Di5B2dMrO3NbnpPrLY=; b=QSsA4/nCCxNx8LgwE0NS+HzNlGfYht3zEk0Z9up1ihNQ6VejkVRwh2fHyVFpvKlhGY HuySXxYsqgVKhJ3t92ZfIhlf/OVjAPXWHsMY3jrtWtx23vl3WQbNX2WzwxvLTGNo2Ta+ DEbUYpDe6RHrtzX3gIYjtn87NCP+qIRxAEtUaLvpyAxTktXh+0tyMMo3ROc4xcYqPLx4 GJH9/wodJ37InW2o7xuQpzOSCAgOKNRhHCWPtkPIMNOTkkEzfOtltRSKfA9Gfx7I+YR3 TA1rhwZ5jBXKU/m71Uzmuqd5nIdH3G+InpqgBy07pz79XxQ1jOdgRYKfNx8GlhFKLu4L EwBA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org" Received: from sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id cq10-20020a056402220a00b0044eae9b2c48si1454324edb.273.2022.09.30.02.21.12 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 30 Sep 2022 02:21:12 -0700 (PDT) Received-SPF: pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E14D13854163 for ; Fri, 30 Sep 2022 09:21:10 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from NelsondeMBP.localdomain (114-25-69-246.dynamic-ip.hinet.net [114.25.69.246]) by sourceware.org (Postfix) with ESMTP id 0F4B43858CDB for ; Fri, 30 Sep 2022 09:21:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0F4B43858CDB Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=rivosinc.com Authentication-Results: sourceware.org; spf=none smtp.mailfrom=NelsondeMBP.localdomain Received: by NelsondeMBP.localdomain (Postfix, from userid 501) id 5053629C52C; Fri, 30 Sep 2022 17:21:01 +0800 (CST) From: Nelson Chu To: binutils@sourceware.org, nelson@rivosinc.com Subject: [PATCH 2/2] RISC-V: Refer mapping symbol to R_RISCV_RELAX for rvc relaxations. Date: Fri, 30 Sep 2022 17:20:58 +0800 Message-Id: <20220930092058.71286-2-nelson@rivosinc.com> X-Mailer: git-send-email 2.37.0 (Apple Git-136) In-Reply-To: <20220930092058.71286-1-nelson@rivosinc.com> References: <20220930092058.71286-1-nelson@rivosinc.com> MIME-Version: 1.0 X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, KAM_STOCKGEN, KHOP_HELO_FCRDNS, NO_DNS_FOR_FROM, RCVD_IN_PBL, RCVD_IN_SORBS_DUL, RDNS_DYNAMIC, SPF_HELO_NONE, SPF_NONE, TXREP 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: , Errors-To: binutils-bounces+ouuuleilei=gmail.com@sourceware.org Sender: "Binutils" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1745385866114863620?= X-GMAIL-MSGID: =?utf-8?q?1745385866114863620?= RISC-V Psabi pr116, https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/116 bfd/ * elfnn-riscv.c (_bfd_riscv_enable_rvc): New function to check the mapping symbol with architecture string in the R_RISCV_RELAX, to see if rvc is enabled or not. If we don't find any mapping symbols, then just check the elf header flag as usual. (_bfd_riscv_relax_call): Updated since above change. (_bfd_riscv_relax_lui): Likewise. gas/ * config/tc-riscv.c (append_insn): Store $x+arch in tc_fix_data if exsit. (md_apply_fix): Refer the $x+arch from tc_fix_data into R_RISCV_RELAX, these only for the relocations used to do rvc relaxation. Besides, set addend of R_RISCV_RELAX (fx_offset) to zero. * config/tc-riscv.h (TC_FIX_TYPE): Defined to store $x+arch in each fixup only for risc-v target. (struct riscv_fixup_type): Likewise. (TC_INIT_FIX_DATA): Likewise. * testsuite/gas/riscv/mapping-relax.d: New testcase. * testsuite/gas/riscv/mapping-relax.s: Likewise. ld/ * testsuite/ld-riscv-elf/c-relax.d: New testcase for specific rvc relaxation. * testsuite/ld-riscv-elf/c-relax.s: Likewise. * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated. --- bfd/elfnn-riscv.c | 31 +++++++++++++++++++--- gas/config/tc-riscv.c | 15 +++++++++-- gas/config/tc-riscv.h | 7 +++++ gas/testsuite/gas/riscv/mapping-relax.d | 23 ++++++++++++++++ gas/testsuite/gas/riscv/mapping-relax.s | 21 +++++++++++++++ ld/testsuite/ld-riscv-elf/c-relax.d | 16 +++++++++++ ld/testsuite/ld-riscv-elf/c-relax.s | 12 +++++++++ ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 1 + 8 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 gas/testsuite/gas/riscv/mapping-relax.d create mode 100644 gas/testsuite/gas/riscv/mapping-relax.s create mode 100644 ld/testsuite/ld-riscv-elf/c-relax.d create mode 100644 ld/testsuite/ld-riscv-elf/c-relax.s diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 3d2ddf4e651..e5c41707437 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -4168,6 +4168,31 @@ typedef bool (*relax_func_t) (bfd *, asection *, asection *, riscv_pcgp_relocs *, bool undefined_weak); +/* Check the mapping symbol with architecture string in the R_RISCV_RELAX, + to see if rvc is enabled or not. If we don't find any mapping symbols, + then just check the elf header flag as usual. */ + +static int +_bfd_riscv_enable_rvc (bfd *abfd, Elf_Internal_Rela *rel) +{ + Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd); + int rvc = elf_elfheader (abfd)->e_flags & EF_RISCV_RVC; + if (ELFNN_R_SYM (rel->r_info) < symtab_hdr->sh_info) + { + Elf_Internal_Sym *isym = ((Elf_Internal_Sym *) symtab_hdr->contents + + ELFNN_R_SYM (rel->r_info)); + + if (isym->st_shndx == SHN_UNDEF + || isym->st_shndx >= elf_numsections (abfd)) + return rvc; + + const char *name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL); + rvc = (name && strncmp (name, "$xrv", 4) == 0 + && strstr (name, "_c") != NULL) ? 1 : 0; + } + return rvc; +} + /* Relax AUIPC + JALR into JAL. */ static bool @@ -4185,7 +4210,8 @@ _bfd_riscv_relax_call (bfd *abfd, asection *sec, asection *sym_sec, bfd_vma foff = symval - (sec_addr (sec) + rel->r_offset); bool near_zero = (symval + RISCV_IMM_REACH / 2) < RISCV_IMM_REACH; bfd_vma auipc, jalr; - int rd, r_type, len = 4, rvc = elf_elfheader (abfd)->e_flags & EF_RISCV_RVC; + int rd, r_type, len = 4; + int rvc = _bfd_riscv_enable_rvc (abfd, rel + 1); /* If the call crosses section boundaries, an alignment directive could cause the PC-relative offset to later increase, so we need to add in the @@ -4279,7 +4305,6 @@ _bfd_riscv_relax_lui (bfd *abfd, { bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; bfd_vma gp = riscv_global_pointer_value (link_info); - int use_rvc = elf_elfheader (abfd)->e_flags & EF_RISCV_RVC; BFD_ASSERT (rel->r_offset + 4 <= sec->size); @@ -4347,7 +4372,7 @@ _bfd_riscv_relax_lui (bfd *abfd, account for this assuming page alignment at worst. In the presence of RELRO segment the linker aligns it by one page size, therefore sections after the segment can be moved more than one page. */ - + int use_rvc = _bfd_riscv_enable_rvc (abfd, rel + 1); if (use_rvc && ELFNN_R_TYPE (rel->r_info) == R_RISCV_HI20 && VALID_CITYPE_LUI_IMM (RISCV_CONST_HIGH_PART (symval)) diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index 99bd0a06d97..77a5e45392d 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -511,7 +511,8 @@ make_mapping_symbol (enum riscv_seg_mstate state, symbol_get_bfdsym (symbol)->flags |= (BSF_NO_FLAGS | BSF_LOCAL); if (reset_seg_arch_str) { - /* Store current $x+arch into tc_segment_info. */ + /* Store current $x+arch into tc_segment_info, so that we can + refer to the correct $x+arch for each R_RISCV_RELAX. */ seg_info (now_seg)->tc_segment_info_data.arch_map_symbol = symbol; xfree ((void *) buff); } @@ -1558,6 +1559,8 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr, address_expr, false, reloc_type); ip->fixp->fx_tcbit = riscv_opts.relax; + ip->fixp->tc_fix_data.arch_map_symbol = + seg_info (now_seg)->tc_segment_info_data.arch_map_symbol; } } @@ -3731,6 +3734,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) unsigned int subtype; bfd_byte *buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where); bool relaxable = false; + bool rvc_relaxable = false; offsetT loc; segT sub_segment; @@ -3747,6 +3751,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) if (fixP->fx_addsy == NULL) fixP->fx_done = true; relaxable = true; + rvc_relaxable = true; break; case BFD_RELOC_RISCV_GOT_HI20: @@ -3940,6 +3945,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) case BFD_RELOC_RISCV_CALL: case BFD_RELOC_RISCV_CALL_PLT: relaxable = true; + rvc_relaxable = true; break; case BFD_RELOC_RISCV_PCREL_HI20: @@ -3964,9 +3970,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) if (relaxable && fixP->fx_tcbit && fixP->fx_addsy != NULL) { fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP)); - fixP->fx_next->fx_addsy = fixP->fx_next->fx_subsy = NULL; + /* Currently only rvc relaxations need $x+arch. */ + fixP->fx_next->fx_addsy = (need_arch_map_symbol && rvc_relaxable) + ? fixP->tc_fix_data.arch_map_symbol : NULL; + fixP->fx_next->fx_subsy = NULL; fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_RELAX; fixP->fx_next->fx_size = 0; + /* Set addend to zero. */ + fixP->fx_next->fx_offset = 0; } } diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h index 19c45ba2d12..333731c6120 100644 --- a/gas/config/tc-riscv.h +++ b/gas/config/tc-riscv.h @@ -152,6 +152,13 @@ struct riscv_frag_type #define TC_FRAG_INIT(fragp, max_bytes) riscv_init_frag (fragp, max_bytes) extern void riscv_init_frag (struct frag *, int); +#define TC_FIX_TYPE struct riscv_fixup_type +struct riscv_fixup_type +{ + symbolS *arch_map_symbol; +}; +#define TC_INIT_FIX_DATA(FIX) ((FIX)->tc_fix_data.arch_map_symbol = NULL) + #define obj_adjust_symtab() riscv_adjust_symtab () extern void riscv_adjust_symtab (void); diff --git a/gas/testsuite/gas/riscv/mapping-relax.d b/gas/testsuite/gas/riscv/mapping-relax.d new file mode 100644 index 00000000000..a12edba7ebf --- /dev/null +++ b/gas/testsuite/gas/riscv/mapping-relax.d @@ -0,0 +1,23 @@ +#name: +#source: mapping-relax.s +#as: +#readelf: -rW + +Relocation section '.rela.text' at .* +[ ]+Offset[ ]+Info[ ]+Type[ ]+.* +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_HI20[ ]+[0-9a-f]+[ ]+foo \+ 0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_RELAX[ ]+[0-9a-f]+[ ]+\$xrv32i2p1 \+ 0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_LO12_I[ ]+[0-9a-f]+[ ]+foo \+ 4 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_RELAX[ ]+[0-9a-f]+[ ]+\$xrv32i2p1 \+ 0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_TPREL_HI20[ ]+[0-9a-f]+[ ]+i \+ 0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_RELAX[ ]+0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_TPREL_ADD[ ]+[0-9a-f]+[ ]+i \+ 0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_RELAX[ ]+0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_TPREL_LO12_I[ ]+[0-9a-f]+[ ]+i \+ 0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_RELAX[ ]+0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_PCREL_HI20[ ]+[0-9a-f]+[ ]+foo \+ 0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_RELAX[ ]+0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_PCREL_LO12_I[ ]+[0-9a-f]+[ ]+L1 \+ 0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_RELAX[ ]+0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_CALL_PLT[ ]+[0-9a-f]+[ ]+foo \+ 0 +[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_RISCV_RELAX[ ]+[0-9a-f]+[ ]+\$xrv32i2p1_c2p0 \+ 0 diff --git a/gas/testsuite/gas/riscv/mapping-relax.s b/gas/testsuite/gas/riscv/mapping-relax.s new file mode 100644 index 00000000000..0fa7693a6bb --- /dev/null +++ b/gas/testsuite/gas/riscv/mapping-relax.s @@ -0,0 +1,21 @@ +.attribute arch, "rv32i" +.option relax +foo: +.align 2 +lui a0, %hi (foo) +addi a0, a0, %lo (foo + 4) +.option arch, +a +lui a0, %tprel_hi (i) +add a0, a0, tp, %tprel_add (i) +lw a1, %tprel_lo (i) (a0) +.option arch, -a, +c +L1: auipc a0, %pcrel_hi (foo) +addi a0, a0, %pcrel_lo (L1) +call foo + +.globl i +.section .tbss, "awT", @nobits +.type i, @object +.size i, 4 +i: +.zero 4 diff --git a/ld/testsuite/ld-riscv-elf/c-relax.d b/ld/testsuite/ld-riscv-elf/c-relax.d new file mode 100644 index 00000000000..c0a5e611a8f --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/c-relax.d @@ -0,0 +1,16 @@ +#source: c-relax.s +#ld: --relax +#objdump: -d -Mno-aliases + +.*:[ ]+file format .* + + +Disassembly of section .text: + +0+[0-9a-f]+ <_start>: +.*:[ ]+[0-9a-f]+[ ]+lui[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+addi[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+c\.lui[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+addi[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+c\.j[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+jal[ ]+.* diff --git a/ld/testsuite/ld-riscv-elf/c-relax.s b/ld/testsuite/ld-riscv-elf/c-relax.s new file mode 100644 index 00000000000..80e52dea1c8 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/c-relax.s @@ -0,0 +1,12 @@ +.option relax +.option arch, -c +.globl _start +_start: +lui a0, %hi (_start) +addi a0, a0, %lo (_start) +.option arch, +c +lui a0, %hi (_start) +addi a0, a0, %lo (_start) +call zero, _start +.option arch, -c +call zero, _start diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp index df89e0ee68b..684275508a5 100644 --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp @@ -125,6 +125,7 @@ if [istarget "riscv*-*-*"] { run_dump_test "pcgp-relax-02" run_dump_test "c-lui" run_dump_test "c-lui-2" + run_dump_test "c-relax" run_dump_test "disas-jalr" run_dump_test "pcrel-lo-addend" run_dump_test "pcrel-lo-addend-2a"