From patchwork Sat Mar 25 00:41:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nelson Chu X-Patchwork-Id: 74795 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp118087vqo; Fri, 24 Mar 2023 17:41:29 -0700 (PDT) X-Google-Smtp-Source: AKy350Y62mEJ1VYMn+6wAbv2Qda3h9Kyhf55vbron2mi+67a91FR+n2PbNpFGTntG3H6/ALS5mnn X-Received: by 2002:a17:907:d40c:b0:933:3a65:67ed with SMTP id vi12-20020a170907d40c00b009333a6567edmr4999711ejc.75.1679704889500; Fri, 24 Mar 2023 17:41:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679704889; cv=none; d=google.com; s=arc-20160816; b=gJfISUTTBk/CtQmzRG4jisNeDTpWiq1zb+vjKiSjItbtExZHMLWwf5WfnhFyVsfxX0 kHt73YP8S/3ZVFGnpsqLJmfI0aG14QLSjq3hLSjhpObv8Fb3kbCU/KN5m4OunwMQxsRd CparTcWzY/HWTh4ho0KhNfn5bS/zwOVqXMZXL9fwY0M8z2ohcyIH7C0bFyLRXFFnytWH HsRuEIBMTG9o4RNTXuzDJ8wzeumcZDdP+1aMsQl1258V4MPqRe86xVndzwEpA6wrR4tJ 880F+AicfwGqQ5/IgJALA2GE/fHMnqo3FoRi8un7TatF7EhIwdAoGUzOgqNfKtjCd5ml LPiQ== 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:message-id:date:subject:cc:to:from:dmarc-filter :delivered-to; bh=+X6adtgNCy7hF7hrEihol1g04VJA++G9Lfzom9nRQWU=; b=x7yuUbuXaf+1Fefvusb9tSiqG3CeDNSPFbWbMGoSEyQC/VV0z4bnVC3mnFD47Gi5fO 8VtYPL8DTqvfjdyanNj2e07xjlnWnbpuhQ093Zxhz6dYrhO4mVmr6m0jljG7pfVh0BtK NKbQX4pYLRU+sdq0K9QoDIlPH/C1so27s7OyPwJf2/gynNOhePega1xSgOOjS6LAopLP BVBxdv2Dnx2mXryWqQR/vWdxgIpgMQf5X+3yLjEXjqhHmxiL9lgeOAuQ2s7pRx13cibC 7yvzLmnDcg31PxwYLEodeDBUqw3uOf1QsFnuqTt03cNS5pRb6dB+4BMz8HxfDk6YBcSV e+Eg== 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 1-20020a170906300100b008d78cb027b7si20716883ejz.667.2023.03.24.17.41.29 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Mar 2023 17:41:29 -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 44AE83858C00 for ; Sat, 25 Mar 2023 00:41:25 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from NelsondeMBP.localdomain (114-25-107-156.dynamic-ip.hinet.net [114.25.107.156]) by sourceware.org (Postfix) with ESMTP id 1C8533858D28 for ; Sat, 25 Mar 2023 00:41:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1C8533858D28 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 799E5A59E00; Sat, 25 Mar 2023 08:41:14 +0800 (CST) From: Nelson Chu To: binutils@sourceware.org, jim.wilson.gcc@gmail.com, palmer@dabbelt.com Cc: nelson@rivosinc.com Subject: [PATCH 1/3] RISC-V: Extract the ld code which are too complicated, and may be reused. Date: Sat, 25 Mar 2023 08:41:11 +0800 Message-Id: <20230325004113.22673-1-nelson@rivosinc.com> X-Mailer: git-send-email 2.37.1 (Apple Git-137.1) MIME-Version: 1.0 X-Spam-Status: No, score=-4.3 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, PDS_RDNS_DYNAMIC_FP, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_PBL, 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?1761298234469795995?= X-GMAIL-MSGID: =?utf-8?q?1761298234469795995?= These types of codes are different for each target, I am not sure what are the best for RISC-V, so extract them out may be more easy to compare what's the difference. bfd/ * elfnn-riscv.c (RISCV_NEED_DYNAMIC_RELOC): New defined. Extracted from riscv_elf_check_relocs, to see if dynamic reloc is needed for the specific relocation. (RISCV_GENERATE_DYNAMIC_RELOC): New defined. Extracted from riscv_elf_relocate_section, to see if R_RISCV_32/64 need to generate dynamic relocation. (RISCV_COPY_INPUT_RELOC): New defined. Extracted from riscv_elf_relocate_section, to see if R_RISCV_32/64 need to copy itslef tp output file. (RISCV_RESOLVED_LOCALLY): New defined. Extracted from riscv_elf_relocate_section, to see if R_RISCV_GOT_HI20 can be resolved locally. --- bfd/elfnn-riscv.c | 156 ++++++++++++++++++++++++---------------------- 1 file changed, 82 insertions(+), 74 deletions(-) diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 1200e6b11b5..59e949a2cb5 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -38,6 +38,79 @@ #define CHAR_BIT 8 #endif +/* True if dynamic relocation is needed. If we are creating a shared library, + and this is a reloc against a global symbol, or a non PC relative reloc + against a local symbol, then we need to copy the reloc into the shared + library. However, if we are linking with -Bsymbolic, we do not need to + copy a reloc against a global symbol which is defined in an object we are + including in the link (i.e., DEF_REGULAR is set). + + At this point we have not seen all the input files, so it is possible that + DEF_REGULAR is not set now but will be set later (it is never cleared). + In case of a weak definition, DEF_REGULAR may be cleared later by a strong + definition in a shared library. We account for that possibility below by + storing information in the relocs_copied field of the hash table entry. + A similar situation occurs when creating shared libraries and symbol + visibility changes render the symbol local. + + If on the other hand, we are creating an executable, we may need to keep + relocations for symbols satisfied by a dynamic library if we manage to + avoid copy relocs for the symbol. + + Generate dynamic pointer relocation against STT_GNU_IFUNC symbol in the + non-code section (R_RISCV_32/R_RISCV_64). */ +#define RISCV_NEED_DYNAMIC_RELOC(PCREL, INFO, H, SEC) \ + ((bfd_link_pic (INFO) \ + && ((SEC)->flags & SEC_ALLOC) != 0 \ + && (!(PCREL) \ + || ((H) != NULL \ + && (!(INFO)->symbolic \ + || (H)->root.type == bfd_link_hash_defweak \ + || !(H)->def_regular)))) \ + || (!bfd_link_pic (INFO) \ + && ((SEC)->flags & SEC_ALLOC) != 0 \ + && (H) != NULL \ + && ((H)->root.type == bfd_link_hash_defweak \ + || !(H)->def_regular)) \ + || (!bfd_link_pic (INFO) \ + && (H) != NULL \ + && (H)->type == STT_GNU_IFUNC \ + && ((SEC)->flags & SEC_CODE) == 0)) + +/* True if dynamic relocation should be generated. */ +#define RISCV_GENERATE_DYNAMIC_RELOC(PCREL, INFO, H, RESOLVED_TO_ZERO) \ + ((bfd_link_pic (INFO) \ + && ((H) == NULL \ + || (ELF_ST_VISIBILITY ((H)->other) == STV_DEFAULT && !(RESOLVED_TO_ZERO)) \ + || (H)->root.type != bfd_link_hash_undefweak) \ + && (!(PCREL) \ + || !SYMBOL_CALLS_LOCAL ((INFO), (H)))) \ + || (!bfd_link_pic (INFO) \ + && (H) != NULL \ + && (H)->dynindx != -1 \ + && !(H)->non_got_ref \ + && (((H)->def_dynamic && !(H)->def_regular) \ + || (H)->root.type == bfd_link_hash_undefweak \ + || (H)->root.type == bfd_link_hash_undefined))) + +/* True if this input relocation should be copied to output. H->dynindx + may be -1 if this symbol was marked to become local. */ +#define RISCV_COPY_INPUT_RELOC(INFO, H) \ + ((H) != NULL \ + && (H)->dynindx != -1 \ + && (!bfd_link_pic (INFO) \ + || !SYMBOLIC_BIND ((INFO), (H)) \ + || !(H)->def_regular)) + +/* True if this is actually a static link, or it is a -Bsymbolic link + and the symbol is defined locally, or the symbol was forced to be + local because of a version file. */ +#define RISCV_RESOLVED_LOCALLY(INFO, H) \ + (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (elf_hash_table (INFO)->dynamic_sections_created, \ + bfd_link_pic (INFO), (H)) \ + || (bfd_link_pic (INFO) \ + && SYMBOL_REFERENCES_LOCAL ((INFO), (H)))) + /* Internal relocations used exclusively by the relaxation pass. */ #define R_RISCV_DELETE (R_RISCV_max + 1) @@ -835,48 +908,8 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, } } - /* If we are creating a shared library, and this is a reloc - against a global symbol, or a non PC relative reloc - against a local symbol, then we need to copy the reloc - into the shared library. However, if we are linking with - -Bsymbolic, we do not need to copy a reloc against a - global symbol which is defined in an object we are - including in the link (i.e., DEF_REGULAR is set). At - this point we have not seen all the input files, so it is - possible that DEF_REGULAR is not set now but will be set - later (it is never cleared). In case of a weak definition, - DEF_REGULAR may be cleared later by a strong definition in - a shared library. We account for that possibility below by - storing information in the relocs_copied field of the hash - table entry. A similar situation occurs when creating - shared libraries and symbol visibility changes render the - symbol local. - - If on the other hand, we are creating an executable, we - may need to keep relocations for symbols satisfied by a - dynamic library if we manage to avoid copy relocs for the - symbol. - - Generate dynamic pointer relocation against STT_GNU_IFUNC - symbol in the non-code section (R_RISCV_32/R_RISCV_64). */ - reloc_howto_type * r = riscv_elf_rtype_to_howto (abfd, r_type); - - if ((bfd_link_pic (info) - && (sec->flags & SEC_ALLOC) != 0 - && ((r != NULL && !r->pc_relative) - || (h != NULL - && (!info->symbolic - || h->root.type == bfd_link_hash_defweak - || !h->def_regular)))) - || (!bfd_link_pic (info) - && (sec->flags & SEC_ALLOC) != 0 - && h != NULL - && (h->root.type == bfd_link_hash_defweak - || !h->def_regular)) - || (!bfd_link_pic (info) - && h != NULL - && h->type == STT_GNU_IFUNC - && (sec->flags & SEC_CODE) == 0)) + reloc_howto_type *r = riscv_elf_rtype_to_howto (abfd, r_type); + if (RISCV_NEED_DYNAMIC_RELOC (r->pc_relative, info, h, sec)) { struct elf_dyn_relocs *p; struct elf_dyn_relocs **head; @@ -2329,23 +2362,14 @@ riscv_elf_relocate_section (bfd *output_bfd, case R_RISCV_GOT_HI20: if (h != NULL) { - bool dyn, pic; - off = h->got.offset; BFD_ASSERT (off != (bfd_vma) -1); - dyn = elf_hash_table (info)->dynamic_sections_created; - pic = bfd_link_pic (info); - if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, pic, h) - || (pic && SYMBOL_REFERENCES_LOCAL (info, h))) + if (RISCV_RESOLVED_LOCALLY (info, h)) { - /* This is actually a static link, or it is a - -Bsymbolic link and the symbol is defined - locally, or the symbol was forced to be local - because of a version file. We must initialize - this entry in the global offset table. Since the - offset must always be a multiple of the word size, - we use the least significant bit to record whether + /* We must initialize this entry in the global offset table. + Since the offset must always be a multiple of the word + size, we use the least significant bit to record whether we have initialized it already. When doing a dynamic link, we create a .rela.got @@ -2610,21 +2634,8 @@ riscv_elf_relocate_section (bfd *output_bfd, if ((input_section->flags & SEC_ALLOC) == 0) break; - if ((bfd_link_pic (info) - && (h == NULL - || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - && !resolved_to_zero) - || h->root.type != bfd_link_hash_undefweak) - && (!howto->pc_relative - || !SYMBOL_CALLS_LOCAL (info, h))) - || (!bfd_link_pic (info) - && h != NULL - && h->dynindx != -1 - && !h->non_got_ref - && ((h->def_dynamic - && !h->def_regular) - || h->root.type == bfd_link_hash_undefweak - || h->root.type == bfd_link_hash_undefined))) + if (RISCV_GENERATE_DYNAMIC_RELOC (howto->pc_relative, info, h, + resolved_to_zero)) { Elf_Internal_Rela outrel; asection *sreloc; @@ -2643,10 +2654,7 @@ riscv_elf_relocate_section (bfd *output_bfd, if (skip_dynamic_relocation) memset (&outrel, 0, sizeof outrel); - else if (h != NULL && h->dynindx != -1 - && !(bfd_link_pic (info) - && SYMBOLIC_BIND (info, h) - && h->def_regular)) + else if (RISCV_COPY_INPUT_RELOC (info, h)) { outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type); outrel.r_addend = rel->r_addend;