linux-bk/arch/um/kernel/tt/ptproxy/ptrace.c
<<
>>
Prefs
   1/**********************************************************************
   2ptrace.c
   3
   4Copyright (C) 1999 Lars Brinkhoff.  See the file COPYING for licensing
   5terms and conditions.
   6
   7Jeff Dike (jdike@karaya.com) : Modified for integration into uml
   8**********************************************************************/
   9
  10#include <errno.h>
  11#include <unistd.h>
  12#include <signal.h>
  13#include <sys/types.h>
  14#include <sys/time.h>
  15#include <sys/ptrace.h>
  16#include <sys/wait.h>
  17#include <asm/ptrace.h>
  18
  19#include "ptproxy.h"
  20#include "debug.h"
  21#include "user_util.h"
  22#include "kern_util.h"
  23#include "ptrace_user.h"
  24#include "tt.h"
  25
  26long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,
  27                  long arg3, long arg4, pid_t child, int *ret)
  28{
  29        sigset_t relay;
  30        long result;
  31        int status;
  32
  33        *ret = 0;
  34        if(debugger->debugee->died) return(-ESRCH);
  35
  36        switch(arg1){
  37        case PTRACE_ATTACH:
  38                if(debugger->debugee->traced) return(-EPERM);
  39
  40                debugger->debugee->pid = arg2;
  41                debugger->debugee->traced = 1;
  42
  43                if(is_valid_pid(arg2) && (arg2 != child)){
  44                        debugger->debugee->in_context = 0;
  45                        kill(arg2, SIGSTOP);
  46                        debugger->debugee->event = 1;
  47                        debugger->debugee->wait_status = W_STOPCODE(SIGSTOP);
  48                }
  49                else {
  50                        debugger->debugee->in_context = 1;
  51                        if(debugger->debugee->stopped) 
  52                                child_proxy(child, W_STOPCODE(SIGSTOP));
  53                        else kill(child, SIGSTOP);
  54                }
  55
  56                return(0);
  57
  58        case PTRACE_DETACH:
  59                if(!debugger->debugee->traced) return(-EPERM);
  60                
  61                debugger->debugee->traced = 0;
  62                debugger->debugee->pid = 0;
  63                if(!debugger->debugee->in_context)
  64                        kill(child, SIGCONT);
  65
  66                return(0);
  67
  68        case PTRACE_CONT:
  69                if(!debugger->debugee->in_context) return(-EPERM);
  70                *ret = PTRACE_CONT;
  71                return(ptrace(PTRACE_CONT, child, arg3, arg4));
  72
  73#ifdef UM_HAVE_GETFPREGS
  74        case PTRACE_GETFPREGS:
  75        {
  76                long regs[FP_FRAME_SIZE];
  77                int i, result;
  78
  79                result = ptrace(PTRACE_GETFPREGS, child, 0, regs);
  80                if(result == -1) return(-errno);
  81                
  82                for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
  83                        ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
  84                               regs[i]);
  85                return(result);
  86        }
  87#endif
  88
  89#ifdef UM_HAVE_GETFPXREGS
  90        case PTRACE_GETFPXREGS:
  91        {
  92                long regs[FPX_FRAME_SIZE];
  93                int i, result;
  94
  95                result = ptrace(PTRACE_GETFPXREGS, child, 0, regs);
  96                if(result == -1) return(-errno);
  97                
  98                for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
  99                        ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
 100                               regs[i]);
 101                return(result);
 102        }
 103#endif
 104
 105#ifdef UM_HAVE_GETREGS
 106        case PTRACE_GETREGS:
 107        {
 108                long regs[FRAME_SIZE];
 109                int i, result;
 110
 111                result = ptrace(PTRACE_GETREGS, child, 0, regs);
 112                if(result == -1) return(-errno);
 113
 114                for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
 115                        ptrace (PTRACE_POKEDATA, debugger->pid,
 116                                arg4 + 4 * i, regs[i]);
 117                return(result);
 118        }
 119        break;
 120#endif
 121
 122        case PTRACE_KILL:
 123                result = ptrace(PTRACE_KILL, child, arg3, arg4);
 124                if(result == -1) return(-errno);
 125
 126                return(result);
 127
 128        case PTRACE_PEEKDATA:
 129        case PTRACE_PEEKTEXT:
 130        case PTRACE_PEEKUSER:
 131                /* The value being read out could be -1, so we have to 
 132                 * check errno to see if there's an error, and zero it
 133                 * beforehand so we're not faked out by an old error
 134                 */
 135
 136                errno = 0;
 137                result = ptrace(arg1, child, arg3, 0);
 138                if((result == -1) && (errno != 0)) return(-errno);
 139
 140                result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result);
 141                if(result == -1) return(-errno);
 142                        
 143                return(result);
 144
 145        case PTRACE_POKEDATA:
 146        case PTRACE_POKETEXT:
 147        case PTRACE_POKEUSER:
 148                result = ptrace(arg1, child, arg3, arg4);
 149                if(result == -1) return(-errno);
 150
 151                if(arg1 == PTRACE_POKEUSER) ptrace_pokeuser(arg3, arg4);
 152                return(result);
 153
 154#ifdef UM_HAVE_SETFPREGS
 155        case PTRACE_SETFPREGS:
 156        {
 157                long regs[FP_FRAME_SIZE];
 158                int i;
 159
 160                for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
 161                        regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
 162                                          arg4 + 4 * i, 0);
 163                result = ptrace(PTRACE_SETFPREGS, child, 0, regs);
 164                if(result == -1) return(-errno);
 165
 166                return(result);
 167        }
 168#endif
 169
 170#ifdef UM_HAVE_SETFPXREGS
 171        case PTRACE_SETFPXREGS:
 172        {
 173                long regs[FPX_FRAME_SIZE];
 174                int i;
 175
 176                for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
 177                        regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
 178                                          arg4 + 4 * i, 0);
 179                result = ptrace(PTRACE_SETFPXREGS, child, 0, regs);
 180                if(result == -1) return(-errno);
 181
 182                return(result);
 183        }
 184#endif
 185
 186#ifdef UM_HAVE_SETREGS
 187        case PTRACE_SETREGS:
 188        {
 189                long regs[FRAME_SIZE];
 190                int i;
 191
 192                for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
 193                        regs[i] = ptrace(PTRACE_PEEKDATA, debugger->pid,
 194                                         arg4 + 4 * i, 0);
 195                result = ptrace(PTRACE_SETREGS, child, 0, regs);
 196                if(result == -1) return(-errno);
 197
 198                return(result);
 199        }
 200#endif
 201
 202        case PTRACE_SINGLESTEP:
 203                if(!debugger->debugee->in_context) return(-EPERM);
 204                sigemptyset(&relay);
 205                sigaddset(&relay, SIGSEGV);
 206                sigaddset(&relay, SIGILL);
 207                sigaddset(&relay, SIGBUS);
 208                result = ptrace(PTRACE_SINGLESTEP, child, arg3, arg4);
 209                if(result == -1) return(-errno);
 210                
 211                status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP,
 212                                       &relay);
 213                child_proxy(child, status);
 214                return(result);
 215
 216        case PTRACE_SYSCALL:
 217                if(!debugger->debugee->in_context) return(-EPERM);
 218                result = ptrace(PTRACE_SYSCALL, child, arg3, arg4);
 219                if(result == -1) return(-errno);
 220
 221                *ret = PTRACE_SYSCALL;
 222                return(result);
 223
 224        case PTRACE_TRACEME:
 225        default:
 226                return(-EINVAL);
 227        }
 228}
 229
 230/*
 231 * Overrides for Emacs so that we follow Linus's tabbing style.
 232 * Emacs will notice this stuff at the end of the file and automatically
 233 * adjust the settings for this buffer only.  This must remain at the end
 234 * of the file.
 235 * ---------------------------------------------------------------------------
 236 * Local variables:
 237 * c-file-style: "linux"
 238 * End:
 239 */
 240
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.