Home | History | Annotate | Line # | Download | only in arch
      1  1.1  christos /* Target description related code for GNU/Linux x86 (i386 and x86-64).
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 2024 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    This file is part of GDB.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify
      8  1.1  christos    it under the terms of the GNU General Public License as published by
      9  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10  1.1  christos    (at your option) any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  christos    GNU General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19  1.1  christos 
     20  1.1  christos #include "arch/x86-linux-tdesc-features.h"
     21  1.1  christos 
     22  1.1  christos /* A structure used to describe a single xstate feature bit that might, or
     23  1.1  christos    might not, be checked for when creating a target description for one of
     24  1.1  christos    i386, amd64, or x32.
     25  1.1  christos 
     26  1.1  christos    The different CPU/ABI types check for different xstate features when
     27  1.1  christos    creating a target description.
     28  1.1  christos 
     29  1.1  christos    We want to cache target descriptions, and this is currently done in
     30  1.1  christos    three separate caches, one each for i386, amd64, and x32.  Additionally,
     31  1.1  christos    the caching we're discussing here is Linux only, and for Linux, the only
     32  1.1  christos    thing that has an impact on target description creation is the xcr0
     33  1.1  christos    value.
     34  1.1  christos 
     35  1.1  christos    In order to ensure the cache functions correctly we need to filter out
     36  1.1  christos    only those xcr0 feature bits that are relevant, we can then cache target
     37  1.1  christos    descriptions based on the relevant feature bits.  Two xcr0 values might
     38  1.1  christos    be different, but have the same relevant feature bits.  In this case we
     39  1.1  christos    would expect the two xcr0 values to map to the same cache entry.  */
     40  1.1  christos 
     41  1.1  christos struct x86_xstate_feature {
     42  1.1  christos   /* The xstate feature mask.  This is a mask against an xcr0 value.  */
     43  1.1  christos   uint64_t feature;
     44  1.1  christos 
     45  1.1  christos   /* Is this feature checked when creating an i386 target description.  */
     46  1.1  christos   bool is_i386;
     47  1.1  christos 
     48  1.1  christos   /* Is this feature checked when creating an amd64 target description.  */
     49  1.1  christos   bool is_amd64;
     50  1.1  christos 
     51  1.1  christos   /* Is this feature checked when creating an x32 target description.  */
     52  1.1  christos   bool is_x32;
     53  1.1  christos };
     54  1.1  christos 
     55  1.1  christos /* A constant table that describes all of the xstate features that are
     56  1.1  christos    checked when building a target description for i386, amd64, or x32.
     57  1.1  christos 
     58  1.1  christos    If in the future, due to simplifications or refactoring, this table ever
     59  1.1  christos    ends up with 'true' for every xcr0 feature on every target type, then this
     60  1.1  christos    is an indication that this table should probably be removed, and that the
     61  1.1  christos    rest of the code in this file can be simplified.  */
     62  1.1  christos 
     63  1.1  christos static constexpr x86_xstate_feature x86_linux_all_xstate_features[] = {
     64  1.1  christos   /* Feature,           i386,	amd64,	x32.  */
     65  1.1  christos   { X86_XSTATE_PKRU,	true,	true, 	true },
     66  1.1  christos   { X86_XSTATE_AVX512,	true,	true, 	true },
     67  1.1  christos   { X86_XSTATE_AVX,	true,	true, 	true },
     68  1.1  christos   { X86_XSTATE_SSE,	true,	false, 	false },
     69  1.1  christos   { X86_XSTATE_X87,	true,	false, 	false }
     70  1.1  christos };
     71  1.1  christos 
     72  1.1  christos /* Return a compile time constant which is a mask of all the xstate features
     73  1.1  christos    that are checked for when building an i386 target description.  */
     74  1.1  christos 
     75  1.1  christos static constexpr uint64_t
     76  1.1  christos x86_linux_i386_xcr0_feature_mask_1 ()
     77  1.1  christos {
     78  1.1  christos   uint64_t mask = 0;
     79  1.1  christos 
     80  1.1  christos   for (const auto &entry : x86_linux_all_xstate_features)
     81  1.1  christos     if (entry.is_i386)
     82  1.1  christos       mask |= entry.feature;
     83  1.1  christos 
     84  1.1  christos   return mask;
     85  1.1  christos }
     86  1.1  christos 
     87  1.1  christos /* Return a compile time constant which is a mask of all the xstate features
     88  1.1  christos    that are checked for when building an amd64 target description.  */
     89  1.1  christos 
     90  1.1  christos static constexpr uint64_t
     91  1.1  christos x86_linux_amd64_xcr0_feature_mask_1 ()
     92  1.1  christos {
     93  1.1  christos   uint64_t mask = 0;
     94  1.1  christos 
     95  1.1  christos   for (const auto &entry : x86_linux_all_xstate_features)
     96  1.1  christos     if (entry.is_amd64)
     97  1.1  christos       mask |= entry.feature;
     98  1.1  christos 
     99  1.1  christos   return mask;
    100  1.1  christos }
    101  1.1  christos 
    102  1.1  christos /* Return a compile time constant which is a mask of all the xstate features
    103  1.1  christos    that are checked for when building an x32 target description.  */
    104  1.1  christos 
    105  1.1  christos static constexpr uint64_t
    106  1.1  christos x86_linux_x32_xcr0_feature_mask_1 ()
    107  1.1  christos {
    108  1.1  christos   uint64_t mask = 0;
    109  1.1  christos 
    110  1.1  christos   for (const auto &entry : x86_linux_all_xstate_features)
    111  1.1  christos     if (entry.is_x32)
    112  1.1  christos       mask |= entry.feature;
    113  1.1  christos 
    114  1.1  christos   return mask;
    115  1.1  christos }
    116  1.1  christos 
    117  1.1  christos /* See arch/x86-linux-tdesc-features.h.  */
    118  1.1  christos 
    119  1.1  christos uint64_t
    120  1.1  christos x86_linux_i386_xcr0_feature_mask ()
    121  1.1  christos {
    122  1.1  christos   return x86_linux_i386_xcr0_feature_mask_1 ();
    123  1.1  christos }
    124  1.1  christos 
    125  1.1  christos /* See arch/x86-linux-tdesc-features.h.  */
    126  1.1  christos 
    127  1.1  christos uint64_t
    128  1.1  christos x86_linux_amd64_xcr0_feature_mask ()
    129  1.1  christos {
    130  1.1  christos   return x86_linux_amd64_xcr0_feature_mask_1 ();
    131  1.1  christos }
    132  1.1  christos 
    133  1.1  christos /* See arch/x86-linux-tdesc-features.h.  */
    134  1.1  christos 
    135  1.1  christos uint64_t
    136  1.1  christos x86_linux_x32_xcr0_feature_mask ()
    137  1.1  christos {
    138  1.1  christos   return x86_linux_x32_xcr0_feature_mask_1 ();
    139  1.1  christos }
    140  1.1  christos 
    141  1.1  christos #ifdef GDBSERVER
    142  1.1  christos 
    143  1.1  christos /* See arch/x86-linux-tdesc-features.h.  */
    144  1.1  christos 
    145  1.1  christos int
    146  1.1  christos x86_linux_xcr0_to_tdesc_idx (uint64_t xcr0)
    147  1.1  christos {
    148  1.1  christos   /* The following table shows which features are checked for when creating
    149  1.1  christos      the target descriptions (see nat/x86-linux-tdesc.c), the feature order
    150  1.1  christos      represents the bit order within the generated index number.
    151  1.1  christos 
    152  1.1  christos      i386  | x87 sse avx avx512 pkru
    153  1.1  christos      amd64 |         avx avx512 pkru
    154  1.1  christos      i32   |         avx avx512 pkru
    155  1.1  christos 
    156  1.1  christos      The features are ordered so that for each mode (i386, amd64, i32) the
    157  1.1  christos      generated index will form a continuous range.  */
    158  1.1  christos 
    159  1.1  christos   int idx = 0;
    160  1.1  christos 
    161  1.1  christos   for (int i = 0; i < ARRAY_SIZE (x86_linux_all_xstate_features); ++i)
    162  1.1  christos     {
    163  1.1  christos       if ((xcr0 & x86_linux_all_xstate_features[i].feature)
    164  1.1  christos 	  == x86_linux_all_xstate_features[i].feature)
    165  1.1  christos 	idx |= (1 << i);
    166  1.1  christos     }
    167  1.1  christos 
    168  1.1  christos   return idx;
    169  1.1  christos }
    170  1.1  christos 
    171  1.1  christos #endif /* GDBSERVER */
    172  1.1  christos 
    173  1.1  christos #ifdef IN_PROCESS_AGENT
    174  1.1  christos 
    175  1.1  christos /* Return a compile time constant which is a count of the number of xstate
    176  1.1  christos    features that are checked for when building an i386 target description.  */
    177  1.1  christos 
    178  1.1  christos static constexpr int
    179  1.1  christos x86_linux_i386_tdesc_count_1 ()
    180  1.1  christos {
    181  1.1  christos   uint64_t count = 0;
    182  1.1  christos 
    183  1.1  christos   for (const auto &entry : x86_linux_all_xstate_features)
    184  1.1  christos     if (entry.is_i386)
    185  1.1  christos       ++count;
    186  1.1  christos 
    187  1.1  christos   gdb_assert (count > 0);
    188  1.1  christos 
    189  1.1  christos   return (1 << count);
    190  1.1  christos }
    191  1.1  christos 
    192  1.1  christos /* Return a compile time constant which is a count of the number of xstate
    193  1.1  christos    features that are checked for when building an amd64 target description.  */
    194  1.1  christos 
    195  1.1  christos static constexpr int
    196  1.1  christos x86_linux_amd64_tdesc_count_1 ()
    197  1.1  christos {
    198  1.1  christos   uint64_t count = 0;
    199  1.1  christos 
    200  1.1  christos   for (const auto &entry : x86_linux_all_xstate_features)
    201  1.1  christos     if (entry.is_amd64)
    202  1.1  christos       ++count;
    203  1.1  christos 
    204  1.1  christos   gdb_assert (count > 0);
    205  1.1  christos 
    206  1.1  christos   return (1 << count);
    207  1.1  christos }
    208  1.1  christos 
    209  1.1  christos /* Return a compile time constant which is a count of the number of xstate
    210  1.1  christos    features that are checked for when building an x32 target description.  */
    211  1.1  christos 
    212  1.1  christos static constexpr int
    213  1.1  christos x86_linux_x32_tdesc_count_1 ()
    214  1.1  christos {
    215  1.1  christos   uint64_t count = 0;
    216  1.1  christos 
    217  1.1  christos   for (const auto &entry : x86_linux_all_xstate_features)
    218  1.1  christos     if (entry.is_x32)
    219  1.1  christos       ++count;
    220  1.1  christos 
    221  1.1  christos   gdb_assert (count > 0);
    222  1.1  christos 
    223  1.1  christos   return (1 << count);
    224  1.1  christos }
    225  1.1  christos 
    226  1.1  christos /* See arch/x86-linux-tdesc-features.h.  */
    227  1.1  christos 
    228  1.1  christos int
    229  1.1  christos x86_linux_amd64_tdesc_count ()
    230  1.1  christos {
    231  1.1  christos   return x86_linux_amd64_tdesc_count_1 ();
    232  1.1  christos }
    233  1.1  christos 
    234  1.1  christos /* See arch/x86-linux-tdesc-features.h.  */
    235  1.1  christos 
    236  1.1  christos int
    237  1.1  christos x86_linux_x32_tdesc_count ()
    238  1.1  christos {
    239  1.1  christos   return x86_linux_x32_tdesc_count_1 ();
    240  1.1  christos }
    241  1.1  christos 
    242  1.1  christos /* See arch/x86-linux-tdesc-features.h.  */
    243  1.1  christos 
    244  1.1  christos int
    245  1.1  christos x86_linux_i386_tdesc_count ()
    246  1.1  christos {
    247  1.1  christos   return x86_linux_i386_tdesc_count_1 ();
    248  1.1  christos }
    249  1.1  christos 
    250  1.1  christos /* See arch/x86-linux-tdesc-features.h.  */
    251  1.1  christos 
    252  1.1  christos uint64_t
    253  1.1  christos x86_linux_tdesc_idx_to_xcr0 (int idx)
    254  1.1  christos {
    255  1.1  christos   uint64_t xcr0 = 0;
    256  1.1  christos 
    257  1.1  christos   for (int i = 0; i < ARRAY_SIZE (x86_linux_all_xstate_features); ++i)
    258  1.1  christos     {
    259  1.1  christos       if ((idx & (1 << i)) != 0)
    260  1.1  christos 	xcr0 |= x86_linux_all_xstate_features[i].feature;
    261  1.1  christos     }
    262  1.1  christos 
    263  1.1  christos   return xcr0;
    264  1.1  christos }
    265  1.1  christos 
    266  1.1  christos #endif /* IN_PROCESS_AGENT */
    267