memcheck/tests/libstdc++.supp: rename suppression
[valgrind.git] / coregrind / m_gdbserver / valgrind-low-mips32.c
blob5f965f54a3ee394a8a2372250f56d3376da6b384
1 /* Low level interface to valgrind, for the remote server for GDB integrated
2 in valgrind.
3 Copyright (C) 2012
4 Free Software Foundation, Inc.
6 This file is part of VALGRIND.
7 It has been inspired from a file from gdbserver in gdb 6.6.
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.
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.
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. */
24 #include "server.h"
25 #include "target.h"
26 #include "regdef.h"
27 #include "regcache.h"
29 #include "pub_core_machine.h"
30 #include "pub_core_debuginfo.h"
31 #include "pub_core_threadstate.h"
32 #include "pub_core_transtab.h"
33 #include "pub_core_gdbserver.h"
35 #include "valgrind_low.h"
37 #include "libvex_guest_mips32.h"
39 static struct reg regs[] = {
40 { "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 },
115 #define num_regs (sizeof (regs) / sizeof (regs[0]))
117 static const char *expedite_regs[] = { "r29", "pc", 0 };
119 static
120 CORE_ADDR get_pc (void)
122 unsigned long pc;
124 collect_register_by_name ("pc", &pc);
126 dlog(1, "stop pc is %p\n", (void *) pc);
127 return pc;
130 static
131 void set_pc (CORE_ADDR newpc)
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));
141 /* 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)
147 /* Do a endian load of a 32-bit word, regardless of the
148 endianness of the underlying host. */
149 static inline UInt getUInt(UChar * p)
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;
166 /* Return non-zero if the ADDR instruction has a branch delay slot
167 (i.e. it is a jump or branch instruction). */
168 static UInt
169 mips_instruction_has_delay_slot (Addr addr)
171 UInt op, rs, rt;
172 UInt inst = getUInt((UChar *)addr);
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;
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. */
210 static Addr mips_adjust_breakpoint_address (Addr pc)
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;
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;
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. */
232 // Placing a breakpoint, so pc should be in di of current epoch.
233 const DiEpoch cur_ep = VG_(current_DiEpoch)();
235 if (VG_(get_inst_offset_in_function) (cur_ep, bpaddr, &offset)) {
236 func_addr = bpaddr - offset;
237 if (func_addr > boundary && func_addr <= bpaddr)
238 boundary = func_addr;
241 if (bpaddr == boundary)
242 return bpaddr;
243 /* If the previous instruction has a branch delay slot, we have
244 to move the breakpoint to the branch instruction. */
245 prev_addr = bpaddr - 4;
246 if (mips_instruction_has_delay_slot (prev_addr))
247 bpaddr = prev_addr;
249 return bpaddr;
252 /* store registers in the guest state (gdbserver_to_valgrind)
253 or fetch register from the guest state (valgrind_to_gdbserver). */
254 static
255 void transfer_register (ThreadId tid, int abs_regno, void * buf,
256 transfer_direction dir, int size, Bool *mod)
258 ThreadState* tst = VG_(get_ThreadState)(tid);
259 int set = abs_regno / num_regs;
260 int regno = abs_regno % num_regs;
261 *mod = False;
263 VexGuestMIPS32State* mips1 = (VexGuestMIPS32State*) get_arch (set, tst);
265 switch (regno) {
266 case 0: VG_(transfer) (&mips1->guest_r0, buf, dir, size, mod); break;
267 case 1: VG_(transfer) (&mips1->guest_r1, buf, dir, size, mod); break;
268 case 2: VG_(transfer) (&mips1->guest_r2, buf, dir, size, mod); break;
269 case 3: VG_(transfer) (&mips1->guest_r3, buf, dir, size, mod); break;
270 case 4: VG_(transfer) (&mips1->guest_r4, buf, dir, size, mod); break;
271 case 5: VG_(transfer) (&mips1->guest_r5, buf, dir, size, mod); break;
272 case 6: VG_(transfer) (&mips1->guest_r6, buf, dir, size, mod); break;
273 case 7: VG_(transfer) (&mips1->guest_r7, buf, dir, size, mod); break;
274 case 8: VG_(transfer) (&mips1->guest_r8, buf, dir, size, mod); break;
275 case 9: VG_(transfer) (&mips1->guest_r9, buf, dir, size, mod); break;
276 case 10: VG_(transfer) (&mips1->guest_r10, buf, dir, size, mod); break;
277 case 11: VG_(transfer) (&mips1->guest_r11, buf, dir, size, mod); break;
278 case 12: VG_(transfer) (&mips1->guest_r12, buf, dir, size, mod); break;
279 case 13: VG_(transfer) (&mips1->guest_r13, buf, dir, size, mod); break;
280 case 14: VG_(transfer) (&mips1->guest_r14, buf, dir, size, mod); break;
281 case 15: VG_(transfer) (&mips1->guest_r15, buf, dir, size, mod); break;
282 case 16: VG_(transfer) (&mips1->guest_r16, buf, dir, size, mod); break;
283 case 17: VG_(transfer) (&mips1->guest_r17, buf, dir, size, mod); break;
284 case 18: VG_(transfer) (&mips1->guest_r18, buf, dir, size, mod); break;
285 case 19: VG_(transfer) (&mips1->guest_r19, buf, dir, size, mod); break;
286 case 20: VG_(transfer) (&mips1->guest_r20, buf, dir, size, mod); break;
287 case 21: VG_(transfer) (&mips1->guest_r21, buf, dir, size, mod); break;
288 case 22: VG_(transfer) (&mips1->guest_r22, buf, dir, size, mod); break;
289 case 23: VG_(transfer) (&mips1->guest_r23, buf, dir, size, mod); break;
290 case 24: VG_(transfer) (&mips1->guest_r24, buf, dir, size, mod); break;
291 case 25: VG_(transfer) (&mips1->guest_r25, buf, dir, size, mod); break;
292 case 26: VG_(transfer) (&mips1->guest_r26, buf, dir, size, mod); break;
293 case 27: VG_(transfer) (&mips1->guest_r27, buf, dir, size, mod); break;
294 case 28: VG_(transfer) (&mips1->guest_r28, buf, dir, size, mod); break;
295 case 29: VG_(transfer) (&mips1->guest_r29, buf, dir, size, mod); break;
296 case 30: VG_(transfer) (&mips1->guest_r30, buf, dir, size, mod); break;
297 case 31: VG_(transfer) (&mips1->guest_r31, buf, dir, size, mod); break;
298 case 32: *mod = False; break; // GDBTD???? VEX { "status", 1024, 32 },
299 case 33: VG_(transfer) (&mips1->guest_LO, buf, dir, size, mod); break;
300 case 34: VG_(transfer) (&mips1->guest_HI, buf, dir, size, mod); break;
301 case 35: *mod = False; break; // GDBTD???? VEX { "badvaddr", 1120, 32 },
302 case 36: *mod = False; break; // GDBTD???? VEX { "cause", 1152, 32 },
303 case 37:
304 /* If a breakpoint is set on the instruction in a branch delay slot,
305 GDB gets confused. When the breakpoint is hit, the PC isn't on
306 the instruction in the branch delay slot, the PC will point to
307 the branch instruction. */
308 mips1->guest_PC = mips_adjust_breakpoint_address(mips1->guest_PC);
309 VG_(transfer) (&mips1->guest_PC, buf, dir, size, mod);
310 break;
311 case 38: VG_(transfer) (&mips1->guest_f0, buf, dir, size, mod); break;
312 case 39: VG_(transfer) (&mips1->guest_f1, buf, dir, size, mod); break;
313 case 40: VG_(transfer) (&mips1->guest_f2, buf, dir, size, mod); break;
314 case 41: VG_(transfer) (&mips1->guest_f3, buf, dir, size, mod); break;
315 case 42: VG_(transfer) (&mips1->guest_f4, buf, dir, size, mod); break;
316 case 43: VG_(transfer) (&mips1->guest_f5, buf, dir, size, mod); break;
317 case 44: VG_(transfer) (&mips1->guest_f6, buf, dir, size, mod); break;
318 case 45: VG_(transfer) (&mips1->guest_f7, buf, dir, size, mod); break;
319 case 46: VG_(transfer) (&mips1->guest_f8, buf, dir, size, mod); break;
320 case 47: VG_(transfer) (&mips1->guest_f9, buf, dir, size, mod); break;
321 case 48: VG_(transfer) (&mips1->guest_f10, buf, dir, size, mod); break;
322 case 49: VG_(transfer) (&mips1->guest_f11, buf, dir, size, mod); break;
323 case 50: VG_(transfer) (&mips1->guest_f12, buf, dir, size, mod); break;
324 case 51: VG_(transfer) (&mips1->guest_f13, buf, dir, size, mod); break;
325 case 52: VG_(transfer) (&mips1->guest_f14, buf, dir, size, mod); break;
326 case 53: VG_(transfer) (&mips1->guest_f15, buf, dir, size, mod); break;
327 case 54: VG_(transfer) (&mips1->guest_f16, buf, dir, size, mod); break;
328 case 55: VG_(transfer) (&mips1->guest_f17, buf, dir, size, mod); break;
329 case 56: VG_(transfer) (&mips1->guest_f18, buf, dir, size, mod); break;
330 case 57: VG_(transfer) (&mips1->guest_f19, buf, dir, size, mod); break;
331 case 58: VG_(transfer) (&mips1->guest_f20, buf, dir, size, mod); break;
332 case 59: VG_(transfer) (&mips1->guest_f21, buf, dir, size, mod); break;
333 case 60: VG_(transfer) (&mips1->guest_f22, buf, dir, size, mod); break;
334 case 61: VG_(transfer) (&mips1->guest_f23, buf, dir, size, mod); break;
335 case 62: VG_(transfer) (&mips1->guest_f24, buf, dir, size, mod); break;
336 case 63: VG_(transfer) (&mips1->guest_f25, buf, dir, size, mod); break;
337 case 64: VG_(transfer) (&mips1->guest_f26, buf, dir, size, mod); break;
338 case 65: VG_(transfer) (&mips1->guest_f27, buf, dir, size, mod); break;
339 case 66: VG_(transfer) (&mips1->guest_f28, buf, dir, size, mod); break;
340 case 67: VG_(transfer) (&mips1->guest_f29, buf, dir, size, mod); break;
341 case 68: VG_(transfer) (&mips1->guest_f30, buf, dir, size, mod); break;
342 case 69: VG_(transfer) (&mips1->guest_f31, buf, dir, size, mod); break;
343 case 70: VG_(transfer) (&mips1->guest_FCSR, buf, dir, size, mod); break;
344 case 71: VG_(transfer) (&mips1->guest_FIR, buf, dir, size, mod); break;
345 case 72: *mod = False; break; // GDBTD???? VEX{ "restart", 2304, 32 },
346 default: VG_(printf)("regno: %d\n", regno); vg_assert(0);
350 static
351 const char* target_xml (Bool shadow_mode)
353 if (shadow_mode) {
354 return "mips-linux-valgrind.xml";
355 } else {
356 return "mips-linux.xml";
360 static CORE_ADDR** target_get_dtv (ThreadState *tst)
362 VexGuestMIPS32State* mips32 = (VexGuestMIPS32State*)&tst->arch.vex;
363 // Top of MIPS tcbhead structure is located 0x7000 bytes before the value
364 // of ULR. Dtv is the first of two pointers in tcbhead structure.
365 // More details can be found in GLIBC/sysdeps/nptl/tls.h.
366 return (CORE_ADDR**)((CORE_ADDR)mips32->guest_ULR
367 - 0x7000 - 2 * sizeof(CORE_ADDR));
370 static struct valgrind_target_ops low_target = {
371 num_regs,
372 regs,
373 29, //sp = r29, which is register offset 29 in regs
374 transfer_register,
375 get_pc,
376 set_pc,
377 "mips",
378 target_xml,
379 target_get_dtv
382 void mips32_init_architecture (struct valgrind_target_ops *target)
384 *target = low_target;
385 set_register_cache (regs, num_regs);
386 gdbserver_expedite_regs = expedite_regs;