1 /* Low level interface to valgrind, for the remote server for GDB integrated 2 in valgrind. 3 Copyright (C) 2011 4 Free Software Foundation, Inc. 5 6 This file is part of VALGRIND. 7 It has been inspired from a file from gdbserver in gdb 6.6. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 Boston, MA 02110-1301, USA. */ 23 24 #include "server.h" 25 #include "target.h" 26 #include "regdef.h" 27 #include "regcache.h" 28 29 #include "pub_core_aspacemgr.h" 30 #include "pub_core_machine.h" 31 #include "pub_core_threadstate.h" 32 #include "pub_core_transtab.h" 33 #include "pub_core_gdbserver.h" 34 35 #include "valgrind_low.h" 36 37 #include "libvex_guest_amd64.h" 38 /* GDBTD: ??? have a cleaner way to get the f80 <> f64 conversion functions */ 39 /* below include needed for conversion f80 <> f64 */ 40 #include "../../VEX/priv/guest_generic_x87.h" 41 42 /* below loosely inspired from file generated with gdb regdat.sh */ 43 44 static struct reg regs[] = { 45 { "rax", 0, 64 }, 46 { "rbx", 64, 64 }, 47 { "rcx", 128, 64 }, 48 { "rdx", 192, 64 }, 49 { "rsi", 256, 64 }, 50 { "rdi", 320, 64 }, 51 { "rbp", 384, 64 }, 52 { "rsp", 448, 64 }, 53 { "r8", 512, 64 }, 54 { "r9", 576, 64 }, 55 { "r10", 640, 64 }, 56 { "r11", 704, 64 }, 57 { "r12", 768, 64 }, 58 { "r13", 832, 64 }, 59 { "r14", 896, 64 }, 60 { "r15", 960, 64 }, 61 { "rip", 1024, 64 }, 62 { "eflags", 1088, 32 }, 63 { "cs", 1120, 32 }, 64 { "ss", 1152, 32 }, 65 { "ds", 1184, 32 }, 66 { "es", 1216, 32 }, 67 { "fs", 1248, 32 }, 68 { "gs", 1280, 32 }, 69 { "st0", 1312, 80 }, 70 { "st1", 1392, 80 }, 71 { "st2", 1472, 80 }, 72 { "st3", 1552, 80 }, 73 { "st4", 1632, 80 }, 74 { "st5", 1712, 80 }, 75 { "st6", 1792, 80 }, 76 { "st7", 1872, 80 }, 77 { "fctrl", 1952, 32 }, 78 { "fstat", 1984, 32 }, 79 { "ftag", 2016, 32 }, 80 { "fiseg", 2048, 32 }, 81 { "fioff", 2080, 32 }, 82 { "foseg", 2112, 32 }, 83 { "fooff", 2144, 32 }, 84 { "fop", 2176, 32 }, 85 { "xmm0", 2208, 128 }, 86 { "xmm1", 2336, 128 }, 87 { "xmm2", 2464, 128 }, 88 { "xmm3", 2592, 128 }, 89 { "xmm4", 2720, 128 }, 90 { "xmm5", 2848, 128 }, 91 { "xmm6", 2976, 128 }, 92 { "xmm7", 3104, 128 }, 93 { "xmm8", 3232, 128 }, 94 { "xmm9", 3360, 128 }, 95 { "xmm10", 3488, 128 }, 96 { "xmm11", 3616, 128 }, 97 { "xmm12", 3744, 128 }, 98 { "xmm13", 3872, 128 }, 99 { "xmm14", 4000, 128 }, 100 { "xmm15", 4128, 128 }, 101 { "mxcsr", 4256, 32 }, 102 #if defined(VGO_linux) 103 { "orig_rax", 4288, 64 }, 104 #endif 105 { "ymm0h", 4352, 128 }, // The ymm?h registers only to be given to GDB 106 { "ymm1h", 4480, 128 }, // if Valgrind is running with AVX instructions. 107 { "ymm2h", 4608, 128 }, 108 { "ymm3h", 4736, 128 }, 109 { "ymm4h", 4864, 128 }, 110 { "ymm5h", 4992, 128 }, 111 { "ymm6h", 5120, 128 }, 112 { "ymm7h", 5248, 128 }, 113 { "ymm8h", 5376, 128 }, 114 { "ymm9h", 5504, 128 }, 115 { "ymm10h", 5632, 128 }, 116 { "ymm11h", 5760, 128 }, 117 { "ymm12h", 5888, 128 }, 118 { "ymm13h", 6016, 128 }, 119 { "ymm14h", 6144, 128 }, 120 { "ymm15h", 6272, 128 } 121 }; 122 static const char *expedite_regs[] = { "rbp", "rsp", "rip", 0 }; 123 #define max_num_regs (sizeof (regs) / sizeof (regs[0])) 124 static int dyn_num_regs; // if no AVX, we have to give less registers to gdb. 125 126 127 static 128 CORE_ADDR get_pc (void) 129 { 130 unsigned long pc; 131 132 collect_register_by_name ("rip", &pc); 133 134 dlog(1, "stop pc is %p\n", (void *) pc); 135 return pc; 136 } 137 138 static 139 void set_pc (CORE_ADDR newpc) 140 { 141 Bool mod; 142 supply_register_by_name ("rip", &newpc, &mod); 143 if (mod) 144 dlog(1, "set pc to %p\n", C2v (newpc)); 145 else 146 dlog(1, "set pc not changed %p\n", C2v (newpc)); 147 } 148 149 /* store registers in the guest state (gdbserver_to_valgrind) 150 or fetch register from the guest state (valgrind_to_gdbserver). */ 151 static 152 void transfer_register (ThreadId tid, int abs_regno, void * buf, 153 transfer_direction dir, int size, Bool *mod) 154 { 155 ThreadState* tst = VG_(get_ThreadState)(tid); 156 int set = abs_regno / dyn_num_regs; 157 int regno = abs_regno % dyn_num_regs; 158 *mod = False; 159 160 VexGuestAMD64State* amd64 = (VexGuestAMD64State*) get_arch (set, tst); 161 162 switch (regno) { 163 // numbers here have to match the order of regs above. 164 // Attention: gdb order does not match valgrind order. 165 case 0: VG_(transfer) (&amd64->guest_RAX, buf, dir, size, mod); break; 166 case 1: VG_(transfer) (&amd64->guest_RBX, buf, dir, size, mod); break; 167 case 2: VG_(transfer) (&amd64->guest_RCX, buf, dir, size, mod); break; 168 case 3: VG_(transfer) (&amd64->guest_RDX, buf, dir, size, mod); break; 169 case 4: VG_(transfer) (&amd64->guest_RSI, buf, dir, size, mod); break; 170 case 5: VG_(transfer) (&amd64->guest_RDI, buf, dir, size, mod); break; 171 case 6: VG_(transfer) (&amd64->guest_RBP, buf, dir, size, mod); break; 172 case 7: VG_(transfer) (&amd64->guest_RSP, buf, dir, size, mod); break; 173 case 8: VG_(transfer) (&amd64->guest_R8, buf, dir, size, mod); break; 174 case 9: VG_(transfer) (&amd64->guest_R9, buf, dir, size, mod); break; 175 case 10: VG_(transfer) (&amd64->guest_R10, buf, dir, size, mod); break; 176 case 11: VG_(transfer) (&amd64->guest_R11, buf, dir, size, mod); break; 177 case 12: VG_(transfer) (&amd64->guest_R12, buf, dir, size, mod); break; 178 case 13: VG_(transfer) (&amd64->guest_R13, buf, dir, size, mod); break; 179 case 14: VG_(transfer) (&amd64->guest_R14, buf, dir, size, mod); break; 180 case 15: VG_(transfer) (&amd64->guest_R15, buf, dir, size, mod); break; 181 case 16: VG_(transfer) (&amd64->guest_RIP, buf, dir, size, mod); break; 182 case 17: 183 if (dir == valgrind_to_gdbserver) { 184 ULong rflags; 185 /* we can only retrieve the real flags (set 0) 186 retrieving shadow flags is not ok */ 187 if (set == 0) 188 rflags = LibVEX_GuestAMD64_get_rflags (amd64); 189 else 190 rflags = 0; 191 VG_(transfer) (&rflags, buf, dir, size, mod); 192 } else { 193 *mod = False; //GDBTD? how do we store rflags in libvex_guest_amd64.h ??? 194 } 195 break; 196 case 18: *mod = False; break; //GDBTD VG_(transfer) (&amd64->guest_CS, buf, dir, size, mod); 197 case 19: *mod = False; break; //GDBTD VG_(transfer) (&amd64->guest_SS, buf, dir, size, mod); 198 case 20: *mod = False; break; //GDBTD VG_(transfer) (&amd64->guest_DS, buf, dir, size, mod); 199 case 21: *mod = False; break; //GDBTD VG_(transfer) (&amd64->guest_ES, buf, dir, size, mod); 200 case 22: *mod = False; break; //GDBTD VG_(transfer) (&amd64->guest_FS, buf, dir, size, mod); 201 case 23: VG_(transfer) (&amd64->guest_GS_0x60, buf, dir, size, mod); break; 202 case 24: 203 case 25: 204 case 26: 205 case 27: /* register 24 to 31 are float registers 80 bits but 64 bits in valgrind */ 206 case 28: 207 case 29: 208 case 30: 209 case 31: 210 if (dir == valgrind_to_gdbserver) { 211 UChar fpreg80[10]; 212 convert_f64le_to_f80le ((UChar *)&amd64->guest_FPREG[regno-24], 213 fpreg80); 214 VG_(transfer) (&fpreg80, buf, dir, sizeof(fpreg80), mod); 215 } else { 216 ULong fpreg64; 217 convert_f80le_to_f64le (buf, (UChar *)&fpreg64); 218 VG_(transfer) (&amd64->guest_FPREG[regno-24], &fpreg64, 219 dir, sizeof(fpreg64), mod); 220 } 221 break; 222 case 32: 223 if (dir == valgrind_to_gdbserver) { 224 // vex only models the rounding bits (see libvex_guest_amd64.h) 225 UWord value = 0x037f; 226 value |= amd64->guest_FPROUND << 10; 227 VG_(transfer)(&value, buf, dir, size, mod); 228 } else { 229 *mod = False; // GDBTD???? VEX equivalent fcrtl 230 } 231 break; 232 case 33: 233 if (dir == valgrind_to_gdbserver) { 234 UWord value = amd64->guest_FC3210; 235 value |= (amd64->guest_FTOP & 7) << 11; 236 VG_(transfer)(&value, buf, dir, size, mod); 237 } else { 238 *mod = False; // GDBTD???? VEX equivalent fstat 239 } 240 break; 241 case 34: 242 if (dir == valgrind_to_gdbserver) { 243 // vex doesn't model these precisely 244 UWord value = 245 ((amd64->guest_FPTAG[0] ? 0 : 3) << 0) | 246 ((amd64->guest_FPTAG[1] ? 0 : 3) << 2) | 247 ((amd64->guest_FPTAG[2] ? 0 : 3) << 4) | 248 ((amd64->guest_FPTAG[3] ? 0 : 3) << 6) | 249 ((amd64->guest_FPTAG[4] ? 0 : 3) << 8) | 250 ((amd64->guest_FPTAG[5] ? 0 : 3) << 10) | 251 ((amd64->guest_FPTAG[6] ? 0 : 3) << 12) | 252 ((amd64->guest_FPTAG[7] ? 0 : 3) << 14); 253 VG_(transfer)(&value, buf, dir, size, mod); 254 } else { 255 *mod = False; // GDBTD???? VEX equivalent ftag 256 } 257 break; 258 case 35: *mod = False; break; // GDBTD ??? equivalent of fiseg 259 case 36: *mod = False; break; // GDBTD ??? equivalent of fioff 260 case 37: *mod = False; break; // GDBTD ??? equivalent of foseg 261 case 38: *mod = False; break; // GDBTD ??? equivalent of fooff 262 case 39: *mod = False; break; // GDBTD ??? equivalent of fop 263 case 40: VG_(transfer) (&amd64->guest_YMM0[0], buf, dir, size, mod); break; 264 case 41: VG_(transfer) (&amd64->guest_YMM1[0], buf, dir, size, mod); break; 265 case 42: VG_(transfer) (&amd64->guest_YMM2[0], buf, dir, size, mod); break; 266 case 43: VG_(transfer) (&amd64->guest_YMM3[0], buf, dir, size, mod); break; 267 case 44: VG_(transfer) (&amd64->guest_YMM4[0], buf, dir, size, mod); break; 268 case 45: VG_(transfer) (&amd64->guest_YMM5[0], buf, dir, size, mod); break; 269 case 46: VG_(transfer) (&amd64->guest_YMM6[0], buf, dir, size, mod); break; 270 case 47: VG_(transfer) (&amd64->guest_YMM7[0], buf, dir, size, mod); break; 271 case 48: VG_(transfer) (&amd64->guest_YMM8[0], buf, dir, size, mod); break; 272 case 49: VG_(transfer) (&amd64->guest_YMM9[0], buf, dir, size, mod); break; 273 case 50: VG_(transfer) (&amd64->guest_YMM10[0], buf, dir, size, mod); break; 274 case 51: VG_(transfer) (&amd64->guest_YMM11[0], buf, dir, size, mod); break; 275 case 52: VG_(transfer) (&amd64->guest_YMM12[0], buf, dir, size, mod); break; 276 case 53: VG_(transfer) (&amd64->guest_YMM13[0], buf, dir, size, mod); break; 277 case 54: VG_(transfer) (&amd64->guest_YMM14[0], buf, dir, size, mod); break; 278 case 55: VG_(transfer) (&amd64->guest_YMM15[0], buf, dir, size, mod); break; 279 case 56: 280 if (dir == valgrind_to_gdbserver) { 281 // vex only models the rounding bits (see libvex_guest_x86.h) 282 UWord value = 0x1f80; 283 value |= amd64->guest_SSEROUND << 13; 284 VG_(transfer)(&value, buf, dir, size, mod); 285 } else { 286 *mod = False; // GDBTD???? VEX equivalent mxcsr 287 } 288 break; 289 case 57: *mod = False; break; // GDBTD???? VEX equivalent { "orig_rax"}, 290 case 58: VG_(transfer) (&amd64->guest_YMM0[4], buf, dir, size, mod); break; 291 case 59: VG_(transfer) (&amd64->guest_YMM1[4], buf, dir, size, mod); break; 292 case 60: VG_(transfer) (&amd64->guest_YMM2[4], buf, dir, size, mod); break; 293 case 61: VG_(transfer) (&amd64->guest_YMM3[4], buf, dir, size, mod); break; 294 case 62: VG_(transfer) (&amd64->guest_YMM4[4], buf, dir, size, mod); break; 295 case 63: VG_(transfer) (&amd64->guest_YMM5[4], buf, dir, size, mod); break; 296 case 64: VG_(transfer) (&amd64->guest_YMM6[4], buf, dir, size, mod); break; 297 case 65: VG_(transfer) (&amd64->guest_YMM7[4], buf, dir, size, mod); break; 298 case 66: VG_(transfer) (&amd64->guest_YMM8[4], buf, dir, size, mod); break; 299 case 67: VG_(transfer) (&amd64->guest_YMM9[4], buf, dir, size, mod); break; 300 case 68: VG_(transfer) (&amd64->guest_YMM10[4], buf, dir, size, mod); break; 301 case 69: VG_(transfer) (&amd64->guest_YMM11[4], buf, dir, size, mod); break; 302 case 70: VG_(transfer) (&amd64->guest_YMM12[4], buf, dir, size, mod); break; 303 case 71: VG_(transfer) (&amd64->guest_YMM13[4], buf, dir, size, mod); break; 304 case 72: VG_(transfer) (&amd64->guest_YMM14[4], buf, dir, size, mod); break; 305 case 73: VG_(transfer) (&amd64->guest_YMM15[4], buf, dir, size, mod); break; 306 default: vg_assert(0); 307 } 308 } 309 310 static 311 Bool have_avx(void) 312 { 313 VexArch va; 314 VexArchInfo vai; 315 VG_(machine_get_VexArchInfo) (&va, &vai); 316 return (vai.hwcaps & VEX_HWCAPS_AMD64_AVX ? True : False); 317 } 318 static 319 const char* target_xml (Bool shadow_mode) 320 { 321 if (shadow_mode) { 322 #if defined(VGO_linux) 323 if (have_avx()) 324 return "amd64-avx-linux-valgrind.xml"; 325 else 326 return "amd64-linux-valgrind.xml"; 327 #else 328 if (have_avx()) 329 return "amd64-avx-coresse-valgrind.xml"; 330 else 331 return "amd64-coresse-valgrind.xml"; 332 #endif 333 } else { 334 #if defined(VGO_linux) 335 if (have_avx()) 336 return "amd64-avx-linux.xml"; 337 else 338 return NULL; 339 #else 340 if (have_avx()) 341 return "amd64-avx-coresse.xml"; 342 else 343 return NULL; 344 #endif 345 } 346 } 347 348 static struct valgrind_target_ops low_target = { 349 -1, // Must be computed at init time. 350 regs, 351 7, //RSP 352 transfer_register, 353 get_pc, 354 set_pc, 355 "amd64", 356 target_xml 357 }; 358 359 void amd64_init_architecture (struct valgrind_target_ops *target) 360 { 361 *target = low_target; 362 if (have_avx()) 363 dyn_num_regs = max_num_regs; 364 else 365 dyn_num_regs = max_num_regs - 16; // remove the AVX "high" registers. 366 target->num_regs = dyn_num_regs; 367 set_register_cache (regs, dyn_num_regs); 368 gdbserver_expedite_regs = expedite_regs; 369 } 370