From patchwork Fri Dec 1 09:04:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lulu Cai X-Patchwork-Id: 172329 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:bcd1:0:b0:403:3b70:6f57 with SMTP id r17csp982372vqy; Fri, 1 Dec 2023 01:06:13 -0800 (PST) X-Google-Smtp-Source: AGHT+IGSCjTWC0MDBcoIrj/rO7cAd4Mdxv/zSaCmEacknC5yQs1VekTZ6MfKFECqi6lS0CbzkVgH X-Received: by 2002:ac8:4e8b:0:b0:418:af7:e001 with SMTP id 11-20020ac84e8b000000b004180af7e001mr34930229qtp.41.1701421573797; Fri, 01 Dec 2023 01:06:13 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1701421573; cv=pass; d=google.com; s=arc-20160816; b=iv9s3uMOFoXM7uTs8nmb3IHNlbNoDD/yYXEH47Ol7IlTgaE7urwPODc/SAAHbrcCHC T+DxaQmiWsYULdDjDpb8rFQhD2soOYd+Koi4Am/0VQ2g+/W58/ownP6E3epd1ZfMnpqz 80Yn2wqhayGsHet4SfKIZcbz2ws+wK7hdMrHy0CRk6wU7NutYvXoGvrK19zEFsRJhTeR JPmvGM9aD6S43ME6+/dj/1QF2UTt8NIFK22/iEXj26D1gIrJmNsGdspN9rozzqJZIJ/K hT83lCIvw0iA+07jyQb8YOdKQVUXWf2yoN+7jdRJS0iHe5Lfl31SZrrOknj6xf3wp0zO I3Qw== 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:references:in-reply-to:message-id:date:subject:cc:to :from:arc-filter:dmarc-filter:delivered-to; bh=sDe9aCmLXZXfUSAQkEtqXdnX/hE/eWyq9PglPRaV2zE=; fh=FvlVQEmCpm5H8oBXQswexzCupeeQXnbssobXN+3R2Wg=; b=Al78A2A9zMxSRvmjjoe+yqFQ9Lh2/BA1xB1afMK+tbsHoSnYnneojdQWahTHiBz8C2 RJmvcAvo0Dh98qstyzzq4OS5XCy/UUElFl9B7DDcpotP1dy+I+fB3YaAC5IAAs/KA9CI 6RBfg0eTaGoCqB9HIi8K4nfzIYoB+6uCFF07RqHKLo4JGtoo0o5T2aeZzcprnKmHrWrC 9kPusZlDBCk5aTCqDawFHwX5K7EvD1fskg80RJdpMEteuiDkc7MB9Id13dGALqKiUm8g Wl66KV4dQwclDBG9Wtmw4dkjnPHczwtDFmvptl/c97WlbRZzragn1LP8S/wDXSiRqROl VEEQ== 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 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org" Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id ay38-20020a05622a22a600b0040f2b1cde26si2986569qtb.590.2023.12.01.01.06.13 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Dec 2023 01:06:13 -0800 (PST) Received-SPF: pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; arc=pass (i=1); spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 2620:52:3:1:0:246e:9693:128c 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 DC4E6384DED9 for ; Fri, 1 Dec 2023 09:06:08 +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 46EC638618DA for ; Fri, 1 Dec 2023 09:04:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 46EC638618DA 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 46EC638618DA 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=1701421484; cv=none; b=DX8ijebz+1DVbUmS/TZC2ZZaIQA9gzEsUxJd8cjaXxm8L6JJzsF1kpZeEm6JbRVQvqSavzOWAXYUaTXy+Jmry3rbjQ0HPgBk9zRa6WRpUEeFI02v5fHu/kj689DIJ3CP9YS9H9ySydMAkkJf063Psj+kZr4Ye5HnewfcLbz5qIo= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701421484; c=relaxed/simple; bh=YUO1mzkgIxpAqoFjg6sCQU42Trw8kzd5CE5mw0BtWfQ=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=u8QgVWRpsgL+nJN+983n3Eh5O0b11h2YCJ14aVghhJewpeDzUShEIh9fXVznSykfDbmaPOxQh07pCg1XjlMDTecpWFG8YJxeXyUmx9ElQ8NuUZZSAFYmibRJHweV5vpaT6/x13ALqmC2zj4ZS/32CXMbYw7O3vFgrH9kMXq0RAk= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from loongson.cn (unknown [10.2.6.5]) by gateway (Coremail) with SMTP id _____8AxEvCgoWll7ig+AA--.57914S3; Fri, 01 Dec 2023 17:04:32 +0800 (CST) Received: from 5.5.5 (unknown [10.2.6.5]) by localhost.localdomain (Coremail) with SMTP id AQAAf8DxS9yaoWll53hRAA--.48257S7; Fri, 01 Dec 2023 17:04:31 +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 v1 3/4] LoongArch: Add transition support for DESC to LE. Date: Fri, 1 Dec 2023 17:04:23 +0800 Message-Id: <20231201090424.854662-4-cailulu@loongson.cn> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20231201090424.854662-1-cailulu@loongson.cn> References: <20231201090424.854662-1-cailulu@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf8DxS9yaoWll53hRAA--.48257S7 X-CM-SenderInfo: xfdlz3tox6z05rqj20fqof0/1tbiAQAMB2VpQqsHiAAAsg X-Coremail-Antispam: 1Uk129KBj93XoW3GFWruF1xuryUKr1xWrWkKrX_yoW7CryDpr y3Z3y5Kr4F9F4xW34kXayrCF43t3yxWrWxtFy3tr4Fkrs7JrW8XFnrtr1jv3WrGw4kKr92 vrWF9w4Uu3W8A3XCm3ZEXasCq-sJn29KB7ZKAUJUUUU5529EdanIXcx71UUUUU7KY7ZEXa 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.5 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: 1784069828307171993 X-GMAIL-MSGID: 1784069828307171993 --- bfd/elfnn-loongarch.c | 108 ++++++++++++++++++++++++++++++++++++- include/opcode/loongarch.h | 3 ++ 2 files changed, 110 insertions(+), 1 deletion(-) diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index e1cf7c1eda0..d8095aaae54 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -145,6 +145,12 @@ struct loongarch_elf_link_hash_table #define elf_backend_rela_normal 1 #define elf_backend_default_execstack 0 +#define IS_LOONGARCH_TLS_DESC_RELOC(R_TYPE) \ + ((R_TYPE) == R_LARCH_TLS_DESC_PC_HI20 \ + || (R_TYPE) == R_LARCH_TLS_DESC_LD_PC_LO12 \ + || (R_TYPE) == R_LARCH_TLS_DESC_ADD_PC_LO12 \ + || (R_TYPE) == R_LARCH_TLS_DESC_CALL) + /* Generate a PLT header. */ static bool @@ -605,6 +611,58 @@ loongarch_elf_record_tls_and_got_reference (bfd *abfd, return true; } +/* Return true if DESC can transition to LE. */ +static bool +loongarch_can_relax_tls (struct bfd_link_info *info, unsigned int r_type, + struct elf_link_hash_entry *h) +{ + if (! IS_LOONGARCH_TLS_DESC_RELOC (r_type)) + return false; + + bool local_exec = bfd_link_executable (info) + && SYMBOL_REFERENCES_LOCAL (info, h); + if (! local_exec) + return false; + + if (h && h->root.type == bfd_link_hash_undefweak) + return false; + + return true; +} + +/* Perform the transition from DESC relocation to LE relocation. */ +static unsigned int +loongarch_tls_transition_without_check (unsigned int r_type) +{ + switch (r_type) + { + case R_LARCH_TLS_DESC_PC_HI20: + return R_LARCH_TLS_LE_HI20; + + case R_LARCH_TLS_DESC_LD_PC_LO12: + return R_LARCH_TLS_LE_LO12; + + case R_LARCH_TLS_DESC_ADD_PC_LO12: + case R_LARCH_TLS_DESC_CALL: + return R_LARCH_NONE; + + default: + break; + } + + return r_type; +} + +static unsigned int +loongarch_tls_transition (struct bfd_link_info *info, unsigned int r_type, + struct elf_link_hash_entry *h) +{ + if (! loongarch_can_relax_tls (info, r_type, h)) + return r_type; + + return loongarch_tls_transition_without_check (r_type); +} + /* Look through the relocs for a section during the first phase, and allocate space in the global offset table or procedure linkage table. */ @@ -706,6 +764,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, int need_dynreloc = 0; int only_need_pcrel = 0; + r_type = loongarch_tls_transition (info, r_type, h); switch (r_type) { case R_LARCH_GOT_PC_HI20: @@ -2397,6 +2456,45 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info, relocation += 0x100000000; \ }) +/* Transition DESC instruction sequence to LE instruction sequence. */ +static bool +loongarch_tls_relax (bfd *abfd, asection *sec, Elf_Internal_Rela *rel, + int r_type) +{ + bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; + switch (r_type) + { + case R_LARCH_TLS_DESC_PC_HI20: + /* DESC -> LE relaxation: + pcalalau12i $a0,%desc_pc_hi20(var) => lu12i.w $a0,%le_hi20(var) + */ + bfd_put (32, abfd, LARCH_LU12I_W_A0, contents + rel->r_offset); + + return true; + + case R_LARCH_TLS_DESC_LD_PC_LO12: + /* DESC -> LE relaxation: + ld.d $a1,$a0,%desc_ld_pc_lo12(var) => ori $a0,$a0,le_lo12(var) + */ + bfd_put (32, abfd, LARCH_ORI_A0, contents + rel->r_offset); + + return true; + + case R_LARCH_TLS_DESC_ADD_PC_LO12: + case R_LARCH_TLS_DESC_CALL: + /* DESC -> LE relaxation: + addi.d $a0,$a0,%desc_add_pc_lo12(var) => NOP + jirl $ra,$a1,%desc_call(var) => NOP + */ + bfd_put (32, abfd, LARCH_NOP, contents + rel->r_offset); + + return true; + } + + return false; +} + + static int loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd, asection *input_section, @@ -2420,7 +2518,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, relend = relocs + input_section->reloc_count; for (rel = relocs; rel < relend; rel++) { - int r_type = ELFNN_R_TYPE (rel->r_info); + unsigned int r_type = ELFNN_R_TYPE (rel->r_info); unsigned long r_symndx = ELFNN_R_SYM (rel->r_info); bfd_vma pc = sec_addr (input_section) + rel->r_offset; reloc_howto_type *howto = NULL; @@ -2430,6 +2528,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, const char *name; bfd_reloc_status_type r = bfd_reloc_ok; bool is_ie, is_desc, is_undefweak, unresolved_reloc, defined_local; + unsigned int relaxed_r_type; bool resolved_local, resolved_dynly, resolved_to_const; char tls_type; bfd_vma relocation, off, ie_off, desc_off; @@ -2561,6 +2660,13 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, BFD_ASSERT (!resolved_local || defined_local); + relaxed_r_type = loongarch_tls_transition (info, r_type, h); + if (relaxed_r_type != r_type) + { + loongarch_tls_relax (input_bfd, input_section, rel, r_type); + r_type = relaxed_r_type; + } + is_desc = false; is_ie = false; switch (r_type) diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h index da936f7945a..9a4a95d1177 100644 --- a/include/opcode/loongarch.h +++ b/include/opcode/loongarch.h @@ -42,6 +42,9 @@ extern "C" ((value) < (-(1 << ((bits) - 1) << align)) \ || (value) > ((((1 << ((bits) - 1)) - 1) << align))) + #define LARCH_LU12I_W_A0 0x14000004 + #define LARCH_ORI_A0 0x03800084 + typedef uint32_t insn_t; struct loongarch_opcode