Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/compat/linux/arch/mips Initial support for running Linux...
details: https://anonhg.NetBSD.org/src/rev/cbe2264e815b
branches: trunk
changeset: 515362:cbe2264e815b
user: manu <manu%NetBSD.org@localhost>
date: Sat Sep 22 21:19:10 2001 +0000
description:
Initial support for running Linux binaries on the Mips. Both static and
dynamic binaries work on 32 bit mips. Signals are completely broken yet,
and ptrace is not supported.
diffstat:
sys/compat/linux/arch/mips/files.linux_mips | 18 +
sys/compat/linux/arch/mips/linux_machdep.c | 370 ++++++++++++++++++++++++++++
sys/compat/linux/arch/mips/linux_ptrace.c | 71 +++++
3 files changed, 459 insertions(+), 0 deletions(-)
diffs (truncated from 471 to 300 lines):
diff -r e07c512d8a5c -r cbe2264e815b sys/compat/linux/arch/mips/files.linux_mips
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/compat/linux/arch/mips/files.linux_mips Sat Sep 22 21:19:10 2001 +0000
@@ -0,0 +1,18 @@
+# $NetBSD: files.linux_mips,v 1.1 2001/09/22 21:19:10 manu Exp $
+#
+# Config file description for mips-dependent Linux compat code.
+
+file compat/linux/arch/mips/linux_machdep.c compat_linux
+file compat/linux/arch/mips/linux_ptrace.c compat_linux
+file compat/linux/arch/mips/linux_syscalls.c compat_linux
+file compat/linux/arch/mips/linux_sysent.c compat_linux
+file compat/linux/arch/mips/linux_sigarray.c compat_linux
+
+file compat/linux/common/linux_pipe.c compat_linux
+file compat/linux/common/linux_ipccall.c compat_linux
+file compat/linux/common/linux_misc_notalpha.c compat_linux
+file compat/linux/common/linux_sig_notalpha.c compat_linux
+file compat/linux/common/linux_sigaction.c compat_linux
+file compat/linux/common/linux_socketcall.c compat_linux
+file compat/linux/common/linux_llseek.c compat_linux
+file compat/linux/common/linux_olduname.c compat_linux
diff -r e07c512d8a5c -r cbe2264e815b sys/compat/linux/arch/mips/linux_machdep.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/compat/linux/arch/mips/linux_machdep.c Sat Sep 22 21:19:10 2001 +0000
@@ -0,0 +1,370 @@
+/* $NetBSD: linux_machdep.c,v 1.1 2001/09/22 21:19:10 manu Exp $ */
+
+/*-
+ * Copyright (c) 1995, 2000, 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Frank van der Linden and Emmanuel Dreyfus.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/signalvar.h>
+#include <sys/kernel.h>
+#include <sys/map.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/buf.h>
+#include <sys/reboot.h>
+#include <sys/conf.h>
+#include <sys/exec.h>
+#include <sys/file.h>
+#include <sys/callout.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/msgbuf.h>
+#include <sys/mount.h>
+#include <sys/vnode.h>
+#include <sys/device.h>
+#include <sys/syscallargs.h>
+#include <sys/filedesc.h>
+#include <sys/exec_elf.h>
+#include <sys/disklabel.h>
+#include <sys/ioctl.h>
+#include <miscfs/specfs/specdev.h>
+
+#include <compat/linux/common/linux_types.h>
+#include <compat/linux/common/linux_signal.h>
+#include <compat/linux/common/linux_util.h>
+#include <compat/linux/common/linux_ioctl.h>
+#include <compat/linux/common/linux_hdio.h>
+#include <compat/linux/common/linux_exec.h>
+#include <compat/linux/common/linux_machdep.h>
+
+#include <compat/linux/linux_syscallargs.h>
+
+#include <machine/cpu.h>
+#include <machine/psl.h>
+#include <machine/reg.h>
+#include <machine/regnum.h>
+#include <machine/vmparam.h>
+#include <machine/locore.h>
+
+/*
+ * To see whether wscons is configured (for virtual console ioctl calls).
+ */
+#if defined(_KERNEL_OPT)
+#include "wsdisplay.h"
+#endif
+#if (NWSDISPLAY > 0)
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsdisplay_usl_io.h>
+#endif
+
+/*
+ * Set set up registers on exec.
+ * XXX not used at the moment since in sys/kern/exec_conf, LINUX_COMPAT
+ * entry uses NetBSD's native setregs instead of linux_setregs
+ */
+void
+linux_setregs(p, pack, stack)
+ struct proc *p;
+ struct exec_package *pack;
+ u_long stack;
+{
+ setregs(p, pack, stack);
+ return;
+}
+
+/*
+ * Send an interrupt to process.
+ *
+ * Adapted from sys/arch/mips/mips/mips_machdep.c
+ *
+ * XXX Does not work well yet with RT signals
+ *
+ */
+
+void
+linux_sendsig(catcher, sig, mask, code) /* XXX Check me */
+ sig_t catcher;
+ int sig;
+ sigset_t *mask;
+ u_long code;
+{
+ struct proc *p = curproc;
+ struct linux_sigframe *fp;
+ struct frame *f;
+ int i,onstack;
+ struct linux_sigframe sf;
+
+ printf("linux_sendsig()\n");
+ f = (struct frame *)p->p_md.md_regs;
+ printf("f = %p\n", f);
+
+ /*
+ * Do we need to jump onto the signal stack?
+ */
+ onstack =
+ (p->p_sigctx.ps_sigstk.ss_flags & (SS_DISABLE | SS_ONSTACK)) == 0 &&
+ (SIGACTION(p, sig).sa_flags & SA_ONSTACK) != 0;
+
+ /*
+ * Signal stack is broken (see at the end of linux_sigreturn), so we do
+ * not use it yet. XXX fix this.
+ */
+ onstack=0;
+
+ /*
+ * Allocate space for the signal handler context.
+ */
+ if (onstack)
+ fp = (struct linux_sigframe *)
+ ((caddr_t)p->p_sigctx.ps_sigstk.ss_sp
+ + p->p_sigctx.ps_sigstk.ss_size);
+ else
+ /* cast for _MIPS_BSD_API == _MIPS_BSD_API_LP32_64CLEAN case */
+ fp = (struct linux_sigframe *)(u_int32_t)f->f_regs[SP];
+
+ printf("fp = %p, sf = %p\n", fp, &sf);
+ /* Build stack frame for signal trampoline. */
+ memset(&sf, 0, sizeof sf);
+ sf.lsf_ass[0] = 0; /* XXX */
+ sf.lsf_ass[1] = 0;
+ sf.lsf_code[0] = 0x24020000; /* li v0, __NR_sigreturn */
+ sf.lsf_code[0] = 0x0000000c; /* syscall */
+ native_to_linux_sigset(mask, &sf.lsf_mask);
+ for (i=0; i<32; i++)
+ sf.lsf_sc.lsc_regs[i] = f->f_regs[i];
+ sf.lsf_sc.lsc_mdhi = f->f_regs[MULHI];
+ sf.lsf_sc.lsc_mdlo = f->f_regs[MULLO];
+ sf.lsf_sc.lsc_pc = f->f_regs[PC];
+ sf.lsf_sc.lsc_status = 0; /* XXX */
+ sf.lsf_sc.lsc_ownedfp = 0; /* XXX */
+ sf.lsf_sc.lsc_fpc_csr = f->f_regs[SR];
+ sf.lsf_sc.lsc_fpc_eir = f->f_regs[RA]; /* XXX */
+ sf.lsf_sc.lsc_cause = f->f_regs[CAUSE];
+ sf.lsf_sc.lsc_badvaddr = f->f_regs[BADVADDR]; /* XXX */
+
+
+ /*
+ * Save signal stack. XXX broken
+ */
+ /* kregs.sc_onstack = p->p_sigctx.ps_sigstk.ss_flags & SS_ONSTACK; */
+
+ /*
+ * Install the sigframe onto the stack
+ */
+ fp -= sizeof(struct linux_sigframe);
+ if (copyout(&sf, fp, sizeof(sf)) != 0) {
+ /*
+ * Process has trashed its stack; give it an illegal
+ * instruction to halt it in its tracks.
+ */
+ sigexit(p, SIGILL);
+ /* NOTREACHED */
+ }
+
+ /* Set up the registers to return to sigcode. */
+ f->f_regs[A0] = native_to_linux_sig[sig];
+ f->f_regs[A1] = 0;
+ f->f_regs[A2] = (int)&fp->lsf_sc;
+
+ f->f_regs[SP] = (int)fp;
+ f->f_regs[RA] = (int)fp->lsf_code;
+ f->f_regs[T9] = (int)catcher;
+ f->f_regs[PC] = (int)catcher;
+
+ /* Signal trampoline code is at base of user stack. */
+
+ /* Remember that we're now on the signal stack. */
+ if (onstack)
+ p->p_sigctx.ps_sigstk.ss_flags |= SS_ONSTACK;
+
+ return;
+}
+
+/*
+ * System call to cleanup state after a signal
+ * has been taken. Reset signal mask and
+ * stack state from context left by sendsig (above).
+ */
+int
+linux_sys_sigreturn(p, v, retval)
+ struct proc *p;
+ void *v;
+ register_t *retval;
+{
+ struct linux_sys_sigreturn_args /* {
+ syscallarg(struct linux_pt_regs) regs;
+ } */ *uap = v;
+ struct linux_pt_regs regs, kregs;
+ struct linux_sigframe *sf, ksf;
+ struct frame *f;
+ sigset_t mask;
+ int i, error;
+
+ printf("linux_sys_sigreturn()\n");
+ /*
+ * The trampoline code hands us the context.
+ * It is unsafe to keep track of it ourselves, in the event that a
+ * program jumps out of a signal handler.
+ */
+ regs = SCARG(uap, regs);
+
+ kregs = regs;
+ /* if ((error = copyin(regs, &kregs, sizeof(kregs))) != 0)
+ return (error); */
+
+ sf = (struct linux_sigframe *)kregs.lregs[29];
+ if ((error = copyin(sf, &ksf, sizeof(ksf))) != 0)
+ return (error);
+
+ /* Restore the register context. */
+ f = (struct frame *)p->p_md.md_regs;
+ printf("sf = %p, f = %p\n", sf, f);
+ for (i=0; i<32; i++)
+ f->f_regs[i] = kregs.lregs[i];
+ f->f_regs[MULLO] = kregs.llo;
+ f->f_regs[MULHI] = kregs.lhi;
+ f->f_regs[PC] = kregs.lcp0_spc;
+ f->f_regs[BADVADDR] = kregs.lcp0_badvaddr;
+ f->f_regs[CAUSE] = kregs.lcp0_cause;
+
+ /* Restore signal stack. */
+ p->p_sigctx.ps_sigstk.ss_flags &= ~SS_ONSTACK;
+
+ /* Restore signal mask. */
+ linux_to_native_sigset((linux_sigset_t *)&ksf.lsf_mask, &mask);
+ (void)sigprocmask1(p, SIG_SETMASK, &mask, 0);
+
+ return (EJUSTRETURN);
+}
+
+
+int
Home |
Main Index |
Thread Index |
Old Index