1 // TODO some minor issues 2 /* 3 * This file is subject to the terms and conditions of the GNU General Public 4 * License. See the file "COPYING" in the main directory of this archive 5 * for more details. 6 * 7 * Copyright (C) 2001 - 2007 Tensilica Inc. 8 * 9 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com> 10 * Chris Zankel <chris@zankel.net> 11 * Scott Foehner<sfoehner@yahoo.com>, 12 * Kevin Chea 13 * Marc Gauthier<marc@tensilica.com> <marc@alumni.uwaterloo.ca> 14 */ 15 16 #include <linux/errno.h> 17 #include <linux/hw_breakpoint.h> 18 #include <linux/kernel.h> 19 #include <linux/mm.h> 20 #include <linux/perf_event.h> 21 #include <linux/ptrace.h> 22 #include <linux/sched.h> 23 #include <linux/security.h> 24 #include <linux/signal.h> 25 #include <linux/smp.h> 26 27 #include <asm/coprocessor.h> 28 #include <asm/elf.h> 29 #include <asm/page.h> 30 #include <asm/pgtable.h> 31 #include <asm/ptrace.h> 32 #include <asm/uaccess.h> 33 34 35 void user_enable_single_step(struct task_struct *child) 36 { 37 child->ptrace |= PT_SINGLESTEP; 38 } 39 40 void user_disable_single_step(struct task_struct *child) 41 { 42 child->ptrace &= ~PT_SINGLESTEP; 43 } 44 45 /* 46 * Called by kernel/ptrace.c when detaching to disable single stepping. 47 */ 48 49 void ptrace_disable(struct task_struct *child) 50 { 51 /* Nothing to do.. */ 52 } 53 54 int ptrace_getregs(struct task_struct *child, void __user *uregs) 55 { 56 struct pt_regs *regs = task_pt_regs(child); 57 xtensa_gregset_t __user *gregset = uregs; 58 unsigned long wb = regs->windowbase; 59 int i; 60 61 if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t))) 62 return -EIO; 63 64 __put_user(regs->pc, &gregset->pc); 65 __put_user(regs->ps & ~(1 << PS_EXCM_BIT), &gregset->ps); 66 __put_user(regs->lbeg, &gregset->lbeg); 67 __put_user(regs->lend, &gregset->lend); 68 __put_user(regs->lcount, &gregset->lcount); 69 __put_user(regs->windowstart, &gregset->windowstart); 70 __put_user(regs->windowbase, &gregset->windowbase); 71 __put_user(regs->threadptr, &gregset->threadptr); 72 73 for (i = 0; i < XCHAL_NUM_AREGS; i++) 74 __put_user(regs->areg[i], 75 gregset->a + ((wb * 4 + i) % XCHAL_NUM_AREGS)); 76 77 return 0; 78 } 79 80 int ptrace_setregs(struct task_struct *child, void __user *uregs) 81 { 82 struct pt_regs *regs = task_pt_regs(child); 83 xtensa_gregset_t *gregset = uregs; 84 const unsigned long ps_mask = PS_CALLINC_MASK | PS_OWB_MASK; 85 unsigned long ps; 86 unsigned long wb, ws; 87 88 if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t))) 89 return -EIO; 90 91 __get_user(regs->pc, &gregset->pc); 92 __get_user(ps, &gregset->ps); 93 __get_user(regs->lbeg, &gregset->lbeg); 94 __get_user(regs->lend, &gregset->lend); 95 __get_user(regs->lcount, &gregset->lcount); 96 __get_user(ws, &gregset->windowstart); 97 __get_user(wb, &gregset->windowbase); 98 __get_user(regs->threadptr, &gregset->threadptr); 99 100 regs->ps = (regs->ps & ~ps_mask) | (ps & ps_mask) | (1 << PS_EXCM_BIT); 101 102 if (wb >= XCHAL_NUM_AREGS / 4) 103 return -EFAULT; 104 105 if (wb != regs->windowbase || ws != regs->windowstart) { 106 unsigned long rotws, wmask; 107 108 rotws = (((ws | (ws << WSBITS)) >> wb) & 109 ((1 << WSBITS) - 1)) & ~1; 110 wmask = ((rotws ? WSBITS + 1 - ffs(rotws) : 0) << 4) | 111 (rotws & 0xF) | 1; 112 regs->windowbase = wb; 113 regs->windowstart = ws; 114 regs->wmask = wmask; 115 } 116 117 if (wb != 0 && __copy_from_user(regs->areg + XCHAL_NUM_AREGS - wb * 4, 118 gregset->a, wb * 16)) 119 return -EFAULT; 120 121 if (__copy_from_user(regs->areg, gregset->a + wb * 4, 122 (WSBITS - wb) * 16)) 123 return -EFAULT; 124 125 return 0; 126 } 127 128 129 int ptrace_getxregs(struct task_struct *child, void __user *uregs) 130 { 131 struct pt_regs *regs = task_pt_regs(child); 132 struct thread_info *ti = task_thread_info(child); 133 elf_xtregs_t __user *xtregs = uregs; 134 int ret = 0; 135 136 if (!access_ok(VERIFY_WRITE, uregs, sizeof(elf_xtregs_t))) 137 return -EIO; 138 139 #if XTENSA_HAVE_COPROCESSORS 140 /* Flush all coprocessor registers to memory. */ 141 coprocessor_flush_all(ti); 142 ret |= __copy_to_user(&xtregs->cp0, &ti->xtregs_cp, 143 sizeof(xtregs_coprocessor_t)); 144 #endif 145 ret |= __copy_to_user(&xtregs->opt, ®s->xtregs_opt, 146 sizeof(xtregs->opt)); 147 ret |= __copy_to_user(&xtregs->user,&ti->xtregs_user, 148 sizeof(xtregs->user)); 149 150 return ret ? -EFAULT : 0; 151 } 152 153 int ptrace_setxregs(struct task_struct *child, void __user *uregs) 154 { 155 struct thread_info *ti = task_thread_info(child); 156 struct pt_regs *regs = task_pt_regs(child); 157 elf_xtregs_t *xtregs = uregs; 158 int ret = 0; 159 160 if (!access_ok(VERIFY_READ, uregs, sizeof(elf_xtregs_t))) 161 return -EFAULT; 162 163 #if XTENSA_HAVE_COPROCESSORS 164 /* Flush all coprocessors before we overwrite them. */ 165 coprocessor_flush_all(ti); 166 coprocessor_release_all(ti); 167 168 ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0, 169 sizeof(xtregs_coprocessor_t)); 170 #endif 171 ret |= __copy_from_user(®s->xtregs_opt, &xtregs->opt, 172 sizeof(xtregs->opt)); 173 ret |= __copy_from_user(&ti->xtregs_user, &xtregs->user, 174 sizeof(xtregs->user)); 175 176 return ret ? -EFAULT : 0; 177 } 178 179 int ptrace_peekusr(struct task_struct *child, long regno, long __user *ret) 180 { 181 struct pt_regs *regs; 182 unsigned long tmp; 183 184 regs = task_pt_regs(child); 185 tmp = 0; /* Default return value. */ 186 187 switch(regno) { 188 189 case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1: 190 tmp = regs->areg[regno - REG_AR_BASE]; 191 break; 192 193 case REG_A_BASE ... REG_A_BASE + 15: 194 tmp = regs->areg[regno - REG_A_BASE]; 195 break; 196 197 case REG_PC: 198 tmp = regs->pc; 199 break; 200 201 case REG_PS: 202 /* Note: PS.EXCM is not set while user task is running; 203 * its being set in regs is for exception handling 204 * convenience. */ 205 tmp = (regs->ps & ~(1 << PS_EXCM_BIT)); 206 break; 207 208 case REG_WB: 209 break; /* tmp = 0 */ 210 211 case REG_WS: 212 { 213 unsigned long wb = regs->windowbase; 214 unsigned long ws = regs->windowstart; 215 tmp = ((ws>>wb) | (ws<<(WSBITS-wb))) & ((1<<WSBITS)-1); 216 break; 217 } 218 case REG_LBEG: 219 tmp = regs->lbeg; 220 break; 221 222 case REG_LEND: 223 tmp = regs->lend; 224 break; 225 226 case REG_LCOUNT: 227 tmp = regs->lcount; 228 break; 229 230 case REG_SAR: 231 tmp = regs->sar; 232 break; 233 234 case SYSCALL_NR: 235 tmp = regs->syscall; 236 break; 237 238 default: 239 return -EIO; 240 } 241 return put_user(tmp, ret); 242 } 243 244 int ptrace_pokeusr(struct task_struct *child, long regno, long val) 245 { 246 struct pt_regs *regs; 247 regs = task_pt_regs(child); 248 249 switch (regno) { 250 case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1: 251 regs->areg[regno - REG_AR_BASE] = val; 252 break; 253 254 case REG_A_BASE ... REG_A_BASE + 15: 255 regs->areg[regno - REG_A_BASE] = val; 256 break; 257 258 case REG_PC: 259 regs->pc = val; 260 break; 261 262 case SYSCALL_NR: 263 regs->syscall = val; 264 break; 265 266 default: 267 return -EIO; 268 } 269 return 0; 270 } 271 272 #ifdef CONFIG_HAVE_HW_BREAKPOINT 273 static void ptrace_hbptriggered(struct perf_event *bp, 274 struct perf_sample_data *data, 275 struct pt_regs *regs) 276 { 277 int i; 278 siginfo_t info; 279 struct arch_hw_breakpoint *bkpt = counter_arch_bp(bp); 280 281 if (bp->attr.bp_type & HW_BREAKPOINT_X) { 282 for (i = 0; i < XCHAL_NUM_IBREAK; ++i) 283 if (current->thread.ptrace_bp[i] == bp) 284 break; 285 i <<= 1; 286 } else { 287 for (i = 0; i < XCHAL_NUM_DBREAK; ++i) 288 if (current->thread.ptrace_wp[i] == bp) 289 break; 290 i = (i << 1) | 1; 291 } 292 293 info.si_signo = SIGTRAP; 294 info.si_errno = i; 295 info.si_code = TRAP_HWBKPT; 296 info.si_addr = (void __user *)bkpt->address; 297 298 force_sig_info(SIGTRAP, &info, current); 299 } 300 301 static struct perf_event *ptrace_hbp_create(struct task_struct *tsk, int type) 302 { 303 struct perf_event_attr attr; 304 305 ptrace_breakpoint_init(&attr); 306 307 /* Initialise fields to sane defaults. */ 308 attr.bp_addr = 0; 309 attr.bp_len = 1; 310 attr.bp_type = type; 311 attr.disabled = 1; 312 313 return register_user_hw_breakpoint(&attr, ptrace_hbptriggered, NULL, 314 tsk); 315 } 316 317 /* 318 * Address bit 0 choose instruction (0) or data (1) break register, bits 319 * 31..1 are the register number. 320 * Both PTRACE_GETHBPREGS and PTRACE_SETHBPREGS transfer two 32-bit words: 321 * address (0) and control (1). 322 * Instruction breakpoint contorl word is 0 to clear breakpoint, 1 to set. 323 * Data breakpoint control word bit 31 is 'trigger on store', bit 30 is 324 * 'trigger on load, bits 29..0 are length. Length 0 is used to clear a 325 * breakpoint. To set a breakpoint length must be a power of 2 in the range 326 * 1..64 and the address must be length-aligned. 327 */ 328 329 static long ptrace_gethbpregs(struct task_struct *child, long addr, 330 long __user *datap) 331 { 332 struct perf_event *bp; 333 u32 user_data[2] = {0}; 334 bool dbreak = addr & 1; 335 unsigned idx = addr >> 1; 336 337 if ((!dbreak && idx >= XCHAL_NUM_IBREAK) || 338 (dbreak && idx >= XCHAL_NUM_DBREAK)) 339 return -EINVAL; 340 341 if (dbreak) 342 bp = child->thread.ptrace_wp[idx]; 343 else 344 bp = child->thread.ptrace_bp[idx]; 345 346 if (bp) { 347 user_data[0] = bp->attr.bp_addr; 348 user_data[1] = bp->attr.disabled ? 0 : bp->attr.bp_len; 349 if (dbreak) { 350 if (bp->attr.bp_type & HW_BREAKPOINT_R) 351 user_data[1] |= DBREAKC_LOAD_MASK; 352 if (bp->attr.bp_type & HW_BREAKPOINT_W) 353 user_data[1] |= DBREAKC_STOR_MASK; 354 } 355 } 356 357 if (copy_to_user(datap, user_data, sizeof(user_data))) 358 return -EFAULT; 359 360 return 0; 361 } 362 363 static long ptrace_sethbpregs(struct task_struct *child, long addr, 364 long __user *datap) 365 { 366 struct perf_event *bp; 367 struct perf_event_attr attr; 368 u32 user_data[2]; 369 bool dbreak = addr & 1; 370 unsigned idx = addr >> 1; 371 int bp_type = 0; 372 373 if ((!dbreak && idx >= XCHAL_NUM_IBREAK) || 374 (dbreak && idx >= XCHAL_NUM_DBREAK)) 375 return -EINVAL; 376 377 if (copy_from_user(user_data, datap, sizeof(user_data))) 378 return -EFAULT; 379 380 if (dbreak) { 381 bp = child->thread.ptrace_wp[idx]; 382 if (user_data[1] & DBREAKC_LOAD_MASK) 383 bp_type |= HW_BREAKPOINT_R; 384 if (user_data[1] & DBREAKC_STOR_MASK) 385 bp_type |= HW_BREAKPOINT_W; 386 } else { 387 bp = child->thread.ptrace_bp[idx]; 388 bp_type = HW_BREAKPOINT_X; 389 } 390 391 if (!bp) { 392 bp = ptrace_hbp_create(child, 393 bp_type ? bp_type : HW_BREAKPOINT_RW); 394 if (IS_ERR(bp)) 395 return PTR_ERR(bp); 396 if (dbreak) 397 child->thread.ptrace_wp[idx] = bp; 398 else 399 child->thread.ptrace_bp[idx] = bp; 400 } 401 402 attr = bp->attr; 403 attr.bp_addr = user_data[0]; 404 attr.bp_len = user_data[1] & ~(DBREAKC_LOAD_MASK | DBREAKC_STOR_MASK); 405 attr.bp_type = bp_type; 406 attr.disabled = !attr.bp_len; 407 408 return modify_user_hw_breakpoint(bp, &attr); 409 } 410 #endif 411 412 long arch_ptrace(struct task_struct *child, long request, 413 unsigned long addr, unsigned long data) 414 { 415 int ret = -EPERM; 416 void __user *datap = (void __user *) data; 417 418 switch (request) { 419 case PTRACE_PEEKTEXT: /* read word at location addr. */ 420 case PTRACE_PEEKDATA: 421 ret = generic_ptrace_peekdata(child, addr, data); 422 break; 423 424 case PTRACE_PEEKUSR: /* read register specified by addr. */ 425 ret = ptrace_peekusr(child, addr, datap); 426 break; 427 428 case PTRACE_POKETEXT: /* write the word at location addr. */ 429 case PTRACE_POKEDATA: 430 ret = generic_ptrace_pokedata(child, addr, data); 431 break; 432 433 case PTRACE_POKEUSR: /* write register specified by addr. */ 434 ret = ptrace_pokeusr(child, addr, data); 435 break; 436 437 case PTRACE_GETREGS: 438 ret = ptrace_getregs(child, datap); 439 break; 440 441 case PTRACE_SETREGS: 442 ret = ptrace_setregs(child, datap); 443 break; 444 445 case PTRACE_GETXTREGS: 446 ret = ptrace_getxregs(child, datap); 447 break; 448 449 case PTRACE_SETXTREGS: 450 ret = ptrace_setxregs(child, datap); 451 break; 452 #ifdef CONFIG_HAVE_HW_BREAKPOINT 453 case PTRACE_GETHBPREGS: 454 ret = ptrace_gethbpregs(child, addr, datap); 455 break; 456 457 case PTRACE_SETHBPREGS: 458 ret = ptrace_sethbpregs(child, addr, datap); 459 break; 460 #endif 461 default: 462 ret = ptrace_request(child, request, addr, data); 463 break; 464 } 465 466 return ret; 467 } 468 469 void do_syscall_trace(void) 470 { 471 /* 472 * The 0x80 provides a way for the tracing parent to distinguish 473 * between a syscall stop and SIGTRAP delivery 474 */ 475 ptrace_notify(SIGTRAP|((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); 476 477 /* 478 * this isn't the same as continuing with a signal, but it will do 479 * for normal use. strace only continues with a signal if the 480 * stopping signal is not SIGTRAP. -brl 481 */ 482 if (current->exit_code) { 483 send_sig(current->exit_code, current, 1); 484 current->exit_code = 0; 485 } 486 } 487 488 void do_syscall_trace_enter(struct pt_regs *regs) 489 { 490 if (test_thread_flag(TIF_SYSCALL_TRACE) 491 && (current->ptrace & PT_PTRACED)) 492 do_syscall_trace(); 493 494 #if 0 495 audit_syscall_entry(...); 496 #endif 497 } 498 499 void do_syscall_trace_leave(struct pt_regs *regs) 500 { 501 if ((test_thread_flag(TIF_SYSCALL_TRACE)) 502 && (current->ptrace & PT_PTRACED)) 503 do_syscall_trace(); 504 } 505