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