![Christoph Hellwig](/assets/img/avatar_default.png)
While in theory user_enable_single_step/user_disable_single_step/ user_enable_blockstep could also be provided as an inline or macro there's no good reason to do so, and having the prototype in one places keeps code size and confusion down. Roland said: The original thought there was that user_enable_single_step() et al might well be only an instruction or three on a sane machine (as if we have any of those!), and since there is only one call site inlining would be beneficial. But I agree that there is no strong reason to care about inlining it. As to the arch changes, there is only one thought I'd add to the record. It was always my thinking that for an arch where PTRACE_SINGLESTEP does text-modifying breakpoint insertion, user_enable_single_step() should not be provided. That is, arch_has_single_step()=>true means that there is an arch facility with "pure" semantics that does not have any unexpected side effects. Inserting a breakpoint might do very unexpected strange things in multi-threaded situations. Aside from that, it is a peculiar side effect that user_{enable,disable}_single_step() should cause COW de-sharing of text pages and so forth. For PTRACE_SINGLESTEP, all these peculiarities are the status quo ante for that arch, so having arch_ptrace() itself do those is one thing. But for building other things in the future, it is nicer to have a uniform "pure" semantics that arch-independent code can expect. OTOH, all such arch issues are really up to the arch maintainer. As of today, there is nothing but ptrace using user_enable_single_step() et al so it's a distinction without a practical difference. If/when there are other facilities that use user_enable_single_step() and might care, the affected arch's can revisit the question when someone cares about the quality of the arch support for said new facility. Signed-off-by: Christoph Hellwig <hch@lst.de> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Roland McGrath <roland@redhat.com> Acked-by: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
97 lines
2.4 KiB
C
97 lines
2.4 KiB
C
#ifndef _ASM_SCORE_PTRACE_H
|
|
#define _ASM_SCORE_PTRACE_H
|
|
|
|
#define PTRACE_GETREGS 12
|
|
#define PTRACE_SETREGS 13
|
|
|
|
#define PC 32
|
|
#define CONDITION 33
|
|
#define ECR 34
|
|
#define EMA 35
|
|
#define CEH 36
|
|
#define CEL 37
|
|
#define COUNTER 38
|
|
#define LDCR 39
|
|
#define STCR 40
|
|
#define PSR 41
|
|
|
|
#define SINGLESTEP16_INSN 0x7006
|
|
#define SINGLESTEP32_INSN 0x840C8000
|
|
#define BREAKPOINT16_INSN 0x7002 /* work on SPG300 */
|
|
#define BREAKPOINT32_INSN 0x84048000 /* work on SPG300 */
|
|
|
|
/* Define instruction mask */
|
|
#define INSN32_MASK 0x80008000
|
|
|
|
#define J32 0x88008000 /* 1_00010_0000000000_1_000000000000000 */
|
|
#define J32M 0xFC008000 /* 1_11111_0000000000_1_000000000000000 */
|
|
|
|
#define B32 0x90008000 /* 1_00100_0000000000_1_000000000000000 */
|
|
#define B32M 0xFC008000
|
|
#define BL32 0x90008001 /* 1_00100_0000000000_1_000000000000001 */
|
|
#define BL32M B32
|
|
#define BR32 0x80008008 /* 1_00000_0000000000_1_00000000_000100_0 */
|
|
#define BR32M 0xFFE0807E
|
|
#define BRL32 0x80008009 /* 1_00000_0000000000_1_00000000_000100_1 */
|
|
#define BRL32M BR32M
|
|
|
|
#define B32_SET (J32 | B32 | BL32 | BR32 | BRL32)
|
|
|
|
#define J16 0x3000 /* 0_011_....... */
|
|
#define J16M 0xF000
|
|
#define B16 0x4000 /* 0_100_....... */
|
|
#define B16M 0xF000
|
|
#define BR16 0x0004 /* 0_000.......0100 */
|
|
#define BR16M 0xF00F
|
|
#define B16_SET (J16 | B16 | BR16)
|
|
|
|
|
|
/*
|
|
* This struct defines the way the registers are stored on the stack during a
|
|
* system call/exception. As usual the registers k0/k1 aren't being saved.
|
|
*/
|
|
struct pt_regs {
|
|
unsigned long pad0[6]; /* stack arguments */
|
|
unsigned long orig_r4;
|
|
unsigned long orig_r7;
|
|
long is_syscall;
|
|
|
|
unsigned long regs[32];
|
|
|
|
unsigned long cel;
|
|
unsigned long ceh;
|
|
|
|
unsigned long sr0; /* cnt */
|
|
unsigned long sr1; /* lcr */
|
|
unsigned long sr2; /* scr */
|
|
|
|
unsigned long cp0_epc;
|
|
unsigned long cp0_ema;
|
|
unsigned long cp0_psr;
|
|
unsigned long cp0_ecr;
|
|
unsigned long cp0_condition;
|
|
};
|
|
|
|
#ifdef __KERNEL__
|
|
|
|
struct task_struct;
|
|
|
|
/*
|
|
* Does the process account for user or for system time?
|
|
*/
|
|
#define user_mode(regs) ((regs->cp0_psr & 8) == 8)
|
|
|
|
#define instruction_pointer(regs) ((unsigned long)(regs)->cp0_epc)
|
|
#define profile_pc(regs) instruction_pointer(regs)
|
|
|
|
extern void do_syscall_trace(struct pt_regs *regs, int entryexit);
|
|
extern int read_tsk_long(struct task_struct *, unsigned long, unsigned long *);
|
|
extern int read_tsk_short(struct task_struct *, unsigned long,
|
|
unsigned short *);
|
|
|
|
#define arch_has_single_step() (1)
|
|
|
|
#endif /* __KERNEL__ */
|
|
|
|
#endif /* _ASM_SCORE_PTRACE_H */
|