From patchwork Sun Mar 8 06:21:54 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: daichengrong X-Patchwork-Id: 131274 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id C67D84BA23E1 for ; Sun, 8 Mar 2026 06:22:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C67D84BA23E1 X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from cstnet.cn (smtp21.cstnet.cn [159.226.251.21]) by sourceware.org (Postfix) with ESMTPS id 276B34BA2E15 for ; Sun, 8 Mar 2026 06:22:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 276B34BA2E15 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=iscas.ac.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=iscas.ac.cn ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 276B34BA2E15 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=159.226.251.21 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1772950929; cv=none; b=DrCLsAlYd/e5q+wJthbWHR37XEFdakefGKUp5/7ujmTFWCny10DoFooKX+dFUV/5C6M4rWzRG8+o4uEZPZh13EsDmkSrki0ejnmmb161oNpBrdXne6P2aHc+2kXHer16W7gzHEbR9hes8aPE57UWPIU9Zupit+ERuGeWoFaiq/g= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1772950929; c=relaxed/simple; bh=cEI+okkmQ7YiOS9rBhtIStSrM3cq/eDu8ZWiF1l70gQ=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=q1PZzzMlmVXsJtsOcOqvmMHk2kBoHOW2Uk1rHdUINkPYDqlGfU2t+8pRX8qNi57X8Pp5L+L/10OkEJWU3Qd8wu60z2HT4GqfcDT08V8JyP8jpGGd35JchAswL8E4fW9ga5+eYo7m9IMF9iy5tfsjPiYUCXqzMm9EcNkGpbFAsPo= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 276B34BA2E15 Received: from localhost.localdomain (unknown [112.3.246.150]) by APP-01 (Coremail) with SMTP id qwCowAB3H2uJFa1prV9wCQ--.43255S2; Sun, 08 Mar 2026 14:22:02 +0800 (CST) From: daichengrong To: libc-alpha@sourceware.org Cc: adhemerval.zanella@linaro.org, simon.poirier@canonical.com, daichengrong Subject: [RFC v3] RISC-V: Fix SIGSEGV of --static-pie binaries on riscv64 [BZ #33911] Date: Sun, 8 Mar 2026 14:21:54 +0800 Message-Id: <20260308062154.338674-1-daichengrong@iscas.ac.cn> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-CM-TRANSID: qwCowAB3H2uJFa1prV9wCQ--.43255S2 X-Coremail-Antispam: 1UD129KBjvJXoWxGFyxtrWrGF1rAw4kAw47Arb_yoWrKw4DpF W5Ca1rAa1rXrWxWrsIyrn8Ww13C3W8urW8Cry7C3s5ua1aqry8Ww1Yqr48AFyxXrWvqrWa qFn0q3WUKa1rZFDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUym14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK02 1l84ACjcxK6xIIjxv20xvE14v26r4j6ryUM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4j 6F4UM28EF7xvwVC2z280aVAFwI0_Cr1j6rxdM28EF7xvwVC2z280aVCY1x0267AKxVWxJr 0_GcWle2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E 2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJV W8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1l42xK82IYc2Ij64vI r41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x8Gjc xK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF0xvE2Ix0 cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E14v26r1j6r4UMIIF0xvE42xK8V AvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E 14v26r1j6r4UYxBIdaVFxhVjvjDU0xZFpf9x0JUywZ7UUUUU= X-Originating-IP: [112.3.246.150] X-CM-SenderInfo: pgdluxxhqj201qj6x2xfdvhtffof0/ X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org This patch fixes a SIGSEGV observed in --static-pie binaries on riscv64, as reported in BZ #33911. The first issue occurs when compiler optimizations are enabled: memory initialization via `memset` may generate early libcalls before static PIE relocation, leading to incorrect symbol resolution. The second issue occurs when compiler optimizations are not enabled: `memcpy` may be emitted as a direct libc call instead of an inlined instruction sequence, which can also trigger relocation problems. This patch addresses both issues by providing safe early implementations that avoid generating libcalls before static PIE relocation, ensuring memory operations are performed correctly. Signed-off-by: daichengrong --- elf/dynamic-link.h | 67 ++++++++++++++++++++++++++------------ sysdeps/riscv/dl-machine.h | 15 ++++++--- 2 files changed, 57 insertions(+), 25 deletions(-) diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index a46f36b8d4..8c12812b63 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -18,7 +18,14 @@ #include #include +// #include +#ifndef unlikely +#define unlikely(x) __builtin_expect(!!(x), 0) +#endif +#ifndef likely +#define likely(x) __builtin_expect(!!(x), 1) +#endif #ifdef RESOLVE_MAP /* We pass reloc_addr as a pointer to void, as opposed to a pointer to ElfW(Addr), because not all architectures can assume that the @@ -82,11 +89,11 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], do { \ struct { ElfW(Addr) start, size; \ __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \ - ranges[2] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; \ + ranges[2]; \ \ /* With DT_RELR, DT_RELA/DT_REL can have zero value. */ \ - if ((map)->l_info[DT_##RELOC] != NULL \ - && (map)->l_info[DT_##RELOC]->d_un.d_ptr != 0) \ + if (likely((map)->l_info[DT_##RELOC] != NULL \ + && (map)->l_info[DT_##RELOC]->d_un.d_ptr != 0)) \ { \ ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]); \ ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val; \ @@ -94,28 +101,46 @@ elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ranges[0].nrelative \ = map->l_info[VERSYMIDX (DT_##RELOC##COUNT)]->d_un.d_val; \ } \ - if ((map)->l_info[DT_PLTREL] \ - && (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \ + else \ + { \ + ranges[0].size = 0; \ + ranges[0].nrelative = 0; \ + } \ + if (likely((map)->l_info[DT_PLTREL] \ + && (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC))) \ { \ ElfW(Addr) start = D_PTR ((map), l_info[DT_JMPREL]); \ ElfW(Addr) size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \ \ - if (ranges[0].start == 0) \ - ranges[0].start = start; \ - if (ranges[0].start + ranges[0].size == (start + size)) \ - ranges[0].size -= size; \ - if (!(do_lazy) \ - && (ranges[0].start + ranges[0].size) == start) \ - { \ - /* Combine processing the sections. */ \ - ranges[0].size += size; \ - } \ - else \ - { \ - ranges[1].start = start; \ - ranges[1].size = size; \ - ranges[1].lazy = (do_lazy); \ - } \ + if (ranges[0].size == 0) \ + { \ + ranges[0].lazy = (do_lazy); \ + ranges[0].start = start; \ + ranges[0].size = size; \ + ranges[1].size = 0; \ + } \ + else \ + { \ + ranges[1].start = start; \ + ranges[1].size = size; \ + ranges[1].lazy = (do_lazy); \ + if (likely(do_lazy)) \ + { \ + /* Combine processing the sections. */ \ + if (unlikely(ranges[0].start + ranges[0].size == (start + size))) \ + { \ + ranges[1].size = 0; \ + ranges[0].start = ranges[0].start; \ + ranges[1].lazy = 0; \ + ranges[0].size = ranges[0].size + size; \ + ranges[0].lazy = (do_lazy); \ + } \ + } \ + } \ + } \ + else \ + { \ + ranges[1].size = 0; \ } \ \ for (int ranges_index = 0; ranges_index < 2; ++ranges_index) \ diff --git a/sysdeps/riscv/dl-machine.h b/sysdeps/riscv/dl-machine.h index 8c7312ad98..0c6b55c3f3 100644 --- a/sysdeps/riscv/dl-machine.h +++ b/sysdeps/riscv/dl-machine.h @@ -157,10 +157,17 @@ __attribute__ ((always_inline)) elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, void *const reloc_addr) { - /* R_RISCV_RELATIVE might located in debug info section which might not - aligned to XLEN bytes. Also support relocations on unaligned offsets. */ - ElfW(Addr) value = l_addr + reloc->r_addend; - memcpy (reloc_addr, &value, sizeof value); +#if __riscv_xlen == 64 + uint64_t value = l_addr + reloc->r_addend; + + uint32_t lo = (uint32_t)value; + uint32_t hi = (uint32_t)(value >> 32); + + ((uint32_t*)reloc_addr)[0] = lo; + ((uint32_t*)reloc_addr)[1] = hi; +#else + *reloc_addr = l_addr + reloc->r_addend; +#endif } /* Perform a relocation described by R_INFO at the location pointed to