1 /* This testcase is part of GDB, the GNU debugger. 2 3 Copyright 2017-2020 Free Software Foundation, Inc. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program 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 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18 #include <cpuid.h> 19 #include <stdint.h> 20 21 /* 0 if the CPU supports rdrand and non-zero otherwise. */ 22 static unsigned int supports_rdrand; 23 24 /* 0 if the CPU supports rdseed and non-zero otherwise. */ 25 static unsigned int supports_rdseed; 26 27 /* Check supported features and set globals accordingly. The globals 28 can be used to prevent unsupported tests from running. */ 29 30 static void 31 check_supported_features (void) 32 { 33 unsigned int rdrand_mask = (1 << 30); 34 unsigned int rdseed_mask = (1 << 18); 35 unsigned int eax, ebx, ecx, edx; 36 unsigned int vendor; 37 unsigned int max_level; 38 39 max_level = __get_cpuid_max (0, &vendor); 40 41 if (max_level < 1) 42 return; 43 44 __cpuid (1, eax, ebx, ecx, edx); 45 46 supports_rdrand = ((ecx & rdrand_mask) == rdrand_mask); 47 48 if (max_level >= 7) 49 { 50 __cpuid_count (7, 0, eax, ebx, ecx, edx); 51 supports_rdseed = ((ebx & rdseed_mask) == rdseed_mask); 52 } 53 } 54 55 /* Test rdrand support for various output registers. */ 56 57 void 58 rdrand (void) 59 { 60 /* Get a random number from the rdrand assembly instruction. */ 61 register uint64_t number; 62 63 if (!supports_rdrand) 64 return; 65 66 /* 16-bit random numbers. */ 67 __asm__ volatile ("rdrand %%ax;" : "=r" (number)); 68 __asm__ volatile ("rdrand %%bx;" : "=r" (number)); 69 __asm__ volatile ("rdrand %%cx;" : "=r" (number)); 70 __asm__ volatile ("rdrand %%dx;" : "=r" (number)); 71 72 __asm__ volatile ("mov %%di, %%ax;" : "=r" (number)); 73 __asm__ volatile ("rdrand %%di;" : "=r" (number)); 74 __asm__ volatile ("mov %%ax, %%di;" : "=r" (number)); 75 76 __asm__ volatile ("mov %%si, %%ax;" : "=r" (number)); 77 __asm__ volatile ("rdrand %%si;" : "=r" (number)); 78 __asm__ volatile ("mov %%ax, %%si;" : "=r" (number)); 79 80 __asm__ volatile ("mov %%bp, %%ax;" : "=r" (number)); 81 __asm__ volatile ("rdrand %%bp;" : "=r" (number)); 82 __asm__ volatile ("mov %%ax, %%bp;" : "=r" (number)); 83 84 __asm__ volatile ("mov %%sp, %%ax;" : "=r" (number)); 85 __asm__ volatile ("rdrand %%sp;" : "=r" (number)); 86 __asm__ volatile ("mov %%ax, %%sp;" : "=r" (number)); 87 88 __asm__ volatile ("rdrand %%r8w;" : "=r" (number)); 89 __asm__ volatile ("rdrand %%r9w;" : "=r" (number)); 90 __asm__ volatile ("rdrand %%r10w;" : "=r" (number)); 91 __asm__ volatile ("rdrand %%r11w;" : "=r" (number)); 92 __asm__ volatile ("rdrand %%r12w;" : "=r" (number)); 93 __asm__ volatile ("rdrand %%r13w;" : "=r" (number)); 94 __asm__ volatile ("rdrand %%r14w;" : "=r" (number)); 95 __asm__ volatile ("rdrand %%r15w;" : "=r" (number)); 96 97 /* 32-bit random numbers. */ 98 __asm__ volatile ("rdrand %%eax;" : "=r" (number)); 99 __asm__ volatile ("rdrand %%ebx;" : "=r" (number)); 100 __asm__ volatile ("rdrand %%ecx;" : "=r" (number)); 101 __asm__ volatile ("rdrand %%edx;" : "=r" (number)); 102 103 __asm__ volatile ("mov %%rdi, %%rax;" : "=r" (number)); 104 __asm__ volatile ("rdrand %%edi;" : "=r" (number)); 105 __asm__ volatile ("mov %%rax, %%rdi;" : "=r" (number)); 106 107 __asm__ volatile ("mov %%rsi, %%rax;" : "=r" (number)); 108 __asm__ volatile ("rdrand %%esi;" : "=r" (number)); 109 __asm__ volatile ("mov %%rax, %%rsi;" : "=r" (number)); 110 111 __asm__ volatile ("mov %%rbp, %%rax;" : "=r" (number)); 112 __asm__ volatile ("rdrand %%ebp;" : "=r" (number)); 113 __asm__ volatile ("mov %%rax, %%rbp;" : "=r" (number)); 114 115 __asm__ volatile ("mov %%rsp, %%rax;" : "=r" (number)); 116 __asm__ volatile ("rdrand %%esp;" : "=r" (number)); 117 __asm__ volatile ("mov %%rax, %%rsp;" : "=r" (number)); 118 119 __asm__ volatile ("rdrand %%r8d;" : "=r" (number)); 120 __asm__ volatile ("rdrand %%r9d;" : "=r" (number)); 121 __asm__ volatile ("rdrand %%r10d;" : "=r" (number)); 122 __asm__ volatile ("rdrand %%r11d;" : "=r" (number)); 123 __asm__ volatile ("rdrand %%r12d;" : "=r" (number)); 124 __asm__ volatile ("rdrand %%r13d;" : "=r" (number)); 125 __asm__ volatile ("rdrand %%r14d;" : "=r" (number)); 126 __asm__ volatile ("rdrand %%r15d;" : "=r" (number)); 127 128 /* 64-bit random numbers. */ 129 __asm__ volatile ("rdrand %%rax;" : "=r" (number)); 130 __asm__ volatile ("rdrand %%rbx;" : "=r" (number)); 131 __asm__ volatile ("rdrand %%rcx;" : "=r" (number)); 132 __asm__ volatile ("rdrand %%rdx;" : "=r" (number)); 133 134 __asm__ volatile ("mov %%rdi, %%rax;" : "=r" (number)); 135 __asm__ volatile ("rdrand %%rdi;" : "=r" (number)); 136 __asm__ volatile ("mov %%rax, %%rdi;" : "=r" (number)); 137 138 __asm__ volatile ("mov %%rsi, %%rax;" : "=r" (number)); 139 __asm__ volatile ("rdrand %%rsi;" : "=r" (number)); 140 __asm__ volatile ("mov %%rax, %%rsi;" : "=r" (number)); 141 142 __asm__ volatile ("mov %%rbp, %%rax;" : "=r" (number)); 143 __asm__ volatile ("rdrand %%rbp;" : "=r" (number)); 144 __asm__ volatile ("mov %%rax, %%rbp;" : "=r" (number)); 145 146 __asm__ volatile ("mov %%rsp, %%rax;" : "=r" (number)); 147 __asm__ volatile ("rdrand %%rsp;" : "=r" (number)); 148 __asm__ volatile ("mov %%rax, %%rsp;" : "=r" (number)); 149 150 __asm__ volatile ("rdrand %%r8;" : "=r" (number)); 151 __asm__ volatile ("rdrand %%r9;" : "=r" (number)); 152 __asm__ volatile ("rdrand %%r10;" : "=r" (number)); 153 __asm__ volatile ("rdrand %%r11;" : "=r" (number)); 154 __asm__ volatile ("rdrand %%r12;" : "=r" (number)); 155 __asm__ volatile ("rdrand %%r13;" : "=r" (number)); 156 __asm__ volatile ("rdrand %%r14;" : "=r" (number)); 157 __asm__ volatile ("rdrand %%r15;" : "=r" (number)); 158 } 159 160 /* Test rdseed support for various output registers. */ 161 162 void 163 rdseed (void) 164 { 165 /* Get a random seed from the rdseed assembly instruction. */ 166 register long seed; 167 168 if (!supports_rdseed) 169 return; 170 171 /* 16-bit random seeds. */ 172 __asm__ volatile ("rdseed %%ax;" : "=r" (seed)); 173 __asm__ volatile ("rdseed %%bx;" : "=r" (seed)); 174 __asm__ volatile ("rdseed %%cx;" : "=r" (seed)); 175 __asm__ volatile ("rdseed %%dx;" : "=r" (seed)); 176 177 __asm__ volatile ("mov %%di, %%ax;" : "=r" (seed)); 178 __asm__ volatile ("rdseed %%di;" : "=r" (seed)); 179 __asm__ volatile ("mov %%ax, %%di;" : "=r" (seed)); 180 181 __asm__ volatile ("mov %%si, %%ax;" : "=r" (seed)); 182 __asm__ volatile ("rdseed %%si;" : "=r" (seed)); 183 __asm__ volatile ("mov %%ax, %%si;" : "=r" (seed)); 184 185 __asm__ volatile ("mov %%bp, %%ax;" : "=r" (seed)); 186 __asm__ volatile ("rdseed %%bp;" : "=r" (seed)); 187 __asm__ volatile ("mov %%ax, %%bp;" : "=r" (seed)); 188 189 __asm__ volatile ("mov %%sp, %%ax;" : "=r" (seed)); 190 __asm__ volatile ("rdseed %%sp;" : "=r" (seed)); 191 __asm__ volatile ("mov %%ax, %%sp;" : "=r" (seed)); 192 193 __asm__ volatile ("rdseed %%r8w;" : "=r" (seed)); 194 __asm__ volatile ("rdseed %%r9w;" : "=r" (seed)); 195 __asm__ volatile ("rdseed %%r10w;" : "=r" (seed)); 196 __asm__ volatile ("rdseed %%r11w;" : "=r" (seed)); 197 __asm__ volatile ("rdseed %%r12w;" : "=r" (seed)); 198 __asm__ volatile ("rdseed %%r13w;" : "=r" (seed)); 199 __asm__ volatile ("rdseed %%r14w;" : "=r" (seed)); 200 __asm__ volatile ("rdseed %%r15w;" : "=r" (seed)); 201 202 /* 32-bit random seeds. */ 203 __asm__ volatile ("rdseed %%eax;" : "=r" (seed)); 204 __asm__ volatile ("rdseed %%ebx;" : "=r" (seed)); 205 __asm__ volatile ("rdseed %%ecx;" : "=r" (seed)); 206 __asm__ volatile ("rdseed %%edx;" : "=r" (seed)); 207 208 __asm__ volatile ("mov %%rdi, %%rax;" : "=r" (seed)); 209 __asm__ volatile ("rdseed %%edi;" : "=r" (seed)); 210 __asm__ volatile ("mov %%rax, %%rdi;" : "=r" (seed)); 211 212 __asm__ volatile ("mov %%rsi, %%rax;" : "=r" (seed)); 213 __asm__ volatile ("rdseed %%esi;" : "=r" (seed)); 214 __asm__ volatile ("mov %%rax, %%rsi;" : "=r" (seed)); 215 216 __asm__ volatile ("mov %%rbp, %%rax;" : "=r" (seed)); 217 __asm__ volatile ("rdseed %%ebp;" : "=r" (seed)); 218 __asm__ volatile ("mov %%rax, %%rbp;" : "=r" (seed)); 219 220 __asm__ volatile ("mov %%rsp, %%rax;" : "=r" (seed)); 221 __asm__ volatile ("rdseed %%esp;" : "=r" (seed)); 222 __asm__ volatile ("mov %%rax, %%rsp;" : "=r" (seed)); 223 224 __asm__ volatile ("rdseed %%r8d;" : "=r" (seed)); 225 __asm__ volatile ("rdseed %%r9d;" : "=r" (seed)); 226 __asm__ volatile ("rdseed %%r10d;" : "=r" (seed)); 227 __asm__ volatile ("rdseed %%r11d;" : "=r" (seed)); 228 __asm__ volatile ("rdseed %%r12d;" : "=r" (seed)); 229 __asm__ volatile ("rdseed %%r13d;" : "=r" (seed)); 230 __asm__ volatile ("rdseed %%r14d;" : "=r" (seed)); 231 __asm__ volatile ("rdseed %%r15d;" : "=r" (seed)); 232 233 /* 64-bit random seeds. */ 234 __asm__ volatile ("rdseed %%rax;" : "=r" (seed)); 235 __asm__ volatile ("rdseed %%rbx;" : "=r" (seed)); 236 __asm__ volatile ("rdseed %%rcx;" : "=r" (seed)); 237 __asm__ volatile ("rdseed %%rdx;" : "=r" (seed)); 238 239 __asm__ volatile ("mov %%rdi, %%rax;" : "=r" (seed)); 240 __asm__ volatile ("rdseed %%rdi;" : "=r" (seed)); 241 __asm__ volatile ("mov %%rax, %%rdi;" : "=r" (seed)); 242 243 __asm__ volatile ("mov %%rsi, %%rax;" : "=r" (seed)); 244 __asm__ volatile ("rdseed %%rsi;" : "=r" (seed)); 245 __asm__ volatile ("mov %%rax, %%rsi;" : "=r" (seed)); 246 247 __asm__ volatile ("mov %%rbp, %%rax;" : "=r" (seed)); 248 __asm__ volatile ("rdseed %%rbp;" : "=r" (seed)); 249 __asm__ volatile ("mov %%rax, %%rbp;" : "=r" (seed)); 250 251 __asm__ volatile ("mov %%rsp, %%rax;" : "=r" (seed)); 252 __asm__ volatile ("rdseed %%rsp;" : "=r" (seed)); 253 __asm__ volatile ("mov %%rax, %%rsp;" : "=r" (seed)); 254 255 __asm__ volatile ("rdseed %%r8;" : "=r" (seed)); 256 __asm__ volatile ("rdseed %%r9;" : "=r" (seed)); 257 __asm__ volatile ("rdseed %%r10;" : "=r" (seed)); 258 __asm__ volatile ("rdseed %%r11;" : "=r" (seed)); 259 __asm__ volatile ("rdseed %%r12;" : "=r" (seed)); 260 __asm__ volatile ("rdseed %%r13;" : "=r" (seed)); 261 __asm__ volatile ("rdseed %%r14;" : "=r" (seed)); 262 __asm__ volatile ("rdseed %%r15;" : "=r" (seed)); 263 } 264 265 /* Initialize arch-specific bits. */ 266 267 static void 268 initialize (void) 269 { 270 /* Initialize supported features. */ 271 check_supported_features (); 272 } 273 274 /* Functions testing instruction decodings. GDB will test all of these. */ 275 static testcase_ftype testcases[] = 276 { 277 rdrand, 278 rdseed 279 }; 280