From patchwork Mon Nov 18 08:38:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lulu Cai X-Patchwork-Id: 101402 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AC39B385B513 for ; Mon, 18 Nov 2024 08:40:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AC39B385B513 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 80ED9385B530 for ; Mon, 18 Nov 2024 08:39:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 80ED9385B530 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 80ED9385B530 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=1731919158; cv=none; b=vKbMA4tE5GQOrzRJA+tKJGLHhcVrqToB6S4/LzAWBOKBeDSJp+tdnbIeG6dHw4EMtxaBlbUOHBooVlp5A83rNJ79kJWFCLvxNYhyGIsZ2NZPT/t7d8aXkb+PQBOLLLJWnriKqMMROp+SBCa++JQ1ldT7uWcgsfXkbvROz0N+YHQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1731919158; c=relaxed/simple; bh=yAacpsNp14VPg9O3l/s918H1KyxgA+ywzgSr8rLQb6c=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=kQT9Ni4WDqr5C8Lxvl/0abAdb35dqjnX9BjjcK6nqQ9IkBCSlsQVo/SshkhJbFiJjBirm+ruOiwxfXLmi0gVZACTmu0hSSPoMAsLEZIeEk5UUshzSr/RoMPa2BGfydrJX/h3ajrRrE6MUuG2VXGkhTIpoYS/ekhPSBZZiH2eZ00= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 80ED9385B530 Received: from loongson.cn (unknown [10.2.6.5]) by gateway (Coremail) with SMTP id _____8DxmeAy_TpnjyFBAA--.62637S3; Mon, 18 Nov 2024 16:39:14 +0800 (CST) Received: from 5.. (unknown [10.2.6.5]) by front1 (Coremail) with SMTP id qMiowMBxrsIw_Tpn51dbAA--.60135S4; Mon, 18 Nov 2024 16:39:12 +0800 (CST) From: Lulu Cai To: binutils@sourceware.org Cc: xuchenghua@loongson.cn, chenglulu@loongson.cn, mengqinggang@loongson.cn, xry111@xry111.site, i.swmail@xen0n.name, maskray@google.com, luweining@loongson.cn, hejinyang@loongson.cn, Lulu Cai Subject: [PATCH v1] LoongArch: Fix the infinite loop caused by calling undefweak symbol Date: Mon, 18 Nov 2024 16:38:37 +0800 Message-Id: <20241118083837.199774-1-cailulu@loongson.cn> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-CM-TRANSID: qMiowMBxrsIw_Tpn51dbAA--.60135S4 X-CM-SenderInfo: xfdlz3tox6z05rqj20fqof0/1tbiAgEFB2c6eNEHuwABsI X-Coremail-Antispam: 1Uk129KBj93XoW3Kr1ruFW5Wr1fWF4rur1rAFc_yoWkXF1xpr y7Zr4SyF4rCFnrWF1DGa45Wr4xXw1xWFWxZa4ftr1Iyrs7Xry8Zwn7trW3XF4UGw4qyw1f XwnYv34UZF1kA3cCm3ZEXasCq-sJn29KB7ZKAUJUUUUr529EdanIXcx71UUUUU7KY7ZEXa sCq-sGcSsGvfJ3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU 0xBIdaVrnRJUUU90b4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2 IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48v e4kI8wA2z4x0Y4vE2Ix0cI8IcVAFwI0_Jr0_JF4l84ACjcxK6xIIjxv20xvEc7CjxVAFwI 0_Gr0_Cr1l84ACjcxK6I8E87Iv67AKxVWxJVW8Jr1l84ACjcxK6I8E87Iv6xkF7I0E14v2 6r4UJVWxJr1ln4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12 xvs2x26I8E6xACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r10 6r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64 vIr41l42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1l4IxYO2xFxVAFwI0_ Jrv_JF1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1V AY17CE14v26r1q6r43MIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAI cVC0I7IYx2IY6xkF7I0E14v26r1j6r4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42 IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r1j6r4UYxBIdaVFxhVj vjDU0xZFpf9x07UMyIUUUUUU= X-Spam-Status: No, score=-13.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, 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.30 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: binutils-bounces~patchwork=sourceware.org@sourceware.org The undefweak symbol value of non-default visibility is 0 and does not use plt entry, and will not be relocated in the relocate_secion function. As a result, an infinite loop is generated because bl %plt(sym) => bl 0. Fix this by converting the bl/call36 instructions to nop or removing them. --- bfd/elfnn-loongarch.c | 49 +++++++++++++++++++ gas/config/tc-loongarch.c | 3 +- .../gas/loongarch/double_quotation_marks.d | 1 + gas/testsuite/gas/loongarch/jmp_op.d | 2 + gas/testsuite/gas/loongarch/reloc.d | 4 ++ gas/testsuite/gas/loongarch/relocs_64.d | 1 + .../ld-loongarch-elf/call_undefweak.d | 30 ++++++++++++ .../ld-loongarch-elf/call_undefweak.s | 48 ++++++++++++++++++ ld/testsuite/ld-loongarch-elf/jmp_op.d | 2 + .../ld-loongarch-elf/ld-loongarch-elf.exp | 10 ++++ 10 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 ld/testsuite/ld-loongarch-elf/call_undefweak.d create mode 100644 ld/testsuite/ld-loongarch-elf/call_undefweak.s diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index 608d179c168..3fe54721244 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -222,6 +222,10 @@ loongarch_elf_new_section_hook (bfd *abfd, asection *sec) || (R_TYPE) == R_LARCH_TLS_LE64_LO20 \ || (R_TYPE) == R_LARCH_TLS_LE64_HI12) +#define IS_CALL_RELOC(R_TYPE) \ + ((R_TYPE) == R_LARCH_B26 \ + || (R_TYPE) == R_LARCH_CALL36) + /* 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. */ @@ -5277,6 +5281,33 @@ loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec, return true; } +/* Delete the call undefweak instruction without plt entries when relax + is enabled, otherwise it will be converted to nop. */ +static bool +loongarch_relax_call_undefweak (bfd *abfd, asection *sec, + Elf_Internal_Rela *rel, + struct bfd_link_info *info, + bool with_relax_reloc) +{ + bfd_byte *contents = elf_section_data (sec)->this_hdr.contents; + unsigned long r_type = ELFNN_R_TYPE (rel->r_info); + + bfd_put (32, abfd, LARCH_NOP, contents + rel->r_offset); + /* Medium call uses pcaddu18i + jirl, so jirl also needs + to be converted to nop. */ + if (r_type == R_LARCH_CALL36) + bfd_put (32, abfd, LARCH_NOP, contents + rel->r_offset + 4); + + if (with_relax_reloc && !info->disable_target_specific_optimizations) + { + loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, info); + if (r_type == R_LARCH_CALL36) + loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, info); + } + rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE); + return true; +} + /* Traverse all output sections and return the max alignment. */ static bfd_vma @@ -5398,6 +5429,24 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, r_type = ELFNN_R_TYPE (rel->r_info); } + /* The undefweak symbol value of non-default visibility is 0 + and does not use plt entry, and will not be relocated in + the relocate_secion function. As a result, an infinite loop + is generated because bl %plt(sym) => bl 0. */ + if (h != NULL + && h->root.type == bfd_link_hash_undefweak + && !h->needs_plt + && IS_CALL_RELOC (r_type)) + { + bool with_relax_reloc = false; + if (i + 1 != sec->reloc_count + && ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX) + with_relax_reloc = true; + + loongarch_relax_call_undefweak (abfd, sec, rel, info, + with_relax_reloc); + r_type = ELFNN_R_TYPE (rel->r_info); + } relax_func_t relax_func = NULL; if (info->relax_pass == 0) { diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c index 411c24b41f0..e5837d75f76 100644 --- a/gas/config/tc-loongarch.c +++ b/gas/config/tc-loongarch.c @@ -853,7 +853,8 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2, || BFD_RELOC_LARCH_TLS_LE_LO12 == reloc_type || BFD_RELOC_LARCH_TLS_LE64_LO20 == reloc_type || BFD_RELOC_LARCH_TLS_LE64_HI12 == reloc_type - || BFD_RELOC_LARCH_CALL36 == reloc_type)) + || BFD_RELOC_LARCH_CALL36 == reloc_type + || BFD_RELOC_LARCH_B26 == reloc_type)) { ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX; ip->reloc_info[ip->reloc_num].value = const_0; diff --git a/gas/testsuite/gas/loongarch/double_quotation_marks.d b/gas/testsuite/gas/loongarch/double_quotation_marks.d index a42534b94a4..3a058921799 100644 --- a/gas/testsuite/gas/loongarch/double_quotation_marks.d +++ b/gas/testsuite/gas/loongarch/double_quotation_marks.d @@ -9,5 +9,6 @@ Disassembly of section .text: .* <.text>: [ ]+0:[ ]+50000000[ ]+b[ ]+0[ ]+# 0x0 [ ]+0: R_LARCH_B26[ ]+.L1 +[ ]+0: R_LARCH_RELAX[ ]+\*ABS\* [ ]+4:[ ]+5800018d[ ]+beq[ ]+\$t0, \$t1, 0[ ]+# 0x4 [ ]+4: R_LARCH_B16[ ]+.L1 diff --git a/gas/testsuite/gas/loongarch/jmp_op.d b/gas/testsuite/gas/loongarch/jmp_op.d index 21576072aab..2c2f8e68645 100644 --- a/gas/testsuite/gas/loongarch/jmp_op.d +++ b/gas/testsuite/gas/loongarch/jmp_op.d @@ -25,8 +25,10 @@ Disassembly of section .text: [ ]+20:[ ]+4c000080[ ]+jr[ ]+\$a0 [ ]+24:[ ]+53ffdfff[ ]+b[ ]+-36[ ]+#[ ]+0[ ]+<\.L1> [ ]+24:[ ]+R_LARCH_B26[ ]+\.L1 +[ ]+24:[ ]+R_LARCH_RELAX[ ]+\*ABS\* [ ]+28:[ ]+57ffdbff[ ]+bl[ ]+-40[ ]+#[ ]+0[ ]+<\.L1> [ ]+28:[ ]+R_LARCH_B26[ ]+\.L1 +[ ]+28:[ ]+R_LARCH_RELAX[ ]+\*ABS\* [ ]+2c:[ ]+5bffd485[ ]+beq[ ]+\$a0,[ ]+\$a1,[ ]+-44[ ]+#[ ]+0[ ]+<\.L1> [ ]+2c:[ ]+R_LARCH_B16[ ]+\.L1 [ ]+30:[ ]+5fffd085[ ]+bne[ ]+\$a0,[ ]+\$a1,[ ]+-48[ ]+#[ ]+0[ ]+<\.L1> diff --git a/gas/testsuite/gas/loongarch/reloc.d b/gas/testsuite/gas/loongarch/reloc.d index 6a8f0e1f5d9..65fbac7bca9 100644 --- a/gas/testsuite/gas/loongarch/reloc.d +++ b/gas/testsuite/gas/loongarch/reloc.d @@ -29,8 +29,10 @@ Disassembly of section .text: [ ]+24:[ ]+R_LARCH_B21[ ]+.L1 [ ]+28:[ ]+50000000[ ]+b[ ]+0[ ]+#[ ]+0x28 [ ]+28:[ ]+R_LARCH_B26[ ]+.L1 +[ ]+28:[ ]+R_LARCH_RELAX[ ]+\*ABS\* [ ]+2c:[ ]+54000000[ ]+bl[ ]+0[ ]+#[ ]+0x2c [ ]+2c:[ ]+R_LARCH_B26[ ]+.L1 +[ ]+2c:[ ]+R_LARCH_RELAX[ ]+\*ABS\* [ ]+30:[ ]+14000004[ ]+lu12i.w[ ]+\$a0,[ ]+0 [ ]+30:[ ]+R_LARCH_ABS_HI20[ ]+.L1 [ ]+34:[ ]+038000a4[ ]+ori[ ]+\$a0,[ ]+\$a1,[ ]+0x0 @@ -111,8 +113,10 @@ Disassembly of section .text: [ ]+c0:[ ]+R_LARCH_B21[ ]+.L1\+0x8 [ ]+c4:[ ]+50000000[ ]+b[ ]+0[ ]+#[ ]+0xc4 [ ]+c4:[ ]+R_LARCH_B26[ ]+.L1\+0x8 +[ ]+c4:[ ]+R_LARCH_RELAX[ ]+\*ABS\* [ ]+c8:[ ]+54000000[ ]+bl[ ]+0[ ]+#[ ]+0xc8 [ ]+c8:[ ]+R_LARCH_B26[ ]+.L1\+0x8 +[ ]+c8:[ ]+R_LARCH_RELAX[ ]+\*ABS\* [ ]+cc:[ ]+14000004[ ]+lu12i.w[ ]+\$a0,[ ]+0 [ ]+cc:[ ]+R_LARCH_ABS_HI20[ ]+.L1\+0x8 [ ]+d0:[ ]+038000a4[ ]+ori[ ]+\$a0,[ ]+\$a1,[ ]+0x0 diff --git a/gas/testsuite/gas/loongarch/relocs_64.d b/gas/testsuite/gas/loongarch/relocs_64.d index ce5216a2b73..fb9eb2c86b6 100644 --- a/gas/testsuite/gas/loongarch/relocs_64.d +++ b/gas/testsuite/gas/loongarch/relocs_64.d @@ -14,6 +14,7 @@ Disassembly of section .text: [ ]+4: R_LARCH_B21[ ]+.L1 [ ]+8:[ ]+50008400[ ]+b[ ]+132[ ]+# 8c <.L1> [ ]+8: R_LARCH_B26[ ]+.L1 +[ ]+8: R_LARCH_RELAX[ ]+\*ABS\* [ ]+c:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0 [ ]+c: R_LARCH_ABS_HI20[ ]+.L1 [ ]+10:[ ]+038000a4[ ]+ori[ ]+\$a0, \$a1, 0x0 diff --git a/ld/testsuite/ld-loongarch-elf/call_undefweak.d b/ld/testsuite/ld-loongarch-elf/call_undefweak.d new file mode 100644 index 00000000000..a8ab431cc74 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/call_undefweak.d @@ -0,0 +1,30 @@ +#... +Disassembly of section .plt: +#... +00000001200004d0 : + 1200004d0: 1c00010f pcaddu12i \$t3, 8 + 1200004d4: 28ed01ef ld.d \$t3, \$t3, -1216 + 1200004d8: 4c0001ed jirl \$t1, \$t3, 0 + 1200004dc: 03400000 nop + +Disassembly of section .text: +#... +0000000120000668
: + 120000668: 03400000 nop + 12000066c: 03400000 nop + 120000670: 57fe63ff bl -416 # 1200004d0 + +0000000120000674 : + 120000674: 03400000 nop + 120000678: 03400000 nop + 12000067c: 03400000 nop + 120000680: 03400000 nop + 120000684: 1e000001 pcaddu18i \$ra, 0 + 120000688: 4ffe4c21 jirl \$ra, \$ra, -436 + +000000012000068c : + 12000068c: 57fe47ff bl -444 # 1200004d0 + +0000000120000690 : + 120000690: 57fe43ff bl -448 # 1200004d0 +#pass diff --git a/ld/testsuite/ld-loongarch-elf/call_undefweak.s b/ld/testsuite/ld-loongarch-elf/call_undefweak.s new file mode 100644 index 00000000000..684b2964e49 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/call_undefweak.s @@ -0,0 +1,48 @@ + .text + .align 2 + .globl main + .type main, @function +main: + # undefweak symbol with .hidden and .protected + # do not need plt entry, Calls to these symbols + # are converted to nop when relax is disabled. +nornal_call_nop: + .option norelax + bl %plt(fn1) + bl %plt(fn2) + bl %plt(fn3) + + # Medium call uses pcaddu18i+jirl, we need to + # convert two instructions to nop. +medium_call_nop: + pcaddu18i $r1,%call36(fn1) + jirl $r1,$r1,0 + pcaddu18i $r1,%call36(fn2) + jirl $r1,$r1,0 + pcaddu18i $r1,%call36(fn3) + jirl $r1,$r1,0 + + + # These insns call undefweak symbol without + # plt entry will be deleted when relax is + # enabled. +normal_call_delete: + .option relax + bl %plt(fn1) + bl %plt(fn2) + bl %plt(fn3) +medium_call_delete: + pcaddu18i $r1,%call36(fn1) + jirl $r1,$r1,0 + pcaddu18i $r1,%call36(fn2) + jirl $r1,$r1,0 + pcaddu18i $r1,%call36(fn3) + jirl $r1,$r1,0 + + .weak fn1 + .hidden fn1 + + .weak fn2 + .protected fn2 + + .weak fn3 diff --git a/ld/testsuite/ld-loongarch-elf/jmp_op.d b/ld/testsuite/ld-loongarch-elf/jmp_op.d index 231d780923e..fe7715a4678 100644 --- a/ld/testsuite/ld-loongarch-elf/jmp_op.d +++ b/ld/testsuite/ld-loongarch-elf/jmp_op.d @@ -25,8 +25,10 @@ Disassembly of section .text: [ ]+20:[ ]+4c000080[ ]+jirl[ ]+\$zero,[ ]+\$a0,[ ]+0 [ ]+24:[ ]+53ffdfff[ ]+b[ ]+-36[ ]+#[ ]+0[ ]+<.L1> [ ]+24:[ ]+R_LARCH_B26[ ]+.L1 +[ ]+24:[ ]+R_LARCH_RELAX[ ]+\*ABS\* [ ]+28:[ ]+57ffdbff[ ]+bl[ ]+-40[ ]+#[ ]+0[ ]+<.L1> [ ]+28:[ ]+R_LARCH_B26[ ]+.L1 +[ ]+28:[ ]+R_LARCH_RELAX[ ]+\*ABS\* [ ]+2c:[ ]+5bffd485[ ]+beq[ ]+\$a0,[ ]+\$a1,[ ]+-44[ ]+#[ ]+0[ ]+<.L1> [ ]+2c:[ ]+R_LARCH_B16[ ]+.L1 [ ]+30:[ ]+5fffd085[ ]+bne[ ]+\$a0,[ ]+\$a1,[ ]+-48[ ]+#[ ]+0[ ]+<.L1> diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp index 3313f72eee4..8335158dc60 100644 --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp @@ -142,6 +142,16 @@ if [istarget "loongarch64-*-*"] { "abs-global.out" \ ] \ ] + + run_cc_link_tests [list \ + [list \ + "call undefweak symbol" \ + "" "" \ + {call_undefweak.s} \ + {{objdump {-d} call_undefweak.d}} \ + "call_undefweak" \ + ] \ + ] } if [istarget "loongarch64-*-*"] {