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