• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
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_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"
34 
35 #include "valgrind_low.h"
36 
37 #include "libvex_guest_mips64.h"
38 
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 }
113 };
114 
115 
116 #define num_regs (sizeof (regs) / sizeof (regs[0]))
117 
118 static const char *expedite_regs[] = { "r29", "pc", 0 };
119 
120 static
get_pc(void)121 CORE_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 
131 static
set_pc(CORE_ADDR newpc)132 void 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 
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)
147 
148 /* Do a endian load of a 32-bit word, regardless of the
149    endianness of the underlying host. */
getUInt(UChar * p)150 static 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). */
169 static UInt
mips_instruction_has_delay_slot(Addr addr)170 mips_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.  */
mips_adjust_breakpoint_address(Addr pc)211 static Addr mips_adjust_breakpoint_address (Addr pc)
212 {
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;
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 
249 /* store registers in the guest state (gdbserver_to_valgrind)
250    or fetch register from the guest state (valgrind_to_gdbserver). */
251 static
transfer_register(ThreadId tid,int abs_regno,void * buf,transfer_direction dir,int size,Bool * mod)252 void 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 },
300    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;
308    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 
347 static
target_xml(Bool shadow_mode)348 const 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 
target_get_dtv(ThreadState * tst)357 static CORE_ADDR** target_get_dtv (ThreadState *tst)
358 {
359    VexGuestMIPS64State* mips64 = (VexGuestMIPS64State*)&tst->arch.vex;
360    // Top of MIPS tcbhead structure is located 0x7000 bytes before the value
361    // of ULR. Dtv is the first of two pointers in tcbhead structure.
362    // More details can be found in GLIBC/sysdeps/nptl/tls.h.
363    return (CORE_ADDR**)((CORE_ADDR)mips64->guest_ULR
364                         - 0x7000 - 2 * sizeof(CORE_ADDR));
365 }
366 
367 static struct valgrind_target_ops low_target = {
368    num_regs,
369    regs,
370    29, //sp = r29, which is register offset 29 in regs
371    transfer_register,
372    get_pc,
373    set_pc,
374    "mips64",
375    target_xml,
376    target_get_dtv
377 };
378 
mips64_init_architecture(struct valgrind_target_ops * target)379 void mips64_init_architecture (struct valgrind_target_ops *target)
380 {
381    *target = low_target;
382    set_register_cache (regs, num_regs);
383    gdbserver_expedite_regs = expedite_regs;
384 }
385