unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/5] Add more tests for user context functions
@ 2018-07-18 17:53 H.J. Lu
  2018-07-18 17:53 ` [PATCH 1/5] Add a test for swapcontext with a wrapper H.J. Lu
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: H.J. Lu @ 2018-07-18 17:53 UTC (permalink / raw
  To: libc-alpha

When the shadow stack (SHSTK) is enabled, makecontext needs to allocate
a new shadow stack to go with the new stack allocated by the caller.
setcontext and swapcontext must properly handle the corresponding shadow
stack when the stack is switched.  Add more tests for user context
functions to provide more coverage for the shadow stack support.

OK for master branch?

H.J. Lu (5):
  Add a test for swapcontext with a wrapper
  Add a test for multiple makecontext calls
  Add another test for setcontext
  Add a test for multiple setcontext calls
  Add tests for setcontext on the context from makecontext

 stdlib/Makefile           |   5 +-
 stdlib/tst-setcontext4.c  | 217 ++++++++++++++++++++++++++++++++++++++
 stdlib/tst-setcontext5.c  |  88 ++++++++++++++++
 stdlib/tst-setcontext6.c  |  76 +++++++++++++
 stdlib/tst-setcontext7.c  |  96 +++++++++++++++++
 stdlib/tst-setcontext8.c  |  81 ++++++++++++++
 stdlib/tst-setcontext9.c  | 100 ++++++++++++++++++
 stdlib/tst-swapcontext1.c |  91 ++++++++++++++++
 stdlib/tst-swapcontext2.c | 108 +++++++++++++++++++
 9 files changed, 861 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/tst-setcontext4.c
 create mode 100644 stdlib/tst-setcontext5.c
 create mode 100644 stdlib/tst-setcontext6.c
 create mode 100644 stdlib/tst-setcontext7.c
 create mode 100644 stdlib/tst-setcontext8.c
 create mode 100644 stdlib/tst-setcontext9.c
 create mode 100644 stdlib/tst-swapcontext1.c
 create mode 100644 stdlib/tst-swapcontext2.c

-- 
2.17.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/5] Add a test for swapcontext with a wrapper
  2018-07-18 17:53 [PATCH 0/5] Add more tests for user context functions H.J. Lu
@ 2018-07-18 17:53 ` H.J. Lu
  2018-07-18 17:53 ` [PATCH 2/5] Add a test for multiple makecontext calls H.J. Lu
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: H.J. Lu @ 2018-07-18 17:53 UTC (permalink / raw
  To: libc-alpha

Check swapcontext works with a wrapper.

	* stdlib/Makefile (tests): Add tst-swapcontext1.
	* stdlib/tst-swapcontext1.c: New test.
---
 stdlib/Makefile           |  3 +-
 stdlib/tst-swapcontext1.c | 91 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/tst-swapcontext1.c

diff --git a/stdlib/Makefile b/stdlib/Makefile
index 808a8ceab7..ef90f77689 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -84,7 +84,8 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   tst-cxa_atexit tst-on_exit test-atexit-race 		    \
 		   test-at_quick_exit-race test-cxa_atexit-race             \
 		   test-on_exit-race test-dlclose-exit-race 		    \
-		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign
+		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
+		   tst-swapcontext1
 
 tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
 		   tst-tls-atexit tst-tls-atexit-nodelete
diff --git a/stdlib/tst-swapcontext1.c b/stdlib/tst-swapcontext1.c
new file mode 100644
index 0000000000..2ffbecd4a2
--- /dev/null
+++ b/stdlib/tst-swapcontext1.c
@@ -0,0 +1,91 @@
+/* Check swapcontext wrapper.
+   Modified from c-c++-common/asan/swapcontext-test-1.c in GCC testsuite.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+__attribute__((noinline, noclone))
+int
+myswapcontext (ucontext_t *oucp, ucontext_t *ucp)
+{
+  int res = swapcontext (oucp, ucp);
+  return res;
+}
+
+ucontext_t orig_context;
+ucontext_t child_context;
+
+void
+Child (int mode)
+{
+  char x[32] = {0};  /* Stack gets poisoned. */
+  printf("Child: %p\n", x);
+  /* (a) Do nothing, just return to parent function.
+     (b) Jump into the original function. Stack remains poisoned unless we do
+     something. */
+  if (mode == 1)
+    {
+      if (myswapcontext (&child_context, &orig_context) < 0)
+	{
+	  perror ("swapcontext");
+	  _exit (0);
+	}
+    }
+}
+
+int
+Run (int arg, int mode)
+{
+  int i;
+  const int kStackSize = 1 << 20;
+  char child_stack[kStackSize + 1];
+  printf ("Child stack: %p\n", child_stack);
+  /* Setup child context. */
+  getcontext (&child_context);
+  child_context.uc_stack.ss_sp = child_stack;
+  child_context.uc_stack.ss_size = kStackSize / 2;
+  if (mode == 0)
+    child_context.uc_link = &orig_context;
+  makecontext (&child_context, (void (*)(void))Child, 1, mode);
+  if (myswapcontext (&orig_context, &child_context) < 0)
+    {
+      perror("swapcontext");
+      return 0;
+    }
+  /* Touch childs's stack to make sure it's unpoisoned. */
+  for (i = 0; i < kStackSize; i++)
+    child_stack[i] = i;
+  return child_stack[arg];
+}
+
+volatile int zero = 0;
+
+static int
+do_test (void)
+{
+  int ret = 0;
+  ret += Run (zero, 0);
+  fprintf (stderr, "Test1 passed\n");
+  ret += Run (zero, 1);
+  fprintf (stderr, "Test2 passed\n");
+  return ret;
+}
+
+#include <support/test-driver.c>
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/5] Add a test for multiple makecontext calls
  2018-07-18 17:53 [PATCH 0/5] Add more tests for user context functions H.J. Lu
  2018-07-18 17:53 ` [PATCH 1/5] Add a test for swapcontext with a wrapper H.J. Lu
@ 2018-07-18 17:53 ` H.J. Lu
  2018-07-18 17:53 ` [PATCH 3/5] Add another test for setcontext H.J. Lu
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: H.J. Lu @ 2018-07-18 17:53 UTC (permalink / raw
  To: libc-alpha

Check multiple makecontext calls.

	* stdlib/Makefile (tests): Add tst-swapcontext2.
	* stdlib/tst-swapcontext2.c: New test.
---
 stdlib/Makefile           |   2 +-
 stdlib/tst-swapcontext2.c | 108 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 109 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/tst-swapcontext2.c

diff --git a/stdlib/Makefile b/stdlib/Makefile
index ef90f77689..ffd9180471 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -85,7 +85,7 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   test-at_quick_exit-race test-cxa_atexit-race             \
 		   test-on_exit-race test-dlclose-exit-race 		    \
 		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
-		   tst-swapcontext1
+		   tst-swapcontext1 tst-swapcontext2
 
 tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
 		   tst-tls-atexit tst-tls-atexit-nodelete
diff --git a/stdlib/tst-swapcontext2.c b/stdlib/tst-swapcontext2.c
new file mode 100644
index 0000000000..7802df4868
--- /dev/null
+++ b/stdlib/tst-swapcontext2.c
@@ -0,0 +1,108 @@
+/* Check multiple makecontext calls.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+
+static ucontext_t uctx_main, uctx_func1, uctx_func2;
+const char *str1 = "\e[31mswapcontext(&uctx_func1, &uctx_main)\e[0m";
+const char *str2 = "\e[34mswapcontext(&uctx_func2, &uctx_main)\e[0m";
+const char *fmt1 = "\e[31m";
+const char *fmt2 = "\e[34m";
+
+#define handle_error(msg) \
+  do { perror(msg); exit(EXIT_FAILURE); } while (0)
+
+__attribute__((noinline, noclone))
+static void
+func4(ucontext_t *uocp, ucontext_t *ucp, const char *str, const char *fmt)
+{
+  printf("      %sfunc4: %s\e[0m\n", fmt, str);
+  if (swapcontext(uocp, ucp) == -1)
+    handle_error("swapcontext");
+  printf("      %sfunc4: returning\e[0m\n", fmt);
+}
+
+__attribute__((noinline, noclone))
+static void
+func3(ucontext_t *uocp, ucontext_t *ucp, const char *str, const char *fmt)
+{
+  printf("    %sfunc3: func4(uocp, ucp, str)\e[0m\n", fmt);
+  func4(uocp, ucp, str, fmt);
+  printf("    %sfunc3: returning\e[0m\n", fmt);
+}
+
+__attribute__((noinline, noclone))
+static void
+func1(void)
+{
+  while ( 1 )
+    {
+      printf("  \e[31mfunc1: func3(&uctx_func1, &uctx_main, str1)\e[0m\n");
+      func3( &uctx_func1, &uctx_main, str1, fmt1);
+    }
+}
+
+__attribute__((noinline, noclone))
+static void
+func2(void)
+{
+  while ( 1 )
+    {
+      printf("  \e[34mfunc2: func3(&uctx_func2, &uctx_main, str2)\e[0m\n");
+      func3(&uctx_func2, &uctx_main, str2, fmt2);
+    }
+}
+
+static int
+do_test (void)
+{
+  char func1_stack[16384];
+  char func2_stack[16384];
+  int i;
+
+  if (getcontext(&uctx_func1) == -1)
+    handle_error("getcontext");
+  uctx_func1.uc_stack.ss_sp = func1_stack;
+  uctx_func1.uc_stack.ss_size = sizeof(func1_stack);
+  uctx_func1.uc_link = &uctx_main;
+  makecontext(&uctx_func1, func1, 0);
+
+  if (getcontext(&uctx_func2) == -1)
+    handle_error("getcontext");
+  uctx_func2.uc_stack.ss_sp = func2_stack;
+  uctx_func2.uc_stack.ss_size = sizeof(func2_stack);
+  uctx_func2.uc_link = &uctx_func1;
+  makecontext(&uctx_func2, func2, 0);
+
+  for ( i = 0; i < 4; i++ )
+    {
+      if (swapcontext(&uctx_main, &uctx_func1) == -1)
+	handle_error("swapcontext");
+      printf("        \e[35mmain: swapcontext(&uctx_main, &uctx_func2)\n\e[0m");
+      if (swapcontext(&uctx_main, &uctx_func2) == -1)
+	handle_error("swapcontext");
+      printf("        \e[35mmain: swapcontext(&uctx_main, &uctx_func1)\n\e[0m");
+    }
+
+  printf("main: exiting\n");
+  exit(EXIT_SUCCESS);
+}
+
+#include <support/test-driver.c>
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/5] Add another test for setcontext
  2018-07-18 17:53 [PATCH 0/5] Add more tests for user context functions H.J. Lu
  2018-07-18 17:53 ` [PATCH 1/5] Add a test for swapcontext with a wrapper H.J. Lu
  2018-07-18 17:53 ` [PATCH 2/5] Add a test for multiple makecontext calls H.J. Lu
@ 2018-07-18 17:53 ` H.J. Lu
  2018-07-18 17:53 ` [PATCH 4/5] Add a test for multiple setcontext calls H.J. Lu
  2018-07-18 17:53 ` [PATCH 5/5] Add tests for setcontext on the context from makecontext H.J. Lu
  4 siblings, 0 replies; 6+ messages in thread
From: H.J. Lu @ 2018-07-18 17:53 UTC (permalink / raw
  To: libc-alpha

	* stdlib/Makefile (tests): Add tst-setcontext4.
	* stdlib/tst-setcontext4.c: New file.
---
 stdlib/Makefile          |   2 +-
 stdlib/tst-setcontext4.c | 217 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 218 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/tst-setcontext4.c

diff --git a/stdlib/Makefile b/stdlib/Makefile
index ffd9180471..75021e6897 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -85,7 +85,7 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   test-at_quick_exit-race test-cxa_atexit-race             \
 		   test-on_exit-race test-dlclose-exit-race 		    \
 		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
-		   tst-swapcontext1 tst-swapcontext2
+		   tst-swapcontext1 tst-swapcontext2 tst-setcontext4
 
 tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
 		   tst-tls-atexit tst-tls-atexit-nodelete
diff --git a/stdlib/tst-setcontext4.c b/stdlib/tst-setcontext4.c
new file mode 100644
index 0000000000..64d3fc9137
--- /dev/null
+++ b/stdlib/tst-setcontext4.c
@@ -0,0 +1,217 @@
+/* Testcase checks, if setcontext(), swapcontext() restores signal-mask
+   and if pending signals are delivered after those calls.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+volatile int global;
+volatile sig_atomic_t handlerCalled;
+
+static void
+check (const char *funcName)
+{
+  sigset_t set;
+
+  /* check if SIGUSR2 is unblocked after setcontext-call.  */
+  sigprocmask (SIG_BLOCK, NULL, &set);
+
+  if (sigismember (&set, SIGUSR2) != 0)
+    {
+      printf ("FAIL: SIGUSR2 is blocked after %s.\n", funcName);
+      exit (1);
+    }
+
+  if (sigismember (&set, SIGUSR1) != 1)
+    {
+      printf ("FAIL: SIGUSR1 is not blocked after %s.\n", funcName);
+      exit (1);
+    }
+}
+
+static void
+signalmask (int how, int signum)
+{
+  sigset_t set;
+  sigemptyset (&set);
+  sigaddset (&set, signum);
+  if (sigprocmask (how, &set, NULL) != 0)
+    {
+      printf ("FAIL: sigprocmaks (%d, %d, NULL): %m\n", how, signum);
+      exit (1);
+    }
+}
+
+static void
+signalpending (int signum, const char *msg)
+{
+  sigset_t set;
+  sigemptyset (&set);
+  if (sigpending (&set) != 0)
+    {
+      printf ("FAIL: sigpending: %m\n");
+      exit (1);
+    }
+  if (sigismember (&set, SIGUSR2) != 1)
+    {
+      printf ("FAIL: Signal %d is not pending %s\n", signum, msg);
+      exit (1);
+    }
+}
+
+static void
+handler (int __attribute__ ((unused)) signum)
+{
+  handlerCalled ++;
+}
+
+static int
+do_test (void)
+{
+  ucontext_t ctx, oldctx;
+  struct sigaction action;
+  pid_t pid;
+
+  pid = getpid ();
+
+  /* unblock SIGUSR2 */
+  signalmask (SIG_UNBLOCK, SIGUSR2);
+
+  /* block SIGUSR1 */
+  signalmask (SIG_BLOCK, SIGUSR1);
+
+  /* register handler for SIGUSR2  */
+  action.sa_flags = 0;
+  action.sa_handler = handler;
+  sigemptyset (&action.sa_mask);
+  sigaction (SIGUSR2, &action, NULL);
+
+  if (getcontext (&ctx) != 0)
+    {
+      printf ("FAIL: getcontext: %m\n");
+      exit (1);
+    }
+
+  global++;
+
+  if (global == 1)
+    {
+      puts ("after getcontext");
+
+      /* block SIGUSR2  */
+      signalmask (SIG_BLOCK, SIGUSR2);
+
+      /* send SIGUSR2 to me  */
+      handlerCalled = 0;
+      kill (pid, SIGUSR2);
+
+      /* was SIGUSR2 handler called?  */
+      if (handlerCalled != 0)
+	{
+	  puts ("FAIL: signal handler was called, but signal was blocked.");
+	  exit (1);
+	}
+
+      /* is SIGUSR2 pending?  */
+      signalpending (SIGUSR2, "before setcontext");
+
+      /* SIGUSR2 will be unblocked by setcontext-call.  */
+      if (setcontext (&ctx) != 0)
+	{
+	  printf ("FAIL: setcontext: %m\n");
+	  exit (1);
+	}
+    }
+  else if (global == 2)
+    {
+      puts ("after setcontext");
+
+      /* check SIGUSR1/2  */
+      check ("setcontext");
+
+      /* was SIGUSR2 handler called? */
+      if (handlerCalled != 1)
+	{
+	  puts ("FAIL: signal handler was not called after setcontext.");
+	  exit (1);
+	}
+
+      /* block SIGUSR2 */
+      signalmask (SIG_BLOCK, SIGUSR2);
+
+      /* send SIGUSR2 to me  */
+      handlerCalled = 0;
+      kill (pid, SIGUSR2);
+
+      /* was SIGUSR2 handler called?  */
+      if (handlerCalled != 0)
+	{
+	  puts ("FAIL: signal handler was called, but signal was blocked.");
+	  exit (1);
+	}
+
+      /* is SIGUSR2 pending?  */
+      signalpending (SIGUSR2, "before swapcontext");
+
+      if (swapcontext (&oldctx, &ctx) != 0)
+	{
+	  printf ("FAIL: swapcontext: %m\n");
+	  exit (1);
+	}
+
+      puts ("FAIL: returned from (&oldctx, &ctx)");
+      exit (1);
+    }
+  else if ( global != 3 )
+    {
+      puts ("FAIL: 'global' not incremented three times");
+      exit (1);
+    }
+
+  puts ("after swapcontext");
+  /* check SIGUSR1/2  */
+  check ("swapcontext");
+
+  /* was SIGUSR2 handler called? */
+  if (handlerCalled != 1)
+    {
+      puts ("FAIL: signal handler was not called after swapcontext.");
+      exit (1);
+    }
+
+  /* check sigmask in old context of swapcontext-call  */
+  if (sigismember (&oldctx.uc_sigmask, SIGUSR2) != 1)
+    {
+      puts ("FAIL: SIGUSR2 is not blocked in oldctx.uc_sigmask.");
+      exit (1);
+    }
+
+  if (sigismember (&oldctx.uc_sigmask, SIGUSR1) != 1)
+    {
+      puts ("FAIL: SIGUSR1 is not blocked in oldctx.uc_sigmaks.");
+      exit (1);
+    }
+
+  return 0;
+}
+
+#include <support/test-driver.c>
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/5] Add a test for multiple setcontext calls
  2018-07-18 17:53 [PATCH 0/5] Add more tests for user context functions H.J. Lu
                   ` (2 preceding siblings ...)
  2018-07-18 17:53 ` [PATCH 3/5] Add another test for setcontext H.J. Lu
@ 2018-07-18 17:53 ` H.J. Lu
  2018-07-18 17:53 ` [PATCH 5/5] Add tests for setcontext on the context from makecontext H.J. Lu
  4 siblings, 0 replies; 6+ messages in thread
From: H.J. Lu @ 2018-07-18 17:53 UTC (permalink / raw
  To: libc-alpha

Check multiple setcontext calls.

	* stdlib/Makefile ((tests): Add tst-setcontext5.
	* stdlib/tst-setcontext5.c: New file.
---
 stdlib/Makefile          |  3 +-
 stdlib/tst-setcontext5.c | 88 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/tst-setcontext5.c

diff --git a/stdlib/Makefile b/stdlib/Makefile
index 75021e6897..5861f6f5e0 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -85,7 +85,8 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   test-at_quick_exit-race test-cxa_atexit-race             \
 		   test-on_exit-race test-dlclose-exit-race 		    \
 		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
-		   tst-swapcontext1 tst-swapcontext2 tst-setcontext4
+		   tst-swapcontext1 tst-swapcontext2 tst-setcontext4 \
+		   tst-setcontext5
 
 tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
 		   tst-tls-atexit tst-tls-atexit-nodelete
diff --git a/stdlib/tst-setcontext5.c b/stdlib/tst-setcontext5.c
new file mode 100644
index 0000000000..7dcc15cb8e
--- /dev/null
+++ b/stdlib/tst-setcontext5.c
@@ -0,0 +1,88 @@
+/* Check multiple setcontext calls.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+static ucontext_t ctx[2];
+static volatile int done;
+
+static void f2 (void);
+
+static void
+__attribute__ ((noinline, noclone))
+f1 (void)
+{
+  printf ("start f1\n");
+  f2 ();
+}
+
+static void
+__attribute__ ((noinline, noclone))
+f2 (void)
+{
+  printf ("start f2\n");
+  if (setcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+}
+
+static void
+f3 (void)
+{
+  printf ("start f3\n");
+  if (done)
+    exit (EXIT_SUCCESS);
+  done = 1;
+  if (setcontext (&ctx[0]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+}
+
+static int
+do_test (void)
+{
+  char st1[32768];
+
+  puts ("making contexts");
+  if (getcontext (&ctx[0]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (getcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: getcontext: %m\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];
+  makecontext (&ctx[1], (void (*) (void)) f3, 0);
+  f1 ();
+  puts ("FAIL: returned from f1 ()");
+  exit (EXIT_FAILURE);
+}
+
+#include <support/test-driver.c>
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 5/5] Add tests for setcontext on the context from makecontext
  2018-07-18 17:53 [PATCH 0/5] Add more tests for user context functions H.J. Lu
                   ` (3 preceding siblings ...)
  2018-07-18 17:53 ` [PATCH 4/5] Add a test for multiple setcontext calls H.J. Lu
@ 2018-07-18 17:53 ` H.J. Lu
  4 siblings, 0 replies; 6+ messages in thread
From: H.J. Lu @ 2018-07-18 17:53 UTC (permalink / raw
  To: libc-alpha

	* stdlib/Makefile ((tests): Add tst-setcontext6, tst-setcontext7,
	tst-setcontext8 and tst-setcontext9.
	* stdlib/tst-setcontext6.c: New file.
	* stdlib/tst-setcontext7.c: Likewise.
	* stdlib/tst-setcontext8.c: Likewise.
	* stdlib/tst-setcontext9.c: Likewise.
---
 stdlib/Makefile          |   3 +-
 stdlib/tst-setcontext6.c |  76 +++++++++++++++++++++++++++++
 stdlib/tst-setcontext7.c |  96 +++++++++++++++++++++++++++++++++++++
 stdlib/tst-setcontext8.c |  81 +++++++++++++++++++++++++++++++
 stdlib/tst-setcontext9.c | 100 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 355 insertions(+), 1 deletion(-)
 create mode 100644 stdlib/tst-setcontext6.c
 create mode 100644 stdlib/tst-setcontext7.c
 create mode 100644 stdlib/tst-setcontext8.c
 create mode 100644 stdlib/tst-setcontext9.c

diff --git a/stdlib/Makefile b/stdlib/Makefile
index 5861f6f5e0..6c6f8237ed 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -86,7 +86,8 @@ tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv   \
 		   test-on_exit-race test-dlclose-exit-race 		    \
 		   tst-makecontext-align test-bz22786 tst-strtod-nan-sign \
 		   tst-swapcontext1 tst-swapcontext2 tst-setcontext4 \
-		   tst-setcontext5
+		   tst-setcontext5 tst-setcontext6 tst-setcontext7 \
+		   tst-setcontext8 tst-setcontext9
 
 tests-internal	:= tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
 		   tst-tls-atexit tst-tls-atexit-nodelete
diff --git a/stdlib/tst-setcontext6.c b/stdlib/tst-setcontext6.c
new file mode 100644
index 0000000000..c719e2d678
--- /dev/null
+++ b/stdlib/tst-setcontext6.c
@@ -0,0 +1,76 @@
+/* Check getcontext and setcontext on the context from makecontext.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+static ucontext_t ctx[3];
+static volatile int done;
+
+static void
+f1 (void)
+{
+  printf ("start f1\n");
+  if (!done)
+    {
+      if (getcontext (&ctx[2]) != 0)
+	{
+	  printf ("%s: getcontext: %m\n", __FUNCTION__);
+	  exit (EXIT_FAILURE);
+	}
+      if (done)
+	exit (EXIT_SUCCESS);
+    }
+  done++;
+  if (setcontext (&ctx[2]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+}
+
+static int
+do_test (void)
+{
+  char st1[32768];
+  puts ("making contexts");
+  if (getcontext (&ctx[0]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (getcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: getcontext: %m\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];
+  makecontext (&ctx[1], (void (*) (void)) f1, 0);
+  if (setcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  exit (EXIT_FAILURE);
+}
+
+#include <support/test-driver.c>
diff --git a/stdlib/tst-setcontext7.c b/stdlib/tst-setcontext7.c
new file mode 100644
index 0000000000..e331e511ef
--- /dev/null
+++ b/stdlib/tst-setcontext7.c
@@ -0,0 +1,96 @@
+/* Check setcontext on the context from makecontext.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+static ucontext_t ctx[5];
+static volatile int done;
+
+static void
+f1 (void)
+{
+  puts ("start f1");
+  if (!done)
+    {
+      if (getcontext (&ctx[2]) != 0)
+	{
+	  printf ("%s: getcontext: %m\n", __FUNCTION__);
+	  exit (EXIT_FAILURE);
+	}
+      if (done)
+	{
+	  puts ("set context in f1");
+	  if (setcontext (&ctx[3]) != 0)
+	    {
+	      printf ("%s: setcontext: %m\n", __FUNCTION__);
+	      exit (EXIT_FAILURE);
+	    }
+	}
+    }
+  done++;
+  puts ("swap contexts in f1");
+  if (swapcontext (&ctx[4], &ctx[2]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  puts ("end f1");
+  exit (done == 2 ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+static int
+do_test (void)
+{
+  char st1[32768];
+  puts ("making contexts");
+  if (getcontext (&ctx[0]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (getcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: getcontext: %m\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];
+  makecontext (&ctx[1], (void (*) (void)) f1, 0);
+  puts ("swap contexts");
+  if (swapcontext (&ctx[3], &ctx[1]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (done != 1)
+    exit (EXIT_FAILURE);
+  done++;
+  puts ("set context");
+  if (setcontext (&ctx[4]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  exit (EXIT_FAILURE);
+}
+
+#include <support/test-driver.c>
diff --git a/stdlib/tst-setcontext8.c b/stdlib/tst-setcontext8.c
new file mode 100644
index 0000000000..a7febf6c67
--- /dev/null
+++ b/stdlib/tst-setcontext8.c
@@ -0,0 +1,81 @@
+/* Check getcontext and setcontext on the context from makecontext.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+static ucontext_t ctx[3];
+static volatile int done;
+
+static void
+__attribute__((noinline, noclone))
+f2 (void)
+{
+  printf ("start f2\n");
+  done++;
+  if (setcontext (&ctx[2]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+}
+
+static void
+f1 (void)
+{
+  printf ("start f1\n");
+  if (getcontext (&ctx[2]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (done)
+    exit (EXIT_SUCCESS);
+  f2 ();
+}
+
+static int
+do_test (void)
+{
+  char st1[32768];
+  puts ("making contexts");
+  if (getcontext (&ctx[0]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (getcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: getcontext: %m\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];
+  makecontext (&ctx[1], (void (*) (void)) f1, 0);
+  if (setcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  exit (EXIT_FAILURE);
+}
+
+#include <support/test-driver.c>
diff --git a/stdlib/tst-setcontext9.c b/stdlib/tst-setcontext9.c
new file mode 100644
index 0000000000..53609d4b10
--- /dev/null
+++ b/stdlib/tst-setcontext9.c
@@ -0,0 +1,100 @@
+/* Check setcontext on the context from makecontext.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+static ucontext_t ctx[5];
+static volatile int done;
+
+static void
+__attribute__((noinline, noclone))
+f2 (void)
+{
+  done++;
+  puts ("swap contexts in f2");
+  if (swapcontext (&ctx[4], &ctx[2]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  puts ("end f2");
+  exit (done == 2 ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+static void
+f1 (void)
+{
+  puts ("start f1");
+  if (getcontext (&ctx[2]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (done)
+    {
+      puts ("set context in f1");
+      if (setcontext (&ctx[3]) != 0)
+	{
+	  printf ("%s: setcontext: %m\n", __FUNCTION__);
+	  exit (EXIT_FAILURE);
+	}
+    }
+  f2 ();
+}
+
+static int
+do_test (void)
+{
+  char st1[32768];
+  puts ("making contexts");
+  if (getcontext (&ctx[0]) != 0)
+    {
+      printf ("%s: getcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (getcontext (&ctx[1]) != 0)
+    {
+      printf ("%s: getcontext: %m\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];
+  makecontext (&ctx[1], (void (*) (void)) f1, 0);
+  puts ("swap contexts");
+  if (swapcontext (&ctx[3], &ctx[1]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  if (done != 1)
+    exit (EXIT_FAILURE);
+  done++;
+  puts ("set context");
+  if (setcontext (&ctx[4]) != 0)
+    {
+      printf ("%s: setcontext: %m\n", __FUNCTION__);
+      exit (EXIT_FAILURE);
+    }
+  exit (EXIT_FAILURE);
+}
+
+#include <support/test-driver.c>
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-07-18 17:54 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-07-18 17:53 [PATCH 0/5] Add more tests for user context functions H.J. Lu
2018-07-18 17:53 ` [PATCH 1/5] Add a test for swapcontext with a wrapper H.J. Lu
2018-07-18 17:53 ` [PATCH 2/5] Add a test for multiple makecontext calls H.J. Lu
2018-07-18 17:53 ` [PATCH 3/5] Add another test for setcontext H.J. Lu
2018-07-18 17:53 ` [PATCH 4/5] Add a test for multiple setcontext calls H.J. Lu
2018-07-18 17:53 ` [PATCH 5/5] Add tests for setcontext on the context from makecontext H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).