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