1 /* Low level interface to valgrind, for the remote server for GDB integrated 2 in valgrind. 3 Copyright (C) 2014 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 #include "pub_core_debuginfo.h" 34 35 #include "valgrind_low.h" 36 37 #include "libvex_guest_arm64.h" 38 39 static struct reg regs[] = { 40 { "x0", 0, 64 }, 41 { "x1", 64, 64 }, 42 { "x2", 128, 64 }, 43 { "x3", 192, 64 }, 44 { "x4", 256, 64 }, 45 { "x5", 320, 64 }, 46 { "x6", 384, 64 }, 47 { "x7", 448, 64 }, 48 { "x8", 512, 64 }, 49 { "x9", 576, 64 }, 50 { "x10", 640, 64 }, 51 { "x11", 704, 64 }, 52 { "x12", 768, 64 }, 53 { "x13", 832, 64 }, 54 { "x14", 896, 64 }, 55 { "x15", 960, 64 }, 56 { "x16", 1024, 64 }, 57 { "x17", 1088, 64 }, 58 { "x18", 1152, 64 }, 59 { "x19", 1216, 64 }, 60 { "x20", 1280, 64 }, 61 { "x21", 1344, 64 }, 62 { "x22", 1408, 64 }, 63 { "x23", 1472, 64 }, 64 { "x24", 1536, 64 }, 65 { "x25", 1600, 64 }, 66 { "x26", 1664, 64 }, 67 { "x27", 1728, 64 }, 68 { "x28", 1792, 64 }, 69 { "x29", 1856, 64 }, 70 { "x30", 1920, 64 }, 71 { "sp", 1984, 64 }, 72 { "pc", 2048, 64 }, 73 { "cpsr", 2112, 32 }, 74 { "v0", 2144, 128 }, 75 { "v1", 2272, 128 }, 76 { "v2", 2400, 128 }, 77 { "v3", 2528, 128 }, 78 { "v4", 2656, 128 }, 79 { "v5", 2784, 128 }, 80 { "v6", 2912, 128 }, 81 { "v7", 3040, 128 }, 82 { "v8", 3168, 128 }, 83 { "v9", 3296, 128 }, 84 { "v10", 3424, 128 }, 85 { "v11", 3552, 128 }, 86 { "v12", 3680, 128 }, 87 { "v13", 3808, 128 }, 88 { "v14", 3936, 128 }, 89 { "v15", 4064, 128 }, 90 { "v16", 4192, 128 }, 91 { "v17", 4320, 128 }, 92 { "v18", 4448, 128 }, 93 { "v19", 4576, 128 }, 94 { "v20", 4704, 128 }, 95 { "v21", 4832, 128 }, 96 { "v22", 4960, 128 }, 97 { "v23", 5088, 128 }, 98 { "v24", 5216, 128 }, 99 { "v25", 5344, 128 }, 100 { "v26", 5472, 128 }, 101 { "v27", 5600, 128 }, 102 { "v28", 5728, 128 }, 103 { "v29", 5856, 128 }, 104 { "v30", 5984, 128 }, 105 { "v31", 6112, 128 }, 106 { "fpsr", 6240, 32 }, 107 { "fpcr", 6272, 32 }, 108 }; 109 110 static const char *expedite_regs[] = { "x29", "sp", "pc", 0 }; 111 112 #define num_regs (sizeof (regs) / sizeof (regs[0])) 113 114 static 115 CORE_ADDR get_pc (void) 116 { 117 unsigned long pc; 118 119 collect_register_by_name ("pc", &pc); 120 121 dlog(1, "stop pc is %p\n", (void *) pc); 122 return pc; 123 } 124 125 static 126 void set_pc (CORE_ADDR newpc) 127 { 128 Bool mod; 129 supply_register_by_name ("pc", &newpc, &mod); 130 if (mod) 131 dlog(1, "set pc to %p\n", C2v (newpc)); 132 else 133 dlog(1, "set pc not changed %p\n", C2v (newpc)); 134 } 135 136 /* store registers in the guest state (gdbserver_to_valgrind) 137 or fetch register from the guest state (valgrind_to_gdbserver). */ 138 static 139 void transfer_register (ThreadId tid, int abs_regno, void * buf, 140 transfer_direction dir, int size, Bool *mod) 141 { 142 ThreadState* tst = VG_(get_ThreadState)(tid); 143 int set = abs_regno / num_regs; 144 int regno = abs_regno % num_regs; 145 *mod = False; 146 147 VexGuestARM64State* arm = (VexGuestARM64State*) get_arch (set, tst); 148 149 switch (regno) { 150 // numbers here have to match the order of regs above 151 // Attention: gdb order does not match valgrind order. 152 case 0: VG_(transfer) (&arm->guest_X0, buf, dir, size, mod); break; 153 case 1: VG_(transfer) (&arm->guest_X1, buf, dir, size, mod); break; 154 case 2: VG_(transfer) (&arm->guest_X2, buf, dir, size, mod); break; 155 case 3: VG_(transfer) (&arm->guest_X3, buf, dir, size, mod); break; 156 case 4: VG_(transfer) (&arm->guest_X4, buf, dir, size, mod); break; 157 case 5: VG_(transfer) (&arm->guest_X5, buf, dir, size, mod); break; 158 case 6: VG_(transfer) (&arm->guest_X6, buf, dir, size, mod); break; 159 case 7: VG_(transfer) (&arm->guest_X7, buf, dir, size, mod); break; 160 case 8: VG_(transfer) (&arm->guest_X8, buf, dir, size, mod); break; 161 case 9: VG_(transfer) (&arm->guest_X9, buf, dir, size, mod); break; 162 case 10: VG_(transfer) (&arm->guest_X10, buf, dir, size, mod); break; 163 case 11: VG_(transfer) (&arm->guest_X11, buf, dir, size, mod); break; 164 case 12: VG_(transfer) (&arm->guest_X12, buf, dir, size, mod); break; 165 case 13: VG_(transfer) (&arm->guest_X13, buf, dir, size, mod); break; 166 case 14: VG_(transfer) (&arm->guest_X14, buf, dir, size, mod); break; 167 case 15: VG_(transfer) (&arm->guest_X15, buf, dir, size, mod); break; 168 case 16: VG_(transfer) (&arm->guest_X16, buf, dir, size, mod); break; 169 case 17: VG_(transfer) (&arm->guest_X17, buf, dir, size, mod); break; 170 case 18: VG_(transfer) (&arm->guest_X18, buf, dir, size, mod); break; 171 case 19: VG_(transfer) (&arm->guest_X19, buf, dir, size, mod); break; 172 case 20: VG_(transfer) (&arm->guest_X20, buf, dir, size, mod); break; 173 case 21: VG_(transfer) (&arm->guest_X21, buf, dir, size, mod); break; 174 case 22: VG_(transfer) (&arm->guest_X22, buf, dir, size, mod); break; 175 case 23: VG_(transfer) (&arm->guest_X23, buf, dir, size, mod); break; 176 case 24: VG_(transfer) (&arm->guest_X24, buf, dir, size, mod); break; 177 case 25: VG_(transfer) (&arm->guest_X25, buf, dir, size, mod); break; 178 case 26: VG_(transfer) (&arm->guest_X26, buf, dir, size, mod); break; 179 case 27: VG_(transfer) (&arm->guest_X27, buf, dir, size, mod); break; 180 case 28: VG_(transfer) (&arm->guest_X28, buf, dir, size, mod); break; 181 case 29: VG_(transfer) (&arm->guest_X29, buf, dir, size, mod); break; 182 case 30: VG_(transfer) (&arm->guest_X30, buf, dir, size, mod); break; 183 case 31: VG_(transfer) (&arm->guest_XSP, buf, dir, size, mod); break; 184 case 32: VG_(transfer) (&arm->guest_PC, buf, dir, size, mod); break; 185 case 33: *mod = False; break; // GDBTD cpsr what to do for arm64 ??? 186 187 case 34: VG_(transfer) (&arm->guest_Q0, buf, dir, size, mod); break; 188 case 35: VG_(transfer) (&arm->guest_Q1, buf, dir, size, mod); break; 189 case 36: VG_(transfer) (&arm->guest_Q2, buf, dir, size, mod); break; 190 case 37: VG_(transfer) (&arm->guest_Q3, buf, dir, size, mod); break; 191 case 38: VG_(transfer) (&arm->guest_Q4, buf, dir, size, mod); break; 192 case 39: VG_(transfer) (&arm->guest_Q5, buf, dir, size, mod); break; 193 case 40: VG_(transfer) (&arm->guest_Q6, buf, dir, size, mod); break; 194 case 41: VG_(transfer) (&arm->guest_Q7, buf, dir, size, mod); break; 195 case 42: VG_(transfer) (&arm->guest_Q8, buf, dir, size, mod); break; 196 case 43: VG_(transfer) (&arm->guest_Q9, buf, dir, size, mod); break; 197 case 44: VG_(transfer) (&arm->guest_Q10, buf, dir, size, mod); break; 198 case 45: VG_(transfer) (&arm->guest_Q11, buf, dir, size, mod); break; 199 case 46: VG_(transfer) (&arm->guest_Q12, buf, dir, size, mod); break; 200 case 47: VG_(transfer) (&arm->guest_Q13, buf, dir, size, mod); break; 201 case 48: VG_(transfer) (&arm->guest_Q14, buf, dir, size, mod); break; 202 case 49: VG_(transfer) (&arm->guest_Q15, buf, dir, size, mod); break; 203 case 50: VG_(transfer) (&arm->guest_Q16, buf, dir, size, mod); break; 204 case 51: VG_(transfer) (&arm->guest_Q17, buf, dir, size, mod); break; 205 case 52: VG_(transfer) (&arm->guest_Q18, buf, dir, size, mod); break; 206 case 53: VG_(transfer) (&arm->guest_Q19, buf, dir, size, mod); break; 207 case 54: VG_(transfer) (&arm->guest_Q20, buf, dir, size, mod); break; 208 case 55: VG_(transfer) (&arm->guest_Q21, buf, dir, size, mod); break; 209 case 56: VG_(transfer) (&arm->guest_Q22, buf, dir, size, mod); break; 210 case 57: VG_(transfer) (&arm->guest_Q23, buf, dir, size, mod); break; 211 case 58: VG_(transfer) (&arm->guest_Q24, buf, dir, size, mod); break; 212 case 59: VG_(transfer) (&arm->guest_Q25, buf, dir, size, mod); break; 213 case 60: VG_(transfer) (&arm->guest_Q26, buf, dir, size, mod); break; 214 case 61: VG_(transfer) (&arm->guest_Q27, buf, dir, size, mod); break; 215 case 62: VG_(transfer) (&arm->guest_Q28, buf, dir, size, mod); break; 216 case 63: VG_(transfer) (&arm->guest_Q29, buf, dir, size, mod); break; 217 case 64: VG_(transfer) (&arm->guest_Q30, buf, dir, size, mod); break; 218 case 65: VG_(transfer) (&arm->guest_Q31, buf, dir, size, mod); break; 219 case 66: { 220 /* The VEX ARM64 FPSR representation is not the same as the 221 architecturally defined representation. Hence use conversion 222 functions to convert to/from it. 223 VEX FPSR only models QC (bit 27), and uses a 64 bits to store 224 this FPSR QC bit. So, we need to transfer from/to the lowest 225 significant part of the ULong that VEX provides/needs, 226 as GDB expects or gives only 4 bytes. */ 227 if (dir == valgrind_to_gdbserver) { 228 ULong fpsr64 = LibVEX_GuestARM64_get_fpsr(arm); 229 UInt fpsr = (UInt)fpsr64; 230 VG_(transfer) (&fpsr, buf, dir, size, mod); 231 } else { 232 UInt fpsr; 233 ULong fpsr64; 234 VG_(transfer) ((UInt*)&fpsr, buf, dir, size, mod); 235 fpsr64 = fpsr; 236 LibVEX_GuestARM64_set_fpsr(arm, fpsr64); 237 /* resync the cache with the part of fpsr that VEX represents. */ 238 fpsr64 = LibVEX_GuestARM64_get_fpsr(arm); 239 fpsr = (UInt)fpsr64; 240 VG_(transfer) (&fpsr, buf, valgrind_to_gdbserver, size, mod); 241 } 242 break; 243 } 244 case 67: VG_(transfer) (&arm->guest_FPCR, buf, dir, size, mod); break; 245 default: vg_assert(0); 246 } 247 } 248 249 static 250 const char* target_xml (Bool shadow_mode) 251 { 252 return NULL; 253 #if 0 254 GDBTD 255 if (shadow_mode) { 256 return "arm-with-vfpv3-valgrind.xml"; 257 } else { 258 return "arm-with-vfpv3.xml"; 259 } 260 #endif 261 } 262 263 static CORE_ADDR** target_get_dtv (ThreadState *tst) 264 { 265 VexGuestARM64State* arm64 = (VexGuestARM64State*)&tst->arch.vex; 266 // arm64 dtv is pointed to by TPIDR_EL0. 267 return (CORE_ADDR**)((CORE_ADDR)arm64->guest_TPIDR_EL0); 268 } 269 270 static struct valgrind_target_ops low_target = { 271 num_regs, 272 regs, 273 31, //SP 274 transfer_register, 275 get_pc, 276 set_pc, 277 "arm64", 278 target_xml, 279 target_get_dtv 280 }; 281 282 void arm64_init_architecture (struct valgrind_target_ops *target) 283 { 284 *target = low_target; 285 set_register_cache (regs, num_regs); 286 gdbserver_expedite_regs = expedite_regs; 287 } 288