From patchwork Wed Sep 2 12:43:49 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stian Halseth X-Patchwork-Id: 142709 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id ECB874BA2E25 for ; Wed, 2 Sep 2026 12:44:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org ECB874BA2E25 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, secure) header.d=itx.no header.i=@itx.no header.a=rsa-sha256 header.s=mx.itx.no header.b=XcjbYIHd X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mx.itxnorge.no (itx-kvm-14.itxnorge.no [91.189.121.228]) by sourceware.org (Postfix) with ESMTPS id AA7CF4BA2E05 for ; Wed, 2 Sep 2026 12:44:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AA7CF4BA2E05 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=itx.no Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=itx.no ARC-Filter: OpenARC Filter v1.0.0 sourceware.org AA7CF4BA2E05 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=91.189.121.228 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788353042; cv=none; b=CNzcbU4cP2/vtkHsVptbQZ/UFNFytugBeu0MVW4xkHh0QIX0+xmkREcicUcaeK7bfJ3kfJR53wcSM6Nl/Tt/di3FjEmD1lvz12ghmb5f17jg4SjY8tXhk3H7NBLD3VSF1ldAUj3xlawNKt4NuEuSEvD0N6Pz1vfxuFjmVSwyEQQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1788353042; c=relaxed/simple; bh=80s4bej8lVzKdUluecKJSSDFaiR0oVwBN20AWqrsAbk=; h=From:DKIM-Signature:To:Subject:Date:Message-ID:MIME-Version; b=qOXt/+RRHTSeAq+XgKBAeXeXiSjhrU6wM1besxK66ZVO4wqwqfCmp8yaWZnMJ3x8Hz3lMnX2P+BQaoh3is6xGdHOsH7Umy4ROVlrgJ4eCYzuR9gJb3Zd2EJ58cLz4VDUZwzBEnDJmaDdDLCp/t/3d/QfqI7bh4TsTwH/xaXZ4Yc= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, secure) header.d=itx.no header.i=@itx.no header.a=rsa-sha256 header.s=mx.itx.no header.b=XcjbYIHd DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AA7CF4BA2E05 From: Stian Halseth DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=itx.no; s=mx.itx.no; t=1788353040; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=umaganyTAiF107d12NbIbgboSM/5l4Q5axYZG688rhg=; b=XcjbYIHdNeobeNJ3lhGQRHU5sM19+t/fpRIMTUaZ8B2INu3lfBEH3FvLshs7IiusrfsVwb yjH3iSgif8OLc5KCs8Ok8QGPAS3pdDgJjWawUX7TYI/dPZjkuJSR1jiStUcS4ajpvVcX0Y Ap+e1SpeNGKVrZSfG76rAQ8EEKd9T1I= To: libc-alpha@sourceware.org Cc: sam@gentoo.org, Stian Halseth Subject: [PATCH] Mark swapcontext returns_twice without indirect_return [BZ #23130] Date: Wed, 2 Sep 2026 14:43:49 +0200 Message-ID: <20260902124349.3501576-1-stian@itx.no> MIME-Version: 1.0 X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP shortcircuit=no 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 swapcontext does not restore every callee-saved register on all targets. On sparc the %l and %i registers are not in the saved context at all: they live in the register window save area of the calling frame, which another pass through that frame can overwrite. stdlib/tst-setcontext2 fails on sparc64 for this reason at -O2 with PIC, where gcc keeps &global in %i5 across swapcontext and reuses %i5 as the GOT base on another path through the same frame. Make the generic bits/indirect-return.h fall back to returns_twice where indirect_return is unavailable, covering every affected target. x86 and aarch64 keep their own headers, which gate on CET and on GCS, so those targets are unchanged. string/tst-xbzero-opt.c calls swapcontext from an always_inline function, which a returns_twice callee forbids; key its guard on the availability of indirect_return rather than on __CET__. It is the only such site in the tree. Tested on sparc64: full make check is clean, with no test that passed before failing after. Signed-off-by: Stian Halseth --- bits/indirect-return.h | 15 +++++++++++++-- string/tst-xbzero-opt.c | 7 +++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/bits/indirect-return.h b/bits/indirect-return.h index 819bd25b..4bfe3d35 100644 --- a/bits/indirect-return.h +++ b/bits/indirect-return.h @@ -21,5 +21,16 @@ #endif /* __INDIRECT_RETURN is used on swapcontext to indicate if it requires - special compiler treatment. */ -#define __INDIRECT_RETURN + special compiler treatment. swapcontext does not restore every + callee-saved register on all targets -- on sparc the %l and %i + registers are not in the saved context at all -- so where + indirect_return is unavailable, returns_twice stops the compiler + assuming such a value survives the call. Targets that need this only + under an optional feature override this file. */ +#if __glibc_has_attribute (__indirect_return__) +# define __INDIRECT_RETURN __attribute__ ((__indirect_return__)) +#elif __glibc_has_attribute (__returns_twice__) +# define __INDIRECT_RETURN __attribute__ ((__returns_twice__)) +#else +# define __INDIRECT_RETURN +#endif diff --git a/string/tst-xbzero-opt.c b/string/tst-xbzero-opt.c index 3aa13d03..26e2ec1c 100644 --- a/string/tst-xbzero-opt.c +++ b/string/tst-xbzero-opt.c @@ -111,10 +111,9 @@ use_test_buffer (unsigned char *buf) /* Always check the test buffer immediately after filling it; this makes externally visible side effects depend on the buffer existing and having been filled in. */ -#if defined __CET__ && !__glibc_has_attribute (__indirect_return__) -/* Note: swapcontext returns via indirect branch when SHSTK is enabled. - Without indirect_return attribute, swapcontext is marked with - returns_twice attribute, which prevents always_inline to work. */ +#if !__glibc_has_attribute (__indirect_return__) +/* Without indirect_return, swapcontext is marked returns_twice, which + prevents always_inline from working. */ # define ALWAYS_INLINE #else # define ALWAYS_INLINE __attribute__ ((always_inline))