1e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata/*
2e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This file is part of ltrace.
319e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata * Copyright (C) 2012, 2013 Petr Machata, Red Hat Inc.
4e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 1998,2004,2008,2009 Juan Cespedes
5e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Copyright (C) 2006 Ian Wienand
6e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata *
7e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This program is free software; you can redistribute it and/or
8e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * modify it under the terms of the GNU General Public License as
9e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * published by the Free Software Foundation; either version 2 of the
10e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * License, or (at your option) any later version.
11e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata *
12e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * This program is distributed in the hope that it will be useful, but
13e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * WITHOUT ANY WARRANTY; without even the implied warranty of
14e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * General Public License for more details.
16e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata *
17e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * You should have received a copy of the GNU General Public License
18e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * along with this program; if not, write to the Free Software
19e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata * 02110-1301 USA
21e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata */
22e99af270a60891e68d465c4cd97dbe29cd1a05e4Petr Machata
23d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes#include "config.h"
24d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes
2563184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes#include <string.h>
268e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes#include <sys/types.h>
278e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes#include <sys/wait.h>
288e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes#include <signal.h>
298e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes#include <sys/ptrace.h>
308e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes#include <asm/ptrace.h>
318e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes
32d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata#include "bits.h"
33f728123bd75a65a6a1536e198c3c30719e494e71Juan Cespedes#include "common.h"
34d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata#include "proc.h"
3563184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes#include "output.h"
3663184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes#include "ptrace.h"
379fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata#include "regs.h"
38f25af517a06521f69fbc53eaf3c245a7a2298c75Petr Machata#include "type.h"
398e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes
408e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes#if (!defined(PTRACE_PEEKUSER) && defined(PTRACE_PEEKUSR))
418e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes# define PTRACE_PEEKUSER PTRACE_PEEKUSR
428e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes#endif
438e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes
448e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes#if (!defined(PTRACE_POKEUSER) && defined(PTRACE_POKEUSR))
458e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes# define PTRACE_POKEUSER PTRACE_POKEUSR
468e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes#endif
478e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes
48f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid
49929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machataget_arch_dep(struct process *proc)
50929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata{
5163184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes	proc_archdep *a;
5263184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes
5363184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes	if (!proc->arch_ptr)
5463184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes		proc->arch_ptr = (void *)malloc(sizeof(proc_archdep));
5563184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes	a = (proc_archdep *) (proc->arch_ptr);
5663184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes	a->valid = (ptrace(PTRACE_GETREGS, proc->pid, 0, &a->regs) >= 0);
575c3fe0697b202cc7d95e90459de0fb312b297b27Juan Cespedes}
585c3fe0697b202cc7d95e90459de0fb312b297b27Juan Cespedes
5963184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes/* Returns 0 if not a syscall,
6063184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes *         1 if syscall entry, 2 if syscall exit,
6163184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes *         3 if arch-specific syscall entry, 4 if arch-specific syscall exit,
6263184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes *         -1 on error.
638e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes */
64f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesint
65929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machatasyscall_p(struct process *proc, int status, int *sysnum)
66929bd57ca202fd2f2e8485ebf65d683e664f67b5Petr Machata{
672d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	if (WIFSTOPPED(status)
682d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand	    && WSTOPSIG(status) == (SIGTRAP | proc->tracesysgood)) {
69f25af517a06521f69fbc53eaf3c245a7a2298c75Petr Machata		uint32_t pc, ip;
70f25af517a06521f69fbc53eaf3c245a7a2298c75Petr Machata		if (arm_get_register(proc, ARM_REG_PC, &pc) < 0
71f25af517a06521f69fbc53eaf3c245a7a2298c75Petr Machata		    || arm_get_register(proc, ARM_REG_IP, &ip) < 0)
72f25af517a06521f69fbc53eaf3c245a7a2298c75Petr Machata			return -1;
73f25af517a06521f69fbc53eaf3c245a7a2298c75Petr Machata
74c897cb796dc4a7d256cbfbf0137ef7cdff9e8ecePetr Machata		pc = pc - 4;
75f25af517a06521f69fbc53eaf3c245a7a2298c75Petr Machata
768e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes		/* fetch the SWI instruction */
77c897cb796dc4a7d256cbfbf0137ef7cdff9e8ecePetr Machata		unsigned insn = ptrace(PTRACE_PEEKTEXT, proc->pid,
78c897cb796dc4a7d256cbfbf0137ef7cdff9e8ecePetr Machata				       (void *)pc, 0);
792d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand
80e280a5e51b72825ab3234c532f832cd64695bc1eZach Welch		if (insn == 0xef000000 || insn == 0x0f000000
81e280a5e51b72825ab3234c532f832cd64695bc1eZach Welch		    || (insn & 0xffff0000) == 0xdf000000) {
8263184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			/* EABI syscall */
83f25af517a06521f69fbc53eaf3c245a7a2298c75Petr Machata			uint32_t r7;
84f25af517a06521f69fbc53eaf3c245a7a2298c75Petr Machata			if (arm_get_register(proc, ARM_REG_R7, &r7) < 0)
85f25af517a06521f69fbc53eaf3c245a7a2298c75Petr Machata				return -1;
86f25af517a06521f69fbc53eaf3c245a7a2298c75Petr Machata			*sysnum = r7;
8763184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes		} else if ((insn & 0xfff00000) == 0xef900000) {
8863184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			/* old ABI syscall */
8963184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			*sysnum = insn & 0xfffff;
9063184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes		} else {
9163184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			/* TODO: handle swi<cond> variations */
9263184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			/* one possible reason for getting in here is that we
9363184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			 * are coming from a signal handler, so the current
9463184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			 * PC does not point to the instruction just after the
9563184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			 * "swi" one. */
96c897cb796dc4a7d256cbfbf0137ef7cdff9e8ecePetr Machata			output_line(proc, "unexpected instruction 0x%x at %p",
97c897cb796dc4a7d256cbfbf0137ef7cdff9e8ecePetr Machata				    insn, pc);
9832e8e76f492a48ee3e6284e237f958b71d4d3e71Arnaud Patard			return 0;
9963184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes		}
10063184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes		if ((*sysnum & 0xf0000) == 0xf0000) {
10163184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			/* arch-specific syscall */
10263184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			*sysnum &= ~0xf0000;
10363184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes			return ip ? 4 : 3;
1048e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes		}
10563184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes		/* ARM syscall convention: on syscall entry, ip is zero;
10663184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes		 * on syscall exit, ip is non-zero */
10763184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes		return ip ? 2 : 1;
1088e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes	}
1098e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes	return 0;
1108e3e082c27716245619721207cd5067d8c6271f9Juan Cespedes}
1112d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand
11219e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machatastatic arch_addr_t
11319e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machataarm_branch_dest(const arch_addr_t pc, const uint32_t insn)
11419e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata{
11519e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	/* Bits 0-23 are signed immediate value.  */
11619e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	return pc + ((((insn & 0xffffff) ^ 0x800000) - 0x800000) << 2) + 8;
11719e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata}
11819e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata
1199fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata/* Addresses for calling Thumb functions have the bit 0 set.
1209fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata   Here are some macros to test, set, or clear bit 0 of addresses.  */
1219fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata/* XXX double cast */
1229fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata#define IS_THUMB_ADDR(addr)	((uintptr_t)(addr) & 1)
1239fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata#define MAKE_THUMB_ADDR(addr)	((arch_addr_t)((uintptr_t)(addr) | 1))
1249fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata#define UNMAKE_THUMB_ADDR(addr) ((arch_addr_t)((uintptr_t)(addr) & ~1))
1259fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
126037f37c72e252b05c59e53826d5007d24d54ac74Petr Machataenum {
127037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata	COND_ALWAYS = 0xe,
128037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata	COND_NV = 0xf,
129037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata	FLAG_C = 0x20000000,
130037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata};
131037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
13219e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machatastatic int
133d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machataarm_get_next_pcs(struct process *proc,
134d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata		 const arch_addr_t pc, arch_addr_t next_pcs[2])
13519e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata{
1369fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata	uint32_t this_instr;
1379fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata	uint32_t status;
1389fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata	if (proc_read_32(proc, pc, &this_instr) < 0
1399fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata	    || arm_get_register(proc, ARM_REG_CPSR, &status) < 0)
14019e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata		return -1;
14119e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata
14219e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	/* In theory, we sometimes don't even need to add any
14319e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	 * breakpoints at all.  If the conditional bits of the
14419e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	 * instruction indicate that it should not be taken, then we
14519e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	 * can just skip it altogether without bothering.  We could
1467aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata	 * also emulate the instruction under the breakpoint.
14719e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	 *
14819e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	 * Here, we make it as simple as possible (though We Accept
14919e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	 * Patches).  */
15019e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	int nr = 0;
15119e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata
15219e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	/* ARM can branch either relatively by using a branch
15319e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	 * instruction, or absolutely, by doing arbitrary arithmetic
1549fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata	 * with PC as the destination.  */
1559fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata	const unsigned cond = BITS(this_instr, 28, 31);
1569fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata	const unsigned opcode = BITS(this_instr, 24, 27);
1579fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
1589fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata	if (cond == COND_NV)
1599fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		switch (opcode) {
1609fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			arch_addr_t addr;
1619fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		case 0xa:
1629fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		case 0xb:
1639fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			/* Branch with Link and change to Thumb.  */
1649fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			/* XXX double cast.  */
1659fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			addr = (arch_addr_t)
1669fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				((uint32_t)arm_branch_dest(pc, this_instr)
1679fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				 | (((this_instr >> 24) & 0x1) << 1));
1689fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			next_pcs[nr++] = MAKE_THUMB_ADDR(addr);
1699fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			break;
1709fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		}
1719fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata	else
1729fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		switch (opcode) {
1739fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			uint32_t operand1, operand2, result = 0;
1749fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		case 0x0:
1759fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		case 0x1:			/* data processing */
1769fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		case 0x2:
1779fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		case 0x3:
1789fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			if (BITS(this_instr, 12, 15) != ARM_REG_PC)
1799fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				break;
1809fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
1819fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			if (BITS(this_instr, 22, 25) == 0
1829fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			    && BITS(this_instr, 4, 7) == 9) {	/* multiply */
1839fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			invalid:
1849fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				fprintf(stderr,
1859fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				"Invalid update to pc in instruction.\n");
1869fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				break;
1879fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			}
1889fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
1899fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			/* BX <reg>, BLX <reg> */
1909fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			if (BITS(this_instr, 4, 27) == 0x12fff1
1919fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			    || BITS(this_instr, 4, 27) == 0x12fff3) {
1929fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				enum arm_register reg = BITS(this_instr, 0, 3);
1939fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				/* XXX double cast: no need to go
1949fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				 * through tmp.  */
1959fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				uint32_t tmp;
1969fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				if (arm_get_register_offpc(proc, reg, &tmp) < 0)
1979fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata					return -1;
1989fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				next_pcs[nr++] = (arch_addr_t)tmp;
1999fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				return 0;
2009fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			}
2019fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2029fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			/* Multiply into PC.  */
2039fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			if (arm_get_register_offpc
2049fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			    (proc, BITS(this_instr, 16, 19), &operand1) < 0)
2059fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				return -1;
2069fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2079fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			int c = (status & FLAG_C) ? 1 : 0;
2089fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			if (BIT(this_instr, 25)) {
2099fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				uint32_t immval = BITS(this_instr, 0, 7);
2109fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				uint32_t rotate = 2 * BITS(this_instr, 8, 11);
2119fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				operand2 = (((immval >> rotate)
2129fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata					     | (immval << (32 - rotate)))
2139fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata					    & 0xffffffff);
2149fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			} else {
2159fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				/* operand 2 is a shifted register.  */
2169fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				if (arm_get_shifted_register
2179fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				    (proc, this_instr, c, pc, &operand2) < 0)
2189fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata					return -1;
2199fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			}
2209fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2219fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			switch (BITS(this_instr, 21, 24)) {
2229fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			case 0x0:	/*and */
2239fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				result = operand1 & operand2;
2249fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				break;
2259fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2269fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			case 0x1:	/*eor */
2279fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				result = operand1 ^ operand2;
2289fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				break;
2299fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2309fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			case 0x2:	/*sub */
2319fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				result = operand1 - operand2;
2329fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				break;
2339fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2349fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			case 0x3:	/*rsb */
2359fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				result = operand2 - operand1;
2369fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				break;
2379fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2389fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			case 0x4:	/*add */
2399fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				result = operand1 + operand2;
2409fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				break;
2419fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2429fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			case 0x5:	/*adc */
2439fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				result = operand1 + operand2 + c;
2449fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				break;
2459fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2469fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			case 0x6:	/*sbc */
2479fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				result = operand1 - operand2 + c;
2489fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				break;
2499fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2509fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			case 0x7:	/*rsc */
2519fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				result = operand2 - operand1 + c;
2529fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				break;
2539fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2549fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			case 0x8:
2559fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			case 0x9:
2569fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			case 0xa:
2579fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			case 0xb:	/* tst, teq, cmp, cmn */
2589fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				/* Only take the default branch.  */
2599fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				result = 0;
2609fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				break;
2619fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2629fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			case 0xc:	/*orr */
2639fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				result = operand1 | operand2;
2649fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				break;
2659fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2669fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			case 0xd:	/*mov */
2679fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				/* Always step into a function.  */
2689fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				result = operand2;
2699fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				break;
2709fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2719fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			case 0xe:	/*bic */
2729fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				result = operand1 & ~operand2;
2739fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				break;
2749fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2759fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			case 0xf:	/*mvn */
2769fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				result = ~operand2;
2779fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				break;
2789fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			}
2799fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2809fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			/* XXX double cast */
2819fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			next_pcs[nr++] = (arch_addr_t)result;
2829fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			break;
2839fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2849fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		case 0x4:
2859fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		case 0x5:		/* data transfer */
2869fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		case 0x6:
2879fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		case 0x7:
2889fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			/* Ignore if insn isn't load or Rn not PC.  */
2899fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			if (!BIT(this_instr, 20)
2909fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			    || BITS(this_instr, 12, 15) != ARM_REG_PC)
2919fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				break;
2929fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2939fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			if (BIT(this_instr, 22))
2949fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				goto invalid;
2959fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
2969fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			/* byte write to PC */
2979fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			uint32_t base;
2989fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			if (arm_get_register_offpc
2999fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			    (proc, BITS(this_instr, 16, 19), &base) < 0)
3009fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				return -1;
3019fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
3029fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			if (BIT(this_instr, 24)) {
3039fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				/* pre-indexed */
3049fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				int c = (status & FLAG_C) ? 1 : 0;
3059fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				uint32_t offset;
3069fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				if (BIT(this_instr, 25)) {
3079fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata					if (arm_get_shifted_register
3089fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata					    (proc, this_instr, c,
3099fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata					     pc, &offset) < 0)
3109fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata						return -1;
3119fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				} else {
3129fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata					offset = BITS(this_instr, 0, 11);
3139fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				}
3149fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
3159fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				if (BIT(this_instr, 23))
3169fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata					base += offset;
3179fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				else
3189fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata					base -= offset;
3199fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			}
3209fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
3219fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			/* XXX two double casts.  */
3229fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			uint32_t next;
3239fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			if (proc_read_32(proc, (arch_addr_t)base, &next) < 0)
3249fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata				return -1;
3259fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			next_pcs[nr++] = (arch_addr_t)next;
3269fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			break;
3279fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata
3287aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata		case 0x8:
3297aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata		case 0x9:		/* block transfer */
3307aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata			if (!BIT(this_instr, 20))
3317aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata				break;
3327aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata			/* LDM */
3337aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata			if (BIT(this_instr, 15)) {
3347aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata				/* Loading pc.  */
3357aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata				int offset = 0;
3367aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata				enum arm_register rn = BITS(this_instr, 16, 19);
3377aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata				uint32_t rn_val;
3387aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata				if (arm_get_register(proc, rn, &rn_val) < 0)
3397aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata					return -1;
3407aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata
3417aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata				int pre = BIT(this_instr, 24);
3427aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata				if (BIT(this_instr, 23)) {
3437aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata					/* Bit U = up.  */
3447aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata					unsigned reglist
3457aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata						= BITS(this_instr, 0, 14);
3467aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata					offset = bitcount(reglist) * 4;
3477aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata					if (pre)
3487aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata						offset += 4;
3497aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata				} else if (pre) {
3507aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata					offset = -4;
3517aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata				}
3527aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata
3537aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata				/* XXX double cast.  */
3547aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata				arch_addr_t addr
3557aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata					= (arch_addr_t)(rn_val + offset);
3567aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata				uint32_t next;
3577aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata				if (proc_read_32(proc, addr, &next) < 0)
3587aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata					return -1;
3597aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata				next_pcs[nr++] = (arch_addr_t)next;
3607aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata			}
3617aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata			break;
3627aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata
3639fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		case 0xb:		/* branch & link */
3649fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		case 0xa:		/* branch */
3659fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			next_pcs[nr++] = arm_branch_dest(pc, this_instr);
3669fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata			break;
3677aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata
3687aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata		case 0xc:
3697aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata		case 0xd:
3707aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata		case 0xe:		/* coproc ops */
3717aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata		case 0xf:		/* SWI */
3727aa7b404588184ef9a45eeafbfc5ef4afc7fbf82Petr Machata			break;
3739fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		}
37419e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata
37519e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	/* Otherwise take the next instruction.  */
3769fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata	if (cond != COND_ALWAYS || nr == 0)
3779fa2b1850e664aa70a9559e41befca1a5975f08cPetr Machata		next_pcs[nr++] = pc + 4;
37819e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	return 0;
37919e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata}
38019e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata
381037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata/* Return the size in bytes of the complete Thumb instruction whose
382037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata * first halfword is INST1.  */
383037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
384037f37c72e252b05c59e53826d5007d24d54ac74Petr Machatastatic int
385037f37c72e252b05c59e53826d5007d24d54ac74Petr Machatathumb_insn_size (unsigned short inst1)
386037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata{
387037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata  if ((inst1 & 0xe000) == 0xe000 && (inst1 & 0x1800) != 0)
388037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata	  return 4;
389037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata  else
390037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata	  return 2;
391037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata}
392037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
393d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machatastatic int
394d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machatathumb_get_next_pcs(struct process *proc,
395d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata		   const arch_addr_t pc, arch_addr_t next_pcs[2])
396d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata{
397d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	uint16_t inst1;
398d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	uint32_t status;
399d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	if (proc_read_16(proc, pc, &inst1) < 0
400d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	    || arm_get_register(proc, ARM_REG_CPSR, &status) < 0)
401d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata		return -1;
402d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata
403d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	int nr = 0;
404d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata
405d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	/* We currently ignore Thumb-2 conditional execution support
406d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	 * (the IT instruction).  No branches are allowed in IT block,
407d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	 * and it's not legal to jump in the middle of it, so unless
408d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	 * we need to singlestep through large swaths of code, which
409d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	 * we currently don't, we can ignore them.  */
410d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata
411d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	if ((inst1 & 0xff00) == 0xbd00)	{ /* pop {rlist, pc} */
412d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata		/* Fetch the saved PC from the stack.  It's stored
413d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata		 * above all of the other registers.  */
414037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata		const unsigned offset = bitcount(BITS(inst1, 0, 7)) * 4;
415d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata		uint32_t sp;
416d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata		uint32_t next;
417d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata		/* XXX two double casts */
418d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata		if (arm_get_register(proc, ARM_REG_SP, &sp) < 0
419d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata		    || proc_read_32(proc, (arch_addr_t)(sp + offset),
420d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata				    &next) < 0)
421d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata			return -1;
422d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata		next_pcs[nr++] = (arch_addr_t)next;
423037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata	} else if ((inst1 & 0xf000) == 0xd000) { /* conditional branch */
424037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata		const unsigned long cond = BITS(inst1, 8, 11);
425037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata		if (cond != 0x0f) { /* SWI */
426037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			next_pcs[nr++] = pc + (SBITS(inst1, 0, 7) << 1);
427037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			if (cond == COND_ALWAYS)
428037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				return 0;
429037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata		}
430037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata	} else if ((inst1 & 0xf800) == 0xe000) { /* unconditional branch */
431037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata		next_pcs[nr++] = pc + (SBITS(inst1, 0, 10) << 1);
432037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata	} else if (thumb_insn_size(inst1) == 4) { /* 32-bit instruction */
433037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata		unsigned short inst2;
434037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata		if (proc_read_16(proc, pc + 2, &inst2) < 0)
435037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			return -1;
436037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
437037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata		if ((inst1 & 0xf800) == 0xf000 && (inst2 & 0x8000) == 0x8000) {
438037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			/* Branches and miscellaneous control instructions.  */
439037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
440037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			if ((inst2 & 0x1000) != 0
441037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			    || (inst2 & 0xd001) == 0xc000) {
442037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* B, BL, BLX.  */
443037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
444037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				const int imm1 = SBITS(inst1, 0, 10);
445037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				const unsigned imm2 = BITS(inst2, 0, 10);
446037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				const unsigned j1 = BIT(inst2, 13);
447037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				const unsigned j2 = BIT(inst2, 11);
448037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
449037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				int32_t offset
450037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata					= ((imm1 << 12) + (imm2 << 1));
451037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				offset ^= ((!j2) << 22) | ((!j1) << 23);
452037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
453037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* XXX double cast */
454037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				uint32_t next = (uint32_t)(pc + offset);
455037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* For BLX make sure to clear the low bits.  */
456037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				if (BIT(inst2, 12) == 0)
457037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata					next = next & 0xfffffffc;
458037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* XXX double cast */
459037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				next_pcs[nr++] = (arch_addr_t)next;
460037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				return 0;
461037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			} else if (inst1 == 0xf3de
462037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				   && (inst2 & 0xff00) == 0x3f00) {
463037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* SUBS PC, LR, #imm8.  */
464037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				uint32_t next;
465037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				if (arm_get_register(proc, ARM_REG_LR,
466037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata						     &next) < 0)
467037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata					return -1;
468037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				next -= inst2 & 0x00ff;
469037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* XXX double cast */
470037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				next_pcs[nr++] = (arch_addr_t)next;
471037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				return 0;
472037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			} else if ((inst2 & 0xd000) == 0x8000
473037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				   && (inst1 & 0x0380) != 0x0380) {
474037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* Conditional branch.  */
475037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				const int sign = SBITS(inst1, 10, 10);
476037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				const unsigned imm1 = BITS(inst1, 0, 5);
477037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				const unsigned imm2 = BITS(inst2, 0, 10);
478037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				const unsigned j1 = BIT(inst2, 13);
479037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				const unsigned j2 = BIT(inst2, 11);
480037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
481037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				int32_t offset = (sign << 20)
482037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata					+ (j2 << 19) + (j1 << 18);
483037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				offset += (imm1 << 12) + (imm2 << 1);
484037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				next_pcs[nr++] = pc + offset;
485037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				if (BITS(inst1, 6, 9) == COND_ALWAYS)
486037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata					return 0;
487037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			}
488037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata		} else if ((inst1 & 0xfe50) == 0xe810) {
489037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			int load_pc = 1;
490037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			int offset;
491037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			const enum arm_register rn = BITS(inst1, 0, 3);
492037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
493037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			if (BIT(inst1, 7) && !BIT(inst1, 8)) {
494037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* LDMIA or POP */
495037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				if (!BIT(inst2, 15))
496037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata					load_pc = 0;
497037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				offset = bitcount(inst2) * 4 - 4;
498037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			} else if (!BIT(inst1, 7) && BIT(inst1, 8)) {
499037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* LDMDB */
500037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				if (!BIT(inst2, 15))
501037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata					load_pc = 0;
502037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				offset = -4;
503037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			} else if (BIT(inst1, 7) && BIT(inst1, 8)) {
504037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* RFEIA */
505037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				offset = 0;
506037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			} else if (!BIT(inst1, 7) && !BIT(inst1, 8)) {
507037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* RFEDB */
508037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				offset = -8;
509037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			} else {
510037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				load_pc = 0;
511037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			}
512037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
513037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			if (load_pc) {
514037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				uint32_t addr;
515037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				if (arm_get_register(proc, rn, &addr) < 0)
516037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata					return -1;
517037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				arch_addr_t a = (arch_addr_t)(addr + offset);
518037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				uint32_t next;
519037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				if (proc_read_32(proc, a, &next) < 0)
520037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata					return -1;
521037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* XXX double cast */
522037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				next_pcs[nr++] = (arch_addr_t)next;
523037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			}
524037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata		} else if ((inst1 & 0xffef) == 0xea4f
525037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			   && (inst2 & 0xfff0) == 0x0f00) {
526037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			/* MOV PC or MOVS PC.  */
527037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			const enum arm_register rn = BITS(inst2, 0, 3);
528037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			uint32_t next;
529037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			if (arm_get_register(proc, rn, &next) < 0)
530037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				return -1;
531037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			/* XXX double cast */
532037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			next_pcs[nr++] = (arch_addr_t)next;
533037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata		} else if ((inst1 & 0xff70) == 0xf850
534037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			   && (inst2 & 0xf000) == 0xf000) {
535037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			/* LDR PC.  */
536037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			const enum arm_register rn = BITS(inst1, 0, 3);
537037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			uint32_t base;
538037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			if (arm_get_register(proc, rn, &base) < 0)
539037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				return -1;
540037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
541037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			int load_pc = 1;
542037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			if (rn == ARM_REG_PC) {
543037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				base = (base + 4) & ~(uint32_t)0x3;
544037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				if (BIT(inst1, 7))
545037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata					base += BITS(inst2, 0, 11);
546037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				else
547037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata					base -= BITS(inst2, 0, 11);
548037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			} else if (BIT(inst1, 7)) {
549037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				base += BITS(inst2, 0, 11);
550037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			} else if (BIT(inst2, 11)) {
551037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				if (BIT(inst2, 10)) {
552037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata					if (BIT(inst2, 9))
553037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata						base += BITS(inst2, 0, 7);
554037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata					else
555037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata						base -= BITS(inst2, 0, 7);
556037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				}
557037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			} else if ((inst2 & 0x0fc0) == 0x0000) {
558037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				const int shift = BITS(inst2, 4, 5);
559037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				const enum arm_register rm = BITS(inst2, 0, 3);
560037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				uint32_t v;
561037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				if (arm_get_register(proc, rm, &v) < 0)
562037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata					return -1;
563037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				base += v << shift;
564037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			} else {
565037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* Reserved.  */
566037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				load_pc = 0;
567037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			}
568037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
569037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			if (load_pc) {
570037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* xxx double casts */
571037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				uint32_t next;
572037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				if (proc_read_32(proc,
573037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata						 (arch_addr_t)base, &next) < 0)
574037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata					return -1;
575037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				next_pcs[nr++] = (arch_addr_t)next;
576037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			}
577037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata		} else if ((inst1 & 0xfff0) == 0xe8d0
578037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			   && (inst2 & 0xfff0) == 0xf000) {
579037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			/* TBB.  */
580037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			const enum arm_register tbl_reg = BITS(inst1, 0, 3);
581037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			const enum arm_register off_reg = BITS(inst2, 0, 3);
582037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
583037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			uint32_t table;
584037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			if (tbl_reg == ARM_REG_PC)
585037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* Regcache copy of PC isn't right yet.  */
586037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* XXX double cast */
587037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				table = (uint32_t)pc + 4;
588037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			else if (arm_get_register(proc, tbl_reg, &table) < 0)
589037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				return -1;
590037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
591037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			uint32_t offset;
592037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			if (arm_get_register(proc, off_reg, &offset) < 0)
593037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				return -1;
594037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
595037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			table += offset;
596037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			uint8_t length;
597037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			/* XXX double cast */
598037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			if (proc_read_8(proc, (arch_addr_t)table, &length) < 0)
599037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				return -1;
600037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
601037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			next_pcs[nr++] = pc + 2 * length;
602037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
603037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata		} else if ((inst1 & 0xfff0) == 0xe8d0
604037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			   && (inst2 & 0xfff0) == 0xf010) {
605037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			/* TBH.  */
606037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			const enum arm_register tbl_reg = BITS(inst1, 0, 3);
607037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			const enum arm_register off_reg = BITS(inst2, 0, 3);
608037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
609037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			uint32_t table;
610037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			if (tbl_reg == ARM_REG_PC)
611037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* Regcache copy of PC isn't right yet.  */
612037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				/* XXX double cast */
613037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				table = (uint32_t)pc + 4;
614037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			else if (arm_get_register(proc, tbl_reg, &table) < 0)
615037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				return -1;
616037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
617037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			uint32_t offset;
618037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			if (arm_get_register(proc, off_reg, &offset) < 0)
619037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				return -1;
620037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
621037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			table += 2 * offset;
622037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			uint16_t length;
623037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			/* XXX double cast */
624037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			if (proc_read_16(proc, (arch_addr_t)table, &length) < 0)
625037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata				return -1;
626037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
627037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata			next_pcs[nr++] = pc + 2 * length;
628037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata		}
629d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	}
630d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata
631037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata
632d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	/* Otherwise take the next instruction.  */
633d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	if (nr == 0)
634037f37c72e252b05c59e53826d5007d24d54ac74Petr Machata		next_pcs[nr++] = pc + thumb_insn_size(inst1);
635d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	return 0;
636d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata}
637d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata
63819e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machataenum sw_singlestep_status
63919e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machataarch_sw_singlestep(struct process *proc, struct breakpoint *sbp,
64019e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata		   int (*add_cb)(arch_addr_t, struct sw_singlestep_data *),
64119e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata		   struct sw_singlestep_data *add_cb_data)
64219e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata{
643d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	const arch_addr_t pc = get_instruction_pointer(proc);
644d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata
645d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	uint32_t cpsr;
646d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	if (arm_get_register(proc, ARM_REG_CPSR, &cpsr) < 0)
647d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata		return SWS_FAIL;
648d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata
649d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	const unsigned thumb_p = BIT(cpsr, 5);
65019e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	arch_addr_t next_pcs[2] = {};
651d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	if ((thumb_p ? &thumb_get_next_pcs
652d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata	     : &arm_get_next_pcs)(proc, pc, next_pcs) < 0)
65319e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata		return SWS_FAIL;
65419e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata
65519e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	int i;
65619e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	for (i = 0; i < 2; ++i) {
657d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata		/* XXX double cast.  */
658d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata		arch_addr_t target
659d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata			= (arch_addr_t)(((uintptr_t)next_pcs[i]) | thumb_p);
660d4a5447503b7bddfb6d7667747ee1eedd20ae491Petr Machata		if (next_pcs[i] != 0 && add_cb(target, add_cb_data) < 0)
66119e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata			return SWS_FAIL;
66219e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	}
66319e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata
66419e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	debug(1, "PTRACE_CONT");
66519e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	ptrace(PTRACE_CONT, proc->pid, 0, 0);
66619e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata	return SWS_OK;
66719e74b5815987bb4260351bc1e5ef4a1ea08b1b4Petr Machata}
668427a43ee9972763993a1241815d56921f30623efPetr Machata
669427a43ee9972763993a1241815d56921f30623efPetr Machatasize_t
670427a43ee9972763993a1241815d56921f30623efPetr Machataarch_type_sizeof(struct process *proc, struct arg_type_info *info)
671427a43ee9972763993a1241815d56921f30623efPetr Machata{
672427a43ee9972763993a1241815d56921f30623efPetr Machata	if (proc == NULL)
673427a43ee9972763993a1241815d56921f30623efPetr Machata		return (size_t)-2;
674427a43ee9972763993a1241815d56921f30623efPetr Machata
675427a43ee9972763993a1241815d56921f30623efPetr Machata	switch (info->type) {
676427a43ee9972763993a1241815d56921f30623efPetr Machata	case ARGTYPE_VOID:
677427a43ee9972763993a1241815d56921f30623efPetr Machata		return 0;
678427a43ee9972763993a1241815d56921f30623efPetr Machata
679427a43ee9972763993a1241815d56921f30623efPetr Machata	case ARGTYPE_CHAR:
680427a43ee9972763993a1241815d56921f30623efPetr Machata		return 1;
681427a43ee9972763993a1241815d56921f30623efPetr Machata
682427a43ee9972763993a1241815d56921f30623efPetr Machata	case ARGTYPE_SHORT:
683427a43ee9972763993a1241815d56921f30623efPetr Machata	case ARGTYPE_USHORT:
684427a43ee9972763993a1241815d56921f30623efPetr Machata		return 2;
685427a43ee9972763993a1241815d56921f30623efPetr Machata
686427a43ee9972763993a1241815d56921f30623efPetr Machata	case ARGTYPE_INT:
687427a43ee9972763993a1241815d56921f30623efPetr Machata	case ARGTYPE_UINT:
688427a43ee9972763993a1241815d56921f30623efPetr Machata	case ARGTYPE_LONG:
689427a43ee9972763993a1241815d56921f30623efPetr Machata	case ARGTYPE_ULONG:
690427a43ee9972763993a1241815d56921f30623efPetr Machata	case ARGTYPE_POINTER:
691427a43ee9972763993a1241815d56921f30623efPetr Machata		return 4;
692427a43ee9972763993a1241815d56921f30623efPetr Machata
693427a43ee9972763993a1241815d56921f30623efPetr Machata	case ARGTYPE_FLOAT:
694427a43ee9972763993a1241815d56921f30623efPetr Machata		return 4;
695427a43ee9972763993a1241815d56921f30623efPetr Machata	case ARGTYPE_DOUBLE:
696427a43ee9972763993a1241815d56921f30623efPetr Machata		return 8;
697427a43ee9972763993a1241815d56921f30623efPetr Machata
698427a43ee9972763993a1241815d56921f30623efPetr Machata	case ARGTYPE_ARRAY:
699427a43ee9972763993a1241815d56921f30623efPetr Machata	case ARGTYPE_STRUCT:
700427a43ee9972763993a1241815d56921f30623efPetr Machata		/* Use default value.  */
701427a43ee9972763993a1241815d56921f30623efPetr Machata		return (size_t)-2;
702427a43ee9972763993a1241815d56921f30623efPetr Machata
703427a43ee9972763993a1241815d56921f30623efPetr Machata	default:
704427a43ee9972763993a1241815d56921f30623efPetr Machata		assert(info->type != info->type);
705427a43ee9972763993a1241815d56921f30623efPetr Machata		abort();
706427a43ee9972763993a1241815d56921f30623efPetr Machata	}
707427a43ee9972763993a1241815d56921f30623efPetr Machata}
708427a43ee9972763993a1241815d56921f30623efPetr Machata
709427a43ee9972763993a1241815d56921f30623efPetr Machatasize_t
710427a43ee9972763993a1241815d56921f30623efPetr Machataarch_type_alignof(struct process *proc, struct arg_type_info *info)
711427a43ee9972763993a1241815d56921f30623efPetr Machata{
712427a43ee9972763993a1241815d56921f30623efPetr Machata	return arch_type_sizeof(proc, info);
713427a43ee9972763993a1241815d56921f30623efPetr Machata}
714