Path: blob/master/arch/cris/arch-v32/kernel/ptrace.c
15125 views
/*1* Copyright (C) 2000-2007, Axis Communications AB.2*/34#include <linux/kernel.h>5#include <linux/sched.h>6#include <linux/mm.h>7#include <linux/smp.h>8#include <linux/errno.h>9#include <linux/ptrace.h>10#include <linux/user.h>11#include <linux/signal.h>12#include <linux/security.h>1314#include <asm/uaccess.h>15#include <asm/page.h>16#include <asm/pgtable.h>17#include <asm/system.h>18#include <asm/processor.h>19#include <arch/hwregs/supp_reg.h>2021/*22* Determines which bits in CCS the user has access to.23* 1 = access, 0 = no access.24*/25#define CCS_MASK 0x00087c00 /* SXNZVC */2627#define SBIT_USER (1 << (S_CCS_BITNR + CCS_SHIFT))2829static int put_debugreg(long pid, unsigned int regno, long data);30static long get_debugreg(long pid, unsigned int regno);31static unsigned long get_pseudo_pc(struct task_struct *child);32void deconfigure_bp(long pid);3334extern unsigned long cris_signal_return_page;3536/*37* Get contents of register REGNO in task TASK.38*/39long get_reg(struct task_struct *task, unsigned int regno)40{41/* USP is a special case, it's not in the pt_regs struct but42* in the tasks thread struct43*/44unsigned long ret;4546if (regno <= PT_EDA)47ret = ((unsigned long *)task_pt_regs(task))[regno];48else if (regno == PT_USP)49ret = task->thread.usp;50else if (regno == PT_PPC)51ret = get_pseudo_pc(task);52else if (regno <= PT_MAX)53ret = get_debugreg(task->pid, regno);54else55ret = 0;5657return ret;58}5960/*61* Write contents of register REGNO in task TASK.62*/63int put_reg(struct task_struct *task, unsigned int regno, unsigned long data)64{65if (regno <= PT_EDA)66((unsigned long *)task_pt_regs(task))[regno] = data;67else if (regno == PT_USP)68task->thread.usp = data;69else if (regno == PT_PPC) {70/* Write pseudo-PC to ERP only if changed. */71if (data != get_pseudo_pc(task))72task_pt_regs(task)->erp = data;73} else if (regno <= PT_MAX)74return put_debugreg(task->pid, regno, data);75else76return -1;77return 0;78}7980void user_enable_single_step(struct task_struct *child)81{82unsigned long tmp;8384/*85* Set up SPC if not set already (in which case we have no other86* choice but to trust it).87*/88if (!get_reg(child, PT_SPC)) {89/* In case we're stopped in a delay slot. */90tmp = get_reg(child, PT_ERP) & ~1;91put_reg(child, PT_SPC, tmp);92}93tmp = get_reg(child, PT_CCS) | SBIT_USER;94put_reg(child, PT_CCS, tmp);95}9697void user_disable_single_step(struct task_struct *child)98{99put_reg(child, PT_SPC, 0);100101if (!get_debugreg(child->pid, PT_BP_CTRL)) {102unsigned long tmp;103/* If no h/w bp configured, disable S bit. */104tmp = get_reg(child, PT_CCS) & ~SBIT_USER;105put_reg(child, PT_CCS, tmp);106}107}108109/*110* Called by kernel/ptrace.c when detaching.111*112* Make sure the single step bit is not set.113*/114void115ptrace_disable(struct task_struct *child)116{117unsigned long tmp;118119/* Deconfigure SPC and S-bit. */120user_disable_single_step(child);121put_reg(child, PT_SPC, 0);122123/* Deconfigure any watchpoints associated with the child. */124deconfigure_bp(child->pid);125}126127128long arch_ptrace(struct task_struct *child, long request,129unsigned long addr, unsigned long data)130{131int ret;132unsigned int regno = addr >> 2;133unsigned long __user *datap = (unsigned long __user *)data;134135switch (request) {136/* Read word at location address. */137case PTRACE_PEEKTEXT:138case PTRACE_PEEKDATA: {139unsigned long tmp;140int copied;141142ret = -EIO;143144/* The signal trampoline page is outside the normal user-addressable145* space but still accessible. This is hack to make it possible to146* access the signal handler code in GDB.147*/148if ((addr & PAGE_MASK) == cris_signal_return_page) {149/* The trampoline page is globally mapped, no page table to traverse.*/150tmp = *(unsigned long*)addr;151} else {152copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);153154if (copied != sizeof(tmp))155break;156}157158ret = put_user(tmp,datap);159break;160}161162/* Read the word at location address in the USER area. */163case PTRACE_PEEKUSR: {164unsigned long tmp;165166ret = -EIO;167if ((addr & 3) || regno > PT_MAX)168break;169170tmp = get_reg(child, regno);171ret = put_user(tmp, datap);172break;173}174175/* Write the word at location address. */176case PTRACE_POKETEXT:177case PTRACE_POKEDATA:178ret = generic_ptrace_pokedata(child, addr, data);179break;180181/* Write the word at location address in the USER area. */182case PTRACE_POKEUSR:183ret = -EIO;184if ((addr & 3) || regno > PT_MAX)185break;186187if (regno == PT_CCS) {188/* don't allow the tracing process to change stuff like189* interrupt enable, kernel/user bit, dma enables etc.190*/191data &= CCS_MASK;192data |= get_reg(child, PT_CCS) & ~CCS_MASK;193}194if (put_reg(child, regno, data))195break;196ret = 0;197break;198199/* Get all GP registers from the child. */200case PTRACE_GETREGS: {201int i;202unsigned long tmp;203204for (i = 0; i <= PT_MAX; i++) {205tmp = get_reg(child, i);206207if (put_user(tmp, datap)) {208ret = -EFAULT;209goto out_tsk;210}211212datap++;213}214215ret = 0;216break;217}218219/* Set all GP registers in the child. */220case PTRACE_SETREGS: {221int i;222unsigned long tmp;223224for (i = 0; i <= PT_MAX; i++) {225if (get_user(tmp, datap)) {226ret = -EFAULT;227goto out_tsk;228}229230if (i == PT_CCS) {231tmp &= CCS_MASK;232tmp |= get_reg(child, PT_CCS) & ~CCS_MASK;233}234235put_reg(child, i, tmp);236datap++;237}238239ret = 0;240break;241}242243default:244ret = ptrace_request(child, request, addr, data);245break;246}247248out_tsk:249return ret;250}251252void do_syscall_trace(void)253{254if (!test_thread_flag(TIF_SYSCALL_TRACE))255return;256257if (!(current->ptrace & PT_PTRACED))258return;259260/* the 0x80 provides a way for the tracing parent to distinguish261between a syscall stop and SIGTRAP delivery */262ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)263? 0x80 : 0));264265/*266* This isn't the same as continuing with a signal, but it will do for267* normal use.268*/269if (current->exit_code) {270send_sig(current->exit_code, current, 1);271current->exit_code = 0;272}273}274275/* Returns the size of an instruction that has a delay slot. */276277static int insn_size(struct task_struct *child, unsigned long pc)278{279unsigned long opcode;280int copied;281int opsize = 0;282283/* Read the opcode at pc (do what PTRACE_PEEKTEXT would do). */284copied = access_process_vm(child, pc, &opcode, sizeof(opcode), 0);285if (copied != sizeof(opcode))286return 0;287288switch ((opcode & 0x0f00) >> 8) {289case 0x0:290case 0x9:291case 0xb:292opsize = 2;293break;294case 0xe:295case 0xf:296opsize = 6;297break;298case 0xd:299/* Could be 4 or 6; check more bits. */300if ((opcode & 0xff) == 0xff)301opsize = 4;302else303opsize = 6;304break;305default:306panic("ERROR: Couldn't find size of opcode 0x%lx at 0x%lx\n",307opcode, pc);308}309310return opsize;311}312313static unsigned long get_pseudo_pc(struct task_struct *child)314{315/* Default value for PC is ERP. */316unsigned long pc = get_reg(child, PT_ERP);317318if (pc & 0x1) {319unsigned long spc = get_reg(child, PT_SPC);320/* Delay slot bit set. Report as stopped on proper321instruction. */322if (spc) {323/* Rely on SPC if set. FIXME: We might want to check324that EXS indicates we stopped due to a single-step325exception. */326pc = spc;327} else {328/* Calculate the PC from the size of the instruction329that the delay slot we're in belongs to. */330pc += insn_size(child, pc & ~1) - 1;331}332}333return pc;334}335336static long bp_owner = 0;337338/* Reachable from exit_thread in signal.c, so not static. */339void deconfigure_bp(long pid)340{341int bp;342343/* Only deconfigure if the pid is the owner. */344if (bp_owner != pid)345return;346347for (bp = 0; bp < 6; bp++) {348unsigned long tmp;349/* Deconfigure start and end address (also gets rid of ownership). */350put_debugreg(pid, PT_BP + 3 + (bp * 2), 0);351put_debugreg(pid, PT_BP + 4 + (bp * 2), 0);352353/* Deconfigure relevant bits in control register. */354tmp = get_debugreg(pid, PT_BP_CTRL) & ~(3 << (2 + (bp * 4)));355put_debugreg(pid, PT_BP_CTRL, tmp);356}357/* No owner now. */358bp_owner = 0;359}360361static int put_debugreg(long pid, unsigned int regno, long data)362{363int ret = 0;364register int old_srs;365366#ifdef CONFIG_ETRAX_KGDB367/* Ignore write, but pretend it was ok if value is 0368(we don't want POKEUSR/SETREGS failing unnessecarily). */369return (data == 0) ? ret : -1;370#endif371372/* Simple owner management. */373if (!bp_owner)374bp_owner = pid;375else if (bp_owner != pid) {376/* Ignore write, but pretend it was ok if value is 0377(we don't want POKEUSR/SETREGS failing unnessecarily). */378return (data == 0) ? ret : -1;379}380381/* Remember old SRS. */382SPEC_REG_RD(SPEC_REG_SRS, old_srs);383/* Switch to BP bank. */384SUPP_BANK_SEL(BANK_BP);385386switch (regno - PT_BP) {387case 0:388SUPP_REG_WR(0, data); break;389case 1:390case 2:391if (data)392ret = -1;393break;394case 3:395SUPP_REG_WR(3, data); break;396case 4:397SUPP_REG_WR(4, data); break;398case 5:399SUPP_REG_WR(5, data); break;400case 6:401SUPP_REG_WR(6, data); break;402case 7:403SUPP_REG_WR(7, data); break;404case 8:405SUPP_REG_WR(8, data); break;406case 9:407SUPP_REG_WR(9, data); break;408case 10:409SUPP_REG_WR(10, data); break;410case 11:411SUPP_REG_WR(11, data); break;412case 12:413SUPP_REG_WR(12, data); break;414case 13:415SUPP_REG_WR(13, data); break;416case 14:417SUPP_REG_WR(14, data); break;418default:419ret = -1;420break;421}422423/* Restore SRS. */424SPEC_REG_WR(SPEC_REG_SRS, old_srs);425/* Just for show. */426NOP();427NOP();428NOP();429430return ret;431}432433static long get_debugreg(long pid, unsigned int regno)434{435register int old_srs;436register long data;437438if (pid != bp_owner) {439return 0;440}441442/* Remember old SRS. */443SPEC_REG_RD(SPEC_REG_SRS, old_srs);444/* Switch to BP bank. */445SUPP_BANK_SEL(BANK_BP);446447switch (regno - PT_BP) {448case 0:449SUPP_REG_RD(0, data); break;450case 1:451case 2:452/* error return value? */453data = 0;454break;455case 3:456SUPP_REG_RD(3, data); break;457case 4:458SUPP_REG_RD(4, data); break;459case 5:460SUPP_REG_RD(5, data); break;461case 6:462SUPP_REG_RD(6, data); break;463case 7:464SUPP_REG_RD(7, data); break;465case 8:466SUPP_REG_RD(8, data); break;467case 9:468SUPP_REG_RD(9, data); break;469case 10:470SUPP_REG_RD(10, data); break;471case 11:472SUPP_REG_RD(11, data); break;473case 12:474SUPP_REG_RD(12, data); break;475case 13:476SUPP_REG_RD(13, data); break;477case 14:478SUPP_REG_RD(14, data); break;479default:480/* error return value? */481data = 0;482}483484/* Restore SRS. */485SPEC_REG_WR(SPEC_REG_SRS, old_srs);486/* Just for show. */487NOP();488NOP();489NOP();490491return data;492}493494495