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