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