linux/arch/cris/arch-v32/kernel/ptrace.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2000-2007, Axis Communications AB.
   3 */
   4
   5#include <linux/kernel.h>
   6#include <linux/sched.h>
   7#include <linux/mm.h>
   8#include <linux/smp.h>
   9#include <linux/errno.h>
  10#include <linux/ptrace.h>
  11#include <linux/user.h>
  12#include <linux/signal.h>
  13#include <linux/security.h>
  14
  15#include <asm/uaccess.h>
  16#include <asm/page.h>
  17#include <asm/pgtable.h>
  18#include <asm/system.h>
  19#include <asm/processor.h>
  20#include <arch/hwregs/supp_reg.h>
  21
  22/*
  23 * Determines which bits in CCS the user has access to.
  24 * 1 = access, 0 = no access.
  25 */
  26#define CCS_MASK 0x00087c00     /* SXNZVC */
  27
  28#define SBIT_USER (1 << (S_CCS_BITNR + CCS_SHIFT))
  29
  30static int put_debugreg(long pid, unsigned int regno, long data);
  31static long get_debugreg(long pid, unsigned int regno);
  32static unsigned long get_pseudo_pc(struct task_struct *child);
  33void deconfigure_bp(long pid);
  34
  35extern unsigned long cris_signal_return_page;
  36
  37/*
  38 * Get contents of register REGNO in task TASK.
  39 */
  40long get_reg(struct task_struct *task, unsigned int regno)
  41{
  42        /* USP is a special case, it's not in the pt_regs struct but
  43         * in the tasks thread struct
  44         */
  45        unsigned long ret;
  46
  47        if (regno <= PT_EDA)
  48                ret = ((unsigned long *)task_pt_regs(task))[regno];
  49        else if (regno == PT_USP)
  50                ret = task->thread.usp;
  51        else if (regno == PT_PPC)
  52                ret = get_pseudo_pc(task);
  53        else if (regno <= PT_MAX)
  54                ret = get_debugreg(task->pid, regno);
  55        else
  56                ret = 0;
  57
  58        return ret;
  59}
  60
  61/*
  62 * Write contents of register REGNO in task TASK.
  63 */
  64int put_reg(struct task_struct *task, unsigned int regno, unsigned long data)
  65{
  66        if (regno <= PT_EDA)
  67                ((unsigned long *)task_pt_regs(task))[regno] = data;
  68        else if (regno == PT_USP)
  69                task->thread.usp = data;
  70        else if (regno == PT_PPC) {
  71                /* Write pseudo-PC to ERP only if changed. */
  72                if (data != get_pseudo_pc(task))
  73                        task_pt_regs(task)->erp = data;
  74        } else if (regno <= PT_MAX)
  75                return put_debugreg(task->pid, regno, data);
  76        else
  77                return -1;
  78        return 0;
  79}
  80
  81/*
  82 * Called by kernel/ptrace.c when detaching.
  83 *
  84 * Make sure the single step bit is not set.
  85 */
  86void
  87ptrace_disable(struct task_struct *child)
  88{
  89        unsigned long tmp;
  90
  91        /* Deconfigure SPC and S-bit. */
  92        tmp = get_reg(child, PT_CCS) & ~SBIT_USER;
  93        put_reg(child, PT_CCS, tmp);
  94        put_reg(child, PT_SPC, 0);
  95
  96        /* Deconfigure any watchpoints associated with the child. */
  97        deconfigure_bp(child->pid);
  98}
  99
 100
 101long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 102{
 103        int ret;
 104        unsigned long __user *datap = (unsigned long __user *)data;
 105
 106        switch (request) {
 107                /* Read word at location address. */
 108                case PTRACE_PEEKTEXT:
 109                case PTRACE_PEEKDATA: {
 110                        unsigned long tmp;
 111                        int copied;
 112
 113                        ret = -EIO;
 114
 115                        /* The signal trampoline page is outside the normal user-addressable
 116                         * space but still accessible. This is hack to make it possible to
 117                         * access the signal handler code in GDB.
 118                         */
 119                        if ((addr & PAGE_MASK) == cris_signal_return_page) {
 120                                /* The trampoline page is globally mapped, no page table to traverse.*/
 121                                tmp = *(unsigned long*)addr;
 122                        } else {
 123                                copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
 124
 125                                if (copied != sizeof(tmp))
 126                                        break;
 127                        }
 128
 129                        ret = put_user(tmp,datap);
 130                        break;
 131                }
 132
 133                /* Read the word at location address in the USER area. */
 134                case PTRACE_PEEKUSR: {
 135                        unsigned long tmp;
 136
 137                        ret = -EIO;
 138                        if ((addr & 3) || addr < 0 || addr > PT_MAX << 2)
 139                                break;
 140
 141                        tmp = get_reg(child, addr >> 2);
 142                        ret = put_user(tmp, datap);
 143                        break;
 144                }
 145
 146                /* Write the word at location address. */
 147                case PTRACE_POKETEXT:
 148                case PTRACE_POKEDATA:
 149                        ret = generic_ptrace_pokedata(child, addr, data);
 150                        break;
 151
 152                /* Write the word at location address in the USER area. */
 153                case PTRACE_POKEUSR:
 154                        ret = -EIO;
 155                        if ((addr & 3) || addr < 0 || addr > PT_MAX << 2)
 156                                break;
 157
 158                        addr >>= 2;
 159
 160                        if (addr == PT_CCS) {
 161                                /* don't allow the tracing process to change stuff like
 162                                 * interrupt enable, kernel/user bit, dma enables etc.
 163                                 */
 164                                data &= CCS_MASK;
 165                                data |= get_reg(child, PT_CCS) & ~CCS_MASK;
 166                        }
 167                        if (put_reg(child, addr, data))
 168                                break;
 169                        ret = 0;
 170                        break;
 171
 172                case PTRACE_SYSCALL:
 173                case PTRACE_CONT:
 174                        ret = -EIO;
 175
 176                        if (!valid_signal(data))
 177                                break;
 178
 179                        /* Continue means no single-step. */
 180                        put_reg(child, PT_SPC, 0);
 181
 182                        if (!get_debugreg(child->pid, PT_BP_CTRL)) {
 183                                unsigned long tmp;
 184                                /* If no h/w bp configured, disable S bit. */
 185                                tmp = get_reg(child, PT_CCS) & ~SBIT_USER;
 186                                put_reg(child, PT_CCS, tmp);
 187                        }
 188
 189                        if (request == PTRACE_SYSCALL) {
 190                                set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 191                        }
 192                        else {
 193                                clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 194                        }
 195
 196                        child->exit_code = data;
 197
 198                        /* TODO: make sure any pending breakpoint is killed */
 199                        wake_up_process(child);
 200                        ret = 0;
 201
 202                        break;
 203
 204                /* Make the child exit by sending it a sigkill. */
 205                case PTRACE_KILL:
 206                        ret = 0;
 207
 208                        if (child->exit_state == EXIT_ZOMBIE)
 209                                break;
 210
 211                        child->exit_code = SIGKILL;
 212
 213                        /* Deconfigure single-step and h/w bp. */
 214                        ptrace_disable(child);
 215
 216                        /* TODO: make sure any pending breakpoint is killed */
 217                        wake_up_process(child);
 218                        break;
 219
 220                /* Set the trap flag. */
 221                case PTRACE_SINGLESTEP: {
 222                        unsigned long tmp;
 223                        ret = -EIO;
 224
 225                        /* Set up SPC if not set already (in which case we have
 226                           no other choice but to trust it). */
 227                        if (!get_reg(child, PT_SPC)) {
 228                                /* In case we're stopped in a delay slot. */
 229                                tmp = get_reg(child, PT_ERP) & ~1;
 230                                put_reg(child, PT_SPC, tmp);
 231                        }
 232                        tmp = get_reg(child, PT_CCS) | SBIT_USER;
 233                        put_reg(child, PT_CCS, tmp);
 234
 235                        if (!valid_signal(data))
 236                                break;
 237
 238                        clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 239
 240                        /* TODO: set some clever breakpoint mechanism... */
 241
 242                        child->exit_code = data;
 243                        wake_up_process(child);
 244                        ret = 0;
 245                        break;
 246
 247                }
 248
 249                /* Get all GP registers from the child. */
 250                case PTRACE_GETREGS: {
 251                        int i;
 252                        unsigned long tmp;
 253
 254                        for (i = 0; i <= PT_MAX; i++) {
 255                                tmp = get_reg(child, i);
 256
 257                                if (put_user(tmp, datap)) {
 258                                        ret = -EFAULT;
 259                                        goto out_tsk;
 260                                }
 261
 262                                datap++;
 263                        }
 264
 265                        ret = 0;
 266                        break;
 267                }
 268
 269                /* Set all GP registers in the child. */
 270                case PTRACE_SETREGS: {
 271                        int i;
 272                        unsigned long tmp;
 273
 274                        for (i = 0; i <= PT_MAX; i++) {
 275                                if (get_user(tmp, datap)) {
 276                                        ret = -EFAULT;
 277                                        goto out_tsk;
 278                                }
 279
 280                                if (i == PT_CCS) {
 281                                        tmp &= CCS_MASK;
 282                                        tmp |= get_reg(child, PT_CCS) & ~CCS_MASK;
 283                                }
 284
 285                                put_reg(child, i, tmp);
 286                                datap++;
 287                        }
 288
 289                        ret = 0;
 290                        break;
 291                }
 292
 293                default:
 294                        ret = ptrace_request(child, request, addr, data);
 295                        break;
 296        }
 297
 298out_tsk:
 299        return ret;
 300}
 301
 302void do_syscall_trace(void)
 303{
 304        if (!test_thread_flag(TIF_SYSCALL_TRACE))
 305                return;
 306
 307        if (!(current->ptrace & PT_PTRACED))
 308                return;
 309
 310        /* the 0x80 provides a way for the tracing parent to distinguish
 311           between a syscall stop and SIGTRAP delivery */
 312        ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
 313                                 ? 0x80 : 0));
 314
 315        /*
 316         * This isn't the same as continuing with a signal, but it will do for
 317         * normal use.
 318         */
 319        if (current->exit_code) {
 320                send_sig(current->exit_code, current, 1);
 321                current->exit_code = 0;
 322        }
 323}
 324
 325/* Returns the size of an instruction that has a delay slot. */
 326
 327static int insn_size(struct task_struct *child, unsigned long pc)
 328{
 329  unsigned long opcode;
 330  int copied;
 331  int opsize = 0;
 332
 333  /* Read the opcode at pc (do what PTRACE_PEEKTEXT would do). */
 334  copied = access_process_vm(child, pc, &opcode, sizeof(opcode), 0);
 335  if (copied != sizeof(opcode))
 336    return 0;
 337
 338  switch ((opcode & 0x0f00) >> 8) {
 339  case 0x0:
 340  case 0x9:
 341  case 0xb:
 342          opsize = 2;
 343          break;
 344  case 0xe:
 345  case 0xf:
 346          opsize = 6;
 347          break;
 348  case 0xd:
 349          /* Could be 4 or 6; check more bits. */
 350          if ((opcode & 0xff) == 0xff)
 351                  opsize = 4;
 352          else
 353                  opsize = 6;
 354          break;
 355  default:
 356          panic("ERROR: Couldn't find size of opcode 0x%lx at 0x%lx\n",
 357                opcode, pc);
 358  }
 359
 360  return opsize;
 361}
 362
 363static unsigned long get_pseudo_pc(struct task_struct *child)
 364{
 365        /* Default value for PC is ERP. */
 366        unsigned long pc = get_reg(child, PT_ERP);
 367
 368        if (pc & 0x1) {
 369                unsigned long spc = get_reg(child, PT_SPC);
 370                /* Delay slot bit set. Report as stopped on proper
 371                   instruction. */
 372                if (spc) {
 373                        /* Rely on SPC if set. FIXME: We might want to check
 374                           that EXS indicates we stopped due to a single-step
 375                           exception. */
 376                        pc = spc;
 377                } else {
 378                        /* Calculate the PC from the size of the instruction
 379                           that the delay slot we're in belongs to. */
 380                        pc += insn_size(child, pc & ~1) - 1;
 381                }
 382        }
 383        return pc;
 384}
 385
 386static long bp_owner = 0;
 387
 388/* Reachable from exit_thread in signal.c, so not static. */
 389void deconfigure_bp(long pid)
 390{
 391        int bp;
 392
 393        /* Only deconfigure if the pid is the owner. */
 394        if (bp_owner != pid)
 395                return;
 396
 397        for (bp = 0; bp < 6; bp++) {
 398                unsigned long tmp;
 399                /* Deconfigure start and end address (also gets rid of ownership). */
 400                put_debugreg(pid, PT_BP + 3 + (bp * 2), 0);
 401                put_debugreg(pid, PT_BP + 4 + (bp * 2), 0);
 402
 403                /* Deconfigure relevant bits in control register. */
 404                tmp = get_debugreg(pid, PT_BP_CTRL) & ~(3 << (2 + (bp * 4)));
 405                put_debugreg(pid, PT_BP_CTRL, tmp);
 406        }
 407        /* No owner now. */
 408        bp_owner = 0;
 409}
 410
 411static int put_debugreg(long pid, unsigned int regno, long data)
 412{
 413        int ret = 0;
 414        register int old_srs;
 415
 416#ifdef CONFIG_ETRAX_KGDB
 417        /* Ignore write, but pretend it was ok if value is 0
 418           (we don't want POKEUSR/SETREGS failing unnessecarily). */
 419        return (data == 0) ? ret : -1;
 420#endif
 421
 422        /* Simple owner management. */
 423        if (!bp_owner)
 424                bp_owner = pid;
 425        else if (bp_owner != pid) {
 426                /* Ignore write, but pretend it was ok if value is 0
 427                   (we don't want POKEUSR/SETREGS failing unnessecarily). */
 428                return (data == 0) ? ret : -1;
 429        }
 430
 431        /* Remember old SRS. */
 432        SPEC_REG_RD(SPEC_REG_SRS, old_srs);
 433        /* Switch to BP bank. */
 434        SUPP_BANK_SEL(BANK_BP);
 435
 436        switch (regno - PT_BP) {
 437        case 0:
 438                SUPP_REG_WR(0, data); break;
 439        case 1:
 440        case 2:
 441                if (data)
 442                        ret = -1;
 443                break;
 444        case 3:
 445                SUPP_REG_WR(3, data); break;
 446        case 4:
 447                SUPP_REG_WR(4, data); break;
 448        case 5:
 449                SUPP_REG_WR(5, data); break;
 450        case 6:
 451                SUPP_REG_WR(6, data); break;
 452        case 7:
 453                SUPP_REG_WR(7, data); break;
 454        case 8:
 455                SUPP_REG_WR(8, data); break;
 456        case 9:
 457                SUPP_REG_WR(9, data); break;
 458        case 10:
 459                SUPP_REG_WR(10, data); break;
 460        case 11:
 461                SUPP_REG_WR(11, data); break;
 462        case 12:
 463                SUPP_REG_WR(12, data); break;
 464        case 13:
 465                SUPP_REG_WR(13, data); break;
 466        case 14:
 467                SUPP_REG_WR(14, data); break;
 468        default:
 469                ret = -1;
 470                break;
 471        }
 472
 473        /* Restore SRS. */
 474        SPEC_REG_WR(SPEC_REG_SRS, old_srs);
 475        /* Just for show. */
 476        NOP();
 477        NOP();
 478        NOP();
 479
 480        return ret;
 481}
 482
 483static long get_debugreg(long pid, unsigned int regno)
 484{
 485        register int old_srs;
 486        register long data;
 487
 488        if (pid != bp_owner) {
 489                return 0;
 490        }
 491
 492        /* Remember old SRS. */
 493        SPEC_REG_RD(SPEC_REG_SRS, old_srs);
 494        /* Switch to BP bank. */
 495        SUPP_BANK_SEL(BANK_BP);
 496
 497        switch (regno - PT_BP) {
 498        case 0:
 499                SUPP_REG_RD(0, data); break;
 500        case 1:
 501        case 2:
 502                /* error return value? */
 503                data = 0;
 504                break;
 505        case 3:
 506                SUPP_REG_RD(3, data); break;
 507        case 4:
 508                SUPP_REG_RD(4, data); break;
 509        case 5:
 510                SUPP_REG_RD(5, data); break;
 511        case 6:
 512                SUPP_REG_RD(6, data); break;
 513        case 7:
 514                SUPP_REG_RD(7, data); break;
 515        case 8:
 516                SUPP_REG_RD(8, data); break;
 517        case 9:
 518                SUPP_REG_RD(9, data); break;
 519        case 10:
 520                SUPP_REG_RD(10, data); break;
 521        case 11:
 522                SUPP_REG_RD(11, data); break;
 523        case 12:
 524                SUPP_REG_RD(12, data); break;
 525        case 13:
 526                SUPP_REG_RD(13, data); break;
 527        case 14:
 528                SUPP_REG_RD(14, data); break;
 529        default:
 530                /* error return value? */
 531                data = 0;
 532        }
 533
 534        /* Restore SRS. */
 535        SPEC_REG_WR(SPEC_REG_SRS, old_srs);
 536        /* Just for show. */
 537        NOP();
 538        NOP();
 539        NOP();
 540
 541        return data;
 542}
 543