test-sig-xstate.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /* Test the state save/restore procedures during signal handling.
  2. Copyright (C) 2025-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #include <assert.h>
  16. #include <pthread.h>
  17. #include <signal.h>
  18. #include <stdbool.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <unistd.h>
  23. #include <stdatomic.h>
  24. #include <mach/message.h>
  25. #include <mach/gnumach.h>
  26. #include <mach/mach_traps.h>
  27. #include <mach-shortcuts.h>
  28. #include <mach_init.h>
  29. #include <hurd/io.h>
  30. #include <hurd/io_reply.h>
  31. #include <support/check.h>
  32. #include <support/xthread.h>
  33. #include "test-xstate.h"
  34. static volatile atomic_bool startflag = ATOMIC_VAR_INIT (false);
  35. static volatile atomic_bool loopflag = ATOMIC_VAR_INIT (true);
  36. void handler (int signum, siginfo_t *info, void *context)
  37. {
  38. char mmxbuf3[MMXSTATE_BUFFER_SIZE];
  39. char xbuf3[XSTATE_BUFFER_SIZE];
  40. memset (mmxbuf3, 0x77, MMXSTATE_BUFFER_SIZE);
  41. memset (xbuf3, 0x77, XSTATE_BUFFER_SIZE);
  42. SET_MMXSTATE (mmxbuf3);
  43. SET_XSTATE (xbuf3);
  44. printf ("signal %d setting a different CPU state\n", signum);
  45. atomic_store_explicit (&loopflag, false, memory_order_release);
  46. }
  47. /* Helper thread to send a signal to the main thread */
  48. void* signal_sender (void *arg)
  49. {
  50. sigset_t ss;
  51. assert (! sigemptyset (&ss));
  52. assert (! sigaddset (&ss, SIGUSR1));
  53. assert (! sigprocmask (SIG_BLOCK, &ss, NULL));
  54. while (!atomic_load_explicit (&startflag, memory_order_acquire))
  55. ;
  56. TEST_COMPARE (kill (getpid (), SIGUSR1), 0);
  57. return NULL;
  58. }
  59. static int do_test (void)
  60. {
  61. #if ! XSTATE_HELPERS_SUPPORTED
  62. FAIL_UNSUPPORTED ("Test not supported on this arch.");
  63. #endif
  64. struct sigaction act = { 0 };
  65. act.sa_sigaction = &handler;
  66. TEST_COMPARE (sigaction (SIGUSR1, &act, NULL), 0);
  67. pthread_t thsender = xpthread_create (NULL, signal_sender, NULL);
  68. char mmxbuf1[MMXSTATE_BUFFER_SIZE], mmxbuf2[MMXSTATE_BUFFER_SIZE];
  69. char xbuf1[XSTATE_BUFFER_SIZE], xbuf2[XSTATE_BUFFER_SIZE];
  70. memset (mmxbuf1, 0x33, MMXSTATE_BUFFER_SIZE);
  71. memset (xbuf1, 0x33, XSTATE_BUFFER_SIZE);
  72. SET_MMXSTATE (mmxbuf1);
  73. SET_XSTATE (xbuf1);
  74. atomic_store_explicit (&startflag, true, memory_order_release);
  75. while (atomic_load_explicit (&loopflag, memory_order_acquire))
  76. ;
  77. GET_MMXSTATE (mmxbuf2);
  78. GET_XSTATE (xbuf2);
  79. TEST_COMPARE_BLOB (mmxbuf1, sizeof (mmxbuf1), mmxbuf2, sizeof (mmxbuf2));
  80. TEST_COMPARE_BLOB (xbuf1, sizeof (xbuf1), xbuf2, sizeof (xbuf2));
  81. xpthread_join (thsender);
  82. return EXIT_SUCCESS;
  83. }
  84. #include <support/test-driver.c>