xref: /openbmc/linux/arch/alpha/kernel/ptrace.c (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
1  // SPDX-License-Identifier: GPL-2.0
2  /* ptrace.c */
3  /* By Ross Biro 1/23/92 */
4  /* edited by Linus Torvalds */
5  /* mangled further by Bob Manson (manson@santafe.edu) */
6  /* more mutilation by David Mosberger (davidm@azstarnet.com) */
7  
8  #include <linux/kernel.h>
9  #include <linux/sched.h>
10  #include <linux/sched/task_stack.h>
11  #include <linux/mm.h>
12  #include <linux/smp.h>
13  #include <linux/errno.h>
14  #include <linux/ptrace.h>
15  #include <linux/user.h>
16  #include <linux/security.h>
17  #include <linux/signal.h>
18  #include <linux/audit.h>
19  
20  #include <linux/uaccess.h>
21  #include <asm/fpu.h>
22  
23  #include "proto.h"
24  
25  #define DEBUG	DBG_MEM
26  #undef DEBUG
27  
28  #ifdef DEBUG
29  enum {
30  	DBG_MEM		= (1<<0),
31  	DBG_BPT		= (1<<1),
32  	DBG_MEM_ALL	= (1<<2)
33  };
34  #define DBG(fac,args)	{if ((fac) & DEBUG) printk args;}
35  #else
36  #define DBG(fac,args)
37  #endif
38  
39  #define BREAKINST	0x00000080	/* call_pal bpt */
40  
41  /*
42   * does not yet catch signals sent when the child dies.
43   * in exit.c or in signal.c.
44   */
45  
46  /*
47   * Processes always block with the following stack-layout:
48   *
49   *  +================================+ <---- task + 2*PAGE_SIZE
50   *  | PALcode saved frame (ps, pc,   | ^
51   *  | gp, a0, a1, a2)		     | |
52   *  +================================+ | struct pt_regs
53   *  |	        		     | |
54   *  | frame generated by SAVE_ALL    | |
55   *  |	        		     | v
56   *  +================================+
57   *  |	        		     | ^
58   *  | frame saved by do_switch_stack | | struct switch_stack
59   *  |	        		     | v
60   *  +================================+
61   */
62  
63  /*
64   * The following table maps a register index into the stack offset at
65   * which the register is saved.  Register indices are 0-31 for integer
66   * regs, 32-63 for fp regs, and 64 for the pc.  Notice that sp and
67   * zero have no stack-slot and need to be treated specially (see
68   * get_reg/put_reg below).
69   */
70  enum {
71  	REG_R0 = 0, REG_F0 = 32, REG_FPCR = 63, REG_PC = 64
72  };
73  
74  #define PT_REG(reg) \
75    (PAGE_SIZE*2 - sizeof(struct pt_regs) + offsetof(struct pt_regs, reg))
76  
77  #define SW_REG(reg) \
78   (PAGE_SIZE*2 - sizeof(struct pt_regs) - sizeof(struct switch_stack) \
79    + offsetof(struct switch_stack, reg))
80  
81  #define FP_REG(reg) (offsetof(struct thread_info, reg))
82  
83  static int regoff[] = {
84  	PT_REG(	   r0), PT_REG(	   r1), PT_REG(	   r2), PT_REG(	  r3),
85  	PT_REG(	   r4), PT_REG(	   r5), PT_REG(	   r6), PT_REG(	  r7),
86  	PT_REG(	   r8), SW_REG(	   r9), SW_REG(	  r10), SW_REG(	 r11),
87  	SW_REG(	  r12), SW_REG(	  r13), SW_REG(	  r14), SW_REG(	 r15),
88  	PT_REG(	  r16), PT_REG(	  r17), PT_REG(	  r18), PT_REG(	 r19),
89  	PT_REG(	  r20), PT_REG(	  r21), PT_REG(	  r22), PT_REG(	 r23),
90  	PT_REG(	  r24), PT_REG(	  r25), PT_REG(	  r26), PT_REG(	 r27),
91  	PT_REG(	  r28), PT_REG(	   gp),		   -1,		   -1,
92  	FP_REG(fp[ 0]), FP_REG(fp[ 1]), FP_REG(fp[ 2]), FP_REG(fp[ 3]),
93  	FP_REG(fp[ 4]), FP_REG(fp[ 5]), FP_REG(fp[ 6]), FP_REG(fp[ 7]),
94  	FP_REG(fp[ 8]), FP_REG(fp[ 9]), FP_REG(fp[10]), FP_REG(fp[11]),
95  	FP_REG(fp[12]), FP_REG(fp[13]), FP_REG(fp[14]), FP_REG(fp[15]),
96  	FP_REG(fp[16]), FP_REG(fp[17]), FP_REG(fp[18]), FP_REG(fp[19]),
97  	FP_REG(fp[20]), FP_REG(fp[21]), FP_REG(fp[22]), FP_REG(fp[23]),
98  	FP_REG(fp[24]), FP_REG(fp[25]), FP_REG(fp[26]), FP_REG(fp[27]),
99  	FP_REG(fp[28]), FP_REG(fp[29]), FP_REG(fp[30]), FP_REG(fp[31]),
100  	PT_REG(	   pc)
101  };
102  
103  static unsigned long zero;
104  
105  /*
106   * Get address of register REGNO in task TASK.
107   */
108  static unsigned long *
get_reg_addr(struct task_struct * task,unsigned long regno)109  get_reg_addr(struct task_struct * task, unsigned long regno)
110  {
111  	unsigned long *addr;
112  
113  	if (regno == 30) {
114  		addr = &task_thread_info(task)->pcb.usp;
115  	} else if (regno == 65) {
116  		addr = &task_thread_info(task)->pcb.unique;
117  	} else if (regno == 31 || regno > 65) {
118  		zero = 0;
119  		addr = &zero;
120  	} else {
121  		addr = task_stack_page(task) + regoff[regno];
122  	}
123  	return addr;
124  }
125  
126  /*
127   * Get contents of register REGNO in task TASK.
128   */
129  static unsigned long
get_reg(struct task_struct * task,unsigned long regno)130  get_reg(struct task_struct * task, unsigned long regno)
131  {
132  	/* Special hack for fpcr -- combine hardware and software bits.  */
133  	if (regno == 63) {
134  		unsigned long fpcr = *get_reg_addr(task, regno);
135  		unsigned long swcr
136  		  = task_thread_info(task)->ieee_state & IEEE_SW_MASK;
137  		swcr = swcr_update_status(swcr, fpcr);
138  		return fpcr | swcr;
139  	}
140  	return *get_reg_addr(task, regno);
141  }
142  
143  /*
144   * Write contents of register REGNO in task TASK.
145   */
146  static int
put_reg(struct task_struct * task,unsigned long regno,unsigned long data)147  put_reg(struct task_struct *task, unsigned long regno, unsigned long data)
148  {
149  	if (regno == 63) {
150  		task_thread_info(task)->ieee_state
151  		  = ((task_thread_info(task)->ieee_state & ~IEEE_SW_MASK)
152  		     | (data & IEEE_SW_MASK));
153  		data = (data & FPCR_DYN_MASK) | ieee_swcr_to_fpcr(data);
154  	}
155  	*get_reg_addr(task, regno) = data;
156  	return 0;
157  }
158  
159  static inline int
read_int(struct task_struct * task,unsigned long addr,int * data)160  read_int(struct task_struct *task, unsigned long addr, int * data)
161  {
162  	int copied = access_process_vm(task, addr, data, sizeof(int),
163  			FOLL_FORCE);
164  	return (copied == sizeof(int)) ? 0 : -EIO;
165  }
166  
167  static inline int
write_int(struct task_struct * task,unsigned long addr,int data)168  write_int(struct task_struct *task, unsigned long addr, int data)
169  {
170  	int copied = access_process_vm(task, addr, &data, sizeof(int),
171  			FOLL_FORCE | FOLL_WRITE);
172  	return (copied == sizeof(int)) ? 0 : -EIO;
173  }
174  
175  /*
176   * Set breakpoint.
177   */
178  int
ptrace_set_bpt(struct task_struct * child)179  ptrace_set_bpt(struct task_struct * child)
180  {
181  	int displ, i, res, reg_b, nsaved = 0;
182  	unsigned int insn, op_code;
183  	unsigned long pc;
184  
185  	pc  = get_reg(child, REG_PC);
186  	res = read_int(child, pc, (int *) &insn);
187  	if (res < 0)
188  		return res;
189  
190  	op_code = insn >> 26;
191  	if (op_code >= 0x30) {
192  		/*
193  		 * It's a branch: instead of trying to figure out
194  		 * whether the branch will be taken or not, we'll put
195  		 * a breakpoint at either location.  This is simpler,
196  		 * more reliable, and probably not a whole lot slower
197  		 * than the alternative approach of emulating the
198  		 * branch (emulation can be tricky for fp branches).
199  		 */
200  		displ = ((s32)(insn << 11)) >> 9;
201  		task_thread_info(child)->bpt_addr[nsaved++] = pc + 4;
202  		if (displ)		/* guard against unoptimized code */
203  			task_thread_info(child)->bpt_addr[nsaved++]
204  			  = pc + 4 + displ;
205  		DBG(DBG_BPT, ("execing branch\n"));
206  	} else if (op_code == 0x1a) {
207  		reg_b = (insn >> 16) & 0x1f;
208  		task_thread_info(child)->bpt_addr[nsaved++] = get_reg(child, reg_b);
209  		DBG(DBG_BPT, ("execing jump\n"));
210  	} else {
211  		task_thread_info(child)->bpt_addr[nsaved++] = pc + 4;
212  		DBG(DBG_BPT, ("execing normal insn\n"));
213  	}
214  
215  	/* install breakpoints: */
216  	for (i = 0; i < nsaved; ++i) {
217  		res = read_int(child, task_thread_info(child)->bpt_addr[i],
218  			       (int *) &insn);
219  		if (res < 0)
220  			return res;
221  		task_thread_info(child)->bpt_insn[i] = insn;
222  		DBG(DBG_BPT, ("    -> next_pc=%lx\n",
223  			      task_thread_info(child)->bpt_addr[i]));
224  		res = write_int(child, task_thread_info(child)->bpt_addr[i],
225  				BREAKINST);
226  		if (res < 0)
227  			return res;
228  	}
229  	task_thread_info(child)->bpt_nsaved = nsaved;
230  	return 0;
231  }
232  
233  /*
234   * Ensure no single-step breakpoint is pending.  Returns non-zero
235   * value if child was being single-stepped.
236   */
237  int
ptrace_cancel_bpt(struct task_struct * child)238  ptrace_cancel_bpt(struct task_struct * child)
239  {
240  	int i, nsaved = task_thread_info(child)->bpt_nsaved;
241  
242  	task_thread_info(child)->bpt_nsaved = 0;
243  
244  	if (nsaved > 2) {
245  		printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
246  		nsaved = 2;
247  	}
248  
249  	for (i = 0; i < nsaved; ++i) {
250  		write_int(child, task_thread_info(child)->bpt_addr[i],
251  			  task_thread_info(child)->bpt_insn[i]);
252  	}
253  	return (nsaved != 0);
254  }
255  
user_enable_single_step(struct task_struct * child)256  void user_enable_single_step(struct task_struct *child)
257  {
258  	/* Mark single stepping.  */
259  	task_thread_info(child)->bpt_nsaved = -1;
260  }
261  
user_disable_single_step(struct task_struct * child)262  void user_disable_single_step(struct task_struct *child)
263  {
264  	ptrace_cancel_bpt(child);
265  }
266  
267  /*
268   * Called by kernel/ptrace.c when detaching..
269   *
270   * Make sure the single step bit is not set.
271   */
ptrace_disable(struct task_struct * child)272  void ptrace_disable(struct task_struct *child)
273  {
274  	user_disable_single_step(child);
275  }
276  
arch_ptrace(struct task_struct * child,long request,unsigned long addr,unsigned long data)277  long arch_ptrace(struct task_struct *child, long request,
278  		 unsigned long addr, unsigned long data)
279  {
280  	unsigned long tmp;
281  	size_t copied;
282  	long ret;
283  
284  	switch (request) {
285  	/* When I and D space are separate, these will need to be fixed.  */
286  	case PTRACE_PEEKTEXT: /* read word at location addr. */
287  	case PTRACE_PEEKDATA:
288  		copied = ptrace_access_vm(child, addr, &tmp, sizeof(tmp),
289  				FOLL_FORCE);
290  		ret = -EIO;
291  		if (copied != sizeof(tmp))
292  			break;
293  
294  		force_successful_syscall_return();
295  		ret = tmp;
296  		break;
297  
298  	/* Read register number ADDR. */
299  	case PTRACE_PEEKUSR:
300  		force_successful_syscall_return();
301  		ret = get_reg(child, addr);
302  		DBG(DBG_MEM, ("peek $%lu->%#lx\n", addr, ret));
303  		break;
304  
305  	/* When I and D space are separate, this will have to be fixed.  */
306  	case PTRACE_POKETEXT: /* write the word at location addr. */
307  	case PTRACE_POKEDATA:
308  		ret = generic_ptrace_pokedata(child, addr, data);
309  		break;
310  
311  	case PTRACE_POKEUSR: /* write the specified register */
312  		DBG(DBG_MEM, ("poke $%lu<-%#lx\n", addr, data));
313  		ret = put_reg(child, addr, data);
314  		break;
315  	default:
316  		ret = ptrace_request(child, request, addr, data);
317  		break;
318  	}
319  	return ret;
320  }
321  
syscall_trace_enter(void)322  asmlinkage unsigned long syscall_trace_enter(void)
323  {
324  	unsigned long ret = 0;
325  	struct pt_regs *regs = current_pt_regs();
326  	if (test_thread_flag(TIF_SYSCALL_TRACE) &&
327  	    ptrace_report_syscall_entry(current_pt_regs()))
328  		ret = -1UL;
329  	audit_syscall_entry(regs->r0, regs->r16, regs->r17, regs->r18, regs->r19);
330  	return ret ?: current_pt_regs()->r0;
331  }
332  
333  asmlinkage void
syscall_trace_leave(void)334  syscall_trace_leave(void)
335  {
336  	audit_syscall_exit(current_pt_regs());
337  	if (test_thread_flag(TIF_SYSCALL_TRACE))
338  		ptrace_report_syscall_exit(current_pt_regs(), 0);
339  }
340