15a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel// TODO some minor issues 25a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel/* 35a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * This file is subject to the terms and conditions of the GNU General Public 45a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * License. See the file "COPYING" in the main directory of this archive 55a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * for more details. 65a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * 7c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel * Copyright (C) 2001 - 2007 Tensilica Inc. 85a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * 95a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com> 105a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * Chris Zankel <chris@zankel.net> 115a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * Scott Foehner<sfoehner@yahoo.com>, 125a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * Kevin Chea 135a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * Marc Gauthier<marc@tensilica.com> <marc@alumni.uwaterloo.ca> 145a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel */ 155a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 165a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel#include <linux/kernel.h> 175a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel#include <linux/sched.h> 185a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel#include <linux/mm.h> 195a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel#include <linux/errno.h> 205a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel#include <linux/ptrace.h> 215a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel#include <linux/smp.h> 225a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel#include <linux/security.h> 230ee23b50f1541aacc3b975edae170a1b995b84f5Jesper Juhl#include <linux/signal.h> 245a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 255a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel#include <asm/pgtable.h> 265a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel#include <asm/page.h> 275a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel#include <asm/uaccess.h> 285a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel#include <asm/ptrace.h> 295a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel#include <asm/elf.h> 30c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel#include <asm/coprocessor.h> 315a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 326d75ca10225be4c7509026f9b61c740b22e734e4Christoph Hellwig 336d75ca10225be4c7509026f9b61c740b22e734e4Christoph Hellwigvoid user_enable_single_step(struct task_struct *child) 346d75ca10225be4c7509026f9b61c740b22e734e4Christoph Hellwig{ 356d75ca10225be4c7509026f9b61c740b22e734e4Christoph Hellwig child->ptrace |= PT_SINGLESTEP; 366d75ca10225be4c7509026f9b61c740b22e734e4Christoph Hellwig} 376d75ca10225be4c7509026f9b61c740b22e734e4Christoph Hellwig 386d75ca10225be4c7509026f9b61c740b22e734e4Christoph Hellwigvoid user_disable_single_step(struct task_struct *child) 396d75ca10225be4c7509026f9b61c740b22e734e4Christoph Hellwig{ 406d75ca10225be4c7509026f9b61c740b22e734e4Christoph Hellwig child->ptrace &= ~PT_SINGLESTEP; 416d75ca10225be4c7509026f9b61c740b22e734e4Christoph Hellwig} 426d75ca10225be4c7509026f9b61c740b22e734e4Christoph Hellwig 435a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel/* 44c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel * Called by kernel/ptrace.c when detaching to disable single stepping. 455a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel */ 465a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 475a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankelvoid ptrace_disable(struct task_struct *child) 485a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel{ 495a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel /* Nothing to do.. */ 505a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel} 515a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 52c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankelint ptrace_getregs(struct task_struct *child, void __user *uregs) 535a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel{ 54c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel struct pt_regs *regs = task_pt_regs(child); 55c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel xtensa_gregset_t __user *gregset = uregs; 56c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel unsigned long wm = regs->wmask; 5742086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel unsigned long wb = regs->windowbase; 5842086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel int live, i; 59c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 60c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t))) 61c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel return -EIO; 62c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 6342086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel __put_user(regs->pc, &gregset->pc); 6442086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel __put_user(regs->ps & ~(1 << PS_EXCM_BIT), &gregset->ps); 6542086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel __put_user(regs->lbeg, &gregset->lbeg); 6642086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel __put_user(regs->lend, &gregset->lend); 6742086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel __put_user(regs->lcount, &gregset->lcount); 6842086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel __put_user(regs->windowstart, &gregset->windowstart); 6942086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel __put_user(regs->windowbase, &gregset->windowbase); 70c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 71c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16; 72c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 7342086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel for (i = 0; i < live; i++) 7442086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel __put_user(regs->areg[i],gregset->a+((wb*4+i)%XCHAL_NUM_AREGS)); 7542086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel for (i = XCHAL_NUM_AREGS - (wm >> 4) * 4; i < XCHAL_NUM_AREGS; i++) 7642086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel __put_user(regs->areg[i],gregset->a+((wb*4+i)%XCHAL_NUM_AREGS)); 7742086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel 7842086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel return 0; 79c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel} 805a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 81c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankelint ptrace_setregs(struct task_struct *child, void __user *uregs) 82c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel{ 83c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel struct pt_regs *regs = task_pt_regs(child); 84c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel xtensa_gregset_t *gregset = uregs; 85c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel const unsigned long ps_mask = PS_CALLINC_MASK | PS_OWB_MASK; 86c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel unsigned long ps; 8742086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel unsigned long wb; 88c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 89c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t))) 90c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel return -EIO; 91c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 9242086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel __get_user(regs->pc, &gregset->pc); 9342086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel __get_user(ps, &gregset->ps); 9442086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel __get_user(regs->lbeg, &gregset->lbeg); 9542086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel __get_user(regs->lend, &gregset->lend); 9642086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel __get_user(regs->lcount, &gregset->lcount); 9742086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel __get_user(regs->windowstart, &gregset->windowstart); 9842086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel __get_user(wb, &gregset->windowbase); 99c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 100c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel regs->ps = (regs->ps & ~ps_mask) | (ps & ps_mask) | (1 << PS_EXCM_BIT); 101c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 10242086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel if (wb >= XCHAL_NUM_AREGS / 4) 10342086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel return -EFAULT; 104c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 10542086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel regs->windowbase = wb; 10642086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel 10742086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel if (wb != 0 && __copy_from_user(regs->areg + XCHAL_NUM_AREGS - wb * 4, 10842086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel gregset->a, wb * 16)) 10942086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel return -EFAULT; 11042086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel 11142086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel if (__copy_from_user(regs->areg, gregset->a + wb*4, (WSBITS-wb) * 16)) 11242086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel return -EFAULT; 11342086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel 11442086cec3263b8c015ca3faa01e8190f0e3ff445Chris Zankel return 0; 115c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel} 1165a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 1175a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 118c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankelint ptrace_getxregs(struct task_struct *child, void __user *uregs) 119c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel{ 120c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel struct pt_regs *regs = task_pt_regs(child); 121c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel struct thread_info *ti = task_thread_info(child); 122c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel elf_xtregs_t __user *xtregs = uregs; 123c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel int ret = 0; 124c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 125c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel if (!access_ok(VERIFY_WRITE, uregs, sizeof(elf_xtregs_t))) 126c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel return -EIO; 127c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 128c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel#if XTENSA_HAVE_COPROCESSORS 129c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel /* Flush all coprocessor registers to memory. */ 130c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel coprocessor_flush_all(ti); 131c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel ret |= __copy_to_user(&xtregs->cp0, &ti->xtregs_cp, 132c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel sizeof(xtregs_coprocessor_t)); 133c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel#endif 134c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel ret |= __copy_to_user(&xtregs->opt, ®s->xtregs_opt, 135c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel sizeof(xtregs->opt)); 136c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel ret |= __copy_to_user(&xtregs->user,&ti->xtregs_user, 137c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel sizeof(xtregs->user)); 1385a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 139c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel return ret ? -EFAULT : 0; 140c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel} 141c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 142c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankelint ptrace_setxregs(struct task_struct *child, void __user *uregs) 143c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel{ 144c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel struct thread_info *ti = task_thread_info(child); 145c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel struct pt_regs *regs = task_pt_regs(child); 146c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel elf_xtregs_t *xtregs = uregs; 147c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel int ret = 0; 148c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 1490d0138ebe24b94065580bd2601f8bb7eb6152f56Dan Rosenberg if (!access_ok(VERIFY_READ, uregs, sizeof(elf_xtregs_t))) 1500d0138ebe24b94065580bd2601f8bb7eb6152f56Dan Rosenberg return -EFAULT; 1510d0138ebe24b94065580bd2601f8bb7eb6152f56Dan Rosenberg 152c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel#if XTENSA_HAVE_COPROCESSORS 153c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel /* Flush all coprocessors before we overwrite them. */ 154c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel coprocessor_flush_all(ti); 155c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel coprocessor_release_all(ti); 156c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 157c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0, 158c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel sizeof(xtregs_coprocessor_t)); 159c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel#endif 160c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel ret |= __copy_from_user(®s->xtregs_opt, &xtregs->opt, 161c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel sizeof(xtregs->opt)); 162c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel ret |= __copy_from_user(&ti->xtregs_user, &xtregs->user, 163c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel sizeof(xtregs->user)); 164c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 165c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel return ret ? -EFAULT : 0; 166c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel} 167c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 168c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankelint ptrace_peekusr(struct task_struct *child, long regno, long __user *ret) 169c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel{ 170c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel struct pt_regs *regs; 171c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel unsigned long tmp; 172c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 173c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel regs = task_pt_regs(child); 174c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel tmp = 0; /* Default return value. */ 1755a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 176c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel switch(regno) { 1775a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 1785a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1: 179c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel tmp = regs->areg[regno - REG_AR_BASE]; 1805a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 181c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 1825a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case REG_A_BASE ... REG_A_BASE + 15: 183c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel tmp = regs->areg[regno - REG_A_BASE]; 1845a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 185c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 1865a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case REG_PC: 1875a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel tmp = regs->pc; 1885a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 189c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 1905a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case REG_PS: 1915a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel /* Note: PS.EXCM is not set while user task is running; 1925a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * its being set in regs is for exception handling 1935a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * convenience. */ 194173d6681380aa1d60dfc35ed7178bd7811ba2784Chris Zankel tmp = (regs->ps & ~(1 << PS_EXCM_BIT)); 1955a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 196c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 1975a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case REG_WB: 198c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel break; /* tmp = 0 */ 199c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 2005a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case REG_WS: 201c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel { 202c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel unsigned long wb = regs->windowbase; 203c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel unsigned long ws = regs->windowstart; 204c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel tmp = ((ws>>wb) | (ws<<(WSBITS-wb))) & ((1<<WSBITS)-1); 2055a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 206c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel } 2075a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case REG_LBEG: 2085a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel tmp = regs->lbeg; 2095a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 210c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 2115a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case REG_LEND: 2125a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel tmp = regs->lend; 2135a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 214c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 2155a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case REG_LCOUNT: 2165a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel tmp = regs->lcount; 2175a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 218c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 2195a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case REG_SAR: 2205a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel tmp = regs->sar; 2215a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 222c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 2235a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case SYSCALL_NR: 2245a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel tmp = regs->syscall; 2255a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 2265a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 227c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel default: 228c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel return -EIO; 229c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel } 230c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel return put_user(tmp, ret); 231c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel} 2325a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 233c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankelint ptrace_pokeusr(struct task_struct *child, long regno, long val) 234c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel{ 235c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel struct pt_regs *regs; 236c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel regs = task_pt_regs(child); 2375a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 238c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel switch (regno) { 2395a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1: 240c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel regs->areg[regno - REG_AR_BASE] = val; 2415a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 242c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 2435a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case REG_A_BASE ... REG_A_BASE + 15: 244c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel regs->areg[regno - REG_A_BASE] = val; 2455a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 246c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 2475a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case REG_PC: 248c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel regs->pc = val; 2495a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 250c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 2515a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case SYSCALL_NR: 252c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel regs->syscall = val; 2535a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 2545a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 2555a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel default: 256c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel return -EIO; 257c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel } 258c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel return 0; 259c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel} 260c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 2619b05a69e0534ec70bc94921936ffa05b330507cbNamhyung Kimlong arch_ptrace(struct task_struct *child, long request, 2629b05a69e0534ec70bc94921936ffa05b330507cbNamhyung Kim unsigned long addr, unsigned long data) 263c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel{ 264c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel int ret = -EPERM; 2655ef45079dd9c8f2e9c7aa788dc3121835ae52863Namhyung Kim void __user *datap = (void __user *) data; 266c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 267c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel switch (request) { 268c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel case PTRACE_PEEKTEXT: /* read word at location addr. */ 269c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel case PTRACE_PEEKDATA: 270c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel ret = generic_ptrace_peekdata(child, addr, data); 271c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel break; 272c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 273c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel case PTRACE_PEEKUSR: /* read register specified by addr. */ 2745ef45079dd9c8f2e9c7aa788dc3121835ae52863Namhyung Kim ret = ptrace_peekusr(child, addr, datap); 275c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel break; 276c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 277c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel case PTRACE_POKETEXT: /* write the word at location addr. */ 278c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel case PTRACE_POKEDATA: 279c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel ret = generic_ptrace_pokedata(child, addr, data); 280c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel break; 281c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 282c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel case PTRACE_POKEUSR: /* write register specified by addr. */ 283c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel ret = ptrace_pokeusr(child, addr, data); 2845a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 2855a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 2865a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case PTRACE_GETREGS: 2875ef45079dd9c8f2e9c7aa788dc3121835ae52863Namhyung Kim ret = ptrace_getregs(child, datap); 2885a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 2895a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 2905a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel case PTRACE_SETREGS: 2915ef45079dd9c8f2e9c7aa788dc3121835ae52863Namhyung Kim ret = ptrace_setregs(child, datap); 2925a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 2935a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 294c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel case PTRACE_GETXTREGS: 2955ef45079dd9c8f2e9c7aa788dc3121835ae52863Namhyung Kim ret = ptrace_getxregs(child, datap); 2965a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 2975a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 298c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel case PTRACE_SETXTREGS: 2995ef45079dd9c8f2e9c7aa788dc3121835ae52863Namhyung Kim ret = ptrace_setxregs(child, datap); 3005a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel break; 3015a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 3025a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel default: 3035a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel ret = ptrace_request(child, request, addr, data); 304c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel break; 3055a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel } 306c658eac628aa8df040dfe614556d95e6da3a9ffbChris Zankel 3075a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel return ret; 3085a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel} 3095a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 3105a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankelvoid do_syscall_trace(void) 3115a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel{ 3125a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel /* 3135a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * The 0x80 provides a way for the tracing parent to distinguish 3145a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * between a syscall stop and SIGTRAP delivery 3155a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel */ 3165a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel ptrace_notify(SIGTRAP|((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); 3175a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel 3185a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel /* 3195a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * this isn't the same as continuing with a signal, but it will do 3205a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * for normal use. strace only continues with a signal if the 3215a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel * stopping signal is not SIGTRAP. -brl 3225a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel */ 3235a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel if (current->exit_code) { 3245a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel send_sig(current->exit_code, current, 1); 3255a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel current->exit_code = 0; 3265a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel } 3275a0015d62668e64c8b6e02e360fbbea121bfd5e6Chris Zankel} 328fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankel 329fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankelvoid do_syscall_trace_enter(struct pt_regs *regs) 330fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankel{ 331fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankel if (test_thread_flag(TIF_SYSCALL_TRACE) 332fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankel && (current->ptrace & PT_PTRACED)) 333fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankel do_syscall_trace(); 334fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankel 335fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankel#if 0 336b05d8447e7821695bc2fa3359431f7a664232743Eric Paris audit_syscall_entry(current, AUDIT_ARCH_XTENSA..); 337fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankel#endif 338fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankel} 339fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankel 340fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankelvoid do_syscall_trace_leave(struct pt_regs *regs) 341fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankel{ 342fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankel if ((test_thread_flag(TIF_SYSCALL_TRACE)) 343fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankel && (current->ptrace & PT_PTRACED)) 344fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankel do_syscall_trace(); 345fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankel} 346fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43Chris Zankel 347