linux/arch/h8300/kernel/ptrace.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/h8300/kernel/ptrace.c
   3 *
   4 *  Yoshinori Sato <ysato@users.sourceforge.jp>
   5 *
   6 *  Based on:
   7 *  linux/arch/m68k/kernel/ptrace.c
   8 *
   9 *  Copyright (C) 1994 by Hamish Macdonald
  10 *  Taken from linux/kernel/ptrace.c and modified for M680x0.
  11 *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
  12 *
  13 * This file is subject to the terms and conditions of the GNU General
  14 * Public License.  See the file COPYING in the main directory of
  15 * this archive for more details.
  16 */
  17
  18#include <linux/kernel.h>
  19#include <linux/sched.h>
  20#include <linux/mm.h>
  21#include <linux/smp.h>
  22#include <linux/errno.h>
  23#include <linux/ptrace.h>
  24#include <linux/user.h>
  25#include <linux/signal.h>
  26
  27#include <asm/uaccess.h>
  28#include <asm/page.h>
  29#include <asm/pgtable.h>
  30#include <asm/processor.h>
  31#include <asm/signal.h>
  32
  33/* cpu depend functions */
  34extern long h8300_get_reg(struct task_struct *task, int regno);
  35extern int  h8300_put_reg(struct task_struct *task, int regno, unsigned long data);
  36
  37
  38void user_disable_single_step(struct task_struct *child)
  39{
  40}
  41
  42/*
  43 * does not yet catch signals sent when the child dies.
  44 * in exit.c or in signal.c.
  45 */
  46
  47void ptrace_disable(struct task_struct *child)
  48{
  49        user_disable_single_step(child);
  50}
  51
  52long arch_ptrace(struct task_struct *child, long request,
  53                 unsigned long addr, unsigned long data)
  54{
  55        int ret;
  56        int regno = addr >> 2;
  57        unsigned long __user *datap = (unsigned long __user *) data;
  58
  59        switch (request) {
  60        /* read the word at location addr in the USER area. */
  61                case PTRACE_PEEKUSR: {
  62                        unsigned long tmp = 0;
  63                        
  64                        if ((addr & 3) || addr >= sizeof(struct user)) {
  65                                ret = -EIO;
  66                                break ;
  67                        }
  68                        
  69                        ret = 0;  /* Default return condition */
  70
  71                        if (regno < H8300_REGS_NO)
  72                                tmp = h8300_get_reg(child, regno);
  73                        else {
  74                                switch (regno) {
  75                                case 49:
  76                                        tmp = child->mm->start_code;
  77                                        break ;
  78                                case 50:
  79                                        tmp = child->mm->start_data;
  80                                        break ;
  81                                case 51:
  82                                        tmp = child->mm->end_code;
  83                                        break ;
  84                                case 52:
  85                                        tmp = child->mm->end_data;
  86                                        break ;
  87                                default:
  88                                        ret = -EIO;
  89                                }
  90                        }
  91                        if (!ret)
  92                                ret = put_user(tmp, datap);
  93                        break ;
  94                }
  95
  96      /* when I and D space are separate, this will have to be fixed. */
  97                case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
  98                        if ((addr & 3) || addr >= sizeof(struct user)) {
  99                                ret = -EIO;
 100                                break ;
 101                        }
 102                            
 103                        if (regno == PT_ORIG_ER0) {
 104                                ret = -EIO;
 105                                break ;
 106                        }
 107                        if (regno < H8300_REGS_NO) {
 108                                ret = h8300_put_reg(child, regno, data);
 109                                break ;
 110                        }
 111                        ret = -EIO;
 112                        break ;
 113
 114                case PTRACE_GETREGS: { /* Get all gp regs from the child. */
 115                        int i;
 116                        unsigned long tmp;
 117                        for (i = 0; i < H8300_REGS_NO; i++) {
 118                            tmp = h8300_get_reg(child, i);
 119                            if (put_user(tmp, datap)) {
 120                                ret = -EFAULT;
 121                                break;
 122                            }
 123                            datap++;
 124                        }
 125                        ret = 0;
 126                        break;
 127                }
 128
 129                case PTRACE_SETREGS: { /* Set all gp regs in the child. */
 130                        int i;
 131                        unsigned long tmp;
 132                        for (i = 0; i < H8300_REGS_NO; i++) {
 133                            if (get_user(tmp, datap)) {
 134                                ret = -EFAULT;
 135                                break;
 136                            }
 137                            h8300_put_reg(child, i, tmp);
 138                            datap++;
 139                        }
 140                        ret = 0;
 141                        break;
 142                }
 143
 144                default:
 145                        ret = ptrace_request(child, request, addr, data);
 146                        break;
 147        }
 148        return ret;
 149}
 150
 151asmlinkage void do_syscall_trace(void)
 152{
 153        if (!test_thread_flag(TIF_SYSCALL_TRACE))
 154                return;
 155        if (!(current->ptrace & PT_PTRACED))
 156                return;
 157        ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
 158                                 ? 0x80 : 0));
 159        /*
 160         * this isn't the same as continuing with a signal, but it will do
 161         * for normal use.  strace only continues with a signal if the
 162         * stopping signal is not SIGTRAP.  -brl
 163         */
 164        if (current->exit_code) {
 165                send_sig(current->exit_code, current, 1);
 166                current->exit_code = 0;
 167        }
 168}
 169