Add DRD suppression patterns for races triggered by std::ostream
[valgrind.git] / coregrind / m_gdbserver / valgrind-low-mips64.c
blob20323a3b69b4e574edf86793129494a8d69e7ead
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.
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_mips64.h"
39 static 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 }
116 #define num_regs (sizeof (regs) / sizeof (regs[0]))
118 static const char *expedite_regs[] = { "r29", "pc", 0 };
120 static
121 CORE_ADDR get_pc (void)
123 unsigned long pc;
125 collect_register_by_name ("pc", &pc);
127 dlog(1, "stop pc is %p\n", (void *) pc);
128 return pc;
131 static
132 void set_pc (CORE_ADDR newpc)
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));
142 /* 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)
148 /* Do a endian load of a 32-bit word, regardless of the
149 endianness of the underlying host. */
150 static inline UInt getUInt(UChar * p)
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;
167 /* Return non-zero if the ADDR instruction has a branch delay slot
168 (i.e. it is a jump or branch instruction). */
169 static UInt
170 mips_instruction_has_delay_slot (Addr addr)
172 UInt op, rs, rt;
173 UInt inst = getUInt((UChar *)addr);
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;
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. */
211 static Addr mips_adjust_breakpoint_address (Addr pc)
213 Addr prev_addr;
214 Addr boundary;
215 Addr func_addr;
216 Addr bpaddr = pc;
217 Addr mask = (Addr)0xffffffffffffffffULL;
218 int segsize;
219 PtrdiffT offset;
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;
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. */
233 // Placing a breakpoint, so pc should be in di of current epoch.
234 const DiEpoch cur_ep = VG_(current_DiEpoch)();
236 if (VG_(get_inst_offset_in_function) (cur_ep, bpaddr, &offset)) {
237 func_addr = bpaddr - offset;
238 if (func_addr > boundary && func_addr <= bpaddr)
239 boundary = func_addr;
242 if (bpaddr == boundary)
243 return bpaddr;
244 /* If the previous instruction has a branch delay slot, we have
245 to move the breakpoint to the branch instruction. */
246 prev_addr = bpaddr - 4;
247 if (mips_instruction_has_delay_slot (prev_addr))
248 bpaddr = prev_addr;
250 return bpaddr;
253 /* store registers in the guest state (gdbserver_to_valgrind)
254 or fetch register from the guest state (valgrind_to_gdbserver). */
255 static
256 void transfer_register (ThreadId tid, int abs_regno, void * buf,
257 transfer_direction dir, int size, Bool *mod)
259 ThreadState* tst = VG_(get_ThreadState)(tid);
260 int set = abs_regno / num_regs;
261 int regno = abs_regno % num_regs;
262 *mod = False;
264 VexGuestMIPS64State* mips1 = (VexGuestMIPS64State*) get_arch (set, tst);
266 switch (regno) {
267 case 0: VG_(transfer) (&mips1->guest_r0, buf, dir, size, mod); break;
268 case 1: VG_(transfer) (&mips1->guest_r1, buf, dir, size, mod); break;
269 case 2: VG_(transfer) (&mips1->guest_r2, buf, dir, size, mod); break;
270 case 3: VG_(transfer) (&mips1->guest_r3, buf, dir, size, mod); break;
271 case 4: VG_(transfer) (&mips1->guest_r4, buf, dir, size, mod); break;
272 case 5: VG_(transfer) (&mips1->guest_r5, buf, dir, size, mod); break;
273 case 6: VG_(transfer) (&mips1->guest_r6, buf, dir, size, mod); break;
274 case 7: VG_(transfer) (&mips1->guest_r7, buf, dir, size, mod); break;
275 case 8: VG_(transfer) (&mips1->guest_r8, buf, dir, size, mod); break;
276 case 9: VG_(transfer) (&mips1->guest_r9, buf, dir, size, mod); break;
277 case 10: VG_(transfer) (&mips1->guest_r10, buf, dir, size, mod); break;
278 case 11: VG_(transfer) (&mips1->guest_r11, buf, dir, size, mod); break;
279 case 12: VG_(transfer) (&mips1->guest_r12, buf, dir, size, mod); break;
280 case 13: VG_(transfer) (&mips1->guest_r13, buf, dir, size, mod); break;
281 case 14: VG_(transfer) (&mips1->guest_r14, buf, dir, size, mod); break;
282 case 15: VG_(transfer) (&mips1->guest_r15, buf, dir, size, mod); break;
283 case 16: VG_(transfer) (&mips1->guest_r16, buf, dir, size, mod); break;
284 case 17: VG_(transfer) (&mips1->guest_r17, buf, dir, size, mod); break;
285 case 18: VG_(transfer) (&mips1->guest_r18, buf, dir, size, mod); break;
286 case 19: VG_(transfer) (&mips1->guest_r19, buf, dir, size, mod); break;
287 case 20: VG_(transfer) (&mips1->guest_r20, buf, dir, size, mod); break;
288 case 21: VG_(transfer) (&mips1->guest_r21, buf, dir, size, mod); break;
289 case 22: VG_(transfer) (&mips1->guest_r22, buf, dir, size, mod); break;
290 case 23: VG_(transfer) (&mips1->guest_r23, buf, dir, size, mod); break;
291 case 24: VG_(transfer) (&mips1->guest_r24, buf, dir, size, mod); break;
292 case 25: VG_(transfer) (&mips1->guest_r25, buf, dir, size, mod); break;
293 case 26: VG_(transfer) (&mips1->guest_r26, buf, dir, size, mod); break;
294 case 27: VG_(transfer) (&mips1->guest_r27, buf, dir, size, mod); break;
295 case 28: VG_(transfer) (&mips1->guest_r28, buf, dir, size, mod); break;
296 case 29: VG_(transfer) (&mips1->guest_r29, buf, dir, size, mod); break;
297 case 30: VG_(transfer) (&mips1->guest_r30, buf, dir, size, mod); break;
298 case 31: VG_(transfer) (&mips1->guest_r31, buf, dir, size, mod); break;
299 case 32: *mod = False; break; // GDBTD???? VEX { "status", 1024, 64 }
300 case 33: VG_(transfer) (&mips1->guest_LO, buf, dir, size, mod); break;
301 case 34: VG_(transfer) (&mips1->guest_HI, buf, dir, size, mod); break;
302 case 35: *mod = False; break; // GDBTD???? VEX { "badvaddr", 1120, 64 },
303 case 36: *mod = False; break; // GDBTD???? VEX { "cause", 1152, 64 },
304 case 37:
305 /* If a breakpoint is set on the instruction in a branch delay slot,
306 GDB gets confused. When the breakpoint is hit, the PC isn't on
307 the instruction in the branch delay slot, the PC will point to
308 the branch instruction. */
309 mips1->guest_PC = mips_adjust_breakpoint_address(mips1->guest_PC);
310 VG_(transfer) (&mips1->guest_PC, buf, dir, size, mod);
311 break;
312 case 38: VG_(transfer) (&mips1->guest_f0, buf, dir, size, mod); break;
313 case 39: VG_(transfer) (&mips1->guest_f1, buf, dir, size, mod); break;
314 case 40: VG_(transfer) (&mips1->guest_f2, buf, dir, size, mod); break;
315 case 41: VG_(transfer) (&mips1->guest_f3, buf, dir, size, mod); break;
316 case 42: VG_(transfer) (&mips1->guest_f4, buf, dir, size, mod); break;
317 case 43: VG_(transfer) (&mips1->guest_f5, buf, dir, size, mod); break;
318 case 44: VG_(transfer) (&mips1->guest_f6, buf, dir, size, mod); break;
319 case 45: VG_(transfer) (&mips1->guest_f7, buf, dir, size, mod); break;
320 case 46: VG_(transfer) (&mips1->guest_f8, buf, dir, size, mod); break;
321 case 47: VG_(transfer) (&mips1->guest_f9, buf, dir, size, mod); break;
322 case 48: VG_(transfer) (&mips1->guest_f10, buf, dir, size, mod); break;
323 case 49: VG_(transfer) (&mips1->guest_f11, buf, dir, size, mod); break;
324 case 50: VG_(transfer) (&mips1->guest_f12, buf, dir, size, mod); break;
325 case 51: VG_(transfer) (&mips1->guest_f13, buf, dir, size, mod); break;
326 case 52: VG_(transfer) (&mips1->guest_f14, buf, dir, size, mod); break;
327 case 53: VG_(transfer) (&mips1->guest_f15, buf, dir, size, mod); break;
328 case 54: VG_(transfer) (&mips1->guest_f16, buf, dir, size, mod); break;
329 case 55: VG_(transfer) (&mips1->guest_f17, buf, dir, size, mod); break;
330 case 56: VG_(transfer) (&mips1->guest_f18, buf, dir, size, mod); break;
331 case 57: VG_(transfer) (&mips1->guest_f19, buf, dir, size, mod); break;
332 case 58: VG_(transfer) (&mips1->guest_f20, buf, dir, size, mod); break;
333 case 59: VG_(transfer) (&mips1->guest_f21, buf, dir, size, mod); break;
334 case 60: VG_(transfer) (&mips1->guest_f22, buf, dir, size, mod); break;
335 case 61: VG_(transfer) (&mips1->guest_f23, buf, dir, size, mod); break;
336 case 62: VG_(transfer) (&mips1->guest_f24, buf, dir, size, mod); break;
337 case 63: VG_(transfer) (&mips1->guest_f25, buf, dir, size, mod); break;
338 case 64: VG_(transfer) (&mips1->guest_f26, buf, dir, size, mod); break;
339 case 65: VG_(transfer) (&mips1->guest_f27, buf, dir, size, mod); break;
340 case 66: VG_(transfer) (&mips1->guest_f28, buf, dir, size, mod); break;
341 case 67: VG_(transfer) (&mips1->guest_f29, buf, dir, size, mod); break;
342 case 68: VG_(transfer) (&mips1->guest_f30, buf, dir, size, mod); break;
343 case 69: VG_(transfer) (&mips1->guest_f31, buf, dir, size, mod); break;
344 case 70: VG_(transfer) (&mips1->guest_FCSR, buf, dir, size, mod); break;
345 case 71: VG_(transfer) (&mips1->guest_FIR, buf, dir, size, mod); break;
346 case 72: *mod = False; break; // GDBTD???? VEX{ "restart", 2304, 64 },
347 default: VG_(printf)("regno: %d\n", regno); vg_assert(0);
351 static
352 const char* target_xml (Bool shadow_mode)
354 if (shadow_mode) {
355 return "mips64-linux-valgrind.xml";
356 } else {
357 return "mips64-linux.xml";
361 static CORE_ADDR** target_get_dtv (ThreadState *tst)
363 VexGuestMIPS64State* mips64 = (VexGuestMIPS64State*)&tst->arch.vex;
364 // Top of MIPS tcbhead structure is located 0x7000 bytes before the value
365 // of ULR. Dtv is the first of two pointers in tcbhead structure.
366 // More details can be found in GLIBC/sysdeps/nptl/tls.h.
367 return (CORE_ADDR**)((CORE_ADDR)mips64->guest_ULR
368 - 0x7000 - 2 * sizeof(CORE_ADDR));
371 static struct valgrind_target_ops low_target = {
372 num_regs,
373 regs,
374 29, //sp = r29, which is register offset 29 in regs
375 transfer_register,
376 get_pc,
377 set_pc,
378 "mips64",
379 target_xml,
380 target_get_dtv
383 void mips64_init_architecture (struct valgrind_target_ops *target)
385 *target = low_target;
386 set_register_cache (regs, num_regs);
387 gdbserver_expedite_regs = expedite_regs;