Home | History | Annotate | Download | only in cris
      1 /*
      2  * This file is part of ltrace.
      3  * Copyright (C) 2010 Edgar E. Iglesias
      4  *
      5  * This program is free software; you can redistribute it and/or
      6  * modify it under the terms of the GNU General Public License as
      7  * published by the Free Software Foundation; either version 2 of the
      8  * License, or (at your option) any later version.
      9  *
     10  * This program is distributed in the hope that it will be useful, but
     11  * WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  * General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU General Public License
     16  * along with this program; if not, write to the Free Software
     17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
     18  * 02110-1301 USA
     19  */
     20 
     21 #if HAVE_CONFIG_H
     22 #include "config.h"
     23 #endif
     24 
     25 #include <sys/types.h>
     26 #include <sys/wait.h>
     27 #include <signal.h>
     28 #include <sys/ptrace.h>
     29 #include <asm/ptrace.h>
     30 #include <elf.h>
     31 
     32 #include "proc.h"
     33 #include "common.h"
     34 
     35 #if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
     36 # define PTRACE_PEEKUSER PTRACE_PEEKUSR
     37 #endif
     38 
     39 #if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR))
     40 # define PTRACE_POKEUSER PTRACE_POKEUSR
     41 #endif
     42 
     43 void get_arch_dep(struct process *proc)
     44 {
     45 }
     46 
     47 /* Returns 1 if syscall, 2 if sysret, 0 otherwise.
     48  */
     49 #define SYSCALL_INSN   0xe93d
     50 int syscall_p(struct process *proc, int status, int *sysnum)
     51 {
     52 	if (WIFSTOPPED(status)
     53 	    && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
     54 		long pc = (long)get_instruction_pointer(proc);
     55 		unsigned int insn =
     56 		    (int)ptrace(PTRACE_PEEKTEXT, proc->pid, pc - sizeof(long),
     57 				0);
     58 
     59 		if ((insn >> 16) == SYSCALL_INSN) {
     60 			*sysnum =
     61 			    (int)ptrace(PTRACE_PEEKUSER, proc->pid,
     62 					sizeof(long) * PT_R9, 0);
     63 			if (proc->callstack_depth > 0
     64 			    && proc->callstack[proc->callstack_depth -
     65 					       1].is_syscall) {
     66 				return 2;
     67 			}
     68 			return 1;
     69 		}
     70 	}
     71 	return 0;
     72 }
     73 
     74 long gimme_arg(enum tof type, struct process *proc, int arg_num,
     75 	       struct arg_type_info *info)
     76 {
     77 	int pid = proc->pid;
     78 
     79 	if (arg_num == -1) {	/* return value */
     80 		return ptrace(PTRACE_PEEKUSER, pid, PT_R10 * 4, 0);
     81 	} else if (arg_num < 6) {
     82 		int pt_arg[6] =
     83 			{
     84 				PT_ORIG_R10, PT_R11, PT_R12, PT_R13, PT_MOF,
     85 				PT_SRP
     86 			};
     87 		return ptrace(PTRACE_PEEKUSER, pid, pt_arg[arg_num] * 4, 0);
     88 	} else {
     89 		return ptrace(PTRACE_PEEKDATA, pid,
     90 			      proc->stack_pointer + 4 * (arg_num - 6), 0);
     91 	}
     92 	return 0;
     93 }
     94