blob: d35df419f53e15defc738d7cc705d3176a2621a0 [file] [log] [blame]
petarj4df0bfc2013-02-27 23:17:33 +00001/* 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"
florianc91f5842013-09-15 10:42:26 +000030#include "pub_core_machine.h"
petarjc3294a92013-07-13 23:50:46 +000031#include "pub_core_debuginfo.h"
petarj4df0bfc2013-02-27 23:17:33 +000032#include "pub_core_threadstate.h"
33#include "pub_core_transtab.h"
34#include "pub_core_gdbserver.h"
35
36#include "valgrind_low.h"
37
38#include "libvex_guest_mips64.h"
39
40static struct reg regs[] = {
41 { "r0", 0, 64 },
42 { "r1", 64, 64 },
43 { "r2", 128, 64 },
44 { "r3", 192, 64 },
45 { "r4", 256, 64 },
46 { "r5", 320, 64 },
47 { "r6", 384, 64 },
48 { "r7", 448, 64 },
49 { "r8", 512, 64 },
50 { "r9", 576, 64 },
51 { "r10", 640, 64 },
52 { "r11", 704, 64 },
53 { "r12", 768, 64 },
54 { "r13", 832, 64 },
55 { "r14", 896, 64 },
56 { "r15", 960, 64 },
57 { "r16", 1024, 64 },
58 { "r17", 1088, 64 },
59 { "r18", 1152, 64 },
60 { "r19", 1216, 64 },
61 { "r20", 1280, 64 },
62 { "r21", 1344, 64 },
63 { "r22", 1408, 64 },
64 { "r23", 1472, 64 },
65 { "r24", 1536, 64 },
66 { "r25", 1600, 64 },
67 { "r26", 1664, 64 },
68 { "r27", 1728, 64 },
69 { "r28", 1792, 64 },
70 { "r29", 1856, 64 },
71 { "r30", 1920, 64 },
72 { "r31", 1984, 64 },
73 { "status", 2048, 64 },
74 { "lo", 2112, 64 },
75 { "hi", 2176, 64 },
76 { "badvaddr", 2240, 64 },
77 { "cause", 2304, 64 },
78 { "pc", 2368, 64 },
79 { "f0", 2432, 64 },
80 { "f1", 2496, 64 },
81 { "f2", 2560, 64 },
82 { "f3", 2624, 64 },
83 { "f4", 2688, 64 },
84 { "f5", 2752, 64 },
85 { "f6", 2816, 64 },
86 { "f7", 2880, 64 },
87 { "f8", 2944, 64 },
88 { "f9", 3008, 64 },
89 { "f10", 3072, 64 },
90 { "f11", 3136, 64 },
91 { "f12", 3200, 64 },
92 { "f13", 3264, 64 },
93 { "f14", 3328, 64 },
94 { "f15", 3392, 64 },
95 { "f16", 3456, 64 },
96 { "f17", 3520, 64 },
97 { "f18", 3584, 64 },
98 { "f19", 3648, 64 },
99 { "f20", 3712, 64 },
100 { "f21", 3776, 64 },
101 { "f22", 3840, 64 },
102 { "f23", 3904, 64 },
103 { "f24", 3968, 64 },
104 { "f25", 4032, 64 },
105 { "f26", 4096, 64 },
106 { "f27", 4160, 64 },
107 { "f28", 4224, 64 },
108 { "f29", 4288, 64 },
109 { "f30", 4352, 64 },
110 { "f31", 4416, 64 },
111 { "fcsr", 4480, 64 },
112 { "fir", 4544, 64 },
113 { "restart", 4608, 64 }
114};
115
116
117#define num_regs (sizeof (regs) / sizeof (regs[0]))
118
119static const char *expedite_regs[] = { "r29", "pc", 0 };
120
121static
122CORE_ADDR get_pc (void)
123{
124 unsigned long pc;
125
126 collect_register_by_name ("pc", &pc);
127
128 dlog(1, "stop pc is %p\n", (void *) pc);
129 return pc;
130}
131
132static
133void set_pc (CORE_ADDR newpc)
134{
135 Bool mod;
136 supply_register_by_name ("pc", &newpc, &mod);
137 if (mod)
138 dlog(1, "set pc to %p\n", C2v (newpc));
139 else
140 dlog(1, "set pc not changed %p\n", C2v (newpc));
141}
142
petarjc3294a92013-07-13 23:50:46 +0000143/* These are the fields of 32 bit mips instructions. */
144#define itype_op(x) (x >> 26)
145#define itype_rs(x) ((x >> 21) & 0x1f)
146#define itype_rt(x) ((x >> 16) & 0x1f)
147#define rtype_funct(x) (x & 0x3f)
148
149/* Do a endian load of a 32-bit word, regardless of the
150 endianness of the underlying host. */
151static inline UInt getUInt(UChar * p)
152{
153 UInt w = 0;
154#if defined (_MIPSEL)
155 w = (w << 8) | p[3];
156 w = (w << 8) | p[2];
157 w = (w << 8) | p[1];
158 w = (w << 8) | p[0];
159#elif defined (_MIPSEB)
160 w = (w << 8) | p[0];
161 w = (w << 8) | p[1];
162 w = (w << 8) | p[2];
163 w = (w << 8) | p[3];
164#endif
165 return w;
166}
167
168/* Return non-zero if the ADDR instruction has a branch delay slot
169 (i.e. it is a jump or branch instruction). */
170static UInt
171mips_instruction_has_delay_slot (Addr addr)
172{
173 UInt op, rs, rt;
174 UInt inst = getUInt((UChar *)addr);
175
176 op = itype_op (inst);
177 if ((inst & 0xe0000000) != 0) {
178 rs = itype_rs (inst);
179 rt = itype_rt (inst);
180 return (op >> 2 == 5 /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */
181 || op == 29 /* JALX: bits 011101 */
182 || (op == 17
183 && (rs == 8 /* BC1F, BC1FL, BC1T, BC1TL: 010001 01000 */
184 || (rs == 9 && (rt & 0x2) == 0)
185 /* BC1ANY2F, BC1ANY2T: bits 010001 01001 */
186 || (rs == 10 && (rt & 0x2) == 0))));
187 /* BC1ANY4F, BC1ANY4T: bits 010001 01010 */
188 } else
189 switch (op & 0x07) { /* extract bits 28,27,26 */
190 case 0: /* SPECIAL */
191 op = rtype_funct (inst);
192 return (op == 8 /* JR */
193 || op == 9); /* JALR */
194 break; /* end SPECIAL */
195 case 1: /* REGIMM */
196 rs = itype_rs (inst);
197 rt = itype_rt (inst); /* branch condition */
198 return ((rt & 0xc) == 0
199 /* BLTZ, BLTZL, BGEZ, BGEZL: bits 000xx */
200 /* BLTZAL, BLTZALL, BGEZAL, BGEZALL: 100xx */
201 || ((rt & 0x1e) == 0x1c && rs == 0));
202 /* BPOSGE32, BPOSGE64: bits 1110x */
203 break; /* end REGIMM */
204 default: /* J, JAL, BEQ, BNE, BLEZ, BGTZ */
205 return 1;
206 break;
207 }
208}
209
210/* Move the breakpoint at BPADDR out of any branch delay slot by shifting
211 it backwards if necessary. Return the address of the new location. */
212static Addr mips_adjust_breakpoint_address (Addr pc)
213{
214 Addr prev_addr;
215 Addr boundary;
216 Addr func_addr;
217 Addr bpaddr = pc;
sewardjbd612e82013-08-01 22:16:10 +0000218 Addr mask = (Addr)0xffffffffffffffffULL;
petarjc3294a92013-07-13 23:50:46 +0000219 int segsize;
220 PtrdiffT offset;
221
222 /* Calculate the starting address of the MIPS memory segment pc is in. */
223 if (bpaddr & 0x80000000) /* kernel segment */
224 segsize = 29;
225 else
226 segsize = 31; /* user segment */
227 mask <<= segsize;
228 boundary = pc & mask;
229
230 /* Make sure we don't scan back before the beginning of the current
231 function, since we may fetch constant data or insns that look like
232 a jump. */
233 if (VG_(get_inst_offset_in_function) (bpaddr, &offset)) {
234 func_addr = bpaddr - offset;
235 if (func_addr > boundary && func_addr <= bpaddr)
236 boundary = func_addr;
237 }
238
239 if (bpaddr == boundary)
240 return bpaddr;
241 /* If the previous instruction has a branch delay slot, we have
242 to move the breakpoint to the branch instruction. */
243 prev_addr = bpaddr - 4;
244 if (mips_instruction_has_delay_slot (prev_addr))
245 bpaddr = prev_addr;
246
247 return bpaddr;
248}
249
petarj4df0bfc2013-02-27 23:17:33 +0000250/* store registers in the guest state (gdbserver_to_valgrind)
251 or fetch register from the guest state (valgrind_to_gdbserver). */
252static
253void 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;
259 *mod = False;
260
261 VexGuestMIPS64State* mips1 = (VexGuestMIPS64State*) get_arch (set, tst);
262
263 switch (regno) {
264 case 0: VG_(transfer) (&mips1->guest_r0, buf, dir, size, mod); break;
265 case 1: VG_(transfer) (&mips1->guest_r1, buf, dir, size, mod); break;
266 case 2: VG_(transfer) (&mips1->guest_r2, buf, dir, size, mod); break;
267 case 3: VG_(transfer) (&mips1->guest_r3, buf, dir, size, mod); break;
268 case 4: VG_(transfer) (&mips1->guest_r4, buf, dir, size, mod); break;
269 case 5: VG_(transfer) (&mips1->guest_r5, buf, dir, size, mod); break;
270 case 6: VG_(transfer) (&mips1->guest_r6, buf, dir, size, mod); break;
271 case 7: VG_(transfer) (&mips1->guest_r7, buf, dir, size, mod); break;
272 case 8: VG_(transfer) (&mips1->guest_r8, buf, dir, size, mod); break;
273 case 9: VG_(transfer) (&mips1->guest_r9, buf, dir, size, mod); break;
274 case 10: VG_(transfer) (&mips1->guest_r10, buf, dir, size, mod); break;
275 case 11: VG_(transfer) (&mips1->guest_r11, buf, dir, size, mod); break;
276 case 12: VG_(transfer) (&mips1->guest_r12, buf, dir, size, mod); break;
277 case 13: VG_(transfer) (&mips1->guest_r13, buf, dir, size, mod); break;
278 case 14: VG_(transfer) (&mips1->guest_r14, buf, dir, size, mod); break;
279 case 15: VG_(transfer) (&mips1->guest_r15, buf, dir, size, mod); break;
280 case 16: VG_(transfer) (&mips1->guest_r16, buf, dir, size, mod); break;
281 case 17: VG_(transfer) (&mips1->guest_r17, buf, dir, size, mod); break;
282 case 18: VG_(transfer) (&mips1->guest_r18, buf, dir, size, mod); break;
283 case 19: VG_(transfer) (&mips1->guest_r19, buf, dir, size, mod); break;
284 case 20: VG_(transfer) (&mips1->guest_r20, buf, dir, size, mod); break;
285 case 21: VG_(transfer) (&mips1->guest_r21, buf, dir, size, mod); break;
286 case 22: VG_(transfer) (&mips1->guest_r22, buf, dir, size, mod); break;
287 case 23: VG_(transfer) (&mips1->guest_r23, buf, dir, size, mod); break;
288 case 24: VG_(transfer) (&mips1->guest_r24, buf, dir, size, mod); break;
289 case 25: VG_(transfer) (&mips1->guest_r25, buf, dir, size, mod); break;
290 case 26: VG_(transfer) (&mips1->guest_r26, buf, dir, size, mod); break;
291 case 27: VG_(transfer) (&mips1->guest_r27, buf, dir, size, mod); break;
292 case 28: VG_(transfer) (&mips1->guest_r28, buf, dir, size, mod); break;
293 case 29: VG_(transfer) (&mips1->guest_r29, buf, dir, size, mod); break;
294 case 30: VG_(transfer) (&mips1->guest_r30, buf, dir, size, mod); break;
295 case 31: VG_(transfer) (&mips1->guest_r31, buf, dir, size, mod); break;
296 case 32: *mod = False; break; // GDBTD???? VEX { "status", 1024, 64 }
297 case 33: VG_(transfer) (&mips1->guest_LO, buf, dir, size, mod); break;
298 case 34: VG_(transfer) (&mips1->guest_HI, buf, dir, size, mod); break;
299 case 35: *mod = False; break; // GDBTD???? VEX { "badvaddr", 1120, 64 },
300 case 36: *mod = False; break; // GDBTD???? VEX { "cause", 1152, 64 },
petarjc3294a92013-07-13 23:50:46 +0000301 case 37:
302 /* If a breakpoint is set on the instruction in a branch delay slot,
303 GDB gets confused. When the breakpoint is hit, the PC isn't on
304 the instruction in the branch delay slot, the PC will point to
305 the branch instruction. */
306 mips1->guest_PC = mips_adjust_breakpoint_address(mips1->guest_PC);
307 VG_(transfer) (&mips1->guest_PC, buf, dir, size, mod);
308 break;
petarj4df0bfc2013-02-27 23:17:33 +0000309 case 38: VG_(transfer) (&mips1->guest_f0, buf, dir, size, mod); break;
310 case 39: VG_(transfer) (&mips1->guest_f1, buf, dir, size, mod); break;
311 case 40: VG_(transfer) (&mips1->guest_f2, buf, dir, size, mod); break;
312 case 41: VG_(transfer) (&mips1->guest_f3, buf, dir, size, mod); break;
313 case 42: VG_(transfer) (&mips1->guest_f4, buf, dir, size, mod); break;
314 case 43: VG_(transfer) (&mips1->guest_f5, buf, dir, size, mod); break;
315 case 44: VG_(transfer) (&mips1->guest_f6, buf, dir, size, mod); break;
316 case 45: VG_(transfer) (&mips1->guest_f7, buf, dir, size, mod); break;
317 case 46: VG_(transfer) (&mips1->guest_f8, buf, dir, size, mod); break;
318 case 47: VG_(transfer) (&mips1->guest_f9, buf, dir, size, mod); break;
319 case 48: VG_(transfer) (&mips1->guest_f10, buf, dir, size, mod); break;
320 case 49: VG_(transfer) (&mips1->guest_f11, buf, dir, size, mod); break;
321 case 50: VG_(transfer) (&mips1->guest_f12, buf, dir, size, mod); break;
322 case 51: VG_(transfer) (&mips1->guest_f13, buf, dir, size, mod); break;
323 case 52: VG_(transfer) (&mips1->guest_f14, buf, dir, size, mod); break;
324 case 53: VG_(transfer) (&mips1->guest_f15, buf, dir, size, mod); break;
325 case 54: VG_(transfer) (&mips1->guest_f16, buf, dir, size, mod); break;
326 case 55: VG_(transfer) (&mips1->guest_f17, buf, dir, size, mod); break;
327 case 56: VG_(transfer) (&mips1->guest_f18, buf, dir, size, mod); break;
328 case 57: VG_(transfer) (&mips1->guest_f19, buf, dir, size, mod); break;
329 case 58: VG_(transfer) (&mips1->guest_f20, buf, dir, size, mod); break;
330 case 59: VG_(transfer) (&mips1->guest_f21, buf, dir, size, mod); break;
331 case 60: VG_(transfer) (&mips1->guest_f22, buf, dir, size, mod); break;
332 case 61: VG_(transfer) (&mips1->guest_f23, buf, dir, size, mod); break;
333 case 62: VG_(transfer) (&mips1->guest_f24, buf, dir, size, mod); break;
334 case 63: VG_(transfer) (&mips1->guest_f25, buf, dir, size, mod); break;
335 case 64: VG_(transfer) (&mips1->guest_f26, buf, dir, size, mod); break;
336 case 65: VG_(transfer) (&mips1->guest_f27, buf, dir, size, mod); break;
337 case 66: VG_(transfer) (&mips1->guest_f28, buf, dir, size, mod); break;
338 case 67: VG_(transfer) (&mips1->guest_f29, buf, dir, size, mod); break;
339 case 68: VG_(transfer) (&mips1->guest_f30, buf, dir, size, mod); break;
340 case 69: VG_(transfer) (&mips1->guest_f31, buf, dir, size, mod); break;
341 case 70: VG_(transfer) (&mips1->guest_FCSR, buf, dir, size, mod); break;
342 case 71: VG_(transfer) (&mips1->guest_FIR, buf, dir, size, mod); break;
343 case 72: *mod = False; break; // GDBTD???? VEX{ "restart", 2304, 64 },
344 default: VG_(printf)("regno: %d\n", regno); vg_assert(0);
345 }
346}
347
348static
349const char* target_xml (Bool shadow_mode)
350{
351 if (shadow_mode) {
352 return "mips64-linux-valgrind.xml";
353 } else {
354 return "mips64-linux.xml";
355 }
356}
357
philippe1670b052014-08-15 10:27:52 +0000358static CORE_ADDR** target_get_dtv (ThreadState *tst)
359{
360#if defined(VGA_mips64)
361 // mips64 dtv location similar to ppc64
362 return (CORE_ADDR**)(tst->arch.vex.guest_ULR - 0x7000 - sizeof(CORE_ADDR));
363 return NULL;
364#else
365 vg_assert(0);
366#endif
367}
368
petarj4df0bfc2013-02-27 23:17:33 +0000369static struct valgrind_target_ops low_target = {
370 num_regs,
371 regs,
372 29, //sp = r29, which is register offset 29 in regs
373 transfer_register,
374 get_pc,
375 set_pc,
376 "mips64",
philippe1670b052014-08-15 10:27:52 +0000377 target_xml,
378 target_get_dtv
petarj4df0bfc2013-02-27 23:17:33 +0000379};
380
381void mips64_init_architecture (struct valgrind_target_ops *target)
382{
383 *target = low_target;
384 set_register_cache (regs, num_regs);
385 gdbserver_expedite_regs = expedite_regs;
386}