From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from xry111.site (xry111.site [89.208.246.23]) by sourceware.org (Postfix) with ESMTPS id 2083B385842F for ; Thu, 25 Jan 2024 13:43:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2083B385842F Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=xry111.site Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=xry111.site ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 2083B385842F Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=89.208.246.23 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706190183; cv=none; b=x5Ub4QZmytpBVwrz+difsRCOnUM/BSANg4BwU3iB7Z1/+h6nzw88//LOTchuK/9E2OBZxohV65Gl358hogJMnJMtIff0ihQLAqftYBqTR4MqgWMwEn7zD8smef+gPkIzOJvXq/f12+QkPlxgW502APMUv0/TU9F6p6VGw+WO9lU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706190183; c=relaxed/simple; bh=U6JpWbbvE8UnXZkGab4pWIJhWdotA2UJ/wg69brighM=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=ZOoRtu2opL99cjbVLgeBhl7fQUnaodw+TxVBQCEFr/nZ7df/GiF6uDNSG1jLtZn6FGe1i2tpqteCAfesTA6rzm/1pOlOOHMJPcaN2eLbLlK1UZIj496BFQ9mmJrSKBHYKFxiENVihe+N4hzUaqvTdlGISzQp2I1PzUYuEpGKVts= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xry111.site; s=default; t=1706190179; bh=U6JpWbbvE8UnXZkGab4pWIJhWdotA2UJ/wg69brighM=; h=From:To:Cc:Subject:Date:From; b=hFghvnzPB1y/VIEl1/nuc6ftVJbz8Q2sS2d6b1/OLdR2Gh7AbvbjYBQn1/Nukmik5 WctZuXTup0CY7Ef7M0OXQ7IY5STFt0iL8NT5bjAamvR8T/h4QwirM+AZrFXCyN2Al3 VVukeT3BG15FwN3W8OMZv+Bjg1VVAs10bM66p7GE= Received: from stargazer.. (unknown [113.200.174.21]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id 53D1366FA0; Thu, 25 Jan 2024 08:42:57 -0500 (EST) From: Xi Ruoyao To: binutils@sourceware.org Cc: mengqinggang@loongson.cn, Nick Clifton , Xi Ruoyao Subject: [PATCH] LoongArch: Disallow TLS transition when a section contains TLS_IE64 or TLS_DESC64 reloc Date: Thu, 25 Jan 2024 21:36:26 +0800 Message-ID: <20240125134238.174841-1-xry111@xry111.site> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-9.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,LIKELY_SPAM_FROM,SPF_HELO_PASS,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 List-Id: We cannot do TLS transition for them without a psABI revision marking some "key" instructions with reloc. Disallow the transition when we see such a reloc in a section to prevent an invalid "partial" transition. Signed-off-by: Xi Ruoyao --- To Nick: Sorry for another late update, but we need this for 2.42 or anything compiled with -mcmodel=extreme and using errno will just blow up :(. bfd/elfnn-loongarch.c | 53 +++++++++++++++++-- .../ld-loongarch-elf/ld-loongarch-elf.exp | 14 +++++ .../ld-loongarch-elf/tls-ie64-notrans.d | 3 ++ .../ld-loongarch-elf/tls-ie64-notrans.s | 7 +++ 4 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 ld/testsuite/ld-loongarch-elf/tls-ie64-notrans.d create mode 100644 ld/testsuite/ld-loongarch-elf/tls-ie64-notrans.s diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index b62bb424644..b9709401f56 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -717,6 +717,40 @@ loongarch_tls_transition (struct bfd_link_info *info, unsigned int r_type, return loongarch_tls_transition_without_check (info, r_type, h); } +/* For TLS IE in extreme code model: + pcalau12i t0, %ie_pc_hi20(x) + li.d t1, %ie_pc_lo12(x) + lu32i.d t1, %ie64_pc_lo20(x) + lu52i.d t1, t1, %ie64_pc_hi12(x) + ldx.d t0, t0, t1 + We've no idea how to remove the ldx.d instruction or turn it into a + nop because there is no reloc on it. But we have to stop turning this + into LE or we'll end up + lu12i.w t0, %le_hi20(x) + ori t1, t1, %le_lo12(x) + lu32i.d t1, %ie64_pc_lo20(x) + lu52i.d t1, t1, %ie64_pc_hi12(x) + ldx.d t0, t0, t1 + which is completely wrong. For TLS DESC it's similar: we cannot remove + the add.d instruction but we have to stop the transition. */ +static bool +loongarch_elf_allow_tls_transition_p (const Elf_Internal_Rela *r_begin, + const Elf_Internal_Rela *r_end) +{ + for (; r_begin != r_end; r_begin++) + switch (ELFNN_R_TYPE (r_begin->r_info)) + { + case R_LARCH_TLS_IE64_PC_HI12: + case R_LARCH_TLS_IE64_PC_LO20: + case R_LARCH_TLS_DESC64_PC_HI12: + case R_LARCH_TLS_DESC64_PC_LO20: + return false; + } + + return true; +} + + /* Look through the relocs for a section during the first phase, and allocate space in the global offset table or procedure linkage table. */ @@ -730,6 +764,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, struct elf_link_hash_entry **sym_hashes; const Elf_Internal_Rela *rel; asection *sreloc = NULL; + bool allow_tls_transition; if (bfd_link_relocatable (info)) return true; @@ -741,6 +776,9 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, if (htab->elf.dynobj == NULL) htab->elf.dynobj = abfd; + allow_tls_transition = loongarch_elf_allow_tls_transition_p ( + relocs, relocs + sec->reloc_count); + for (rel = relocs; rel < relocs + sec->reloc_count; rel++) { unsigned int r_type; @@ -818,7 +856,8 @@ 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, abfd, r_symndx); + if (allow_tls_transition) + r_type = loongarch_tls_transition (info, r_type, h, abfd, r_symndx); switch (r_type) { case R_LARCH_GOT_PC_HI20: @@ -2632,7 +2671,6 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, asection **local_sections) { Elf_Internal_Rela *rel; - Elf_Internal_Rela *relend; bool fatal = false; asection *sreloc = elf_section_data (input_section)->sreloc; struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info); @@ -2643,8 +2681,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, bool is_dyn = elf_hash_table (info)->dynamic_sections_created; asection *plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt; asection *got = htab->elf.sgot; + Elf_Internal_Rela *relend = relocs + input_section->reloc_count; + bool allow_tls_transition = + loongarch_elf_allow_tls_transition_p (relocs, relend); - relend = relocs + input_section->reloc_count; for (rel = relocs; rel < relend; rel++) { unsigned int r_type = ELFNN_R_TYPE (rel->r_info); @@ -2789,7 +2829,12 @@ 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, input_bfd, r_symndx); + relaxed_r_type = + (allow_tls_transition ? loongarch_tls_transition (info, r_type, + h, input_bfd, + r_symndx) + : r_type); + if (relaxed_r_type != r_type) { howto = loongarch_elf_rtype_to_howto (input_bfd, relaxed_r_type); diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp index 2ff06d62236..9e35940f5d6 100644 --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp @@ -88,6 +88,20 @@ if [istarget "loongarch64-*-*"] { "medium-call" \ ] \ ] + + run_ld_link_tests \ + [list \ + [list \ + "disable TLS IE transition with TLS_IE64_PC reloc" \ + "-e 0x0" "" \ + "" \ + {tls-ie64-notrans.s} \ + [list \ + [list objdump -D tls-ie64-notrans.d] \ + ] \ + "tls-ie64-notrans" \ + ] \ + ] } if [istarget "loongarch64-*-*"] { diff --git a/ld/testsuite/ld-loongarch-elf/tls-ie64-notrans.d b/ld/testsuite/ld-loongarch-elf/tls-ie64-notrans.d new file mode 100644 index 00000000000..47d507a0538 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/tls-ie64-notrans.d @@ -0,0 +1,3 @@ +#... +.*pcalau12i.* +#pass diff --git a/ld/testsuite/ld-loongarch-elf/tls-ie64-notrans.s b/ld/testsuite/ld-loongarch-elf/tls-ie64-notrans.s new file mode 100644 index 00000000000..cd8c65ff9d3 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/tls-ie64-notrans.s @@ -0,0 +1,7 @@ +# it had segfaulted the linker due to invalid IE->LE transition +.globl _start +_start: + la.tls.ie $a0, $a1, foo + +.section .tdata +foo: .word 114514 -- 2.43.0