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