/* Test that pthread_exit does not clobber callee-saved registers.
   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 <support/check.h>
#include <support/xthread.h>

/* This test attempts to check that callee-saved registers are
   restored to their original values when destructors are run after
   pthread_exit is called.  GCC PR 83641 causes this test to fail.

   The constants have been chosen randomly and are magic values which
   are used to detect whether registers have been clobbered.  The idea
   is that these values are hidden behind a compiler barrier and only
   present in .rodata initially, so that it is less likely that they
   are in a register by accident.

   The checker class can be stored in registers, and the magic values
   are directly loaded into these registers.  The checker destructor
   is eventually invoked by pthread_exit and calls one of the
   check_magic functions to verify that the class contents (that is,
   register value) is correct.

   These tests are performed both for unsigned int and double values,
   to cover different calling conventions.  */

template <class T>
struct values
{
  T v0;
  T v1;
  T v2;
  T v3;
  T v4;
};

static const values<unsigned int> magic_values =
  {
    0x57f7fc72,
    0xe582daba,
    0x5f6ac994,
    0x35efddb7,
    0x1fbf5a74,
  };

static const values<double> magic_values_double =
  {
    0.6764041905675465,
    0.9533336788140494,
    0.6091161359041452,
    0.7668653957125336,
    0.010374520235509666,
  };

/* Special index value which tells check_magic that no check should be
   performed.  */
enum { no_check = -1 };

/* Check that VALUE is the magic value for INDEX, behind a compiler
   barrier.  */
__attribute__ ((noinline, noclone, weak))
void
check_magic (int index, unsigned int value)
{
  switch (index)
    {
    case 0:
      TEST_COMPARE (value, magic_values.v0);
      break;
    case 1:
      TEST_COMPARE (value, magic_values.v1);
      break;
    case 2:
      TEST_COMPARE (value, magic_values.v2);
      break;
    case 3:
      TEST_COMPARE (value, magic_values.v3);
      break;
    case 4:
      TEST_COMPARE (value, magic_values.v4);
      break;
    case no_check:
      break;
    default:
      FAIL_EXIT1 ("invalid magic value index %d", index);
    }
}

/* Check that VALUE is the magic value for INDEX, behind a compiler
   barrier.  Double variant.  */
__attribute__ ((noinline, noclone, weak))
void
check_magic (int index, double value)
{
  switch (index)
    {
    case 0:
      TEST_VERIFY (value == magic_values_double.v0);
      break;
    case 1:
      TEST_VERIFY (value == magic_values_double.v1);
      break;
    case 2:
      TEST_VERIFY (value == magic_values_double.v2);
      break;
    case 3:
      TEST_VERIFY (value == magic_values_double.v3);
      break;
    case 4:
      TEST_VERIFY (value == magic_values_double.v4);
      break;
    case no_check:
      break;
    default:
      FAIL_EXIT1 ("invalid magic value index %d", index);
    }
}

/* Store a magic value and check, via the destructor, that it has the
   expected value.  */
template <class T, int I>
struct checker
{
  T value;

  checker (T v)
    : value (v)
  {
  }

  ~checker ()
  {
    check_magic (I, value);
  }
};

/* The functions call_pthread_exit_0, call_pthread_exit_1,
   call_pthread_exit are used to call pthread_exit indirectly, with
   the intent of clobbering the register values.  */

__attribute__ ((noinline, noclone, weak))
void
call_pthread_exit_0 (const values<unsigned int> *pvalues)
{
  checker<unsigned int, no_check> c0 (pvalues->v0);
  checker<unsigned int, no_check> c1 (pvalues->v1);
  checker<unsigned int, no_check> c2 (pvalues->v2);
  checker<unsigned int, no_check> c3 (pvalues->v3);
  checker<unsigned int, no_check> c4 (pvalues->v4);

  pthread_exit (NULL);
}

__attribute__ ((noinline, noclone, weak))
void
call_pthread_exit_1 (const values<double> *pvalues)
{
  checker<double, no_check> c0 (pvalues->v0);
  checker<double, no_check> c1 (pvalues->v1);
  checker<double, no_check> c2 (pvalues->v2);
  checker<double, no_check> c3 (pvalues->v3);
  checker<double, no_check> c4 (pvalues->v4);

  values<unsigned int> other_values = { 0, };
  call_pthread_exit_0 (&other_values);
}

__attribute__ ((noinline, noclone, weak))
void
call_pthread_exit ()
{
  values<double> other_values = { 0, };
  call_pthread_exit_1 (&other_values);
}

/* Create on-stack objects and check that their values are restored by
   pthread_exit.  If Nested is true, call pthread_exit indirectly via
   call_pthread_exit.  */
template <class T, bool Nested>
__attribute__ ((noinline, noclone, weak))
void *
threadfunc (void *closure)
{
  const values<T> *pvalues = static_cast<const values<T> *> (closure);

  checker<T, 0> c0 (pvalues->v0);
  checker<T, 1> c1 (pvalues->v1);
  checker<T, 2> c2 (pvalues->v2);
  checker<T, 3> c3 (pvalues->v3);
  checker<T, 4> c4 (pvalues->v4);

  if (Nested)
    call_pthread_exit ();
  else
    pthread_exit (NULL);

  /* This should not be reached.  */
  return const_cast<char *> ("");
}

static int
do_test ()
{
  puts ("info: unsigned int, direct pthread_exit call");
  pthread_t thr
    = xpthread_create (NULL, &threadfunc<unsigned int, false>,
                       const_cast<values<unsigned int> *> (&magic_values));
  TEST_VERIFY (xpthread_join (thr) == NULL);

  puts ("info: double, direct pthread_exit call");
  thr = xpthread_create (NULL, &threadfunc<double, false>,
                         const_cast<values<double> *> (&magic_values_double));
  TEST_VERIFY (xpthread_join (thr) == NULL);

  puts ("info: unsigned int, indirect pthread_exit call");
  thr = xpthread_create (NULL, &threadfunc<unsigned int, true>,
                       const_cast<values<unsigned int> *> (&magic_values));
  TEST_VERIFY (xpthread_join (thr) == NULL);

  puts ("info: double, indirect pthread_exit call");
  thr = xpthread_create (NULL, &threadfunc<double, true>,
                         const_cast<values<double> *> (&magic_values_double));
  TEST_VERIFY (xpthread_join (thr) == NULL);

  return 0;
}

#include <support/test-driver.c>
