(root)/
glibc-2.38/
sysdeps/
x86_64/
tst-auditmod10b.c
       1  /* Copyright (C) 2012-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       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  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  /* Verify that changing AVX512 registers in audit library won't affect
      19     function parameter passing/return.  */
      20  
      21  #include <dlfcn.h>
      22  #include <link.h>
      23  #include <stddef.h>
      24  #include <stdint.h>
      25  #include <stdio.h>
      26  #include <stdlib.h>
      27  #include <string.h>
      28  #include <unistd.h>
      29  #include <bits/wordsize.h>
      30  #include <gnu/lib-names.h>
      31  
      32  unsigned int
      33  la_version (unsigned int v)
      34  {
      35    setlinebuf (stdout);
      36  
      37    printf ("version: %u\n", v);
      38  
      39    char buf[20];
      40    sprintf (buf, "%u", v);
      41  
      42    return v;
      43  }
      44  
      45  void
      46  la_activity (uintptr_t *cookie, unsigned int flag)
      47  {
      48    if (flag == LA_ACT_CONSISTENT)
      49      printf ("activity: consistent\n");
      50    else if (flag == LA_ACT_ADD)
      51      printf ("activity: add\n");
      52    else if (flag == LA_ACT_DELETE)
      53      printf ("activity: delete\n");
      54    else
      55      printf ("activity: unknown activity %u\n", flag);
      56  }
      57  
      58  char *
      59  la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag)
      60  {
      61    char buf[100];
      62    const char *flagstr;
      63    if (flag == LA_SER_ORIG)
      64      flagstr = "LA_SET_ORIG";
      65    else if (flag == LA_SER_LIBPATH)
      66      flagstr = "LA_SER_LIBPATH";
      67    else if (flag == LA_SER_RUNPATH)
      68      flagstr = "LA_SER_RUNPATH";
      69    else if (flag == LA_SER_CONFIG)
      70      flagstr = "LA_SER_CONFIG";
      71    else if (flag == LA_SER_DEFAULT)
      72      flagstr = "LA_SER_DEFAULT";
      73    else if (flag == LA_SER_SECURE)
      74      flagstr = "LA_SER_SECURE";
      75    else
      76      {
      77         sprintf (buf, "unknown flag %d", flag);
      78         flagstr = buf;
      79      }
      80    printf ("objsearch: %s, %s\n", name, flagstr);
      81  
      82    return (char *) name;
      83  }
      84  
      85  unsigned int
      86  la_objopen (struct link_map *l, Lmid_t lmid, uintptr_t *cookie)
      87  {
      88    printf ("objopen: %ld, %s\n", lmid, l->l_name);
      89  
      90    return 3;
      91  }
      92  
      93  void
      94  la_preinit (uintptr_t *cookie)
      95  {
      96    printf ("preinit\n");
      97  }
      98  
      99  unsigned int
     100  la_objclose  (uintptr_t *cookie)
     101  {
     102    printf ("objclose\n");
     103    return 0;
     104  }
     105  
     106  uintptr_t
     107  la_symbind32 (Elf32_Sym *sym, unsigned int ndx, uintptr_t *refcook,
     108  	      uintptr_t *defcook, unsigned int *flags, const char *symname)
     109  {
     110    printf ("symbind32: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n",
     111  	  symname, (long int) sym->st_value, ndx, *flags);
     112  
     113    return sym->st_value;
     114  }
     115  
     116  uintptr_t
     117  la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
     118  	      uintptr_t *defcook, unsigned int *flags, const char *symname)
     119  {
     120    printf ("symbind64: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n",
     121  	  symname, (long int) sym->st_value, ndx, *flags);
     122  
     123    return sym->st_value;
     124  }
     125  
     126  #include <tst-audit.h>
     127  
     128  #ifdef __AVX512F__
     129  #include <immintrin.h>
     130  #include <cpuid.h>
     131  
     132  static int
     133  check_avx512 (void)
     134  {
     135    unsigned int eax, ebx, ecx, edx;
     136  
     137    if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) == 0
     138        || (ecx & (bit_AVX | bit_OSXSAVE)) != (bit_AVX | bit_OSXSAVE))
     139      return 0;
     140  
     141    __cpuid_count (7, 0, eax, ebx, ecx, edx);
     142    if (!(ebx & bit_AVX512F))
     143      return 0;
     144  
     145    asm ("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0));
     146  
     147    /* Verify that ZMM, YMM and XMM states are enabled.  */
     148    return (eax & 0xe6) == 0xe6;
     149  }
     150  
     151  #else
     152  #include <emmintrin.h>
     153  #endif
     154  
     155  ElfW(Addr)
     156  pltenter (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
     157  	  uintptr_t *defcook, La_regs *regs, unsigned int *flags,
     158  	  const char *symname, long int *framesizep)
     159  {
     160    printf ("pltenter: symname=%s, st_value=%#lx, ndx=%u, flags=%u\n",
     161  	  symname, (long int) sym->st_value, ndx, *flags);
     162  
     163  #ifdef __AVX512F__
     164    if (check_avx512 () && strcmp (symname, "audit_test") == 0)
     165      {
     166        __m512i zero = _mm512_setzero_si512 ();
     167        if (memcmp (&regs->lr_vector[0], &zero, sizeof (zero))
     168  	  || memcmp (&regs->lr_vector[1], &zero, sizeof (zero))
     169  	  || memcmp (&regs->lr_vector[2], &zero, sizeof (zero))
     170  	  || memcmp (&regs->lr_vector[3], &zero, sizeof (zero))
     171  	  || memcmp (&regs->lr_vector[4], &zero, sizeof (zero))
     172  	  || memcmp (&regs->lr_vector[5], &zero, sizeof (zero))
     173  	  || memcmp (&regs->lr_vector[6], &zero, sizeof (zero))
     174  	  || memcmp (&regs->lr_vector[7], &zero, sizeof (zero)))
     175  	abort ();
     176  
     177        for (int i = 0; i < 8; i++)
     178  	regs->lr_vector[i].zmm[0]
     179  	  = (La_x86_64_zmm) _mm512_set1_epi64 (i + 1);
     180  
     181        __m512i zmm = _mm512_set1_epi64 (-1);
     182        asm volatile ("vmovdqa64 %0, %%zmm0" : : "x" (zmm) : "xmm0" );
     183        asm volatile ("vmovdqa64 %0, %%zmm1" : : "x" (zmm) : "xmm1" );
     184        asm volatile ("vmovdqa64 %0, %%zmm2" : : "x" (zmm) : "xmm2" );
     185        asm volatile ("vmovdqa64 %0, %%zmm3" : : "x" (zmm) : "xmm3" );
     186        asm volatile ("vmovdqa64 %0, %%zmm4" : : "x" (zmm) : "xmm4" );
     187        asm volatile ("vmovdqa64 %0, %%zmm5" : : "x" (zmm) : "xmm5" );
     188        asm volatile ("vmovdqa64 %0, %%zmm6" : : "x" (zmm) : "xmm6" );
     189        asm volatile ("vmovdqa64 %0, %%zmm7" : : "x" (zmm) : "xmm7" );
     190  
     191        *framesizep = 1024;
     192      }
     193  #endif
     194  
     195    return sym->st_value;
     196  }
     197  
     198  unsigned int
     199  pltexit (ElfW(Sym) *sym, unsigned int ndx, uintptr_t *refcook,
     200  	 uintptr_t *defcook, const La_regs *inregs, La_retval *outregs,
     201  	 const char *symname)
     202  {
     203    printf ("pltexit: symname=%s, st_value=%#lx, ndx=%u, retval=%tu\n",
     204  	  symname, (long int) sym->st_value, ndx,
     205  	  (ptrdiff_t) outregs->int_retval);
     206  
     207  #ifdef __AVX512F__
     208    if (check_avx512 () && strcmp (symname, "audit_test") == 0)
     209      {
     210        __m512i zero = _mm512_setzero_si512 ();
     211        if (memcmp (&outregs->lrv_vector0, &zero, sizeof (zero)))
     212  	abort ();
     213  
     214        for (int i = 0; i < 8; i++)
     215  	{
     216  	  __m512i zmm = _mm512_set1_epi64 (i + 1);
     217  	  if (memcmp (&inregs->lr_vector[i], &zmm, sizeof (zmm)) != 0)
     218  	    abort ();
     219  	}
     220  
     221        outregs->lrv_vector0.zmm[0]
     222  	= (La_x86_64_zmm) _mm512_set1_epi64 (0x12349876);
     223  
     224        __m512i zmm = _mm512_set1_epi64 (-1);
     225        asm volatile ("vmovdqa64 %0, %%zmm0" : : "x" (zmm) : "xmm0" );
     226        asm volatile ("vmovdqa64 %0, %%zmm1" : : "x" (zmm) : "xmm1" );
     227      }
     228  #endif
     229  
     230    return 0;
     231  }