(root)/
glibc-2.38/
sysdeps/
x86/
tst-isa-level-1.c
       1  /* Check ISA level on dlopened shared object.
       2     Copyright (C) 2020-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <stdlib.h>
      20  #include <stdbool.h>
      21  #include <string.h>
      22  #include <elf.h>
      23  #include <get-isa-level.h>
      24  #include <support/xdlfcn.h>
      25  #include <support/check.h>
      26  #include <support/test-driver.h>
      27  
      28  static void
      29  do_test_1 (const char *modname, bool fail)
      30  {
      31    int (*fp) (void);
      32    void *h;
      33  
      34    h = dlopen (modname, RTLD_LAZY);
      35    if (h == NULL)
      36      {
      37        const char *err = dlerror ();
      38        if (fail)
      39  	{
      40  	  if (strstr (err, "CPU ISA level is lower than required") == NULL)
      41  	    FAIL_EXIT1 ("incorrect dlopen '%s' error: %s\n", modname, err);
      42  
      43  	  return;
      44  	}
      45  
      46        FAIL_EXIT1 ("cannot open '%s': %s\n", modname, err);
      47      }
      48  
      49    if (fail)
      50      FAIL_EXIT1 ("dlopen '%s' should have failed\n", modname);
      51  
      52    fp = xdlsym (h, "test");
      53  
      54    if (fp () != 0)
      55      FAIL_EXIT1 ("test () != 0\n");
      56  
      57    dlclose (h);
      58  }
      59  
      60  static int
      61  do_test (void)
      62  {
      63    const struct cpu_features *cpu_features = __get_cpu_features ();
      64    unsigned int isa_level = get_isa_level (cpu_features);
      65    bool has_isa_baseline = ((isa_level & GNU_PROPERTY_X86_ISA_1_BASELINE)
      66  			   == GNU_PROPERTY_X86_ISA_1_BASELINE);
      67    bool has_isa_v2 = ((isa_level & GNU_PROPERTY_X86_ISA_1_V2)
      68  			   == GNU_PROPERTY_X86_ISA_1_V2);
      69    bool has_isa_v3 = ((isa_level & GNU_PROPERTY_X86_ISA_1_V3)
      70  			   == GNU_PROPERTY_X86_ISA_1_V3);
      71    bool has_isa_v4 = ((isa_level & GNU_PROPERTY_X86_ISA_1_V4)
      72  			   == GNU_PROPERTY_X86_ISA_1_V4);
      73  
      74    if (!has_isa_baseline)
      75      {
      76        do_test_1 ("tst-isa-level-mod-1-baseline.so", true);
      77        return EXIT_SUCCESS;
      78      }
      79  
      80    do_test_1 ("tst-isa-level-mod-1-baseline.so", false);
      81  
      82    /* Skip on x86-64-v4 platforms since dlopen v4 module always works.  */
      83    if (has_isa_v4)
      84      return EXIT_SUCCESS;
      85  
      86    do_test_1 ("tst-isa-level-mod-1-v4.so", true);
      87  
      88    /* Skip on x86-64-v3 platforms since dlopen v3 module always works.  */
      89    if (has_isa_v3)
      90      return EXIT_SUCCESS;
      91  
      92    do_test_1 ("tst-isa-level-mod-1-v3.so", true);
      93  
      94    /* Skip on x86-64-v2 platforms since dlopen v2 module always works.  */
      95    if (has_isa_v2)
      96      return EXIT_SUCCESS;
      97  
      98    do_test_1 ("tst-isa-level-mod-1-v2.so", true);
      99  
     100    return EXIT_SUCCESS;
     101  }
     102  
     103  #include <support/test-driver.c>