From patchwork Thu Dec 14 19:37:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 1876374 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=IZOJfNjP; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4SrjKw0mHsz23nF for ; Fri, 15 Dec 2023 06:37:24 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2792F3864873 for ; Thu, 14 Dec 2023 19:37:22 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by sourceware.org (Postfix) with ESMTPS id 995C9385E02E for ; Thu, 14 Dec 2023 19:37:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 995C9385E02E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 995C9385E02E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::1035 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1702582629; cv=none; b=gRknSzkQmriB6/tX6Lnjfh+MSn8FRirIFcL6+sj4jJFj+kSi/2PdSgT8Rny2cl0nL3eqLKRy670PXaTINRlCIHYMdkM72vD4cRfOmIcaDaI2zPwhfCurwXZE9E1HhBj3rnBQ6WFB2xJGX321S/kagdqrXGLTl4wn4jkETDFTj/c= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1702582629; c=relaxed/simple; bh=q1M4bP2l1eKrGFLS7c7c0cAa+KxFBSC7iJ+uWdGRI2w=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=wdvhfUtSxA7YNTDmy9gu0mcl9LeoDQZ12jt+AibnLRaWWuACxhsmPRqh8LJr/k4LmxA+a/QqgCEecH9XXgZvqbWkssRUFuKiU5iycdzuSgyXGfoiJ0S5UWRKnDjvgh8Y9SlYdJATS5FiBuXK6ECfFpBsgHAD3CBDGCiblD8J0l8= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-28b02567a05so1038810a91.1 for ; Thu, 14 Dec 2023 11:37:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702582625; x=1703187425; darn=sourceware.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=grtv73JHd2As3l/onMvcw8iaFWeRG8EyDZ2VSL9UqVA=; b=IZOJfNjPUnLEUXtYItwvDKd9hDQmPwWpQ8x2SwU3rJn7NtsSEk4Fbp2JQ/jBLPxVrC 3BLv/hwHLnKEviYB+Epcb8jV+W594YBKtk7I0qaQGvNumAwABdx7DQI3sIfMRwJBRvbU r0XEirxDRrAQvE3yRen3ZGZCsV+NFeofqROzf03ZErf//kTRIaasiswazu/0x9rB12TQ mMun4D1juf+EqgHPhav/MXcV57W0BL/as80FyZO+FsPtU5S02331w5yWShAgthiA0NvO y/HQzvl8GJvLIKzRi0zKkJKIIcJR+yyze+Twat9wVwoRlf5raxWWeSpFdfTMQ/BKcnYx 7oFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702582625; x=1703187425; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=grtv73JHd2As3l/onMvcw8iaFWeRG8EyDZ2VSL9UqVA=; b=MDYe7GFKcswviS5jWV/sC1v6y+HRJVnihU9Zt07Ae3oS+eA63fkXsbZ1kA671+33PE 7BDk88aYl9X+jLUONJnoWGYCLy6h6cp6LRECvafjMEPvERJbY1bfT3ooe83q+v3Pwta7 +AZq9KFZzGMTG2tQchanO+ZXqyvzkR0pDgcJWx/6v1CWOsI+lGuAKMN1bdq9pShk7UWr +5muQP5mcgTC0WyYT6itfOF0zZeSb2oGo9nGfuUsISHzAx7faLkXbXEfs5aqxomghI87 ItXP8o63akq9KYM3jfBq6ZPbasxIR4JImrVQpQSKEdnk+wTr5rfU07z4QHxg3LR6iM8p FjUw== X-Gm-Message-State: AOJu0Ywq24hNl+BPQz5fl9MsoEtcjriiNoZU0P+/D5FvpkfbQDi+3+Cw B8kN0ZnShyhcizGgCcWXfG2OR/rdxbo= X-Google-Smtp-Source: AGHT+IF7KAwMeJ39stmhu/9FItMp+GpcL7B5cFJTABp5+efeSeZpngNeqyMyHtmsC5bRJhNOFkBZxw== X-Received: by 2002:a17:90a:1f45:b0:286:dd95:143a with SMTP id y5-20020a17090a1f4500b00286dd95143amr4500859pjy.98.1702582625249; Thu, 14 Dec 2023 11:37:05 -0800 (PST) Received: from gnu-cfl-3.localdomain ([172.59.129.147]) by smtp.gmail.com with ESMTPSA id li5-20020a17090b48c500b0028b2262e0cdsm332645pjb.56.2023.12.14.11.37.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Dec 2023 11:37:04 -0800 (PST) Received: from gnu-cfl-3.. (localhost [IPv6:::1]) by gnu-cfl-3.localdomain (Postfix) with ESMTP id 748CC7403B0 for ; Thu, 14 Dec 2023 11:37:03 -0800 (PST) From: "H.J. Lu" To: libc-alpha@sourceware.org Subject: [PATCH 2/2] Add a test for setjmp/longjmp within user context Date: Thu, 14 Dec 2023 11:37:03 -0800 Message-ID: <20231214193703.238374-3-hjl.tools@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231214193703.238374-1-hjl.tools@gmail.com> References: <20231214193703.238374-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3024.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, 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: 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+incoming=patchwork.ozlabs.org@sourceware.org Verify that setjmp/longjmp works correctly within a user context. Reviewed-by: Noah Goldstein --- stdlib/Makefile | 1 + stdlib/tst-setcontext11.c | 178 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 stdlib/tst-setcontext11.c diff --git a/stdlib/Makefile b/stdlib/Makefile index 8c6249aab4..0b5ef699a2 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -235,6 +235,7 @@ tests := \ tst-setcontext8 \ tst-setcontext9 \ tst-setcontext10 \ + tst-setcontext11 \ tst-strfmon_l \ tst-strfrom \ tst-strfrom-locale \ diff --git a/stdlib/tst-setcontext11.c b/stdlib/tst-setcontext11.c new file mode 100644 index 0000000000..5f5df5b81b --- /dev/null +++ b/stdlib/tst-setcontext11.c @@ -0,0 +1,178 @@ +/* Check setjmp/longjmp within user context. + Copyright (C) 2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include +#include + +static ucontext_t ctx[3]; +static jmp_buf jmpbuf; + +static int was_in_f1; +static int was_in_f2; +static int longjmp_called; + +static char st2[32768]; + +static void +f1 (int a0, int a1, int a2, int a3) +{ + printf ("start f1(a0=%x,a1=%x,a2=%x,a3=%x)\n", a0, a1, a2, a3); + + if (a0 != 1 || a1 != 2 || a2 != 3 || a3 != -4) + { + puts ("arg mismatch"); + exit (EXIT_FAILURE); + } + + if (swapcontext (&ctx[1], &ctx[2]) != 0) + { + printf ("%s: swapcontext: %m\n", __FUNCTION__); + exit (EXIT_FAILURE); + } + puts ("finish f1"); + was_in_f1 = 1; +} + +static void +__attribute__ ((noinline, noclone)) +call_longjmp (void) +{ + longjmp_called = 1; + longjmp (jmpbuf, 1); +} + +static void +f2 (void) +{ + if (!longjmp_called) + { + if (setjmp (jmpbuf) == 0) + call_longjmp (); + } + + puts ("start f2"); + if (swapcontext (&ctx[2], &ctx[1]) != 0) + { + printf ("%s: swapcontext: %m\n", __FUNCTION__); + exit (EXIT_FAILURE); + } + puts ("finish f2"); + was_in_f2 = 1; +} + +volatile int global; +static int back_in_main; + +static void +check_called (void) +{ + if (back_in_main == 0) + { + puts ("program did not reach main again"); + _exit (EXIT_FAILURE); + } +} + +static int +do_test (void) +{ + atexit (check_called); + + char st1[32768]; + + puts ("making contexts"); + if (getcontext (&ctx[1]) != 0) + { + if (errno == ENOSYS) + { + back_in_main = 1; + exit (EXIT_SUCCESS); + } + + printf ("%s: getcontext: %m\n", __FUNCTION__); + exit (EXIT_FAILURE); + } + + /* Play some tricks with this context. */ + if (++global == 1) + if (setcontext (&ctx[1]) != 0) + { + printf ("%s: setcontext: %m\n", __FUNCTION__); + exit (EXIT_FAILURE); + } + if (global != 2) + { + printf ("%s: 'global' not incremented twice\n", __FUNCTION__); + exit (EXIT_FAILURE); + } + + ctx[1].uc_stack.ss_sp = st1; + ctx[1].uc_stack.ss_size = sizeof st1; + ctx[1].uc_link = &ctx[0]; + { + ucontext_t tempctx = ctx[1]; + makecontext (&ctx[1], (void (*) (void)) f1, 4, 1, 2, 3, -4); + + /* Without this check, a stub makecontext can make us spin forever. */ + if (memcmp (&tempctx, &ctx[1], sizeof ctx[1]) == 0) + { + puts ("makecontext was a no-op, presuming not implemented"); + return 0; + } + } + + if (getcontext (&ctx[2]) != 0) + { + printf ("%s: second getcontext: %m\n", __FUNCTION__); + exit (EXIT_FAILURE); + } + ctx[2].uc_stack.ss_sp = st2; + ctx[2].uc_stack.ss_size = sizeof st2; + ctx[2].uc_link = &ctx[1]; + makecontext (&ctx[2], f2, 0); + + puts ("swapping contexts"); + if (swapcontext (&ctx[0], &ctx[2]) != 0) + { + printf ("%s: swapcontext: %m\n", __FUNCTION__); + exit (EXIT_FAILURE); + } + puts ("back at main program"); + back_in_main = 1; + + if (was_in_f1 == 0) + { + puts ("didn't reach f1"); + exit (EXIT_FAILURE); + } + if (was_in_f2 == 0) + { + puts ("didn't reach f2"); + exit (EXIT_FAILURE); + } + + puts ("test succeeded"); + return 0; +} + +#include