1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1992 Terrence R. Lambert.
5 * Copyright (c) 1982, 1987, 1990 The Regents of the University of California.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * William Jolitz.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 *	from: @(#)machdep.c	7.4 (Berkeley) 6/3/91
36 *	from: src/sys/i386/i386/machdep.c,v 1.385.2.3 2000/05/10 02:04:46 obrien
37 *	JNPR: pm_machdep.c,v 1.9.2.1 2007/08/16 15:59:10 girish
38 */
39
40#include <sys/cdefs.h>
41__FBSDID("$FreeBSD$");
42
43#include <sys/types.h>
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/sysent.h>
47#include <sys/proc.h>
48#include <sys/signalvar.h>
49#include <sys/exec.h>
50#include <sys/imgact.h>
51#include <sys/ucontext.h>
52#include <sys/lock.h>
53#include <sys/syscallsubr.h>
54#include <sys/sysproto.h>
55#include <sys/ptrace.h>
56#include <sys/syslog.h>
57#include <vm/vm.h>
58#include <vm/pmap.h>
59#include <vm/vm_map.h>
60#include <vm/vm_extern.h>
61#include <sys/user.h>
62#include <sys/uio.h>
63#include <machine/abi.h>
64#include <machine/cpuinfo.h>
65#include <machine/reg.h>
66#include <machine/md_var.h>
67#include <machine/sigframe.h>
68#include <machine/tls.h>
69#include <machine/vmparam.h>
70#include <sys/vnode.h>
71#include <fs/pseudofs/pseudofs.h>
72#include <fs/procfs/procfs.h>
73
74#define	UCONTEXT_MAGIC	0xACEDBADE
75
76/*
77 * Send an interrupt to process.
78 *
79 * Stack is set up to allow sigcode stored
80 * at top to call routine, followed by kcall
81 * to sigreturn routine below.	After sigreturn
82 * resets the signal mask, the stack, and the
83 * frame pointer, it returns to the user
84 * specified pc, psl.
85 */
86void
87sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
88{
89	struct proc *p;
90	struct thread *td;
91	struct trapframe *regs;
92	struct sigacts *psp;
93	struct sigframe sf, *sfp;
94	int sig;
95	int oonstack;
96
97	td = curthread;
98	p = td->td_proc;
99	PROC_LOCK_ASSERT(p, MA_OWNED);
100	sig = ksi->ksi_signo;
101	psp = p->p_sigacts;
102	mtx_assert(&psp->ps_mtx, MA_OWNED);
103
104	regs = td->td_frame;
105	oonstack = sigonstack(regs->sp);
106
107	/* save user context */
108	bzero(&sf, sizeof(struct sigframe));
109	sf.sf_uc.uc_sigmask = *mask;
110	sf.sf_uc.uc_stack = td->td_sigstk;
111	sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
112	sf.sf_uc.uc_mcontext.mc_pc = regs->pc;
113	sf.sf_uc.uc_mcontext.mullo = regs->mullo;
114	sf.sf_uc.uc_mcontext.mulhi = regs->mulhi;
115	sf.sf_uc.uc_mcontext.mc_tls = td->td_md.md_tls;
116	sf.sf_uc.uc_mcontext.mc_regs[0] = UCONTEXT_MAGIC;  /* magic number */
117	bcopy((void *)&regs->ast, (void *)&sf.sf_uc.uc_mcontext.mc_regs[1],
118	    sizeof(sf.sf_uc.uc_mcontext.mc_regs) - sizeof(register_t));
119	sf.sf_uc.uc_mcontext.mc_fpused = td->td_md.md_flags & MDTD_FPUSED;
120	if (sf.sf_uc.uc_mcontext.mc_fpused) {
121		/* if FPU has current state, save it first */
122		if (td == PCPU_GET(fpcurthread))
123			MipsSaveCurFPState(td);
124		bcopy((void *)&td->td_frame->f0,
125		    (void *)sf.sf_uc.uc_mcontext.mc_fpregs,
126		    sizeof(sf.sf_uc.uc_mcontext.mc_fpregs));
127	}
128
129	/* Allocate and validate space for the signal handler context. */
130	if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
131	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
132		sfp = (struct sigframe *)(((uintptr_t)td->td_sigstk.ss_sp +
133		    td->td_sigstk.ss_size - sizeof(struct sigframe))
134		    & ~(STACK_ALIGN - 1));
135	} else
136		sfp = (struct sigframe *)((vm_offset_t)(regs->sp -
137		    sizeof(struct sigframe)) & ~(STACK_ALIGN - 1));
138
139	/* Build the argument list for the signal handler. */
140	regs->a0 = sig;
141	regs->a2 = (register_t)(intptr_t)&sfp->sf_uc;
142	if (SIGISMEMBER(psp->ps_siginfo, sig)) {
143		/* Signal handler installed with SA_SIGINFO. */
144		regs->a1 = (register_t)(intptr_t)&sfp->sf_si;
145		/* sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; */
146
147		/* fill siginfo structure */
148		sf.sf_si = ksi->ksi_info;
149		sf.sf_si.si_signo = sig;
150		sf.sf_si.si_code = ksi->ksi_code;
151		sf.sf_si.si_addr = (void*)(intptr_t)regs->badvaddr;
152	} else {
153		/* Old FreeBSD-style arguments. */
154		regs->a1 = ksi->ksi_code;
155		regs->a3 = regs->badvaddr;
156		/* sf.sf_ahu.sf_handler = catcher; */
157	}
158
159	mtx_unlock(&psp->ps_mtx);
160	PROC_UNLOCK(p);
161
162	/*
163	 * Copy the sigframe out to the user's stack.
164	 */
165	if (copyout(&sf, sfp, sizeof(struct sigframe)) != 0) {
166		/*
167		 * Something is wrong with the stack pointer.
168		 * ...Kill the process.
169		 */
170		PROC_LOCK(p);
171		sigexit(td, SIGILL);
172	}
173
174	regs->pc = (register_t)(intptr_t)catcher;
175	regs->t9 = (register_t)(intptr_t)catcher;
176	regs->sp = (register_t)(intptr_t)sfp;
177	/*
178	 * Signal trampoline code is at base of user stack.
179	 */
180	regs->ra = (register_t)(intptr_t)PS_STRINGS - *(p->p_sysent->sv_szsigcode);
181	PROC_LOCK(p);
182	mtx_lock(&psp->ps_mtx);
183}
184
185/*
186 * System call to cleanup state after a signal
187 * has been taken.  Reset signal mask and
188 * stack state from context left by sendsig (above).
189 * Return to previous pc as specified by
190 * context left by sendsig.
191 */
192int
193sys_sigreturn(struct thread *td, struct sigreturn_args *uap)
194{
195	ucontext_t uc;
196	int error;
197
198	error = copyin(uap->sigcntxp, &uc, sizeof(uc));
199	if (error != 0)
200	    return (error);
201
202	error = set_mcontext(td, &uc.uc_mcontext);
203	if (error != 0)
204		return (error);
205
206	kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0);
207
208	return (EJUSTRETURN);
209}
210
211int
212ptrace_set_pc(struct thread *td, unsigned long addr)
213{
214	td->td_frame->pc = (register_t) addr;
215	return 0;
216}
217
218static int
219ptrace_read_int(struct thread *td, uintptr_t addr, int *v)
220{
221
222	if (proc_readmem(td, td->td_proc, addr, v, sizeof(*v)) != sizeof(*v))
223		return (EFAULT);
224	return (0);
225}
226
227static int
228ptrace_write_int(struct thread *td, uintptr_t addr, int v)
229{
230
231	if (proc_writemem(td, td->td_proc, addr, &v, sizeof(v)) != sizeof(v))
232		return (EFAULT);
233	return (0);
234}
235
236int
237ptrace_single_step(struct thread *td)
238{
239	uintptr_t va;
240	struct trapframe *locr0 = td->td_frame;
241	int error;
242	int bpinstr = MIPS_BREAK_SSTEP;
243	int curinstr;
244	struct proc *p;
245
246	p = td->td_proc;
247	PROC_UNLOCK(p);
248	/*
249	 * Fetch what's at the current location.
250	 */
251	error = ptrace_read_int(td, locr0->pc, &curinstr);
252	if (error)
253		goto out;
254
255	CTR3(KTR_PTRACE,
256	    "ptrace_single_step: tid %d, current instr at %#lx: %#08x",
257	    td->td_tid, locr0->pc, curinstr);
258
259	/* compute next address after current location */
260	if (locr0->cause & MIPS_CR_BR_DELAY) {
261		va = MipsEmulateBranch(locr0, locr0->pc, locr0->fsr,
262		    (uintptr_t)&curinstr);
263	} else {
264		va = locr0->pc + 4;
265	}
266	if (td->td_md.md_ss_addr) {
267		printf("SS %s (%d): breakpoint already set at %p (va %p)\n",
268		    p->p_comm, p->p_pid, (void *)td->td_md.md_ss_addr,
269		    (void *)va); /* XXX */
270		error = EFAULT;
271		goto out;
272	}
273	td->td_md.md_ss_addr = va;
274	/*
275	 * Fetch what's at the current location.
276	 */
277	error = ptrace_read_int(td, (off_t)va, &td->td_md.md_ss_instr);
278	if (error)
279		goto out;
280
281	/*
282	 * Store breakpoint instruction at the "next" location now.
283	 */
284	error = ptrace_write_int(td, va, bpinstr);
285
286	/*
287	 * The sync'ing of I & D caches is done by proc_rwmem()
288	 * through proc_writemem().
289	 */
290
291out:
292	PROC_LOCK(p);
293	if (error == 0)
294		CTR3(KTR_PTRACE,
295		    "ptrace_single_step: tid %d, break set at %#lx: (%#08x)",
296		    td->td_tid, va, td->td_md.md_ss_instr);
297	return (error);
298}
299
300
301void
302makectx(struct trapframe *tf, struct pcb *pcb)
303{
304
305	pcb->pcb_context[PCB_REG_RA] = tf->ra;
306	pcb->pcb_context[PCB_REG_PC] = tf->pc;
307	pcb->pcb_context[PCB_REG_SP] = tf->sp;
308}
309
310int
311fill_regs(struct thread *td, struct reg *regs)
312{
313	memcpy(regs, td->td_frame, sizeof(struct reg));
314	return (0);
315}
316
317int
318set_regs(struct thread *td, struct reg *regs)
319{
320	struct trapframe *f;
321	register_t sr;
322
323	f = (struct trapframe *) td->td_frame;
324	/*
325	 * Don't allow the user to change SR
326	 */
327	sr = f->sr;
328	memcpy(td->td_frame, regs, sizeof(struct reg));
329	f->sr = sr;
330	return (0);
331}
332
333int
334get_mcontext(struct thread *td, mcontext_t *mcp, int flags)
335{
336	struct trapframe *tp;
337
338	tp = td->td_frame;
339	PROC_LOCK(curthread->td_proc);
340	mcp->mc_onstack = sigonstack(tp->sp);
341	PROC_UNLOCK(curthread->td_proc);
342	bcopy((void *)&td->td_frame->zero, (void *)&mcp->mc_regs,
343	    sizeof(mcp->mc_regs));
344
345	mcp->mc_fpused = td->td_md.md_flags & MDTD_FPUSED;
346	if (mcp->mc_fpused) {
347		bcopy((void *)&td->td_frame->f0, (void *)&mcp->mc_fpregs,
348		    sizeof(mcp->mc_fpregs));
349	}
350	if (flags & GET_MC_CLEAR_RET) {
351		mcp->mc_regs[V0] = 0;
352		mcp->mc_regs[V1] = 0;
353		mcp->mc_regs[A3] = 0;
354	}
355
356	mcp->mc_pc = td->td_frame->pc;
357	mcp->mullo = td->td_frame->mullo;
358	mcp->mulhi = td->td_frame->mulhi;
359	mcp->mc_tls = td->td_md.md_tls;
360	return (0);
361}
362
363int
364set_mcontext(struct thread *td, mcontext_t *mcp)
365{
366	struct trapframe *tp;
367
368	tp = td->td_frame;
369	bcopy((void *)&mcp->mc_regs, (void *)&td->td_frame->zero,
370	    sizeof(mcp->mc_regs));
371
372	td->td_md.md_flags = mcp->mc_fpused & MDTD_FPUSED;
373	if (mcp->mc_fpused) {
374		bcopy((void *)&mcp->mc_fpregs, (void *)&td->td_frame->f0,
375		    sizeof(mcp->mc_fpregs));
376	}
377	td->td_frame->pc = mcp->mc_pc;
378	td->td_frame->mullo = mcp->mullo;
379	td->td_frame->mulhi = mcp->mulhi;
380	td->td_md.md_tls = mcp->mc_tls;
381	/* Dont let user to set any bits in status and cause registers. */
382
383	return (0);
384}
385
386int
387fill_fpregs(struct thread *td, struct fpreg *fpregs)
388{
389	if (td == PCPU_GET(fpcurthread))
390		MipsSaveCurFPState(td);
391	memcpy(fpregs, &td->td_frame->f0, sizeof(struct fpreg));
392	fpregs->r_regs[FIR_NUM] = cpuinfo.fpu_id;
393	return 0;
394}
395
396int
397set_fpregs(struct thread *td, struct fpreg *fpregs)
398{
399	if (PCPU_GET(fpcurthread) == td)
400		PCPU_SET(fpcurthread, (struct thread *)0);
401	memcpy(&td->td_frame->f0, fpregs, sizeof(struct fpreg));
402	return 0;
403}
404
405
406/*
407 * Clear registers on exec
408 * $sp is set to the stack pointer passed in.  $pc is set to the entry
409 * point given by the exec_package passed in, as is $t9 (used for PIC
410 * code by the MIPS elf abi).
411 */
412void
413exec_setregs(struct thread *td, struct image_params *imgp, u_long stack)
414{
415
416	bzero((caddr_t)td->td_frame, sizeof(struct trapframe));
417
418	td->td_frame->sp = ((register_t)stack) & ~(STACK_ALIGN - 1);
419
420	/*
421	 * If we're running o32 or n32 programs but have 64-bit registers,
422	 * GCC may use stack-relative addressing near the top of user
423	 * address space that, due to sign extension, will yield an
424	 * invalid address.  For instance, if sp is 0x7fffff00 then GCC
425	 * might do something like this to load a word from 0x7ffffff0:
426	 *
427	 * 	addu	sp, sp, 32768
428	 * 	lw	t0, -32528(sp)
429	 *
430	 * On systems with 64-bit registers, sp is sign-extended to
431	 * 0xffffffff80007f00 and the load is instead done from
432	 * 0xffffffff7ffffff0.
433	 *
434	 * To prevent this, we subtract 64K from the stack pointer here
435	 * for processes with 32-bit pointers.
436	 */
437#if defined(__mips_n32) || defined(__mips_n64)
438	if (!SV_PROC_FLAG(td->td_proc, SV_LP64))
439		td->td_frame->sp -= 65536;
440#endif
441
442	td->td_frame->pc = imgp->entry_addr & ~3;
443	td->td_frame->t9 = imgp->entry_addr & ~3; /* abicall req */
444	td->td_frame->sr = MIPS_SR_KSU_USER | MIPS_SR_EXL | MIPS_SR_INT_IE |
445	    (mips_rd_status() & MIPS_SR_INT_MASK);
446#if defined(__mips_n32)
447	td->td_frame->sr |= MIPS_SR_PX;
448#elif  defined(__mips_n64)
449	td->td_frame->sr |= MIPS_SR_PX | MIPS_SR_UX | MIPS_SR_KX;
450#endif
451	/*
452	 * FREEBSD_DEVELOPERS_FIXME:
453	 * Setup any other CPU-Specific registers (Not MIPS Standard)
454	 * and/or bits in other standard MIPS registers (if CPU-Specific)
455	 *  that are needed.
456	 */
457
458	/*
459	 * Set up arguments for the rtld-capable crt0:
460	 *	a0	stack pointer
461	 *	a1	rtld cleanup (filled in by dynamic loader)
462	 *	a2	rtld object (filled in by dynamic loader)
463	 *	a3	ps_strings
464	 */
465	td->td_frame->a0 = (register_t) stack;
466	td->td_frame->a1 = 0;
467	td->td_frame->a2 = 0;
468	td->td_frame->a3 = (register_t)imgp->ps_strings;
469
470	td->td_md.md_flags &= ~MDTD_FPUSED;
471	if (PCPU_GET(fpcurthread) == td)
472	    PCPU_SET(fpcurthread, (struct thread *)0);
473	td->td_md.md_ss_addr = 0;
474
475	td->td_md.md_tls_tcb_offset = TLS_TP_OFFSET + TLS_TCB_SIZE;
476}
477
478int
479ptrace_clear_single_step(struct thread *td)
480{
481	struct proc *p;
482	int error;
483
484	p = td->td_proc;
485	PROC_LOCK_ASSERT(p, MA_OWNED);
486	if (!td->td_md.md_ss_addr)
487		return EINVAL;
488
489	/*
490	 * Restore original instruction and clear BP
491	 */
492	PROC_UNLOCK(p);
493	CTR3(KTR_PTRACE,
494	    "ptrace_clear_single_step: tid %d, restore instr at %#lx: %#08x",
495	    td->td_tid, td->td_md.md_ss_addr, td->td_md.md_ss_instr);
496	error = ptrace_write_int(td, td->td_md.md_ss_addr,
497	    td->td_md.md_ss_instr);
498	PROC_LOCK(p);
499
500	/* The sync'ing of I & D caches is done by proc_rwmem(). */
501
502	if (error != 0) {
503		log(LOG_ERR,
504		    "SS %s %d: can't restore instruction at %p: %x\n",
505		    p->p_comm, p->p_pid, (void *)td->td_md.md_ss_addr,
506		    td->td_md.md_ss_instr);
507	}
508	td->td_md.md_ss_addr = 0;
509	return 0;
510}
511