From patchwork Sun Feb 4 03:18:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lulu Cai X-Patchwork-Id: 196409 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:168b:b0:106:860b:bbdd with SMTP id ma11csp178334dyb; Sat, 3 Feb 2024 19:18:34 -0800 (PST) X-Google-Smtp-Source: AGHT+IFCP0CvZVyUtd4HdZMF6u+9Rix0OSuGsjW/4SO9zvNNH2GYM7i1YRTZgnJZbzjOsXmAtDLZ X-Received: by 2002:ad4:4eaa:0:b0:68c:7c3e:bbf3 with SMTP id ed10-20020ad44eaa000000b0068c7c3ebbf3mr2679617qvb.11.1707016713825; Sat, 03 Feb 2024 19:18:33 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707016713; cv=pass; d=google.com; s=arc-20160816; b=zcMKu1WcDVa4rv2EIbYorQXW12bhf/76vJDDPIcXtWF5XDXr/WBWDWU0FDJztf4ki6 Lan9hSOCTLYDTokUXtvrd9X0UAlVJG2O8YGRxch8C+e2cXdh2ZUiYUSou4FwiAlyq1Io 7BFj298KJhiZ10JFeuMVRVJ7yBYvAa+uWf4DP3fjnAA5KZiJWsXsTWprC6pGtXU4wuhU m6QH1H0o88ddlottqPuIid7ELjJqqPlXLltGAzjnEtggxvgPZvsuMVUNbQ0toPayFXJI dc+h3CZrPHgVfvQvFIGeWVjKpsulxDHmcP+5ujCcyy/X6bp3E1KM3vGN0aytOGS3ZyEL bWog== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=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:arc-filter :dmarc-filter:delivered-to; bh=t9VDsOw6tkg19KYDyPg4tza9Op8lCXiB3TjA82an2Bs=; fh=A92E+X5sZxTJGs5UiJWcxJKbOzJuxD+epjCTgbIk7z8=; b=FV7IHVV5OLjRHtD+qEJWBTWJ5wCrWBMSFTRS1xj/rnJiXoAHvEitBF3Znu2Cz01C4M TuFsqilXL7XdwsHr0JCGpTLY/wYsMpGLDrI6dTzFpCdrnUA0rLY79SV5yPCQTN2Gi3qS rX4QaDNMCplSF3cyWQRLOk2+1zU4wqQoZTjQHeeATp9uwqurz/PDl/qZ+sVqt47cCP/X fAyiI/u82cd3aHRlU4NKyDEB2vYgHwrB7+8MMMEKDr892vsa/bT0XQ+N7S1XsxIvRH7C sRrnkGppgYaf0u99QLJhHAfEDV+0uPrc2vOqXeYUnVgGu4tft/ENRVE7VrgS3SB/j68h f+Hw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; arc=pass (i=1); 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" X-Forwarded-Encrypted: i=1; AJvYcCXi95GSAgfokVE5f4QfYdPfpdgpkUCavBtKv3MOKV5nxEBgkLP0xWYbaN/YNoSkX7odCaH7TrdOaxmFqOS6FoBRnsevWQ== Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id gu6-20020a056214260600b0068c929892f1si2871946qvb.82.2024.02.03.19.18.33 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 03 Feb 2024 19:18:33 -0800 (PST) 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; arc=pass (i=1); 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 78EF638582B1 for ; Sun, 4 Feb 2024 03:18:33 +0000 (GMT) X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id D32BD3858C42 for ; Sun, 4 Feb 2024 03:18:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D32BD3858C42 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn ARC-Filter: OpenARC Filter v1.0.0 sourceware.org D32BD3858C42 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1707016706; cv=none; b=EkwR5QLd0s8bMMQIfOWml/bxRqPrwQc+ft8os9m1ShgItQT7EP96u/GsyDWOKilDUibNQXhm39WF/nkSAE7TbjxgNjXgtSeQUCjKbIl8ElhIHjmp+3/+2y4i5zi9HPX7CVtanvS1Vok/vILkM+cKA+MMZQ2ijb70eJ2cjkKNqNk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1707016706; c=relaxed/simple; bh=0VQpLYo5haPVePtX+puYL0WdaDmu4U3dDyr70m0qTAo=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=jzveI99OpBbfidQcztnMBDibWVH68iFdSP9moDE5B1PXtiFk4VyGCUYBEc24K7bnwrUCjIuQoVcJgUE4VBn1FpSqBXxxvzraAUr+JRN1hmVMLUAFh4EGo216k910pjh++pOVsemjPN8B3l7Rngw0EX6ae1gdF49lGuhzMRkvG8U= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from loongson.cn (unknown [10.2.6.5]) by gateway (Coremail) with SMTP id _____8CxXOn9Ab9ldIEKAA--.19976S3; Sun, 04 Feb 2024 11:18:21 +0800 (CST) Received: from 5.5.5 (unknown [10.2.6.5]) by localhost.localdomain (Coremail) with SMTP id AQAAf8BxVMz8Ab9lKSUvAA--.51530S4; Sun, 04 Feb 2024 11:18:21 +0800 (CST) From: Lulu Cai To: binutils@sourceware.org Cc: xuchenghua@loongson.cn, chenglulu@loongson.cn, liuzhensong@loongson.cn, mengqinggang@loongson.cn, xry111@xry111.site, i.swmail@xen0n.name, maskray@google.com, luweining@loongson.cn, wanglei@loongson.cn, hejinyang@loongson.cn, Lulu Cai Subject: [PATCH] LoongArch: Fix the issue of excessive relocation generated by IE Date: Sun, 4 Feb 2024 11:18:19 +0800 Message-Id: <20240204031819.3982654-1-cailulu@loongson.cn> X-Mailer: git-send-email 2.39.3 MIME-Version: 1.0 X-CM-TRANSID: AQAAf8BxVMz8Ab9lKSUvAA--.51530S4 X-CM-SenderInfo: xfdlz3tox6z05rqj20fqof0/1tbiAQARB2W9+WIDPwAFst X-Coremail-Antispam: 1Uk129KBj93XoWxtrWrAr4fAw47AF1rGr47Jrc_yoW3AF1Dpr ZIvrWDt348ZFW3W3sFq3W8ZF43C3y8urW2grW7Gwn5ury3Xr9aqa1Sqr1xZFWF9rs2yFsI qrWjvay7Z3WrArbCm3ZEXasCq-sJn29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUUk2b4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Xr0_Ar1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AK xVW8Jr0_Cr1UM2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6xACxx 1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1q6rW5McIj6I8E87Iv 67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82IYc2 Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s02 6x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r1q6r43MIIYrxkI7VAKI48JMIIF0x vE2Ix0cI8IcVAFwI0_Gr0_Xr1lIxAIcVC0I7IYx2IY6xkF7I0E14v26r4j6F4UMIIF0xvE 42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVW8JVWxJwCI42IY6I8E87Iv6x kF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuYvjxU2F4iUUUUU X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_STOCKGEN, SPF_HELO_NONE, SPF_PASS, TXREP, 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.30 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 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789936757679977226 X-GMAIL-MSGID: 1789936757679977226 Currently, whether GD and IE generate dynamic repositioning is determined by SYMBOL_REFERENCES_LOCAL and bfd_link_executable. This results in dynamic relocations still being generated in some situations where dynamic relocations are not necessary (such as the undefined weak symbol in static links). We use RLARCH_TLS_GD_IE_NEED_DYN_RELOC macros to determine whether GD/IE needs dynamic relocation. If GD/IE requires dynamic relocation, set need_reloc/need_relocs to true and indx to be a dynamic index. --- bfd/elfnn-loongarch.c | 156 +++++++++++++++++++++++------------------- 1 file changed, 86 insertions(+), 70 deletions(-) diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index 172c45ef5cb..68c88e6f52b 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -159,6 +159,26 @@ struct loongarch_elf_link_hash_table || (R_TYPE) == R_LARCH_TLS_LE64_LO20 \ || (R_TYPE) == R_LARCH_TLS_LE64_HI12) +/* If TLS GD/IE need dynamic relocations, INDX will be the dynamic indx, + and set NEED_RELOC to true used in allocate_dynrelocs and + loongarch_elf_relocate_section for TLS GD/IE. */ +#define LARCH_TLS_GD_IE_NEED_DYN_RELOC(INFO, DYN, H, INDX, NEED_RELOC) \ + do \ + { \ + if ((H) != NULL \ + && (H)->dynindx != -1 \ + && WILL_CALL_FINISH_DYNAMIC_SYMBOL ((DYN), \ + bfd_link_pic (INFO), (H))) \ + (INDX) = (H)->dynindx; \ + if (((H) == NULL \ + || ELF_ST_VISIBILITY ((H)->other) == STV_DEFAULT \ + || (H)->root.type != bfd_link_hash_undefweak) \ + && (!bfd_link_executable (INFO) \ + || (INDX) != 0)) \ + (NEED_RELOC) = true; \ + } \ + while (0) + /* Generate a PLT header. */ static bool @@ -1276,40 +1296,24 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) h->got.offset = s->size; if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC)) { + int indx = 0; + bool need_reloc = false; + LARCH_TLS_GD_IE_NEED_DYN_RELOC (info, dyn, h, indx, + need_reloc); /* TLS_GD needs two dynamic relocs and two GOT slots. */ if (tls_type & GOT_TLS_GD) { s->size += 2 * GOT_ENTRY_SIZE; - if (bfd_link_executable (info)) - { - /* Link exe and not defined local. */ - if (!SYMBOL_REFERENCES_LOCAL (info, h)) - htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela); - } - else - { - if (SYMBOL_REFERENCES_LOCAL (info, h)) - htab->elf.srelgot->size += sizeof (ElfNN_External_Rela); - else - htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela); - } + if (need_reloc) + htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela); } /* TLS_IE needs one dynamic reloc and one GOT slot. */ if (tls_type & GOT_TLS_IE) { s->size += GOT_ENTRY_SIZE; - - if (bfd_link_executable (info)) - { - /* Link exe and not defined local. */ - if (!SYMBOL_REFERENCES_LOCAL (info, h)) - htab->elf.srelgot->size += sizeof (ElfNN_External_Rela); - } - else - { - htab->elf.srelgot->size += sizeof (ElfNN_External_Rela); - } + if (need_reloc) + htab->elf.srelgot->size += sizeof (ElfNN_External_Rela); } /* TLS_DESC needs one dynamic reloc and two GOT slot. */ @@ -2548,6 +2552,19 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info, }) +#define TP_OFFSET 0 + +/* Return the relocation value for a static TLS tp-relative relocation. */ +static bfd_vma +tls_blockoff (struct bfd_link_info *info, bfd_vma addr) +{ + /* If tls_sec is NULL, we should have signalled an error already. */ + if (elf_hash_table (info)->tls_sec == NULL) + return 0; + return addr - elf_hash_table (info)->tls_sec->vma - TP_OFFSET; +} + + static int loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd, asection *input_section, @@ -3663,53 +3680,56 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, { Elf_Internal_Rela rela; asection *relgot = htab->elf.srelgot; - bfd_vma tls_block_off = 0; - if (SYMBOL_REFERENCES_LOCAL (info, h)) - { - BFD_ASSERT (elf_hash_table (info)->tls_sec); - tls_block_off = relocation - - elf_hash_table (info)->tls_sec->vma; - } + int indx = 0; + bool need_relocs = false; + LARCH_TLS_GD_IE_NEED_DYN_RELOC (info, is_dyn, h, indx, + need_relocs); if (tls_type & GOT_TLS_GD) { - rela.r_offset = sec_addr (got) + got_off; - rela.r_addend = 0; - if (SYMBOL_REFERENCES_LOCAL (info, h)) + if (need_relocs) { - /* Local sym, used in exec, set module id 1. */ - if (bfd_link_executable (info)) - bfd_put_NN (output_bfd, 1, got->contents + got_off); + /* Dynamic resolved Module ID. */ + rela.r_offset = sec_addr (got) + got_off; + rela.r_addend = 0; + rela.r_info = ELFNN_R_INFO (indx,R_LARCH_TLS_DTPMODNN); + bfd_put_NN (output_bfd, 0, got->contents + got_off); + loongarch_elf_append_rela (output_bfd, relgot, &rela); + + if (indx == 0) + { + /* Local symbol, tp offset has been known. */ + BFD_ASSERT (! unresolved_reloc); + bfd_put_NN (output_bfd, tls_blockoff (info, + relocation), + (got->contents + got_off + GOT_ENTRY_SIZE)); + } else { - rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_DTPMODNN); + /* Dynamic resolved block offset. */ + bfd_put_NN (output_bfd, 0, + got->contents + got_off + GOT_ENTRY_SIZE); + rela.r_info = ELFNN_R_INFO (indx, + R_LARCH_TLS_DTPRELNN); + rela.r_offset += GOT_ENTRY_SIZE; loongarch_elf_append_rela (output_bfd, relgot, &rela); } - - bfd_put_NN (output_bfd, tls_block_off, - got->contents + got_off + GOT_ENTRY_SIZE); } - /* Dynamic resolved. */ else { - /* Dynamic relocate module id. */ - rela.r_info = ELFNN_R_INFO (h->dynindx, - R_LARCH_TLS_DTPMODNN); - loongarch_elf_append_rela (output_bfd, relgot, &rela); - - /* Dynamic relocate offset of block. */ - rela.r_offset += GOT_ENTRY_SIZE; - rela.r_info = ELFNN_R_INFO (h->dynindx, - R_LARCH_TLS_DTPRELNN); - loongarch_elf_append_rela (output_bfd, relgot, &rela); + /* In a static link or an executable link with the symbol + binding locally. Mark it as belonging to module 1. */ + bfd_put_NN (output_bfd, 1, got->contents + got_off); + bfd_put_NN (output_bfd, tls_blockoff (info, relocation), + got->contents + got_off + GOT_ENTRY_SIZE); } } if (tls_type & GOT_TLS_GDESC) { /* Unless it is a static link, DESC always emits a dynamic relocation. */ - int indx = h && h->dynindx != -1 ? h->dynindx : 0; + indx = h && h->dynindx != -1 ? h->dynindx : 0; rela.r_offset = sec_addr (got) + got_off + desc_off; rela.r_addend = 0; if (indx == 0) @@ -3722,28 +3742,24 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, } if (tls_type & GOT_TLS_IE) { - rela.r_offset = sec_addr (got) + got_off + ie_off; - if (SYMBOL_REFERENCES_LOCAL (info, h)) + if (need_relocs) { - /* Local sym, used in exec, set module id 1. */ - if (!bfd_link_executable (info)) - { - rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN); - rela.r_addend = tls_block_off; - loongarch_elf_append_rela (output_bfd, relgot, &rela); - } + bfd_put_NN (output_bfd, 0, + got->contents + got_off + ie_off); + rela.r_offset = sec_addr (got) + got_off + ie_off; + rela.r_addend = 0; - bfd_put_NN (output_bfd, tls_block_off, - got->contents + got_off + ie_off); + if (indx == 0) + rela.r_addend = tls_blockoff (info, relocation); + rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_TPRELNN); + loongarch_elf_append_rela (output_bfd, relgot, &rela); } - /* Dynamic resolved. */ else { - /* Dynamic relocate offset of block. */ - rela.r_info = ELFNN_R_INFO (h->dynindx, - R_LARCH_TLS_TPRELNN); - rela.r_addend = 0; - loongarch_elf_append_rela (output_bfd, relgot, &rela); + /* In a static link or an executable link with the symbol + bindinglocally, compute offset directly. */ + bfd_put_NN (output_bfd, tls_blockoff (info, relocation), + got->contents + got_off + ie_off); } } }