blob: 1399b9f9a6ce46e1cffc42be3d08975008f98d64 [file] [log] [blame]
Eric Vaitl1228a912006-12-28 16:16:56 +01001#if HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <sys/types.h>
6#include <sys/wait.h>
7#include <signal.h>
8#include <sys/ptrace.h>
9#include <asm/ptrace.h>
10#include "debug.h"
11#include "ltrace.h"
12#include "mipsel.h"
13#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
14# define PTRACE_PEEKUSER PTRACE_PEEKUSR
15#endif
16
17#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR))
18# define PTRACE_POKEUSER PTRACE_POKEUSR
19#endif
20
21
22/**
23 \addtogroup mipsel Mipsel specific functions.
24
25 These are the functions that it looks like I need to implement in
Juan Cespedesfea4a122009-05-28 16:53:43 +020026 order to get ltrace to work on our target.
Eric Vaitl1228a912006-12-28 16:16:56 +010027
28 @{
29 */
30
31/**
Juan Cespedesfea4a122009-05-28 16:53:43 +020032 \param proc The process that had an event.
Eric Vaitl1228a912006-12-28 16:16:56 +010033
Juan Cespedese2023f72009-04-07 12:12:08 +020034 Called by \c next_event() right after the return from wait.
Eric Vaitl1228a912006-12-28 16:16:56 +010035
36 Most targets just return here. A couple use proc->arch_ptr for a
37 private data area.
38 */
Juan Cespedesf1350522008-12-16 18:19:58 +010039void
Juan Cespedesa8909f72009-04-28 20:02:41 +020040get_arch_dep(Process *proc) {
Eric Vaitl1228a912006-12-28 16:16:56 +010041}
42
43/**
Juan Cespedesfea4a122009-05-28 16:53:43 +020044 \param proc Process that had event.
Eric Vaitl1228a912006-12-28 16:16:56 +010045 \param status From \c wait()
Juan Cespedesfea4a122009-05-28 16:53:43 +020046 \param sysnum 0-based syscall number.
Eric Vaitl1228a912006-12-28 16:16:56 +010047 \return 1 if syscall, 2 if sysret, 0 otherwise.
48
Juan Cespedese2023f72009-04-07 12:12:08 +020049 Called by \c next_event() after the call to get_arch_dep()
Eric Vaitl1228a912006-12-28 16:16:56 +010050
51 It seems that the ptrace call trips twice on a system call, once
52 just before the system call and once when it returns. Both times,
53 the pc points at the instruction just after the mipsel "syscall"
54 instruction.
55
56 There are several possiblities for system call sets, each is offset
57 by a base from the others. On our system, it looks like the base
58 for the system calls is 4000.
59 */
Juan Cespedesf1350522008-12-16 18:19:58 +010060int
Juan Cespedesa8909f72009-04-28 20:02:41 +020061syscall_p(Process *proc, int status, int *sysnum) {
Eric Vaitl1228a912006-12-28 16:16:56 +010062 if (WIFSTOPPED(status)
Juan Cespedes3e94cbf2009-05-22 19:12:07 +020063 && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
64 /* get the user's pc (plus 8) */
65 long pc = (long)get_instruction_pointer(proc);
66 /* fetch the SWI instruction */
67 int insn = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 4, 0);
68 int num = ptrace(PTRACE_PEEKTEXT, proc->pid, pc - 8, 0);
Eric Vaitl1228a912006-12-28 16:16:56 +010069
Juan Cespedes3e94cbf2009-05-22 19:12:07 +020070 /*
71 On a mipsel, syscall looks like:
72 24040fa1 li v0, 0x0fa1 # 4001 --> _exit syscall
73 0000000c syscall
74 */
75 if(insn!=0x0000000c){
76 return 0;
77 }
78
79 *sysnum = (num & 0xFFFF) - 4000;
80 /* if it is a syscall, return 1 or 2 */
81 if (proc->callstack_depth > 0 &&
82 proc->callstack[proc->callstack_depth - 1].is_syscall &&
83 proc->callstack[proc->callstack_depth - 1].c_un.syscall == *sysnum) {
84 return 2;
85 }
86
87 if (*sysnum >= 0) {
88 return 1;
89 }
90 }
Eric Vaitl1228a912006-12-28 16:16:56 +010091 return 0;
92}
93/**
94 \param type Function/syscall call or return.
95 \param proc The process that had an event.
Juan Cespedesfea4a122009-05-28 16:53:43 +020096 \param arg_num -1 for return value,
97 \return The argument to fetch.
Eric Vaitl1228a912006-12-28 16:16:56 +010098
Juan Cespedesfea4a122009-05-28 16:53:43 +020099 A couple of assumptions.
Eric Vaitl1228a912006-12-28 16:16:56 +0100100
101- Type is LT_TOF_FUNCTIONR or LT_TOF_SYSCALLR if arg_num==-1. These
102 types are only used in calls for output_right(), which only uses -1
103 for arg_num.
Juan Cespedesfea4a122009-05-28 16:53:43 +0200104- Type is LT_TOF_FUNCTION or LT_TOF_SYSCALL for args 0...4.
Eric Vaitl1228a912006-12-28 16:16:56 +0100105- I'm only displaying the first 4 args (Registers a0..a3). Good
106 enough for now.
107
108 Mipsel conventions seem to be:
109- syscall parameters: r4...r9
110- syscall return: if(!a3){ return v0;} else{ errno=v0;return -1;}
Juan Cespedesfea4a122009-05-28 16:53:43 +0200111- function call: r4..r7. Not sure how to get arg number 5.
Eric Vaitl1228a912006-12-28 16:16:56 +0100112- function return: v0
113
114The argument registers are wiped by a call, so it is a mistake to ask
115for arguments on a return. If ltrace does this, we will need to cache
116arguments somewhere on the call.
117
Juan Cespedesfea4a122009-05-28 16:53:43 +0200118I'm not doing any floating point support here.
Eric Vaitl1228a912006-12-28 16:16:56 +0100119
120*/
Juan Cespedesf1350522008-12-16 18:19:58 +0100121long
Juan Cespedesa8909f72009-04-28 20:02:41 +0200122gimme_arg(enum tof type, Process *proc, int arg_num, arg_type_info *info) {
Juan Cespedes3e94cbf2009-05-22 19:12:07 +0200123 long ret;
124 debug(2,"type %d arg %d",type,arg_num);
125 if (type == LT_TOF_FUNCTION || type == LT_TOF_SYSCALL){
126 if(arg_num <4){
127 ret=ptrace(PTRACE_PEEKUSER,proc->pid,off_a0+arg_num,0);
128 debug(2,"ret = %#lx",ret);
129 return ret;
130 } else {
131 // If we need this, I think we can look at [sp+16] for arg_num==4.
132 CP;
133 return 0;
134 }
Juan Cespedesfea4a122009-05-28 16:53:43 +0200135 }
Juan Cespedes3e94cbf2009-05-22 19:12:07 +0200136 if(arg_num>=0){
137 fprintf(stderr,"args on return?");
138 }
139 if(type == LT_TOF_FUNCTIONR) {
140 return ptrace(PTRACE_PEEKUSER,proc->pid,off_v0,0);
141 }
142 if (type == LT_TOF_SYSCALLR) {
143 unsigned a3=ptrace(PTRACE_PEEKUSER, proc->pid,off_a3,0);
144 unsigned v0=ptrace(PTRACE_PEEKUSER, proc->pid,off_v0,0);
145 if(!a3){
146 return v0;
147 }
148 return -1;
149 }
150 fprintf(stderr, "gimme_arg called with wrong arguments\n");
Eric Vaitl1228a912006-12-28 16:16:56 +0100151 return 0;
152}
153
154/**
155 \param type Type of call/return
Juan Cespedesfea4a122009-05-28 16:53:43 +0200156 \param proc Process to work with.
157
Eric Vaitl1228a912006-12-28 16:16:56 +0100158 Called by \c output_left(), which is called on a syscall or
159 function.
Juan Cespedesfea4a122009-05-28 16:53:43 +0200160
Eric Vaitl1228a912006-12-28 16:16:56 +0100161 The other architectures stub this out, but seems to be the place to
162 stash off the arguments on a call so we have them on the return.
Juan Cespedesfea4a122009-05-28 16:53:43 +0200163
Eric Vaitl1228a912006-12-28 16:16:56 +0100164*/
Juan Cespedesf1350522008-12-16 18:19:58 +0100165void
Juan Cespedesa8909f72009-04-28 20:02:41 +0200166save_register_args(enum tof type, Process *proc) {
Eric Vaitl1228a912006-12-28 16:16:56 +0100167}
168
169/**@}*/