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