1 /*
2 * This file is part of ltrace.
3 * Copyright (C) 2013 Petr Machata, Red Hat Inc.
4 * Copyright (C) 2012 Edgar E. Iglesias, Axis Communications
5 * Copyright (C) 2010 Arnaud Patard, Mandriva SA
6 * Copyright (C) 2008,2009 Juan Cespedes
7 * Copyright (C) 2006 Eric Vaitl, Cisco Systems, Inc.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * 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 St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 */
24
25 #include "config.h"
26
27 #include <sys/types.h>
28 #include <sys/wait.h>
29 #include <signal.h>
30 #include <sys/ptrace.h>
31 #include <asm/ptrace.h>
32 #include <assert.h>
33
34 #include "backend.h"
35 #include "common.h"
36 #include "debug.h"
37 #include "mips.h"
38 #include "proc.h"
39 #include "type.h"
40
41 #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
42 # define PTRACE_PEEKUSER PTRACE_PEEKUSR
43 #endif
44
45 #if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR))
46 # define PTRACE_POKEUSER PTRACE_POKEUSR
47 #endif
48
49
50 /**
51 \addtogroup mips Mips specific functions.
52
53 These are the functions that it looks like I need to implement in
54 order to get ltrace to work on our target.
55
56 @{
57 */
58
59 /**
60 \param proc The process that had an event.
61
62 Called by \c next_event() right after the return from wait.
63
64 Most targets just return here. A couple use proc->arch_ptr for a
65 private data area.
66 */
67 void
get_arch_dep(struct process * proc)68 get_arch_dep(struct process *proc)
69 {
70 }
71
72 /**
73 \param proc Process that had event.
74 \param status From \c wait()
75 \param sysnum 0-based syscall number.
76 \return 1 if syscall, 2 if sysret, 0 otherwise.
77
78 Called by \c next_event() after the call to get_arch_dep()
79
80 It seems that the ptrace call trips twice on a system call, once
81 just before the system call and once when it returns. Both times,
82 the pc points at the instruction just after the mips "syscall"
83 instruction.
84
85 There are several possiblities for system call sets, each is offset
86 by a base from the others. On our system, it looks like the base
87 for the system calls is 4000.
88 */
89 int
syscall_p(struct process * proc,int status,int * sysnum)90 syscall_p(struct process *proc, int status, int *sysnum)
91 {
92 if (WIFSTOPPED(status)
93 && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
94 /* get the user's pc (plus 8) */
95 long pc = (long)get_instruction_pointer(proc);
96 /* fetch the SWI instruction */
97 int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0);
98 int num = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 8, 0);
99
100 /*
101 On a mips, syscall looks like:
102 24040fa1 li v0, 0x0fa1 # 4001 --> _exit syscall
103 0000000c syscall
104 */
105 if(insn!=0x0000000c){
106 return 0;
107 }
108
109 *sysnum = (num & 0xFFFF) - 4000;
110 /* if it is a syscall, return 1 or 2 */
111 if (proc->callstack_depth > 0 &&
112 proc->callstack[proc->callstack_depth - 1].is_syscall &&
113 proc->callstack[proc->callstack_depth - 1].c_un.syscall == *sysnum) {
114 return 2;
115 }
116
117 if (*sysnum >= 0) {
118 return 1;
119 }
120 }
121 return 0;
122 }
123
124 /* Based on GDB code. */
125 #define mips32_op(x) (x >> 26)
126 #define itype_op(x) (x >> 26)
127 #define itype_rs(x) ((x >> 21) & 0x1f)
128 #define itype_rt(x) ((x >> 16) & 0x1f)
129 #define itype_immediate(x) (x & 0xffff)
130
131 #define jtype_op(x) (x >> 26)
132 #define jtype_target(x) (x & 0x03ffffff)
133
134 #define rtype_op(x) (x >> 26)
135 #define rtype_rs(x) ((x >> 21) & 0x1f)
136 #define rtype_rt(x) ((x >> 16) & 0x1f)
137 #define rtype_rd(x) ((x >> 11) & 0x1f)
138 #define rtype_shamt(x) ((x >> 6) & 0x1f)
139 #define rtype_funct(x) (x & 0x3f)
140
141 static int32_t
mips32_relative_offset(uint32_t inst)142 mips32_relative_offset (uint32_t inst)
143 {
144 return ((itype_immediate(inst) ^ 0x8000) - 0x8000) << 2;
145 }
146
mips_next_pcs(struct process * proc,uint32_t pc,uint32_t * newpc)147 int mips_next_pcs(struct process *proc, uint32_t pc, uint32_t *newpc)
148 {
149 uint32_t inst, rx;
150 int op;
151 int rn;
152 int nr = 0;
153
154 inst = ptrace(PTRACE_PEEKTEXT, proc->pid, pc, 0);
155
156 if ((inst & 0xe0000000) != 0) {
157 /* Check for branches. */
158 if (itype_op(inst) >> 2 == 5) {
159 /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */
160 op = (itype_op(inst) & 0x03);
161 switch (op)
162 {
163 case 0: /* BEQL */
164 case 1: /* BNEL */
165 case 2: /* BLEZL */
166 case 3: /* BGTZL */
167 newpc[nr++] = pc + 8;
168 newpc[nr++] = pc + 4 +
169 mips32_relative_offset(inst);
170 break;
171 default:
172 newpc[nr++] = pc + 4;
173 break;
174 }
175 } else if (itype_op(inst) == 17 && itype_rs(inst) == 8) {
176 /* Step over the branch. */
177 newpc[nr++] = pc + 8;
178 newpc[nr++] = pc + mips32_relative_offset(inst) + 4;
179 } else {
180 newpc[nr++] = pc + 4;
181 }
182 } else {
183 /* Further subdivide into SPECIAL, REGIMM and other. */
184 switch (op = itype_op(inst) & 0x07)
185 {
186 case 0:
187 op = rtype_funct(inst);
188 switch (op)
189 {
190 case 8: /* JR */
191 case 9: /* JALR */
192 rn = rtype_rs(inst);
193
194 rx = ptrace(PTRACE_PEEKUSER,proc->pid, rn, 0);
195 newpc[nr++] = rx;
196 break;
197 default:
198 case 12: /* SYSCALL */
199 newpc[nr++] = pc + 4;
200 break;
201 }
202 break;
203 case 1:
204 op = itype_rt(inst);
205 switch (op)
206 {
207 case 0:
208 case 1:
209 case 2:
210 case 3:
211 case 16:
212 case 17:
213 case 18:
214 case 19:
215 newpc[nr++] = pc + 8;
216 newpc[nr++] = pc + 4 +
217 mips32_relative_offset(inst);
218 break;
219 default:
220 newpc[nr++] = pc + 4;
221 break;
222 }
223 break;
224 case 2: /* J */
225 case 3: /* JAL */
226 rx = jtype_target(inst) << 2;
227 /* Upper four bits get never changed... */
228 newpc[nr++] = rx + ((pc + 4) & ~0x0fffffff);
229 break;
230 case 4: /* BEQ */
231 if (itype_rs(inst) == itype_rt(inst)) {
232 /* Compare the same reg for equality, always
233 * follow the branch. */
234 newpc[nr++] = pc + 4 +
235 mips32_relative_offset(inst);
236 break;
237 }
238 /* Fall through. */
239 default:
240 case 5:
241 case 6:
242 case 7:
243 /* Step over the branch. */
244 newpc[nr++] = pc + 8;
245 newpc[nr++] = pc + mips32_relative_offset(inst) + 4;
246 break;
247 }
248 }
249 if (nr <= 0 || nr > 2)
250 goto fail;
251 if (nr == 2) {
252 if (newpc[1] == 0)
253 goto fail;
254 }
255 if (newpc[0] == 0)
256 goto fail;
257
258 assert(nr == 1 || nr == 2);
259 return nr;
260
261 fail:
262 printf("nr=%d pc=%x\n", nr, pc);
263 printf("pc=%x %x\n", newpc[0], newpc[1]);
264 return 0;
265 }
266
267 enum sw_singlestep_status
arch_sw_singlestep(struct process * proc,struct breakpoint * bp,int (* add_cb)(arch_addr_t,struct sw_singlestep_data *),struct sw_singlestep_data * add_cb_data)268 arch_sw_singlestep(struct process *proc, struct breakpoint *bp,
269 int (*add_cb)(arch_addr_t, struct sw_singlestep_data *),
270 struct sw_singlestep_data *add_cb_data)
271 {
272 uint32_t pc = (uint32_t) get_instruction_pointer(proc);
273 uint32_t newpcs[2];
274 int nr;
275
276 nr = mips_next_pcs(proc, pc, newpcs);
277
278 while (nr-- > 0) {
279 arch_addr_t baddr = (arch_addr_t) newpcs[nr];
280 /* Not sure what to do here. We've already got a bp? */
281 if (DICT_HAS_KEY(proc->leader->breakpoints, &baddr)) {
282 fprintf(stderr, "skip %p %p\n", baddr, add_cb_data);
283 continue;
284 }
285
286 if (add_cb(baddr, add_cb_data) < 0)
287 return SWS_FAIL;
288 }
289
290 ptrace(PTRACE_SYSCALL, proc->pid, 0, 0);
291 return SWS_OK;
292 }
293
294 /**
295 \param type Function/syscall call or return.
296 \param proc The process that had an event.
297 \param arg_num -1 for return value,
298 \return The argument to fetch.
299
300 A couple of assumptions.
301
302 - Type is LT_TOF_FUNCTIONR or LT_TOF_SYSCALLR if arg_num==-1. These
303 types are only used in calls for output_right(), which only uses -1
304 for arg_num.
305 - Type is LT_TOF_FUNCTION or LT_TOF_SYSCALL for args 0...4.
306 - I'm only displaying the first 4 args (Registers a0..a3). Good
307 enough for now.
308
309 Mips conventions seem to be:
310 - syscall parameters: r4...r9
311 - syscall return: if(!a3){ return v0;} else{ errno=v0;return -1;}
312 - function call: r4..r7. Not sure how to get arg number 5.
313 - function return: v0
314
315 The argument registers are wiped by a call, so it is a mistake to ask
316 for arguments on a return. If ltrace does this, we will need to cache
317 arguments somewhere on the call.
318
319 I'm not doing any floating point support here.
320
321 */
322 long
gimme_arg(enum tof type,struct process * proc,int arg_num,struct arg_type_info * info)323 gimme_arg(enum tof type, struct process *proc, int arg_num,
324 struct arg_type_info *info)
325 {
326 long ret;
327 long addr;
328 debug(2,"type %d arg %d",type,arg_num);
329 if (arg_num == -1) {
330 if(type == LT_TOF_FUNCTIONR) {
331 return ptrace(PTRACE_PEEKUSER,proc->pid,off_v0,0);
332 }
333 if (type == LT_TOF_SYSCALLR) {
334 unsigned a3=ptrace(PTRACE_PEEKUSER, proc->pid,off_a3,0);
335 unsigned v0=ptrace(PTRACE_PEEKUSER, proc->pid,off_v0,0);
336 if(!a3){
337 return v0;
338 }
339 return -1;
340 }
341 }
342 if (type == LT_TOF_FUNCTION || type == LT_TOF_SYSCALL) {
343 /* o32: float args are in f12 and f14 */
344 if ((info->type == ARGTYPE_FLOAT) && (arg_num < 2)) {
345 ret=ptrace(PTRACE_PEEKUSER,proc->pid,off_fpr0+12+arg_num*2,0);
346 debug(2,"ret = %#lx",ret);
347 return ret;
348 }
349 if(arg_num <4){
350 ret=ptrace(PTRACE_PEEKUSER,proc->pid,off_a0+arg_num,0);
351 debug(2,"ret = %#lx",ret);
352 return ret;
353 } else {
354 /* not sure it's going to work for something else than syscall */
355 addr=ptrace(PTRACE_PEEKUSER,proc->pid,off_sp,0);
356 if (addr == -1) {
357 debug(2,"ret = %#lx",addr);
358 return addr;
359 }
360 ret = addr + 4*arg_num;
361 ret=ptrace(PTRACE_PEEKTEXT,proc->pid,addr,0);
362 debug(2,"ret = %#lx",ret);
363 return ret;
364 }
365 }
366 if (type == LT_TOF_FUNCTIONR || type == LT_TOF_SYSCALLR){
367 addr=ptrace(PTRACE_PEEKUSER,proc->pid,off_sp,0);
368 if (addr == -1) {
369 debug(2,"ret = %#lx",addr);
370 return addr;
371 }
372 ret = addr + 4*arg_num;
373 ret=ptrace(PTRACE_PEEKTEXT,proc->pid,addr,0);
374 debug(2,"ret = %#lx",ret);
375 return ret;
376 }
377 fprintf(stderr, "gimme_arg called with wrong arguments\n");
378 return 0;
379 }
380
381 /**@}*/
382