trace.c revision 427a43ee9972763993a1241815d56921f30623ef
1/* 2 * This file is part of ltrace. 3 * Copyright (C) 2012, 2013 Petr Machata, Red Hat Inc. 4 * Copyright (C) 1998,2004,2008,2009 Juan Cespedes 5 * Copyright (C) 2006 Ian Wienand 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of the 10 * License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 * 02110-1301 USA 21 */ 22 23#include "config.h" 24 25#include <string.h> 26#include <sys/types.h> 27#include <sys/wait.h> 28#include <signal.h> 29#include <sys/ptrace.h> 30#include <asm/ptrace.h> 31 32#include "bits.h" 33#include "common.h" 34#include "proc.h" 35#include "output.h" 36#include "ptrace.h" 37#include "regs.h" 38 39#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR)) 40# define PTRACE_PEEKUSER PTRACE_PEEKUSR 41#endif 42 43#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR)) 44# define PTRACE_POKEUSER PTRACE_POKEUSR 45#endif 46 47#define off_r0 ((void *)0) 48#define off_r7 ((void *)28) 49#define off_ip ((void *)48) 50#define off_pc ((void *)60) 51#define off_cpsr ((void *)64) 52 53void 54get_arch_dep(struct process *proc) 55{ 56 proc_archdep *a; 57 58 if (!proc->arch_ptr) 59 proc->arch_ptr = (void *)malloc(sizeof(proc_archdep)); 60 a = (proc_archdep *) (proc->arch_ptr); 61 a->valid = (ptrace(PTRACE_GETREGS, proc->pid, 0, &a->regs) >= 0); 62} 63 64/* Returns 0 if not a syscall, 65 * 1 if syscall entry, 2 if syscall exit, 66 * 3 if arch-specific syscall entry, 4 if arch-specific syscall exit, 67 * -1 on error. 68 */ 69int 70syscall_p(struct process *proc, int status, int *sysnum) 71{ 72 if (WIFSTOPPED(status) 73 && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) { 74 /* get the user's pc (plus 8) */ 75 unsigned pc = ptrace(PTRACE_PEEKUSER, proc->pid, off_pc, 0); 76 pc = pc - 4; 77 /* fetch the SWI instruction */ 78 unsigned insn = ptrace(PTRACE_PEEKTEXT, proc->pid, 79 (void *)pc, 0); 80 int ip = ptrace(PTRACE_PEEKUSER, proc->pid, off_ip, 0); 81 82 if (insn == 0xef000000 || insn == 0x0f000000 83 || (insn & 0xffff0000) == 0xdf000000) { 84 /* EABI syscall */ 85 *sysnum = ptrace(PTRACE_PEEKUSER, proc->pid, off_r7, 0); 86 } else if ((insn & 0xfff00000) == 0xef900000) { 87 /* old ABI syscall */ 88 *sysnum = insn & 0xfffff; 89 } else { 90 /* TODO: handle swi<cond> variations */ 91 /* one possible reason for getting in here is that we 92 * are coming from a signal handler, so the current 93 * PC does not point to the instruction just after the 94 * "swi" one. */ 95 output_line(proc, "unexpected instruction 0x%x at %p", 96 insn, pc); 97 return 0; 98 } 99 if ((*sysnum & 0xf0000) == 0xf0000) { 100 /* arch-specific syscall */ 101 *sysnum &= ~0xf0000; 102 return ip ? 4 : 3; 103 } 104 /* ARM syscall convention: on syscall entry, ip is zero; 105 * on syscall exit, ip is non-zero */ 106 return ip ? 2 : 1; 107 } 108 return 0; 109} 110 111long 112gimme_arg(enum tof type, struct process *proc, int arg_num, 113 struct arg_type_info *info) 114{ 115 proc_archdep *a = (proc_archdep *) proc->arch_ptr; 116 117 if (arg_num == -1) { /* return value */ 118 return ptrace(PTRACE_PEEKUSER, proc->pid, off_r0, 0); 119 } 120 121 /* deal with the ARM calling conventions */ 122 if (type == LT_TOF_FUNCTION || type == LT_TOF_FUNCTIONR) { 123 if (arg_num < 4) { 124 if (a->valid && type == LT_TOF_FUNCTION) 125 return a->regs.uregs[arg_num]; 126 if (a->valid && type == LT_TOF_FUNCTIONR) 127 return a->func_arg[arg_num]; 128 return ptrace(PTRACE_PEEKUSER, proc->pid, 129 (void *)(4 * arg_num), 0); 130 } else { 131 return ptrace(PTRACE_PEEKDATA, proc->pid, 132 proc->stack_pointer + 4 * (arg_num - 4), 133 0); 134 } 135 } else if (type == LT_TOF_SYSCALL || type == LT_TOF_SYSCALLR) { 136 if (arg_num < 5) { 137 if (a->valid && type == LT_TOF_SYSCALL) 138 return a->regs.uregs[arg_num]; 139 if (a->valid && type == LT_TOF_SYSCALLR) 140 return a->sysc_arg[arg_num]; 141 return ptrace(PTRACE_PEEKUSER, proc->pid, 142 (void *)(4 * arg_num), 0); 143 } else { 144 return ptrace(PTRACE_PEEKDATA, proc->pid, 145 proc->stack_pointer + 4 * (arg_num - 5), 146 0); 147 } 148 } else { 149 fprintf(stderr, "gimme_arg called with wrong arguments\n"); 150 exit(1); 151 } 152 153 return 0; 154} 155 156static arch_addr_t 157arm_branch_dest(const arch_addr_t pc, const uint32_t insn) 158{ 159 /* Bits 0-23 are signed immediate value. */ 160 return pc + ((((insn & 0xffffff) ^ 0x800000) - 0x800000) << 2) + 8; 161} 162 163/* Addresses for calling Thumb functions have the bit 0 set. 164 Here are some macros to test, set, or clear bit 0 of addresses. */ 165/* XXX double cast */ 166#define IS_THUMB_ADDR(addr) ((uintptr_t)(addr) & 1) 167#define MAKE_THUMB_ADDR(addr) ((arch_addr_t)((uintptr_t)(addr) | 1)) 168#define UNMAKE_THUMB_ADDR(addr) ((arch_addr_t)((uintptr_t)(addr) & ~1)) 169 170enum { 171 COND_ALWAYS = 0xe, 172 COND_NV = 0xf, 173 FLAG_C = 0x20000000, 174}; 175 176static int 177arm_get_next_pcs(struct process *proc, 178 const arch_addr_t pc, arch_addr_t next_pcs[2]) 179{ 180 uint32_t this_instr; 181 uint32_t status; 182 if (proc_read_32(proc, pc, &this_instr) < 0 183 || arm_get_register(proc, ARM_REG_CPSR, &status) < 0) 184 return -1; 185 186 /* In theory, we sometimes don't even need to add any 187 * breakpoints at all. If the conditional bits of the 188 * instruction indicate that it should not be taken, then we 189 * can just skip it altogether without bothering. We could 190 * also emulate the instruction under the breakpoint. 191 * 192 * Here, we make it as simple as possible (though We Accept 193 * Patches). */ 194 int nr = 0; 195 196 /* ARM can branch either relatively by using a branch 197 * instruction, or absolutely, by doing arbitrary arithmetic 198 * with PC as the destination. */ 199 const unsigned cond = BITS(this_instr, 28, 31); 200 const unsigned opcode = BITS(this_instr, 24, 27); 201 202 if (cond == COND_NV) 203 switch (opcode) { 204 arch_addr_t addr; 205 case 0xa: 206 case 0xb: 207 /* Branch with Link and change to Thumb. */ 208 /* XXX double cast. */ 209 addr = (arch_addr_t) 210 ((uint32_t)arm_branch_dest(pc, this_instr) 211 | (((this_instr >> 24) & 0x1) << 1)); 212 next_pcs[nr++] = MAKE_THUMB_ADDR(addr); 213 break; 214 } 215 else 216 switch (opcode) { 217 uint32_t operand1, operand2, result = 0; 218 case 0x0: 219 case 0x1: /* data processing */ 220 case 0x2: 221 case 0x3: 222 if (BITS(this_instr, 12, 15) != ARM_REG_PC) 223 break; 224 225 if (BITS(this_instr, 22, 25) == 0 226 && BITS(this_instr, 4, 7) == 9) { /* multiply */ 227 invalid: 228 fprintf(stderr, 229 "Invalid update to pc in instruction.\n"); 230 break; 231 } 232 233 /* BX <reg>, BLX <reg> */ 234 if (BITS(this_instr, 4, 27) == 0x12fff1 235 || BITS(this_instr, 4, 27) == 0x12fff3) { 236 enum arm_register reg = BITS(this_instr, 0, 3); 237 /* XXX double cast: no need to go 238 * through tmp. */ 239 uint32_t tmp; 240 if (arm_get_register_offpc(proc, reg, &tmp) < 0) 241 return -1; 242 next_pcs[nr++] = (arch_addr_t)tmp; 243 return 0; 244 } 245 246 /* Multiply into PC. */ 247 if (arm_get_register_offpc 248 (proc, BITS(this_instr, 16, 19), &operand1) < 0) 249 return -1; 250 251 int c = (status & FLAG_C) ? 1 : 0; 252 if (BIT(this_instr, 25)) { 253 uint32_t immval = BITS(this_instr, 0, 7); 254 uint32_t rotate = 2 * BITS(this_instr, 8, 11); 255 operand2 = (((immval >> rotate) 256 | (immval << (32 - rotate))) 257 & 0xffffffff); 258 } else { 259 /* operand 2 is a shifted register. */ 260 if (arm_get_shifted_register 261 (proc, this_instr, c, pc, &operand2) < 0) 262 return -1; 263 } 264 265 switch (BITS(this_instr, 21, 24)) { 266 case 0x0: /*and */ 267 result = operand1 & operand2; 268 break; 269 270 case 0x1: /*eor */ 271 result = operand1 ^ operand2; 272 break; 273 274 case 0x2: /*sub */ 275 result = operand1 - operand2; 276 break; 277 278 case 0x3: /*rsb */ 279 result = operand2 - operand1; 280 break; 281 282 case 0x4: /*add */ 283 result = operand1 + operand2; 284 break; 285 286 case 0x5: /*adc */ 287 result = operand1 + operand2 + c; 288 break; 289 290 case 0x6: /*sbc */ 291 result = operand1 - operand2 + c; 292 break; 293 294 case 0x7: /*rsc */ 295 result = operand2 - operand1 + c; 296 break; 297 298 case 0x8: 299 case 0x9: 300 case 0xa: 301 case 0xb: /* tst, teq, cmp, cmn */ 302 /* Only take the default branch. */ 303 result = 0; 304 break; 305 306 case 0xc: /*orr */ 307 result = operand1 | operand2; 308 break; 309 310 case 0xd: /*mov */ 311 /* Always step into a function. */ 312 result = operand2; 313 break; 314 315 case 0xe: /*bic */ 316 result = operand1 & ~operand2; 317 break; 318 319 case 0xf: /*mvn */ 320 result = ~operand2; 321 break; 322 } 323 324 /* XXX double cast */ 325 next_pcs[nr++] = (arch_addr_t)result; 326 break; 327 328 case 0x4: 329 case 0x5: /* data transfer */ 330 case 0x6: 331 case 0x7: 332 /* Ignore if insn isn't load or Rn not PC. */ 333 if (!BIT(this_instr, 20) 334 || BITS(this_instr, 12, 15) != ARM_REG_PC) 335 break; 336 337 if (BIT(this_instr, 22)) 338 goto invalid; 339 340 /* byte write to PC */ 341 uint32_t base; 342 if (arm_get_register_offpc 343 (proc, BITS(this_instr, 16, 19), &base) < 0) 344 return -1; 345 346 if (BIT(this_instr, 24)) { 347 /* pre-indexed */ 348 int c = (status & FLAG_C) ? 1 : 0; 349 uint32_t offset; 350 if (BIT(this_instr, 25)) { 351 if (arm_get_shifted_register 352 (proc, this_instr, c, 353 pc, &offset) < 0) 354 return -1; 355 } else { 356 offset = BITS(this_instr, 0, 11); 357 } 358 359 if (BIT(this_instr, 23)) 360 base += offset; 361 else 362 base -= offset; 363 } 364 365 /* XXX two double casts. */ 366 uint32_t next; 367 if (proc_read_32(proc, (arch_addr_t)base, &next) < 0) 368 return -1; 369 next_pcs[nr++] = (arch_addr_t)next; 370 break; 371 372 case 0x8: 373 case 0x9: /* block transfer */ 374 if (!BIT(this_instr, 20)) 375 break; 376 /* LDM */ 377 if (BIT(this_instr, 15)) { 378 /* Loading pc. */ 379 int offset = 0; 380 enum arm_register rn = BITS(this_instr, 16, 19); 381 uint32_t rn_val; 382 if (arm_get_register(proc, rn, &rn_val) < 0) 383 return -1; 384 385 int pre = BIT(this_instr, 24); 386 if (BIT(this_instr, 23)) { 387 /* Bit U = up. */ 388 unsigned reglist 389 = BITS(this_instr, 0, 14); 390 offset = bitcount(reglist) * 4; 391 if (pre) 392 offset += 4; 393 } else if (pre) { 394 offset = -4; 395 } 396 397 /* XXX double cast. */ 398 arch_addr_t addr 399 = (arch_addr_t)(rn_val + offset); 400 uint32_t next; 401 if (proc_read_32(proc, addr, &next) < 0) 402 return -1; 403 next_pcs[nr++] = (arch_addr_t)next; 404 } 405 break; 406 407 case 0xb: /* branch & link */ 408 case 0xa: /* branch */ 409 next_pcs[nr++] = arm_branch_dest(pc, this_instr); 410 break; 411 412 case 0xc: 413 case 0xd: 414 case 0xe: /* coproc ops */ 415 case 0xf: /* SWI */ 416 break; 417 } 418 419 /* Otherwise take the next instruction. */ 420 if (cond != COND_ALWAYS || nr == 0) 421 next_pcs[nr++] = pc + 4; 422 return 0; 423} 424 425/* Return the size in bytes of the complete Thumb instruction whose 426 * first halfword is INST1. */ 427 428static int 429thumb_insn_size (unsigned short inst1) 430{ 431 if ((inst1 & 0xe000) == 0xe000 && (inst1 & 0x1800) != 0) 432 return 4; 433 else 434 return 2; 435} 436 437static int 438thumb_get_next_pcs(struct process *proc, 439 const arch_addr_t pc, arch_addr_t next_pcs[2]) 440{ 441 uint16_t inst1; 442 uint32_t status; 443 if (proc_read_16(proc, pc, &inst1) < 0 444 || arm_get_register(proc, ARM_REG_CPSR, &status) < 0) 445 return -1; 446 447 int nr = 0; 448 449 /* We currently ignore Thumb-2 conditional execution support 450 * (the IT instruction). No branches are allowed in IT block, 451 * and it's not legal to jump in the middle of it, so unless 452 * we need to singlestep through large swaths of code, which 453 * we currently don't, we can ignore them. */ 454 455 if ((inst1 & 0xff00) == 0xbd00) { /* pop {rlist, pc} */ 456 /* Fetch the saved PC from the stack. It's stored 457 * above all of the other registers. */ 458 const unsigned offset = bitcount(BITS(inst1, 0, 7)) * 4; 459 uint32_t sp; 460 uint32_t next; 461 /* XXX two double casts */ 462 if (arm_get_register(proc, ARM_REG_SP, &sp) < 0 463 || proc_read_32(proc, (arch_addr_t)(sp + offset), 464 &next) < 0) 465 return -1; 466 next_pcs[nr++] = (arch_addr_t)next; 467 } else if ((inst1 & 0xf000) == 0xd000) { /* conditional branch */ 468 const unsigned long cond = BITS(inst1, 8, 11); 469 if (cond != 0x0f) { /* SWI */ 470 next_pcs[nr++] = pc + (SBITS(inst1, 0, 7) << 1); 471 if (cond == COND_ALWAYS) 472 return 0; 473 } 474 } else if ((inst1 & 0xf800) == 0xe000) { /* unconditional branch */ 475 next_pcs[nr++] = pc + (SBITS(inst1, 0, 10) << 1); 476 } else if (thumb_insn_size(inst1) == 4) { /* 32-bit instruction */ 477 unsigned short inst2; 478 if (proc_read_16(proc, pc + 2, &inst2) < 0) 479 return -1; 480 481 if ((inst1 & 0xf800) == 0xf000 && (inst2 & 0x8000) == 0x8000) { 482 /* Branches and miscellaneous control instructions. */ 483 484 if ((inst2 & 0x1000) != 0 485 || (inst2 & 0xd001) == 0xc000) { 486 /* B, BL, BLX. */ 487 488 const int imm1 = SBITS(inst1, 0, 10); 489 const unsigned imm2 = BITS(inst2, 0, 10); 490 const unsigned j1 = BIT(inst2, 13); 491 const unsigned j2 = BIT(inst2, 11); 492 493 int32_t offset 494 = ((imm1 << 12) + (imm2 << 1)); 495 offset ^= ((!j2) << 22) | ((!j1) << 23); 496 497 /* XXX double cast */ 498 uint32_t next = (uint32_t)(pc + offset); 499 /* For BLX make sure to clear the low bits. */ 500 if (BIT(inst2, 12) == 0) 501 next = next & 0xfffffffc; 502 /* XXX double cast */ 503 next_pcs[nr++] = (arch_addr_t)next; 504 return 0; 505 } else if (inst1 == 0xf3de 506 && (inst2 & 0xff00) == 0x3f00) { 507 /* SUBS PC, LR, #imm8. */ 508 uint32_t next; 509 if (arm_get_register(proc, ARM_REG_LR, 510 &next) < 0) 511 return -1; 512 next -= inst2 & 0x00ff; 513 /* XXX double cast */ 514 next_pcs[nr++] = (arch_addr_t)next; 515 return 0; 516 } else if ((inst2 & 0xd000) == 0x8000 517 && (inst1 & 0x0380) != 0x0380) { 518 /* Conditional branch. */ 519 const int sign = SBITS(inst1, 10, 10); 520 const unsigned imm1 = BITS(inst1, 0, 5); 521 const unsigned imm2 = BITS(inst2, 0, 10); 522 const unsigned j1 = BIT(inst2, 13); 523 const unsigned j2 = BIT(inst2, 11); 524 525 int32_t offset = (sign << 20) 526 + (j2 << 19) + (j1 << 18); 527 offset += (imm1 << 12) + (imm2 << 1); 528 next_pcs[nr++] = pc + offset; 529 if (BITS(inst1, 6, 9) == COND_ALWAYS) 530 return 0; 531 } 532 } else if ((inst1 & 0xfe50) == 0xe810) { 533 int load_pc = 1; 534 int offset; 535 const enum arm_register rn = BITS(inst1, 0, 3); 536 537 if (BIT(inst1, 7) && !BIT(inst1, 8)) { 538 /* LDMIA or POP */ 539 if (!BIT(inst2, 15)) 540 load_pc = 0; 541 offset = bitcount(inst2) * 4 - 4; 542 } else if (!BIT(inst1, 7) && BIT(inst1, 8)) { 543 /* LDMDB */ 544 if (!BIT(inst2, 15)) 545 load_pc = 0; 546 offset = -4; 547 } else if (BIT(inst1, 7) && BIT(inst1, 8)) { 548 /* RFEIA */ 549 offset = 0; 550 } else if (!BIT(inst1, 7) && !BIT(inst1, 8)) { 551 /* RFEDB */ 552 offset = -8; 553 } else { 554 load_pc = 0; 555 } 556 557 if (load_pc) { 558 uint32_t addr; 559 if (arm_get_register(proc, rn, &addr) < 0) 560 return -1; 561 arch_addr_t a = (arch_addr_t)(addr + offset); 562 uint32_t next; 563 if (proc_read_32(proc, a, &next) < 0) 564 return -1; 565 /* XXX double cast */ 566 next_pcs[nr++] = (arch_addr_t)next; 567 } 568 } else if ((inst1 & 0xffef) == 0xea4f 569 && (inst2 & 0xfff0) == 0x0f00) { 570 /* MOV PC or MOVS PC. */ 571 const enum arm_register rn = BITS(inst2, 0, 3); 572 uint32_t next; 573 if (arm_get_register(proc, rn, &next) < 0) 574 return -1; 575 /* XXX double cast */ 576 next_pcs[nr++] = (arch_addr_t)next; 577 } else if ((inst1 & 0xff70) == 0xf850 578 && (inst2 & 0xf000) == 0xf000) { 579 /* LDR PC. */ 580 const enum arm_register rn = BITS(inst1, 0, 3); 581 uint32_t base; 582 if (arm_get_register(proc, rn, &base) < 0) 583 return -1; 584 585 int load_pc = 1; 586 if (rn == ARM_REG_PC) { 587 base = (base + 4) & ~(uint32_t)0x3; 588 if (BIT(inst1, 7)) 589 base += BITS(inst2, 0, 11); 590 else 591 base -= BITS(inst2, 0, 11); 592 } else if (BIT(inst1, 7)) { 593 base += BITS(inst2, 0, 11); 594 } else if (BIT(inst2, 11)) { 595 if (BIT(inst2, 10)) { 596 if (BIT(inst2, 9)) 597 base += BITS(inst2, 0, 7); 598 else 599 base -= BITS(inst2, 0, 7); 600 } 601 } else if ((inst2 & 0x0fc0) == 0x0000) { 602 const int shift = BITS(inst2, 4, 5); 603 const enum arm_register rm = BITS(inst2, 0, 3); 604 uint32_t v; 605 if (arm_get_register(proc, rm, &v) < 0) 606 return -1; 607 base += v << shift; 608 } else { 609 /* Reserved. */ 610 load_pc = 0; 611 } 612 613 if (load_pc) { 614 /* xxx double casts */ 615 uint32_t next; 616 if (proc_read_32(proc, 617 (arch_addr_t)base, &next) < 0) 618 return -1; 619 next_pcs[nr++] = (arch_addr_t)next; 620 } 621 } else if ((inst1 & 0xfff0) == 0xe8d0 622 && (inst2 & 0xfff0) == 0xf000) { 623 /* TBB. */ 624 const enum arm_register tbl_reg = BITS(inst1, 0, 3); 625 const enum arm_register off_reg = BITS(inst2, 0, 3); 626 627 uint32_t table; 628 if (tbl_reg == ARM_REG_PC) 629 /* Regcache copy of PC isn't right yet. */ 630 /* XXX double cast */ 631 table = (uint32_t)pc + 4; 632 else if (arm_get_register(proc, tbl_reg, &table) < 0) 633 return -1; 634 635 uint32_t offset; 636 if (arm_get_register(proc, off_reg, &offset) < 0) 637 return -1; 638 639 table += offset; 640 uint8_t length; 641 /* XXX double cast */ 642 if (proc_read_8(proc, (arch_addr_t)table, &length) < 0) 643 return -1; 644 645 next_pcs[nr++] = pc + 2 * length; 646 647 } else if ((inst1 & 0xfff0) == 0xe8d0 648 && (inst2 & 0xfff0) == 0xf010) { 649 /* TBH. */ 650 const enum arm_register tbl_reg = BITS(inst1, 0, 3); 651 const enum arm_register off_reg = BITS(inst2, 0, 3); 652 653 uint32_t table; 654 if (tbl_reg == ARM_REG_PC) 655 /* Regcache copy of PC isn't right yet. */ 656 /* XXX double cast */ 657 table = (uint32_t)pc + 4; 658 else if (arm_get_register(proc, tbl_reg, &table) < 0) 659 return -1; 660 661 uint32_t offset; 662 if (arm_get_register(proc, off_reg, &offset) < 0) 663 return -1; 664 665 table += 2 * offset; 666 uint16_t length; 667 /* XXX double cast */ 668 if (proc_read_16(proc, (arch_addr_t)table, &length) < 0) 669 return -1; 670 671 next_pcs[nr++] = pc + 2 * length; 672 } 673 } 674 675 676 /* Otherwise take the next instruction. */ 677 if (nr == 0) 678 next_pcs[nr++] = pc + thumb_insn_size(inst1); 679 return 0; 680} 681 682enum sw_singlestep_status 683arch_sw_singlestep(struct process *proc, struct breakpoint *sbp, 684 int (*add_cb)(arch_addr_t, struct sw_singlestep_data *), 685 struct sw_singlestep_data *add_cb_data) 686{ 687 const arch_addr_t pc = get_instruction_pointer(proc); 688 689 uint32_t cpsr; 690 if (arm_get_register(proc, ARM_REG_CPSR, &cpsr) < 0) 691 return SWS_FAIL; 692 693 const unsigned thumb_p = BIT(cpsr, 5); 694 arch_addr_t next_pcs[2] = {}; 695 if ((thumb_p ? &thumb_get_next_pcs 696 : &arm_get_next_pcs)(proc, pc, next_pcs) < 0) 697 return SWS_FAIL; 698 699 int i; 700 for (i = 0; i < 2; ++i) { 701 /* XXX double cast. */ 702 arch_addr_t target 703 = (arch_addr_t)(((uintptr_t)next_pcs[i]) | thumb_p); 704 if (next_pcs[i] != 0 && add_cb(target, add_cb_data) < 0) 705 return SWS_FAIL; 706 } 707 708 debug(1, "PTRACE_CONT"); 709 ptrace(PTRACE_CONT, proc->pid, 0, 0); 710 return SWS_OK; 711} 712 713size_t 714arch_type_sizeof(struct process *proc, struct arg_type_info *info) 715{ 716 if (proc == NULL) 717 return (size_t)-2; 718 719 switch (info->type) { 720 case ARGTYPE_VOID: 721 return 0; 722 723 case ARGTYPE_CHAR: 724 return 1; 725 726 case ARGTYPE_SHORT: 727 case ARGTYPE_USHORT: 728 return 2; 729 730 case ARGTYPE_INT: 731 case ARGTYPE_UINT: 732 case ARGTYPE_LONG: 733 case ARGTYPE_ULONG: 734 case ARGTYPE_POINTER: 735 return 4; 736 737 case ARGTYPE_FLOAT: 738 return 4; 739 case ARGTYPE_DOUBLE: 740 return 8; 741 742 case ARGTYPE_ARRAY: 743 case ARGTYPE_STRUCT: 744 /* Use default value. */ 745 return (size_t)-2; 746 747 default: 748 assert(info->type != info->type); 749 abort(); 750 } 751} 752 753size_t 754arch_type_alignof(struct process *proc, struct arg_type_info *info) 755{ 756 return arch_type_sizeof(proc, info); 757} 758