sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 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 | |
florian | c91f584 | 2013-09-15 10:42:26 +0000 | [diff] [blame] | 29 | #include "pub_core_machine.h" |
sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 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_ppc64.h" |
| 37 | |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 38 | /* The PPC64 register layout with vs register support (Power 7 and beyond) |
| 39 | consists of 64 VSR registers of size 128-bits. The 32 floating point |
| 40 | registers fp map to the upper 64-bits of vsr[0] to vsr[31]. The 32 |
| 41 | vr[0] to vr[31] registers of size 128-bits map to vsr[31] to vsr[63]. The |
| 42 | lower 64-bits of the vsr[0] to vsr[31] registers are in the pseudo |
| 43 | registers vs[0]h to vs[31]h registers. These pseudo registers get printed |
| 44 | by GDB but there are no instructions that directly access these registers. |
| 45 | When GDB prints the vsr[0] to vsr[31] registers it combines the contents |
| 46 | of the floating point registers fp[0] to fp[31] and its corresponding |
| 47 | vs[0]h to vs[31]h registers to display the VSR contents. The vsr[32] |
| 48 | to vsr[63] contents are the same as the the vr[0] to vr[31] contents. |
| 49 | |
| 50 | GDB also prints fp[32] to fp[63]. These are simply the upper 64 bits of |
| 51 | vsr[32] to vsr[63] however, these are not "real" floating point registers |
| 52 | as none of the floating point instructions can access these registers. |
| 53 | |
| 54 | Register map. |
| 55 | MSB IBM bit numbering LSB |
| 56 | 0 63 64 127 |
| 57 | vsr[0] | fp[0] | vs[0]h | |
| 58 | vsr[1] | fp[1] | vs[1]h | |
| 59 | vsr[2] | fp[2] | vs[2]h | |
| 60 | ... |
| 61 | vsr[31] | fp[31] | vs[31]h | |
| 62 | vsr[32] | vr[0] | |
| 63 | vsr[33] | vr[1] | |
| 64 | ... |
| 65 | vsr[63] | vr[31] | |
| 66 | |
| 67 | Note, not shown above are the fake fp[32] to fp[63] that GDB prints |
| 68 | |
| 69 | Valgrind has two shadow registers for each real register denoted with |
| 70 | the suffix s1 and s2. When printing the contents of the shadow registers, |
| 71 | GDB does not explicitly print the shadow registers vsr[0] to vsr[63]. GDB |
| 72 | prints the shadow register contents of the 32 floating point registers as |
| 73 | fp[0]s1 to fp[31]s1 and fp[0]s2 to fp[31]s2. The shadow register contents |
| 74 | of vs[0]hs1 to vs[31]hs1 and vs[0]hs2 to vs[31]hs2 are also printed. The |
| 75 | user needs to construct the vsr[i]s1 shadow register contents by looking |
| 76 | at fp[i]s1 for the upper 64-bits and vs[i]hs1 for the lower 64-bits. The |
| 77 | vsr[i]s2 shadow register contents are constructed similarly. |
| 78 | |
| 79 | GDB prints the 128-bit shadow register contents of the 32 vr registers as |
| 80 | vr[0]s1 to vr[31]s1 and vr[0]s2 to vr[31]s2. These are also the value of the |
| 81 | VSR shadow registers vsr[32]s1 to vsr[63]s1 and vsr[32]s2 to vsr[63]s2. */ |
| 82 | |
sewardj | d7209de | 2012-07-21 10:10:44 +0000 | [diff] [blame] | 83 | static struct reg regs[] = { |
sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 84 | { "r0", 0, 64 }, |
| 85 | { "r1", 64, 64 }, |
| 86 | { "r2", 128, 64 }, |
| 87 | { "r3", 192, 64 }, |
| 88 | { "r4", 256, 64 }, |
| 89 | { "r5", 320, 64 }, |
| 90 | { "r6", 384, 64 }, |
| 91 | { "r7", 448, 64 }, |
| 92 | { "r8", 512, 64 }, |
| 93 | { "r9", 576, 64 }, |
| 94 | { "r10", 640, 64 }, |
| 95 | { "r11", 704, 64 }, |
| 96 | { "r12", 768, 64 }, |
| 97 | { "r13", 832, 64 }, |
| 98 | { "r14", 896, 64 }, |
| 99 | { "r15", 960, 64 }, |
| 100 | { "r16", 1024, 64 }, |
| 101 | { "r17", 1088, 64 }, |
| 102 | { "r18", 1152, 64 }, |
| 103 | { "r19", 1216, 64 }, |
| 104 | { "r20", 1280, 64 }, |
| 105 | { "r21", 1344, 64 }, |
| 106 | { "r22", 1408, 64 }, |
| 107 | { "r23", 1472, 64 }, |
| 108 | { "r24", 1536, 64 }, |
| 109 | { "r25", 1600, 64 }, |
| 110 | { "r26", 1664, 64 }, |
| 111 | { "r27", 1728, 64 }, |
| 112 | { "r28", 1792, 64 }, |
| 113 | { "r29", 1856, 64 }, |
| 114 | { "r30", 1920, 64 }, |
| 115 | { "r31", 1984, 64 }, |
| 116 | { "f0", 2048, 64 }, |
| 117 | { "f1", 2112, 64 }, |
| 118 | { "f2", 2176, 64 }, |
| 119 | { "f3", 2240, 64 }, |
| 120 | { "f4", 2304, 64 }, |
| 121 | { "f5", 2368, 64 }, |
| 122 | { "f6", 2432, 64 }, |
| 123 | { "f7", 2496, 64 }, |
| 124 | { "f8", 2560, 64 }, |
| 125 | { "f9", 2624, 64 }, |
| 126 | { "f10", 2688, 64 }, |
| 127 | { "f11", 2752, 64 }, |
| 128 | { "f12", 2816, 64 }, |
| 129 | { "f13", 2880, 64 }, |
| 130 | { "f14", 2944, 64 }, |
| 131 | { "f15", 3008, 64 }, |
| 132 | { "f16", 3072, 64 }, |
| 133 | { "f17", 3136, 64 }, |
| 134 | { "f18", 3200, 64 }, |
| 135 | { "f19", 3264, 64 }, |
| 136 | { "f20", 3328, 64 }, |
| 137 | { "f21", 3392, 64 }, |
| 138 | { "f22", 3456, 64 }, |
| 139 | { "f23", 3520, 64 }, |
| 140 | { "f24", 3584, 64 }, |
| 141 | { "f25", 3648, 64 }, |
| 142 | { "f26", 3712, 64 }, |
| 143 | { "f27", 3776, 64 }, |
| 144 | { "f28", 3840, 64 }, |
| 145 | { "f29", 3904, 64 }, |
| 146 | { "f30", 3968, 64 }, |
| 147 | { "f31", 4032, 64 }, |
| 148 | { "pc", 4096, 64 }, |
| 149 | { "msr", 4160, 64 }, |
| 150 | { "cr", 4224, 32 }, |
| 151 | { "lr", 4256, 64 }, |
| 152 | { "ctr", 4320, 64 }, |
| 153 | { "xer", 4384, 32 }, |
| 154 | { "fpscr", 4416, 32 }, |
| 155 | { "orig_r3", 4448, 64 }, |
| 156 | { "trap", 4512, 64 }, |
| 157 | { "vr0", 4576, 128 }, |
| 158 | { "vr1", 4704, 128 }, |
| 159 | { "vr2", 4832, 128 }, |
| 160 | { "vr3", 4960, 128 }, |
| 161 | { "vr4", 5088, 128 }, |
| 162 | { "vr5", 5216, 128 }, |
| 163 | { "vr6", 5344, 128 }, |
| 164 | { "vr7", 5472, 128 }, |
| 165 | { "vr8", 5600, 128 }, |
| 166 | { "vr9", 5728, 128 }, |
| 167 | { "vr10", 5856, 128 }, |
| 168 | { "vr11", 5984, 128 }, |
| 169 | { "vr12", 6112, 128 }, |
| 170 | { "vr13", 6240, 128 }, |
| 171 | { "vr14", 6368, 128 }, |
| 172 | { "vr15", 6496, 128 }, |
| 173 | { "vr16", 6624, 128 }, |
| 174 | { "vr17", 6752, 128 }, |
| 175 | { "vr18", 6880, 128 }, |
| 176 | { "vr19", 7008, 128 }, |
| 177 | { "vr20", 7136, 128 }, |
| 178 | { "vr21", 7264, 128 }, |
| 179 | { "vr22", 7392, 128 }, |
| 180 | { "vr23", 7520, 128 }, |
| 181 | { "vr24", 7648, 128 }, |
| 182 | { "vr25", 7776, 128 }, |
| 183 | { "vr26", 7904, 128 }, |
| 184 | { "vr27", 8032, 128 }, |
| 185 | { "vr28", 8160, 128 }, |
| 186 | { "vr29", 8288, 128 }, |
| 187 | { "vr30", 8416, 128 }, |
| 188 | { "vr31", 8544, 128 }, |
| 189 | { "vscr", 8672, 32 }, |
| 190 | { "vrsave", 8704, 32 }, |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 191 | { "vs0h", 8736, 64 }, |
| 192 | { "vs1h", 8800, 64 }, |
| 193 | { "vs2h", 8864, 64 }, |
| 194 | { "vs3h", 8928, 64 }, |
| 195 | { "vs4h", 8992, 64 }, |
| 196 | { "vs5h", 9056, 64 }, |
| 197 | { "vs6h", 9120, 64 }, |
| 198 | { "vs7h", 9184, 64 }, |
| 199 | { "vs8h", 9248, 64 }, |
| 200 | { "vs9h", 9312, 64 }, |
| 201 | { "vs10h", 9376, 64 }, |
| 202 | { "vs11h", 9440, 64 }, |
| 203 | { "vs12h", 9504, 64 }, |
| 204 | { "vs13h", 9568, 64 }, |
| 205 | { "vs14h", 9632, 64 }, |
| 206 | { "vs15h", 9696, 64 }, |
| 207 | { "vs16h", 9760, 64 }, |
| 208 | { "vs17h", 9824, 64 }, |
| 209 | { "vs18h", 9888, 64 }, |
| 210 | { "vs19h", 9952, 64 }, |
| 211 | { "vs20h", 10016, 64 }, |
| 212 | { "vs21h", 10080, 64 }, |
| 213 | { "vs22h", 10144, 64 }, |
| 214 | { "vs23h", 10208, 64 }, |
| 215 | { "vs24h", 10272, 64 }, |
| 216 | { "vs25h", 10336, 64 }, |
| 217 | { "vs26h", 10400, 64 }, |
| 218 | { "vs27h", 10464, 64 }, |
| 219 | { "vs28h", 10528, 64 }, |
| 220 | { "vs29h", 10592, 64 }, |
| 221 | { "vs30h", 10656, 64 }, |
| 222 | { "vs31h", 10720, 64 }, |
sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 223 | }; |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 224 | |
sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 225 | static const char *expedite_regs[] = { "r1", "pc", 0 }; |
| 226 | #define num_regs (sizeof (regs) / sizeof (regs[0])) |
| 227 | |
| 228 | static |
| 229 | CORE_ADDR get_pc (void) |
| 230 | { |
| 231 | unsigned long pc; |
| 232 | |
| 233 | collect_register_by_name ("pc", &pc); |
| 234 | |
| 235 | dlog(1, "stop pc is %p\n", (void *) pc); |
| 236 | return pc; |
| 237 | } |
| 238 | |
| 239 | static |
| 240 | void set_pc (CORE_ADDR newpc) |
| 241 | { |
| 242 | Bool mod; |
| 243 | supply_register_by_name ("pc", &newpc, &mod); |
| 244 | if (mod) |
| 245 | dlog(1, "set pc to %p\n", C2v (newpc)); |
| 246 | else |
| 247 | dlog(1, "set pc not changed %p\n", C2v (newpc)); |
| 248 | } |
| 249 | |
| 250 | /* store registers in the guest state (gdbserver_to_valgrind) |
| 251 | or fetch register from the guest state (valgrind_to_gdbserver). */ |
| 252 | static |
| 253 | void transfer_register (ThreadId tid, int abs_regno, void * buf, |
| 254 | transfer_direction dir, int size, Bool *mod) |
| 255 | { |
| 256 | ThreadState* tst = VG_(get_ThreadState)(tid); |
| 257 | int set = abs_regno / num_regs; |
| 258 | int regno = abs_regno % num_regs; |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 259 | int low_offset, high_offset; |
| 260 | |
sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 261 | *mod = False; |
| 262 | |
| 263 | VexGuestPPC64State* ppc64 = (VexGuestPPC64State*) get_arch (set, tst); |
| 264 | |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 265 | |
| 266 | #if defined (VG_LITTLEENDIAN) |
| 267 | /* Fetch the 64-bits for the VR registers (VSR[32] to VSR[63] stored as |
| 268 | * Little Endian. The 128-bit value is stored as an array of four 32-bit |
| 269 | * values. The lower 32-bits are in element 0 in Little Endian format. |
| 270 | */ |
| 271 | low_offset = 0; |
| 272 | |
| 273 | /* Fetch the upper 64-bits for the floating point register stored as |
| 274 | * Little Endian. The 128-bit value is stored as an array of four 32-bit |
| 275 | * values. The upper 32-bits are in element 3 in Little Endian format. |
| 276 | */ |
| 277 | high_offset = 2; |
| 278 | #elif defined (VG_BIGENDIAN) |
| 279 | /* Fetch the 64-bits for the VR registers (VSR[32] to VSR[63] stored as |
| 280 | * Little Endian. The 128-bit value is stored as an array of four 32-bit |
| 281 | * values. The lower 32-bits are in element 3 in Big Endian format. |
| 282 | */ |
| 283 | low_offset = 2; |
| 284 | |
| 285 | /* Fetch the upper 64-bits for the floating point register stored as |
| 286 | * Little Endian. The 128-bit value is stored as an array of four 32-bit |
| 287 | * values. The upper 32-bits are in element 0 in Big Endian format. |
| 288 | */ |
| 289 | high_offset = 0; |
| 290 | #else |
| 291 | # error "Unknown endianness" |
| 292 | #endif |
| 293 | |
| 294 | switch (regno) { |
sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 295 | // numbers here have to match the order of regs above |
| 296 | // Attention: gdb order does not match valgrind order. |
| 297 | case 0: VG_(transfer) (&ppc64->guest_GPR0, buf, dir, size, mod); break; |
| 298 | case 1: VG_(transfer) (&ppc64->guest_GPR1, buf, dir, size, mod); break; |
| 299 | case 2: VG_(transfer) (&ppc64->guest_GPR2, buf, dir, size, mod); break; |
| 300 | case 3: VG_(transfer) (&ppc64->guest_GPR3, buf, dir, size, mod); break; |
| 301 | case 4: VG_(transfer) (&ppc64->guest_GPR4, buf, dir, size, mod); break; |
| 302 | case 5: VG_(transfer) (&ppc64->guest_GPR5, buf, dir, size, mod); break; |
| 303 | case 6: VG_(transfer) (&ppc64->guest_GPR6, buf, dir, size, mod); break; |
| 304 | case 7: VG_(transfer) (&ppc64->guest_GPR7, buf, dir, size, mod); break; |
| 305 | case 8: VG_(transfer) (&ppc64->guest_GPR8, buf, dir, size, mod); break; |
| 306 | case 9: VG_(transfer) (&ppc64->guest_GPR9, buf, dir, size, mod); break; |
| 307 | case 10: VG_(transfer) (&ppc64->guest_GPR10, buf, dir, size, mod); break; |
| 308 | case 11: VG_(transfer) (&ppc64->guest_GPR11, buf, dir, size, mod); break; |
| 309 | case 12: VG_(transfer) (&ppc64->guest_GPR12, buf, dir, size, mod); break; |
| 310 | case 13: VG_(transfer) (&ppc64->guest_GPR13, buf, dir, size, mod); break; |
| 311 | case 14: VG_(transfer) (&ppc64->guest_GPR14, buf, dir, size, mod); break; |
| 312 | case 15: VG_(transfer) (&ppc64->guest_GPR15, buf, dir, size, mod); break; |
| 313 | case 16: VG_(transfer) (&ppc64->guest_GPR16, buf, dir, size, mod); break; |
| 314 | case 17: VG_(transfer) (&ppc64->guest_GPR17, buf, dir, size, mod); break; |
| 315 | case 18: VG_(transfer) (&ppc64->guest_GPR18, buf, dir, size, mod); break; |
| 316 | case 19: VG_(transfer) (&ppc64->guest_GPR19, buf, dir, size, mod); break; |
| 317 | case 20: VG_(transfer) (&ppc64->guest_GPR20, buf, dir, size, mod); break; |
| 318 | case 21: VG_(transfer) (&ppc64->guest_GPR21, buf, dir, size, mod); break; |
| 319 | case 22: VG_(transfer) (&ppc64->guest_GPR22, buf, dir, size, mod); break; |
| 320 | case 23: VG_(transfer) (&ppc64->guest_GPR23, buf, dir, size, mod); break; |
| 321 | case 24: VG_(transfer) (&ppc64->guest_GPR24, buf, dir, size, mod); break; |
| 322 | case 25: VG_(transfer) (&ppc64->guest_GPR25, buf, dir, size, mod); break; |
| 323 | case 26: VG_(transfer) (&ppc64->guest_GPR26, buf, dir, size, mod); break; |
| 324 | case 27: VG_(transfer) (&ppc64->guest_GPR27, buf, dir, size, mod); break; |
| 325 | case 28: VG_(transfer) (&ppc64->guest_GPR28, buf, dir, size, mod); break; |
| 326 | case 29: VG_(transfer) (&ppc64->guest_GPR29, buf, dir, size, mod); break; |
| 327 | case 30: VG_(transfer) (&ppc64->guest_GPR30, buf, dir, size, mod); break; |
| 328 | case 31: VG_(transfer) (&ppc64->guest_GPR31, buf, dir, size, mod); break; |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 329 | |
| 330 | case 32: VG_(transfer) (&ppc64->guest_VSR0[high_offset], buf, dir, size, mod); break; |
| 331 | case 33: VG_(transfer) (&ppc64->guest_VSR1[high_offset], buf, dir, size, mod); break; |
| 332 | case 34: VG_(transfer) (&ppc64->guest_VSR2[high_offset], buf, dir, size, mod); break; |
| 333 | case 35: VG_(transfer) (&ppc64->guest_VSR3[high_offset], buf, dir, size, mod); break; |
| 334 | case 36: VG_(transfer) (&ppc64->guest_VSR4[high_offset], buf, dir, size, mod); break; |
| 335 | case 37: VG_(transfer) (&ppc64->guest_VSR5[high_offset], buf, dir, size, mod); break; |
| 336 | case 38: VG_(transfer) (&ppc64->guest_VSR6[high_offset], buf, dir, size, mod); break; |
| 337 | case 39: VG_(transfer) (&ppc64->guest_VSR7[high_offset], buf, dir, size, mod); break; |
| 338 | case 40: VG_(transfer) (&ppc64->guest_VSR8[high_offset], buf, dir, size, mod); break; |
| 339 | case 41: VG_(transfer) (&ppc64->guest_VSR9[high_offset], buf, dir, size, mod); break; |
| 340 | case 42: VG_(transfer) (&ppc64->guest_VSR10[high_offset], buf, dir, size, mod); break; |
| 341 | case 43: VG_(transfer) (&ppc64->guest_VSR11[high_offset], buf, dir, size, mod); break; |
| 342 | case 44: VG_(transfer) (&ppc64->guest_VSR12[high_offset], buf, dir, size, mod); break; |
| 343 | case 45: VG_(transfer) (&ppc64->guest_VSR13[high_offset], buf, dir, size, mod); break; |
| 344 | case 46: VG_(transfer) (&ppc64->guest_VSR14[high_offset], buf, dir, size, mod); break; |
| 345 | case 47: VG_(transfer) (&ppc64->guest_VSR15[high_offset], buf, dir, size, mod); break; |
| 346 | case 48: VG_(transfer) (&ppc64->guest_VSR16[high_offset], buf, dir, size, mod); break; |
| 347 | case 49: VG_(transfer) (&ppc64->guest_VSR17[high_offset], buf, dir, size, mod); break; |
| 348 | case 50: VG_(transfer) (&ppc64->guest_VSR18[high_offset], buf, dir, size, mod); break; |
| 349 | case 51: VG_(transfer) (&ppc64->guest_VSR19[high_offset], buf, dir, size, mod); break; |
| 350 | case 52: VG_(transfer) (&ppc64->guest_VSR20[high_offset], buf, dir, size, mod); break; |
| 351 | case 53: VG_(transfer) (&ppc64->guest_VSR21[high_offset], buf, dir, size, mod); break; |
| 352 | case 54: VG_(transfer) (&ppc64->guest_VSR22[high_offset], buf, dir, size, mod); break; |
| 353 | case 55: VG_(transfer) (&ppc64->guest_VSR23[high_offset], buf, dir, size, mod); break; |
| 354 | case 56: VG_(transfer) (&ppc64->guest_VSR24[high_offset], buf, dir, size, mod); break; |
| 355 | case 57: VG_(transfer) (&ppc64->guest_VSR25[high_offset], buf, dir, size, mod); break; |
| 356 | case 58: VG_(transfer) (&ppc64->guest_VSR26[high_offset], buf, dir, size, mod); break; |
| 357 | case 59: VG_(transfer) (&ppc64->guest_VSR27[high_offset], buf, dir, size, mod); break; |
| 358 | case 60: VG_(transfer) (&ppc64->guest_VSR28[high_offset], buf, dir, size, mod); break; |
| 359 | case 61: VG_(transfer) (&ppc64->guest_VSR29[high_offset], buf, dir, size, mod); break; |
| 360 | case 62: VG_(transfer) (&ppc64->guest_VSR30[high_offset], buf, dir, size, mod); break; |
| 361 | case 63: VG_(transfer) (&ppc64->guest_VSR31[high_offset], buf, dir, size, mod); break; |
| 362 | |
sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 363 | case 64: VG_(transfer) (&ppc64->guest_CIA, buf, dir, size, mod); break; |
| 364 | case 65: *mod = False; break; // VEX does not model Machine State Register |
| 365 | case 66: { |
| 366 | UInt cr = LibVEX_GuestPPC64_get_CR (ppc64); |
| 367 | if (dir == valgrind_to_gdbserver) { |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 368 | VG_(transfer) (&cr, buf, dir, size, mod); |
sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 369 | } else { |
| 370 | UInt newcr; |
| 371 | VG_(transfer) (&newcr, buf, dir, size, mod); |
| 372 | *mod = newcr != cr; |
| 373 | LibVEX_GuestPPC64_put_CR (newcr, ppc64); |
| 374 | } |
| 375 | break; |
| 376 | } |
| 377 | case 67: VG_(transfer) (&ppc64->guest_LR, buf, dir, size, mod); break; |
| 378 | case 68: VG_(transfer) (&ppc64->guest_CTR, buf, dir, size, mod); break; |
| 379 | case 69: { |
| 380 | UInt xer = LibVEX_GuestPPC64_get_XER (ppc64); |
| 381 | if (dir == valgrind_to_gdbserver) { |
| 382 | VG_(transfer) (&xer, buf, dir, size, mod); |
| 383 | } else { |
| 384 | UInt newxer; |
| 385 | VG_(transfer) (&newxer, buf, dir, size, mod); |
| 386 | *mod = newxer != xer; |
| 387 | LibVEX_GuestPPC64_put_XER (newxer, ppc64); |
| 388 | } |
| 389 | break; |
| 390 | } |
| 391 | case 70: VG_(transfer) (&ppc64->guest_FPROUND, buf, dir, size, mod); break; |
| 392 | case 71: *mod = False; break; // GDBTD???? VEX { "orig_r3", 4448, 64 }, |
| 393 | case 72: *mod = False; break; // GDBTD???? VEX { "trap", 4512, 64 }, |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 394 | |
| 395 | case 73: VG_(transfer) (&ppc64->guest_VSR32, buf, dir, size, mod); break; |
| 396 | case 74: VG_(transfer) (&ppc64->guest_VSR33, buf, dir, size, mod); break; |
| 397 | case 75: VG_(transfer) (&ppc64->guest_VSR34, buf, dir, size, mod); break; |
| 398 | case 76: VG_(transfer) (&ppc64->guest_VSR35, buf, dir, size, mod); break; |
| 399 | case 77: VG_(transfer) (&ppc64->guest_VSR36, buf, dir, size, mod); break; |
| 400 | case 78: VG_(transfer) (&ppc64->guest_VSR37, buf, dir, size, mod); break; |
| 401 | case 79: VG_(transfer) (&ppc64->guest_VSR38, buf, dir, size, mod); break; |
| 402 | case 80: VG_(transfer) (&ppc64->guest_VSR39, buf, dir, size, mod); break; |
| 403 | case 81: VG_(transfer) (&ppc64->guest_VSR40, buf, dir, size, mod); break; |
| 404 | case 82: VG_(transfer) (&ppc64->guest_VSR40, buf, dir, size, mod); break; |
| 405 | case 83: VG_(transfer) (&ppc64->guest_VSR42, buf, dir, size, mod); break; |
| 406 | case 84: VG_(transfer) (&ppc64->guest_VSR43, buf, dir, size, mod); break; |
| 407 | case 85: VG_(transfer) (&ppc64->guest_VSR44, buf, dir, size, mod); break; |
| 408 | case 86: VG_(transfer) (&ppc64->guest_VSR45, buf, dir, size, mod); break; |
| 409 | case 87: VG_(transfer) (&ppc64->guest_VSR46, buf, dir, size, mod); break; |
| 410 | case 88: VG_(transfer) (&ppc64->guest_VSR47, buf, dir, size, mod); break; |
| 411 | case 89: VG_(transfer) (&ppc64->guest_VSR48, buf, dir, size, mod); break; |
| 412 | case 90: VG_(transfer) (&ppc64->guest_VSR49, buf, dir, size, mod); break; |
| 413 | case 91: VG_(transfer) (&ppc64->guest_VSR50, buf, dir, size, mod); break; |
| 414 | case 92: VG_(transfer) (&ppc64->guest_VSR51, buf, dir, size, mod); break; |
| 415 | case 93: VG_(transfer) (&ppc64->guest_VSR52, buf, dir, size, mod); break; |
| 416 | case 94: VG_(transfer) (&ppc64->guest_VSR53, buf, dir, size, mod); break; |
| 417 | case 95: VG_(transfer) (&ppc64->guest_VSR54, buf, dir, size, mod); break; |
| 418 | case 96: VG_(transfer) (&ppc64->guest_VSR55, buf, dir, size, mod); break; |
| 419 | case 97: VG_(transfer) (&ppc64->guest_VSR56, buf, dir, size, mod); break; |
| 420 | case 98: VG_(transfer) (&ppc64->guest_VSR57, buf, dir, size, mod); break; |
| 421 | case 99: VG_(transfer) (&ppc64->guest_VSR58, buf, dir, size, mod); break; |
| 422 | case 100: VG_(transfer) (&ppc64->guest_VSR59, buf, dir, size, mod); break; |
| 423 | case 101: VG_(transfer) (&ppc64->guest_VSR60, buf, dir, size, mod); break; |
| 424 | case 102: VG_(transfer) (&ppc64->guest_VSR61, buf, dir, size, mod); break; |
| 425 | case 103: VG_(transfer) (&ppc64->guest_VSR62, buf, dir, size, mod); break; |
| 426 | case 104: VG_(transfer) (&ppc64->guest_VSR63, buf, dir, size, mod); break; |
| 427 | case 105: VG_(transfer) (&ppc64->guest_VSCR, buf, dir, size, mod); break; |
sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 428 | case 106: VG_(transfer) (&ppc64->guest_VRSAVE, buf, dir, size, mod); break; |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 429 | |
| 430 | /* Fetch the lower 64-bits of the VSR registers. GDB will combine the |
| 431 | * lower 64-bits of the VSR with the upper 64-bits it got fetching the |
| 432 | * corresponding floating point register to display the full 128-bit |
| 433 | * VSR value. |
| 434 | */ |
| 435 | case 107: VG_(transfer) (&ppc64->guest_VSR0[low_offset], buf, dir, size, mod); break; |
| 436 | case 108: VG_(transfer) (&ppc64->guest_VSR1[low_offset], buf, dir, size, mod); break; |
| 437 | case 109: VG_(transfer) (&ppc64->guest_VSR2[low_offset], buf, dir, size, mod); break; |
| 438 | case 110: VG_(transfer) (&ppc64->guest_VSR3[low_offset], buf, dir, size, mod); break; |
| 439 | case 111: VG_(transfer) (&ppc64->guest_VSR4[low_offset], buf, dir, size, mod); break; |
| 440 | case 112: VG_(transfer) (&ppc64->guest_VSR5[low_offset], buf, dir, size, mod); break; |
| 441 | case 113: VG_(transfer) (&ppc64->guest_VSR6[low_offset], buf, dir, size, mod); break; |
| 442 | case 114: VG_(transfer) (&ppc64->guest_VSR7[low_offset], buf, dir, size, mod); break; |
| 443 | case 115: VG_(transfer) (&ppc64->guest_VSR8[low_offset], buf, dir, size, mod); break; |
| 444 | case 116: VG_(transfer) (&ppc64->guest_VSR9[low_offset], buf, dir, size, mod); break; |
| 445 | case 117: VG_(transfer) (&ppc64->guest_VSR10[low_offset], buf, dir, size, mod); break; |
| 446 | case 118: VG_(transfer) (&ppc64->guest_VSR11[low_offset], buf, dir, size, mod); break; |
| 447 | case 119: VG_(transfer) (&ppc64->guest_VSR12[low_offset], buf, dir, size, mod); break; |
| 448 | case 120: VG_(transfer) (&ppc64->guest_VSR13[low_offset], buf, dir, size, mod); break; |
| 449 | case 121: VG_(transfer) (&ppc64->guest_VSR14[low_offset], buf, dir, size, mod); break; |
| 450 | case 122: VG_(transfer) (&ppc64->guest_VSR15[low_offset], buf, dir, size, mod); break; |
| 451 | case 123: VG_(transfer) (&ppc64->guest_VSR16[low_offset], buf, dir, size, mod); break; |
| 452 | case 124: VG_(transfer) (&ppc64->guest_VSR17[low_offset], buf, dir, size, mod); break; |
| 453 | case 125: VG_(transfer) (&ppc64->guest_VSR18[low_offset], buf, dir, size, mod); break; |
| 454 | case 126: VG_(transfer) (&ppc64->guest_VSR19[low_offset], buf, dir, size, mod); break; |
| 455 | case 127: VG_(transfer) (&ppc64->guest_VSR20[low_offset], buf, dir, size, mod); break; |
| 456 | case 128: VG_(transfer) (&ppc64->guest_VSR21[low_offset], buf, dir, size, mod); break; |
| 457 | case 129: VG_(transfer) (&ppc64->guest_VSR22[low_offset], buf, dir, size, mod); break; |
| 458 | case 130: VG_(transfer) (&ppc64->guest_VSR23[low_offset], buf, dir, size, mod); break; |
| 459 | case 131: VG_(transfer) (&ppc64->guest_VSR24[low_offset], buf, dir, size, mod); break; |
| 460 | case 132: VG_(transfer) (&ppc64->guest_VSR25[low_offset], buf, dir, size, mod); break; |
| 461 | case 133: VG_(transfer) (&ppc64->guest_VSR26[low_offset], buf, dir, size, mod); break; |
| 462 | case 134: VG_(transfer) (&ppc64->guest_VSR27[low_offset], buf, dir, size, mod); break; |
| 463 | case 135: VG_(transfer) (&ppc64->guest_VSR28[low_offset], buf, dir, size, mod); break; |
| 464 | case 136: VG_(transfer) (&ppc64->guest_VSR29[low_offset], buf, dir, size, mod); break; |
| 465 | case 137: VG_(transfer) (&ppc64->guest_VSR30[low_offset], buf, dir, size, mod); break; |
| 466 | case 138: VG_(transfer) (&ppc64->guest_VSR31[low_offset], buf, dir, size, mod); break; |
sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 467 | default: vg_assert(0); |
| 468 | } |
| 469 | } |
| 470 | |
philippe | 419d5f2 | 2012-05-24 21:33:17 +0000 | [diff] [blame] | 471 | static |
florian | 6bd9dc1 | 2012-11-23 16:17:43 +0000 | [diff] [blame] | 472 | const char* target_xml (Bool shadow_mode) |
philippe | 419d5f2 | 2012-05-24 21:33:17 +0000 | [diff] [blame] | 473 | { |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 474 | /* NOTE, the current powerpc-altivec64l*.xml files includes the vsx |
| 475 | * registers. Power 6 and earlier power processors do not support the |
| 476 | * vsx registers. GDB has a bug in that it is only checking for ptrace |
| 477 | * support rather then checking the actual HW feature. Hence GDB on |
| 478 | * power 6 prints vsx registers that do not exist. Valgrind GDB support |
| 479 | * also has to include the vsx register definitions to be consistent with |
| 480 | * GDB. |
| 481 | */ |
philippe | 419d5f2 | 2012-05-24 21:33:17 +0000 | [diff] [blame] | 482 | if (shadow_mode) { |
| 483 | return "powerpc-altivec64l-valgrind.xml"; |
| 484 | } else { |
| 485 | return "powerpc-altivec64l.xml"; |
| 486 | } |
| 487 | } |
| 488 | |
philippe | 1670b05 | 2014-08-15 10:27:52 +0000 | [diff] [blame] | 489 | static CORE_ADDR** target_get_dtv (ThreadState *tst) |
| 490 | { |
philippe | 87fc2a9 | 2014-08-15 13:03:24 +0000 | [diff] [blame] | 491 | VexGuestPPC64State* ppc64 = (VexGuestPPC64State*)&tst->arch.vex; |
philippe | 1670b05 | 2014-08-15 10:27:52 +0000 | [diff] [blame] | 492 | // ppc64 dtv is located just before the tcb, which is 0x7000 before |
| 493 | // the thread id (r13) |
philippe | 87fc2a9 | 2014-08-15 13:03:24 +0000 | [diff] [blame] | 494 | return (CORE_ADDR**)((CORE_ADDR)ppc64->guest_GPR13 |
| 495 | - 0x7000 - sizeof(CORE_ADDR)); |
philippe | 1670b05 | 2014-08-15 10:27:52 +0000 | [diff] [blame] | 496 | } |
| 497 | |
sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 498 | static struct valgrind_target_ops low_target = { |
| 499 | num_regs, |
| 500 | regs, |
| 501 | 1, //r1 |
| 502 | transfer_register, |
| 503 | get_pc, |
| 504 | set_pc, |
| 505 | "ppc64", |
philippe | 1670b05 | 2014-08-15 10:27:52 +0000 | [diff] [blame] | 506 | target_xml, |
| 507 | target_get_dtv |
sewardj | 3b29048 | 2011-05-06 21:02:55 +0000 | [diff] [blame] | 508 | }; |
| 509 | |
| 510 | void ppc64_init_architecture (struct valgrind_target_ops *target) |
| 511 | { |
| 512 | *target = low_target; |
| 513 | set_register_cache (regs, num_regs); |
| 514 | gdbserver_expedite_regs = expedite_regs; |
| 515 | } |