aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAndrew Gallatin <gallatin@FreeBSD.org>1999-12-14 22:35:36 +0000
committerAndrew Gallatin <gallatin@FreeBSD.org>1999-12-14 22:35:36 +0000
commit32a8490d32d33364281a0cbef833189f612d8da5 (patch)
treecf7252397706985f3aca44b7da399ff0f787dc32 /sys
parentaf0f298122f7ba0bb626becc1ef9486d325082f9 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/alpha/osf1/Makefile11
-rw-r--r--sys/alpha/osf1/exec_ecoff.h195
-rw-r--r--sys/alpha/osf1/imgact_osf1.c259
-rw-r--r--sys/alpha/osf1/osf1.h274
-rw-r--r--sys/alpha/osf1/osf1_ioctl.c331
-rw-r--r--sys/alpha/osf1/osf1_misc.c1747
-rw-r--r--sys/alpha/osf1/osf1_mount.c391
-rw-r--r--sys/alpha/osf1/osf1_signal.c822
-rw-r--r--sys/alpha/osf1/osf1_signal.h105
-rw-r--r--sys/alpha/osf1/osf1_sysvec.c133
-rw-r--r--sys/alpha/osf1/osf1_util.h83
-rw-r--r--sys/alpha/osf1/syscalls.conf12
-rw-r--r--sys/alpha/osf1/syscalls.master392
-rw-r--r--sys/modules/osf1/Makefile26
-rw-r--r--sys/modules/osf1/osf1.846
-rw-r--r--sys/modules/osf1/osf1.sh36
16 files changed, 4863 insertions, 0 deletions
diff --git a/sys/alpha/osf1/Makefile b/sys/alpha/osf1/Makefile
new file mode 100644
index 000000000000..a161390da90c
--- /dev/null
+++ b/sys/alpha/osf1/Makefile
@@ -0,0 +1,11 @@
+# $FreeBSD$
+# Makefile for syscall tables
+
+all: osf1_sysent.c
+
+osf1_sysent.c osf1_syscall.h osf1_proto.h: ../../kern/makesyscalls.sh \
+ syscalls.master syscalls.conf
+ -mv -f osf1_sysent.c osf1_sysent.c.bak
+ -mv -f osf1_syscall.h osf1_syscall.h.bak
+ -mv -f osf1_proto.h osf1_proto.h.bak
+ sh ../../kern/makesyscalls.sh syscalls.master syscalls.conf
diff --git a/sys/alpha/osf1/exec_ecoff.h b/sys/alpha/osf1/exec_ecoff.h
new file mode 100644
index 000000000000..246fa48bde69
--- /dev/null
+++ b/sys/alpha/osf1/exec_ecoff.h
@@ -0,0 +1,195 @@
+/* $NetBSD: exec_ecoff.h,v 1.10 1996/09/26 22:39:14 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994 Adam Glass
+ * All rights reserved.
+ *
+ * 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 Adam Glass.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_EXEC_ECOFF_H_
+#define _SYS_EXEC_ECOFF_H_
+
+#define ECOFF_LDPGSZ 4096
+
+#define ECOFF_PAD \
+ u_short bldrev; /* XXX */
+
+#define ECOFF_MACHDEP \
+ u_int gprmask; \
+ u_int fprmask; \
+ u_long gp_value
+
+#define ECOFF_MAGIC_ALPHA 0603
+#define ECOFF_MAGIC_NETBSD_ALPHA 0605
+#define ECOFF_BADMAG(ep) ((ep)->f.f_magic != ECOFF_MAGIC_ALPHA)
+
+#define ECOFF_FLAG_EXEC 0002
+#define ECOFF_SEGMENT_ALIGNMENT(ep) \
+ (((ep)->f.f_flags & ECOFF_FLAG_EXEC) == 0 ? 8 : 16)
+
+struct ecoff_symhdr {
+ int16_t magic;
+ int16_t vstamp;
+ int32_t lineMax;
+ int32_t densenumMax;
+ int32_t procMax;
+ int32_t lsymMax;
+ int32_t optsymMax;
+ int32_t auxsymMax;
+ int32_t lstrMax;
+ int32_t estrMax;
+ int32_t fdMax;
+ int32_t rfdMax;
+ int32_t esymMax;
+ long linesize;
+ long cbLineOffset;
+ long cbDnOffset;
+ long cbPdOffset;
+ long cbSymOffset;
+ long cbOptOffset;
+ long cbAuxOffset;
+ long cbSsOffset;
+ long cbSsExtOffset;
+ long cbFdOffset;
+ long cbRfdOffset;
+ long cbExtOffset;
+};
+
+struct ecoff_extsym {
+ long es_value;
+ int es_strindex;
+ unsigned es_type:6;
+ unsigned es_class:5;
+ unsigned :1;
+ unsigned es_symauxindex:20;
+ unsigned es_jmptbl:1;
+ unsigned es_cmain:1;
+ unsigned es_weakext:1;
+ unsigned :29;
+ int es_indexfld;
+};
+
+
+struct ecoff_filehdr {
+ u_short f_magic; /* magic number */
+ u_short f_nscns; /* # of sections */
+ u_int f_timdat; /* time and date stamp */
+ u_long f_symptr; /* file offset of symbol table */
+ u_int f_nsyms; /* # of symbol table entries */
+ u_short f_opthdr; /* sizeof the optional header */
+ u_short f_flags; /* flags??? */
+};
+
+struct ecoff_aouthdr {
+ u_short magic;
+ u_short vstamp;
+ ECOFF_PAD
+ u_long tsize;
+ u_long dsize;
+ u_long bsize;
+ u_long entry;
+ u_long text_start;
+ u_long data_start;
+ u_long bss_start;
+ ECOFF_MACHDEP;
+};
+
+struct ecoff_scnhdr { /* needed for size info */
+ char s_name[8]; /* name */
+ u_long s_paddr; /* physical addr? for ROMing?*/
+ u_long s_vaddr; /* virtual addr? */
+ u_long s_size; /* size */
+ u_long s_scnptr; /* file offset of raw data */
+ u_long s_relptr; /* file offset of reloc data */
+ u_long s_lnnoptr; /* file offset of line data */
+ u_short s_nreloc; /* # of relocation entries */
+ u_short s_nlnno; /* # of line entries */
+ u_int s_flags; /* flags */
+};
+
+struct ecoff_exechdr {
+ struct ecoff_filehdr f;
+ struct ecoff_aouthdr a;
+};
+enum scnhdr_flags {
+ STYP_REG = 0x00, /* regular (alloc'ed, reloc'ed, loaded) */
+ STYP_DSECT = 0x01, /* dummy (reloc'd) */
+ STYP_NOLOAD = 0x02, /* no-load (reloc'd) */
+ STYP_GROUP = 0x04, /* grouped */
+ STYP_PAD = 0x08, /* padding (loaded) */
+ STYP_COPY = 0x10, /* ??? */
+ STYP_TEXT = 0x20, /* text */
+ STYP_DATA = 0x40, /* data */
+ STYP_BSS = 0x80, /* bss */
+ STYP_INFO = 0x200, /* comment (!loaded, !alloc'ed, !reloc'd) */
+ STYP_OVER = 0x400, /* overlay (!allocated, reloc'd, !loaded) */
+ STYP_LIB = 0x800 /* lists shared library files */
+};
+
+#define ECOFF_HDR_SIZE (sizeof(struct ecoff_exechdr))
+
+#define ECOFF_OMAGIC 0407
+#define ECOFF_NMAGIC 0410
+#define ECOFF_ZMAGIC 0413
+
+#define ECOFF_ROUND(value, by) \
+ (((value) + (by) - 1) & ~((by) - 1))
+
+#define ECOFF_BLOCK_ALIGN(ep, value) \
+ ((ep)->a.magic == ECOFF_ZMAGIC ? ECOFF_ROUND((value), ECOFF_LDPGSZ) : \
+ (value))
+
+#define ECOFF_TXTOFF(ep) \
+ ((ep)->a.magic == ECOFF_ZMAGIC ? 0 : \
+ ECOFF_ROUND(ECOFF_HDR_SIZE + (ep)->f.f_nscns * \
+ sizeof(struct ecoff_scnhdr), ECOFF_SEGMENT_ALIGNMENT(ep)))
+
+#define ECOFF_DATOFF(ep) \
+ (ECOFF_BLOCK_ALIGN((ep), ECOFF_TXTOFF(ep) + (ep)->a.tsize))
+
+#define ECOFF_SEGMENT_ALIGN(ep, value) \
+ (ECOFF_ROUND((value), ((ep)->a.magic == ECOFF_ZMAGIC ? ECOFF_LDPGSZ : \
+ ECOFF_SEGMENT_ALIGNMENT(ep))))
+
+typedef struct {
+ char *loader;
+ char exec_path[PATH_MAX];
+ char *executable;
+ struct nameidata *ndp;
+
+} Osf_Auxargs;
+
+#define OSF1_EXEC_NAME (1001)
+#define OSF1_LOADER_NAME (1002)
+#define OSF1_LOADER_FLAGS (1003)
+
+#define DYNAMIC_FLAG 0x3000
+#define DEFAULT_LOADER "/sbin/loader"
+
+#endif /* !_SYS_EXEC_ECOFF_H_ */
diff --git a/sys/alpha/osf1/imgact_osf1.c b/sys/alpha/osf1/imgact_osf1.c
new file mode 100644
index 000000000000..f88ab284d527
--- /dev/null
+++ b/sys/alpha/osf1/imgact_osf1.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 1998-1999 Andrew Gallatin
+ * All rights reserved.
+ *
+ * Based heavily on imgact_linux.c which is
+ * Copyright (c) 1994-1996 Søren Schmidt.
+ * Which in turn is based heavily on /sys/kern/imgact_aout.c which is:
+ * Copyright (c) 1993, David Greenman
+ *
+ * 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
+ * in this position and unchanged.
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/malloc.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mount.h>
+#include <sys/filedesc.h>
+#include <sys/fcntl.h>
+#include <sys/resourcevar.h>
+#include <sys/exec.h>
+#include <sys/mman.h>
+#include <sys/imgact.h>
+#include <sys/imgact_aout.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+#include <sys/lock.h>
+#include <sys/proc.h>
+#include <sys/pioctl.h>
+#include <sys/namei.h>
+#include <sys/sysent.h>
+#include <sys/shm.h>
+#include <sys/sysctl.h>
+#include <sys/vnode.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <vm/vm_extern.h>
+
+#include <alpha/osf1/exec_ecoff.h>
+extern struct sysentvec osf1_sysvec;
+
+#ifdef DEBUG
+#define DPRINTF(a) printf a;
+#else
+#define DPRINTF(a)
+#endif
+
+static int
+exec_osf1_imgact(struct image_params *imgp)
+{
+ int error;
+ int path_not_saved;
+ size_t bytes;
+ const struct ecoff_exechdr *execp;
+ const struct ecoff_aouthdr *eap;
+ struct vmspace *vmspace;
+ vm_offset_t baddr;
+ vm_offset_t bsize;
+ vm_offset_t bss_start;
+ vm_offset_t daddr;
+ vm_offset_t dend;
+ vm_offset_t dsize;
+ vm_offset_t raw_dend;
+ vm_offset_t taddr;
+ vm_offset_t tend;
+ vm_offset_t tsize;
+ struct nameidata *ndp;
+ Osf_Auxargs *osf_auxargs;
+
+ execp = (const struct ecoff_exechdr*)imgp->image_header;
+ eap = &execp->a;
+ ndp = NULL;
+
+/* check to make sure we have an alpha ecoff executable */
+ if (ECOFF_BADMAG(execp))
+ return ENOEXEC;
+
+/* verfify it an OSF/1 exectutable */
+ if (eap->magic != ECOFF_ZMAGIC) {
+ printf("unknown ecoff magic %x\n", eap->magic);
+ return ENOEXEC;
+ }
+ osf_auxargs = malloc(sizeof(Osf_Auxargs), M_TEMP, M_WAITOK);
+ bzero(osf_auxargs, sizeof(Osf_Auxargs));
+ imgp->auxargs = osf_auxargs;
+ osf_auxargs->executable = osf_auxargs->exec_path;
+ path_not_saved = copyinstr(imgp->fname, osf_auxargs->executable,
+ PATH_MAX, &bytes);
+ if (execp->f.f_flags & DYNAMIC_FLAG) {
+ if (path_not_saved) {
+ uprintf("path to dynamic exectutable not found\n");
+ free(imgp->auxargs, M_TEMP);
+ return(path_not_saved);
+ }
+ /*
+ * Unmap the executable & attempt to slide in
+ * /sbin/loader in its place.
+ */
+ if (imgp->firstpage)
+ exec_unmap_first_page(imgp);
+
+ /*
+ * Replicate what execve does, and map the first
+ * page of the loader.
+ */
+ ndp = (struct nameidata *)malloc(sizeof(struct nameidata),
+ M_TEMP, M_WAITOK);
+ NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME, UIO_SYSSPACE,
+ "/compat/osf1/sbin/loader", imgp->proc);
+ error = namei(ndp);
+ if (error) {
+ uprintf("imgact_osf1: can't read /compat/osf1/sbin/loader\n");
+ free(imgp->auxargs, M_TEMP);
+ return(error);
+ }
+ if (imgp->vp) {
+ vrele(imgp->vp);
+ /* leaking in the nameizone ??? XXX */
+ }
+ imgp->vp = ndp->ni_vp;
+ error = exec_map_first_page(imgp);
+ VOP_UNLOCK(imgp->vp, 0, imgp->proc);
+ osf_auxargs->loader = "/compat/osf1/sbin/loader";
+ }
+
+ execp = (const struct ecoff_exechdr*)imgp->image_header;
+ eap = &execp->a;
+ taddr = ECOFF_SEGMENT_ALIGN(execp, eap->text_start);
+ tend = round_page(eap->text_start + eap->tsize);
+ tsize = tend - taddr;
+
+ daddr = ECOFF_SEGMENT_ALIGN(execp, eap->data_start);
+ dend = round_page(eap->data_start + eap->dsize);
+ dsize = dend - daddr;
+
+ bss_start = ECOFF_SEGMENT_ALIGN(execp, eap->bss_start);
+ bsize = eap->bsize;
+
+ imgp->entry_addr = eap->entry;
+ /* copy in arguments and/or environment from old process */
+
+ error = exec_extract_strings(imgp);
+ if (error)
+ goto bail;
+
+ /*
+ * Destroy old process VM and create a new one (with a new stack).
+ */
+ exec_new_vmspace(imgp);
+
+ /*
+ * The vm space can now be changed.
+ */
+ vmspace = imgp->proc->p_vmspace;
+
+ imgp->interpreted = 0;
+ imgp->proc->p_sysent = &osf1_sysvec;
+
+ if ((eap->tsize != 0 || eap->dsize != 0) &&
+ imgp->vp->v_writecount != 0) {
+#ifdef DIAGNOSTIC
+ if (imgp->vp->v_flag & VTEXT)
+ panic("exec: a VTEXT vnode has writecount != 0\n");
+#endif
+ return ETXTBSY;
+ }
+ imgp->vp->v_flag |= VTEXT;
+
+ /* set up text segment */
+ if ((error = vm_mmap(&vmspace->vm_map, &taddr, tsize,
+ VM_PROT_READ|VM_PROT_EXECUTE, VM_PROT_ALL, MAP_FIXED|MAP_COPY,
+ (caddr_t)imgp->vp, ECOFF_TXTOFF(execp)))) {
+ DPRINTF(("%s(%d): error = %d\n", __FILE__, __LINE__, error));
+ return error;
+ }
+ /* .. data .. */
+ if ((error = vm_mmap(&vmspace->vm_map, &daddr, dsize,
+ VM_PROT_READ|VM_PROT_EXECUTE|VM_PROT_WRITE, VM_PROT_ALL,
+ MAP_FIXED|MAP_COPY, (caddr_t)imgp->vp, ECOFF_DATOFF(execp)))) {
+ DPRINTF(("%s(%d): error = %d\n", __FILE__, __LINE__, error));
+ goto bail;
+ }
+ /* .. bss .. */
+ if (round_page(bsize)) {
+ baddr = bss_start;
+ if ((error = vm_map_find(&vmspace->vm_map, NULL,
+ (vm_offset_t) 0, &baddr, round_page(bsize), FALSE,
+ VM_PROT_ALL, VM_PROT_ALL, FALSE))) {
+ DPRINTF(("%s(%d): error = %d\n", __FILE__, __LINE__,
+ error));
+ goto bail;
+
+ }
+ }
+
+
+ raw_dend = (eap->data_start + eap->dsize);
+ if (dend > raw_dend) {
+ caddr_t zeros;
+ zeros = malloc(dend-raw_dend,M_TEMP,M_WAITOK);
+ bzero(zeros,dend-raw_dend);
+ if ((error = copyout(zeros, (caddr_t)raw_dend,
+ dend-raw_dend))) {
+ uprintf("Can't zero start of bss, error %d\n",error);
+ free(zeros,M_TEMP);
+ goto bail;
+ }
+ free(zeros,M_TEMP);
+
+ }
+ vmspace->vm_tsize = btoc(round_page(tsize));
+ vmspace->vm_dsize = btoc((round_page(dsize) + round_page(bsize)));
+ vmspace->vm_taddr = (caddr_t)taddr;
+ vmspace->vm_daddr = (caddr_t)daddr;
+
+ return(0);
+
+ bail:
+ free(imgp->auxargs, M_TEMP);
+ if (ndp) {
+ VOP_CLOSE(ndp->ni_vp, FREAD, imgp->proc->p_ucred, imgp->proc);
+ vrele(ndp->ni_vp);
+ }
+ return(error);
+}
+/*
+ * Tell kern_execve.c about it, with a little help from the linker.
+ */
+struct execsw osf1_execsw = { exec_osf1_imgact, "OSF/1 ECOFF" };
+EXEC_SET(osf1_ecoff, osf1_execsw);
diff --git a/sys/alpha/osf1/osf1.h b/sys/alpha/osf1/osf1.h
new file mode 100644
index 000000000000..085620301143
--- /dev/null
+++ b/sys/alpha/osf1/osf1.h
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 1998-1999 Andrew Gallatin
+ *
+ * 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
+ * in this position and unchanged.
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+extern struct sysent osf1_sysent[];
+extern int bsd_to_osf1_sig[];
+extern int bsd_to_osf1_errno[];
+
+
+/* osf/1 ioctls */
+#define OSF1_IOCPARM_MASK 0x1fff /* parameter length, at most 13 bits */
+#define OSF1_IOCPARM_LEN(x) (((x) >> 16) & OSF1_IOCPARM_MASK)
+#define OSF1_IOCGROUP(x) (((x) >> 8) & 0xff)
+#define OSF1_IOCPARM_MAX NBPG /* max size of ioctl */
+#define OSF1_IOC_VOID 0x20000000 /* no parameters */
+#define OSF1_IOC_OUT 0x40000000 /* copy out parameters */
+#define OSF1_IOC_IN 0x80000000 /* copy in parameters */
+#define OSF1_IOC_INOUT (OSF1_IOC_IN|OSF1_IOC_OUT)
+#define OSF1_IOC_DIRMASK 0xe0000000 /* mask for IN/OUT/VOID */
+#define OSF1_IOCCMD(x) ((x) & 0xff)
+
+/* for get/set sysinfo */
+#define OSF_SET_IEEE_FP_CONTROL 14
+#define OSF_GET_IEEE_FP_CONTROL 45
+#define OSF_GET_PROC_TYPE 60
+#define OSF_GET_HWRPB 101
+
+/* for rlimit */
+#define OSF1_RLIMIT_LASTCOMMON 5 /* last one that's common */
+#define OSF1_RLIMIT_NOFILE 6 /* OSF1's RLIMIT_NOFILE */
+#define OSF1_RLIMIT_NLIMITS 8 /* Number of OSF1 rlimits */
+
+/* mmap flags */
+
+#define OSF1_MAP_SHARED 0x001
+#define OSF1_MAP_PRIVATE 0x002
+#define OSF1_MAP_ANONYMOUS 0x010
+#define OSF1_MAP_FILE 0x000
+#define OSF1_MAP_TYPE 0x0f0
+#define OSF1_MAP_FIXED 0x100
+#define OSF1_MAP_HASSEMAPHORE 0x200
+#define OSF1_MAP_INHERIT 0x400
+#define OSF1_MAP_UNALIGNED 0x800
+
+/* msync flags */
+
+#define OSF1_MS_ASYNC 1
+#define OSF1_MS_SYNC 2
+#define OSF1_MS_INVALIDATE 4
+
+#define OSF1_F_DUPFD 0
+#define OSF1_F_GETFD 1
+#define OSF1_F_SETFD 2
+#define OSF1_F_GETFL 3
+#define OSF1_F_SETFL 4
+
+
+#define _OSF1_PC_CHOWN_RESTRICTED 10
+#define _OSF1_PC_LINK_MAX 11
+#define _OSF1_PC_MAX_CANON 12
+#define _OSF1_PC_MAX_INPUT 13
+#define _OSF1_PC_NAME_MAX 14
+#define _OSF1_PC_NO_TRUNC 15
+#define _OSF1_PC_PATH_MAX 16
+#define _OSF1_PC_PIPE_BUF 17
+#define _OSF1_PC_VDISABLE 18
+
+
+
+#define OSF1_FNONBLOCK 0x00004 /* XXX OSF1_O_NONBLOCK */
+#define OSF1_FAPPEND 0x00008 /* XXX OSF1_O_APPEND */
+#define OSF1_FDEFER 0x00020
+#define OSF1_FASYNC 0x00040
+#define OSF1_FCREAT 0x00200
+#define OSF1_FTRUNC 0x00400
+#define OSF1_FEXCL 0x00800
+#define OSF1_FSYNC 0x04000 /* XXX OSF1_O_SYNC */
+#define OSF1_FNDELAY 0x08000
+
+#define OSF1_RB_ASKNAME 0x001
+#define OSF1_RB_SINGLE 0x002
+#define OSF1_RB_NOSYNC 0x004
+#define OSF1_RB_HALT 0x008
+#define OSF1_RB_INITNAME 0x010
+#define OSF1_RB_DFLTROOT 0x020
+#define OSF1_RB_ALTBOOT 0x040
+#define OSF1_RB_UNIPROC 0x080
+#define OSF1_RB_ALLFLAGS 0x0ff /* all of the above */
+
+/*
+ * osf/1 uses ints in its struct timeval, this means that
+ * any syscalls which means that any system calls using
+ * timevals need to be intercepted.
+ */
+
+
+struct osf1_timeval {
+ int tv_sec; /* seconds */
+ int tv_usec; /* microseconds */
+};
+
+struct osf1_itimerval {
+ struct osf1_timeval it_interval; /* timer interval */
+ struct osf1_timeval it_value; /* current value */
+};
+#define TV_CP(src,dst) {dst.tv_usec = src.tv_usec; dst.tv_sec = src.tv_sec;}
+
+#define timersub(tvp, uvp, vvp) \
+ do { \
+ (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
+ (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
+ if ((vvp)->tv_usec < 0) { \
+ (vvp)->tv_sec--; \
+ (vvp)->tv_usec += 1000000; \
+ } \
+ } while (0)
+
+struct osf1_rusage {
+ struct osf1_timeval ru_utime; /* user time used */
+ struct osf1_timeval ru_stime; /* system time used */
+ long ru_maxrss; /* max resident set size */
+#define ru_first ru_ixrss
+ long ru_ixrss; /* integral shared memory size */
+ long ru_idrss; /* integral unshared data " */
+ long ru_isrss; /* integral unshared stack " */
+ long ru_minflt; /* page reclaims */
+ long ru_majflt; /* page faults */
+ long ru_nswap; /* swaps */
+ long ru_inblock; /* block input operations */
+ long ru_oublock; /* block output operations */
+ long ru_msgsnd; /* messages sent */
+ long ru_msgrcv; /* messages received */
+ long ru_nsignals; /* signals received */
+ long ru_nvcsw; /* voluntary context switches */
+ long ru_nivcsw; /* involuntary " */
+#define ru_last ru_nivcsw
+};
+
+#define OSF1_USC_GET 1
+#define OSF1_USC_SET 2
+#define OSF1_USW_NULLP 0x100
+
+
+/* File system type numbers. */
+#define OSF1_MOUNT_NONE 0
+#define OSF1_MOUNT_UFS 1
+#define OSF1_MOUNT_NFS 2
+#define OSF1_MOUNT_MFS 3
+#define OSF1_MOUNT_PC 4
+#define OSF1_MOUNT_S5FS 5
+#define OSF1_MOUNT_CDFS 6
+#define OSF1_MOUNT_DFS 7
+#define OSF1_MOUNT_EFS 8
+#define OSF1_MOUNT_PROCFS 9
+#define OSF1_MOUNT_MSFS 10
+#define OSF1_MOUNT_FFM 11
+#define OSF1_MOUNT_FDFS 12
+#define OSF1_MOUNT_ADDON 13
+#define OSF1_MOUNT_MAXTYPE OSF1_MOUNT_ADDON
+
+#define OSF1_MNT_WAIT 0x1
+#define OSF1_MNT_NOWAIT 0x2
+
+#define OSF1_MNT_FORCE 0x1
+#define OSF1_MNT_NOFORCE 0x2
+
+/* acceptable flags for various calls */
+#define OSF1_GETFSSTAT_FLAGS (OSF1_MNT_WAIT|OSF1_MNT_NOWAIT)
+#define OSF1_MOUNT_FLAGS 0xffffffff /* XXX */
+#define OSF1_UNMOUNT_FLAGS (OSF1_MNT_FORCE|OSF1_MNT_NOFORCE)
+
+struct osf1_statfs {
+ int16_t f_type; /* 0 */
+ int16_t f_flags; /* 2 */
+ int32_t f_fsize; /* 4 */
+ int32_t f_bsize; /* 8 */
+ int32_t f_blocks; /* 12 */
+ int32_t f_bfree; /* 16 */
+ int32_t f_bavail; /* 20 */
+ int32_t f_files; /* 24 */
+ int32_t f_ffree; /* 28 */
+ int64_t f_fsid; /* 32 */
+ int32_t f_spare[9]; /* 40 (36 bytes) */
+ char f_mntonname[90]; /* 76 (90 bytes) */
+ char f_mntfromname[90]; /* 166 (90 bytes) */
+ char f_xxx[80]; /* 256 (80 bytes) XXX */
+};
+/* Arguments to mount() for various FS types. */
+#ifdef notyet /* XXX */
+struct osf1_ufs_args {
+ char *fspec;
+ int32_t exflags;
+ u_int32_t exroot;
+};
+
+struct osf1_cdfs_args {
+ char *fspec;
+ int32_t exflags;
+ u_int32_t exroot;
+ int32_t flags;
+};
+#endif
+
+struct osf1_mfs_args {
+ char *name;
+ caddr_t base;
+ u_int size;
+};
+
+struct osf1_nfs_args {
+ struct sockaddr_in *addr;
+ void *fh;
+ int32_t flags;
+ int32_t wsize;
+ int32_t rsize;
+ int32_t timeo;
+ int32_t retrans;
+ char *hostname;
+ int32_t acregmin;
+ int32_t acregmax;
+ int32_t acdirmin;
+ int32_t acdirmax;
+ char *netname;
+ void *pathconf;
+};
+
+#define OSF1_NFSMNT_SOFT 0x00001
+#define OSF1_NFSMNT_WSIZE 0x00002
+#define OSF1_NFSMNT_RSIZE 0x00004
+#define OSF1_NFSMNT_TIMEO 0x00008
+#define OSF1_NFSMNT_RETRANS 0x00010
+#define OSF1_NFSMNT_HOSTNAME 0x00020
+#define OSF1_NFSMNT_INT 0x00040
+#define OSF1_NFSMNT_NOCONN 0x00080
+#define OSF1_NFSMNT_NOAC 0x00100 /* ??? */
+#define OSF1_NFSMNT_ACREGMIN 0x00200 /* ??? */
+#define OSF1_NFSMNT_ACREGMAX 0x00400 /* ??? */
+#define OSF1_NFSMNT_ACDIRMIN 0x00800 /* ??? */
+#define OSF1_NFSMNT_ACDIRMAX 0x01000 /* ??? */
+#define OSF1_NFSMNT_NOCTO 0x02000 /* ??? */
+#define OSF1_NFSMNT_POSIX 0x04000 /* ??? */
+#define OSF1_NFSMNT_AUTO 0x08000 /* ??? */
+
+#define OSF1_NFSMNT_FLAGS \
+ (OSF1_NFSMNT_SOFT|OSF1_NFSMNT_WSIZE|OSF1_NFSMNT_RSIZE| \
+ OSF1_NFSMNT_TIMEO|OSF1_NFSMNT_RETRANS|OSF1_NFSMNT_HOSTNAME| \
+ OSF1_NFSMNT_INT|OSF1_NFSMNT_NOCONN)
+
+#define memset(x,y,z) bzero((x),(z))
diff --git a/sys/alpha/osf1/osf1_ioctl.c b/sys/alpha/osf1/osf1_ioctl.c
new file mode 100644
index 000000000000..ce362de1a157
--- /dev/null
+++ b/sys/alpha/osf1/osf1_ioctl.c
@@ -0,0 +1,331 @@
+/* $NetBSD: osf1_ioctl.c,v 1.5 1996/10/13 00:46:53 christos Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * Additional Copyright (c) 1999 by Andrew Gallatin
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/fcntl.h>
+#include <sys/filio.h>
+#include <sys/ioctl_compat.h>
+#include <sys/termios.h>
+#include <sys/filedesc.h>
+#include <sys/file.h>
+#include <sys/proc.h>
+#include <sys/mount.h>
+#include <sys/sysproto.h>
+#include <alpha/osf1/osf1_signal.h>
+#include <alpha/osf1/osf1_proto.h>
+#include <alpha/osf1/osf1.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_types.h>
+#include <sys/sockio.h>
+
+#include "opt_compat.h"
+
+/*#define IOCTL_DEBUG*/
+
+int osf1_ioctl_i __P((struct proc *p, struct ioctl_args *nuap,
+ int cmd, int dir, int len));
+int osf1_ioctl_t __P((struct proc *p, struct ioctl_args *nuap,
+ int cmd, int dir, int len));
+int osf1_ioctl_f __P((struct proc *p, struct ioctl_args *nuap,
+ int cmd, int dir, int len));
+
+int
+osf1_ioctl(p, uap)
+ struct proc *p;
+ struct osf1_ioctl_args *uap;
+{
+ char *dirstr;
+ unsigned int cmd, dir, group, len, op;
+ struct ioctl_args /* {
+ syscallarg(int) fd;
+ syscallarg(u_long) com;
+ syscallarg(caddr_t) data;
+ } */ a;
+
+ op = uap->com;
+ dir = op & OSF1_IOC_DIRMASK;
+ group = OSF1_IOCGROUP(op);
+ cmd = OSF1_IOCCMD(op);
+ len = OSF1_IOCPARM_LEN(op);
+
+ switch (dir) {
+ case OSF1_IOC_VOID:
+ dir = IOC_VOID;
+ dirstr = "none";
+ break;
+
+ case OSF1_IOC_OUT:
+ dir = IOC_OUT;
+ dirstr = "out";
+ break;
+
+ case OSF1_IOC_IN:
+ dir = IOC_IN;
+ dirstr = "in";
+ break;
+
+ case OSF1_IOC_INOUT:
+ dir = IOC_INOUT;
+ dirstr = "in-out";
+ break;
+
+ default:
+ return (EINVAL);
+ break;
+ }
+#ifdef IOCTL_DEBUG
+ uprintf(
+ "OSF/1 IOCTL: group = %c, cmd = %d, len = %d, dir = %s\n",
+ group, cmd, len, dirstr);
+#endif
+
+ a.fd = uap->fd;
+ a.com = (unsigned long)uap->com;
+ bzero(&a.com, sizeof(long));
+ a.com = _IOC(dir, group, cmd, len);
+ a.data = uap->data;
+ switch (group) {
+ case 'i':
+ return osf1_ioctl_i(p, &a, cmd, dir, len);
+ case 't':
+ return osf1_ioctl_t(p, &a, cmd, dir, len);
+ case 'f':
+ return osf1_ioctl_f(p, &a, cmd, dir, len);
+ default:
+ printf(
+ "unimplented OSF/1 IOCTL: group = %c, cmd = %d, len = %d, dir = %s\n",
+ group, cmd, len, dirstr);
+ return (ENOTTY);
+ }
+}
+
+/*
+ * Structure used to query de and qe for physical addresses.
+ */
+struct osf1_ifdevea {
+ char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
+ u_char default_pa[6]; /* default hardware address */
+ u_char current_pa[6]; /* current physical address */
+};
+
+
+int
+osf1_ioctl_i(p, uap, cmd, dir, len)
+ struct proc *p;
+ struct ioctl_args /* {
+ syscallarg(int) fd;
+ syscallarg(u_long) com;
+ syscallarg(caddr_t) data;
+ } */ *uap;
+ int cmd;
+ int dir;
+ int len;
+{
+
+ switch (cmd) {
+ case 20: /* OSF/1 OSIOCGIFCONF */
+ case 36: /* OSF/1 SIOCGIFCONF */
+ case 12: /* OSF/1 SIOCSIFADDR */
+ case 14: /* OSF/1 SIOCSIFDSTADDR */
+ case 16: /* OSF/1 SIOCSIFFLAGS (XXX) */
+ case 17: /* OSF/1 SIOCGIFFLAGS (XXX) */
+ case 19: /* OSF/1 SIOCSIFBRDADDR */
+ case 22: /* OSF/1 SIOCSIFNETMASK */
+ case 23: /* OSF/1 SIOCGIFMETRIC */
+ case 24: /* OSF/1 SIOCSIFMETRIC */
+ case 25: /* OSF/1 SIOCDIFADDR */
+ case 33: /* OSF/1 SIOCGIFADDR */
+ case 34: /* OSF/1 SIOCGIFDSTADDR */
+ case 35: /* OSF/1 SIOCGIFBRDADDR */
+ case 37: /* OSF/1 SIOCGIFNETMASK */
+ /* same as in FreeBSD */
+ return ioctl(p, uap);
+ break;
+
+ case 62: /* OSF/1 SIOCRPHYSADDR */
+
+ {
+ int ifn, retval;
+ struct ifnet *ifp;
+ struct ifaddr *ifa;
+ struct sockaddr_dl *sdl;
+ struct osf1_ifdevea *ifd = (struct osf1_ifdevea *)uap->data;
+
+ /*
+ * Note that we don't actually respect the name in the ifreq
+ * structure, as DU interface names are all different.
+ */
+ for (ifn = 0; ifn < if_index; ifn++) {
+ ifp = ifnet_addrs[ifn]->ifa_ifp; /* pointer to interface */
+ /* Only look at ether interfaces, exclude alteon nics
+ * because osf/1 doesn't know about most of them.
+ */
+ if (ifp->if_type == IFT_ETHER
+ && strcmp(ifp->if_name, "ti")) { /* looks good */
+ /* walk the address list */
+ for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa;
+ ifa = TAILQ_NEXT(ifa, ifa_link)) {
+ if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) /* we have an address structure */
+ && (sdl->sdl_family == AF_LINK) /* it's a link address */
+ && (sdl->sdl_type == IFT_ETHER)) { /* for an ethernet link */
+ retval = copyout(LLADDR(sdl),
+ (caddr_t)&ifd->current_pa,
+ 6);
+ if (!retval) {
+ return(copyout(
+ LLADDR(sdl),
+ (caddr_t)&ifd->default_pa,
+ 6));
+ }
+ }
+ }
+ }
+ }
+ return(ENOENT); /* ??? */
+ }
+
+
+ default:
+ printf("osf1_ioctl_i: cmd = %d\n", cmd);
+ return (ENOTTY);
+ }
+
+
+}
+#ifndef _SGTTYB_
+#define _SGTTYB_
+struct sgttyb {
+ char sg_ispeed; /* input speed */
+ char sg_ospeed; /* output speed */
+ char sg_erase; /* erase character */
+ char sg_kill; /* kill character */
+ short sg_flags; /* mode flags */
+};
+#endif
+
+int
+osf1_ioctl_t(p, uap, cmd, dir, len)
+ struct proc *p;
+ struct ioctl_args /* {
+ syscallarg(int) fd;
+ syscallarg(u_long) com;
+ syscallarg(caddr_t) data;
+ } */ *uap;
+ int cmd;
+ int dir;
+ int len;
+{
+ int retval;
+
+ switch (cmd) {
+#ifdef COMPAT_43
+ case 0: /* OSF/1 COMPAT_43 TIOCGETD */
+ case 1: /* OSF/1 COMPAT_43 TIOCSETD */
+ case 8: /* OSF/1 COMPAT_43 TIOCGETP */
+ case 9: /* OSF/1 COMPAT_43 TIOCSETP */
+ case 10: /* OSF/1 COMPAT_43 TIOCSETN */
+ case 17: /* OSF/1 TIOCSETC (XXX) */
+ case 18: /* OSF/1 TIOCGETC (XXX) */
+ case 116: /* OSF/1 TIOCSLTC */
+ case 117: /* OSF/1 TIOCGLTC */
+ case 124: /* OSF/1 TIOCLGET */
+ case 125: /* OSF/1 TIOCLSET */
+ case 126: /* OSF/1 TIOCLBIC */
+ case 127: /* OSF/1 TIOCLBIS */
+#endif
+ case 19: /* OSF/1 TIOCGETA (XXX) */
+ case 20: /* OSF/1 TIOCSETA (XXX) */
+ case 21: /* OSF/1 TIOCSETAW (XXX) */
+ case 22: /* OSF/1 TIOCSETAF (XXX) */
+ case 26: /* OSF/1 TIOCGETD (XXX) */
+ case 27: /* OSF/1 TIOCSETD (XXX) */
+ case 97: /* OSF/1 TIOCSCTTY */
+ case 103: /* OSF/1 TIOCSWINSZ */
+ case 104: /* OSF/1 TIOCGWINSZ */
+ case 110: /* OSF/1 TIOCSTART */
+ case 111: /* OSF/1 TIOCSTOP */
+ case 118: /* OSF/1 TIOCGPGRP */
+ case 119: /* OSF/1 TIOCGPGRP */
+ /* same as in NetBSD */
+ break;
+
+
+ default:
+ printf("osf1_ioctl_t: cmd = %d\n", cmd);
+ return (ENOTTY);
+ }
+
+ retval = ioctl(p, uap);
+#if 0
+ if (retval)
+ printf("osf1_ioctl_t: cmd = %d, com = 0x%lx, retval = %d\n",
+ cmd, uap->com,retval);
+#endif
+ return retval;
+}
+
+int
+osf1_ioctl_f(p, uap, cmd, dir, len)
+ struct proc *p;
+ struct ioctl_args /* {
+ syscallarg(int) fd;
+ syscallarg(int) com;
+ syscallarg(caddr_t) data;
+ } */ *uap;
+ int cmd;
+ int dir;
+ int len;
+{
+
+ switch (cmd) {
+ case 1: /* OSF/1 FIOCLEX (XXX) */
+ case 2: /* OSF/1 FIONCLEX (XXX) */
+ case 127: /* OSF/1 FIONREAD (XXX) */
+ case 126: /* OSF/1 FIONREAD (XXX) */
+ case 125: /* OSF/1 FIOASYNC (XXX) */
+ case 124: /* OSF/1 FIOSETOWN (XXX) */
+ case 123: /* OSF/1 FIOGETOWN (XXX) */
+ /* same as in FreeBSD */
+ break;
+
+ default:
+ printf("osf1_ioctl_f: cmd = %d\n", cmd);
+ return (ENOTTY);
+ }
+
+ return ioctl(p, uap);
+}
diff --git a/sys/alpha/osf1/osf1_misc.c b/sys/alpha/osf1/osf1_misc.c
new file mode 100644
index 000000000000..4272b52b0d00
--- /dev/null
+++ b/sys/alpha/osf1/osf1_misc.c
@@ -0,0 +1,1747 @@
+/* $NetBSD: osf1_misc.c,v 1.14 1998/05/20 16:34:29 chs Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * Additional Copyright (c) 1999 by Andrew Gallatin
+ * $FreeBSD$
+ */
+
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/namei.h>
+#include <sys/proc.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/filedesc.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/signal.h>
+#include <sys/signalvar.h>
+#include <sys/reboot.h>
+#include <sys/exec.h>
+#include <sys/vnode.h>
+#include <sys/socketvar.h>
+#include <sys/sysproto.h>
+#include <sys/sysent.h>
+#include <sys/resource.h>
+#include <sys/signalvar.h>
+#include <sys/fcntl.h>
+#include <sys/socket.h>
+#include <sys/pipe.h>
+#include <alpha/osf1/osf1_signal.h>
+#include <alpha/osf1/osf1_proto.h>
+#include <alpha/osf1/osf1_syscall.h>
+#include <alpha/osf1/osf1_util.h>
+#include <alpha/osf1/osf1.h>
+#include <sys/proc.h>
+#include <sys/module.h>
+
+#include <vm/vm.h>
+#include <alpha/osf1/exec_ecoff.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/resourcevar.h>
+#include <sys/exec.h>
+#include <sys/mman.h>
+#include <sys/imgact.h>
+
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/vnode.h>
+#include <sys/unistd.h>
+
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+#include <vm/vm_extern.h>
+#include <alpha/osf1/exec_ecoff.h>
+
+#include <sys/user.h>
+#include <machine/cpu.h>
+#include <machine/fpu.h>
+
+#include <sys/sysctl.h>
+#include <sys/utsname.h>
+#include <sys/dkstat.h>
+
+#include <machine/rpb.h>
+
+static void cvtstat2osf1 __P((struct stat *, struct osf1_stat *));
+static int osf2bsd_pathconf __P((int *));
+
+static const char osf1_emul_path[] = "/compat/osf1";
+/*
+ * [ taken from the linux emulator ]
+ * Search an alternate path before passing pathname arguments on
+ * to system calls. Useful for keeping a seperate 'emulation tree'.
+ *
+ * If cflag is set, we check if an attempt can be made to create
+ * the named file, i.e. we check if the directory it should
+ * be in exists.
+ */
+int
+osf1_emul_find(p, sgp, prefix, path, pbuf, cflag)
+ struct proc *p;
+ caddr_t *sgp; /* Pointer to stackgap memory */
+ const char *prefix;
+ char *path;
+ char **pbuf;
+ int cflag;
+{
+ int error;
+ size_t len, sz;
+ char *buf, *cp, *ptr;
+ struct nameidata nd;
+ struct nameidata ndroot;
+ struct vattr vat;
+ struct vattr vatroot;
+
+ buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
+ *pbuf = path;
+
+ for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++)
+ continue;
+
+ sz = MAXPATHLEN - (ptr - buf);
+
+ /*
+ * If sgp is not given then the path is already in kernel space
+ */
+ if (sgp == NULL)
+ error = copystr(path, ptr, sz, &len);
+ else
+ error = copyinstr(path, ptr, sz, &len);
+
+ if (error) {
+ free(buf, M_TEMP);
+ return error;
+ }
+
+ if (*ptr != '/') {
+ free(buf, M_TEMP);
+ return EINVAL;
+ }
+
+ /*
+ * We know that there is a / somewhere in this pathname.
+ * Search backwards for it, to find the file's parent dir
+ * to see if it exists in the alternate tree. If it does,
+ * and we want to create a file (cflag is set). We don't
+ * need to worry about the root comparison in this case.
+ */
+
+ if (cflag) {
+ for (cp = &ptr[len] - 1; *cp != '/'; cp--)
+ ;
+ *cp = '\0';
+
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p);
+
+ if ((error = namei(&nd)) != 0) {
+ free(buf, M_TEMP);
+ return error;
+ }
+
+ *cp = '/';
+ } else {
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p);
+
+ if ((error = namei(&nd)) != 0) {
+ free(buf, M_TEMP);
+ return error;
+ }
+
+ /*
+ * We now compare the vnode of the osf1_root to the one
+ * vnode asked. If they resolve to be the same, then we
+ * ignore the match so that the real root gets used.
+ * This avoids the problem of traversing "../.." to find the
+ * root directory and never finding it, because "/" resolves
+ * to the emulation root directory. This is expensive :-(
+ */
+ NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, osf1_emul_path,
+ p);
+
+ if ((error = namei(&ndroot)) != 0) {
+ /* Cannot happen! */
+ free(buf, M_TEMP);
+ vrele(nd.ni_vp);
+ return error;
+ }
+
+ if ((error = VOP_GETATTR(nd.ni_vp, &vat, p->p_ucred, p)) != 0) {
+ goto bad;
+ }
+
+ if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, p->p_ucred, p))
+ != 0) {
+ goto bad;
+ }
+
+ if (vat.va_fsid == vatroot.va_fsid &&
+ vat.va_fileid == vatroot.va_fileid) {
+ error = ENOENT;
+ goto bad;
+ }
+
+ }
+ if (sgp == NULL)
+ *pbuf = buf;
+ else {
+ sz = &ptr[len] - buf;
+ *pbuf = stackgap_alloc(sgp, sz + 1);
+ error = copyout(buf, *pbuf, sz);
+ free(buf, M_TEMP);
+ }
+
+ vrele(nd.ni_vp);
+ if (!cflag)
+ vrele(ndroot.ni_vp);
+
+ return error;
+
+bad:
+ vrele(ndroot.ni_vp);
+ vrele(nd.ni_vp);
+ free(buf, M_TEMP);
+ return error;
+}
+
+
+int
+osf1_open(p, uap)
+ struct proc *p;
+ struct osf1_open_args *uap;
+{
+ struct open_args /* {
+ syscallarg(char *) path;
+ syscallarg(int) flags;
+ syscallarg(int) mode;
+ } */ a;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, uap->path);
+
+ SCARG(&a, path) = SCARG(uap, path);
+ SCARG(&a, flags) = SCARG(uap, flags); /* XXX translate */
+ SCARG(&a, mode) = SCARG(uap, mode);
+
+ return open(p, &a);
+}
+
+
+int
+osf1_getsysinfo(p, uap)
+ struct proc *p;
+ struct osf1_getsysinfo_args *uap;
+{
+ int error, retval;
+
+ error = retval = 0;
+
+ switch(uap->op) {
+ case OSF_GET_IEEE_FP_CONTROL:
+ error = copyout(&p->p_addr->u_pcb.pcb_fp_control,uap->buffer,
+ sizeof(p->p_addr->u_pcb.pcb_fp_control));
+ retval = 1;
+ break;
+ case OSF_GET_PROC_TYPE: {
+ int unit;
+ long percpu;
+ long proctype;
+
+ if(uap->nbytes < sizeof(proctype))
+ error = EINVAL;
+ else {
+ unit = alpha_pal_whami();
+ proctype = LOCATE_PCS(hwrpb, unit)->pcs_proc_type;
+ error = copyout (&proctype, uap->buffer,
+ sizeof(percpu));
+ retval = 1;
+ }
+ }
+ break;
+ case OSF_GET_HWRPB: { /* note -- osf/1 doesn't have rpb_tbhint[8] */
+ unsigned long rpb_size;
+ rpb_size = (unsigned long)&hwrpb->rpb_tbhint -
+ (unsigned long)hwrpb;
+ if(uap->nbytes < rpb_size){
+ uprintf("nbytes = %ld, sizeof(struct rpb) = %ld\n",
+ uap->nbytes, rpb_size);
+ error = EINVAL;
+ }
+ else {
+ error = copyout(hwrpb, uap->buffer, rpb_size);
+ retval = 1;
+ }
+ }
+ break;
+ default:
+ printf("osf1_getsysinfo called with unknown op=%ld\n", uap->op);
+ return EINVAL;
+ }
+ p->p_retval[0] = retval;
+ return(error);
+}
+
+
+int
+osf1_setsysinfo(p, uap)
+ struct proc *p;
+ struct osf1_setsysinfo_args *uap;
+{
+ int error;
+
+ error = 0;
+
+ switch(uap->op) {
+ case OSF_SET_IEEE_FP_CONTROL:
+ {
+ u_int64_t temp, *fp_control;
+
+ if ((error = copyin(uap->buffer, &temp, sizeof(temp))))
+ break;
+ fp_control = &p->p_addr->u_pcb.pcb_fp_control;
+ *fp_control = temp & IEEE_TRAP_ENABLE_MASK;
+ break;
+ }
+ default:
+ uprintf("osf1_setsysinfo called with op=%ld\n", uap->op);
+ /*error = EINVAL;*/
+ }
+ return (error);
+}
+
+
+int
+osf1_getrlimit(p, uap)
+ struct proc *p;
+ struct osf1_getrlimit_args *uap;
+{
+ struct __getrlimit_args /* {
+ syscallarg(u_int) which;
+ syscallarg(struct orlimit *) rlp;
+ } */ a;
+
+ if (SCARG(uap, which) >= OSF1_RLIMIT_NLIMITS)
+ return (EINVAL);
+
+ if (SCARG(uap, which) <= OSF1_RLIMIT_LASTCOMMON)
+ SCARG(&a, which) = SCARG(uap, which);
+ else if (SCARG(uap, which) == OSF1_RLIMIT_NOFILE)
+ SCARG(&a, which) = RLIMIT_NOFILE;
+ else
+ return (0);
+ SCARG(&a, rlp) = (struct orlimit *)SCARG(uap, rlp);
+
+ return getrlimit(p, &a);
+}
+
+
+int
+osf1_setrlimit(p, uap)
+ struct proc *p;
+ struct osf1_setrlimit_args *uap;
+{
+ struct __setrlimit_args /* {
+ syscallarg(u_int) which;
+ syscallarg(struct orlimit *) rlp;
+ } */ a;
+
+ if (SCARG(uap, which) >= OSF1_RLIMIT_NLIMITS)
+ return (EINVAL);
+
+ if (SCARG(uap, which) <= OSF1_RLIMIT_LASTCOMMON)
+ SCARG(&a, which) = SCARG(uap, which);
+ else if (SCARG(uap, which) == OSF1_RLIMIT_NOFILE)
+ SCARG(&a, which) = RLIMIT_NOFILE;
+ else
+ return (0);
+ SCARG(&a, rlp) = (struct orlimit *)SCARG(uap, rlp);
+
+ return setrlimit(p, &a);
+}
+
+
+/*
+ * As linux says, this is a total guess.
+ */
+
+int
+osf1_set_program_attributes(p, uap)
+ struct proc *p;
+ struct osf1_set_program_attributes_args *uap;
+{
+ struct vmspace *vm = p->p_vmspace;
+
+ vm->vm_taddr = (caddr_t)uap->text_start;
+ vm->vm_tsize = btoc(round_page(uap->text_len));
+ vm->vm_daddr = (caddr_t)uap->bss_start;
+ vm->vm_dsize = btoc(round_page(uap->bss_len));
+
+ return(KERN_SUCCESS);
+}
+
+
+int
+osf1_mmap(p, uap)
+ struct proc *p;
+ struct osf1_mmap_args *uap;
+{
+ struct mmap_args /* {
+ syscallarg(caddr_t) addr;
+ syscallarg(size_t) len;
+ syscallarg(int) prot;
+ syscallarg(int) flags;
+ syscallarg(int) fd;
+ syscallarg(long) pad;
+ syscallarg(off_t) pos;
+ } */ a;
+ int retval;
+ vm_map_t map;
+ vm_offset_t addr, len, newaddr;
+
+ SCARG(&a, addr) = SCARG(uap, addr);
+ SCARG(&a, len) = SCARG(uap, len);
+ SCARG(&a, prot) = SCARG(uap, prot);
+ SCARG(&a, fd) = SCARG(uap, fd);
+ SCARG(&a, pad) = 0;
+ SCARG(&a, pos) = SCARG(uap, pos);
+
+ SCARG(&a, flags) = 0;
+
+ /*
+ * OSF/1's mmap, unlike FreeBSD's, does its best to map memory at the
+ * user's requested address, even if MAP_FIXED is not set. Here we
+ * try to replicate this behaviour as much as we can because some
+ * applications (like /sbin/loader) depend on having things put as
+ * close to where they've requested as possible.
+ */
+
+ if (SCARG(uap, addr) != NULL)
+ addr = round_page((vm_offset_t)SCARG(&a,addr));
+ else
+ /*
+ * Try to use the apparent OSF/1 default placement of 0x10000 for
+ * NULL addrs, this helps to prevent non-64 bit clean binaries from
+ * SEGV'ing.
+ */
+ addr = round_page((vm_offset_t)0x10000UL);
+ len = (vm_offset_t)SCARG(&a, len);
+ map = &p->p_vmspace->vm_map;
+ if (!vm_map_findspace(map, addr, len, &newaddr)) {
+ SCARG(&a,addr) = (caddr_t) newaddr;
+ SCARG(&a, flags) |= (MAP_FIXED);
+ }
+#ifdef DEBUG
+ else
+ uprintf("osf1_mmap:vm_map_findspace failed for: %p 0x%lx\n",
+ (caddr_t)addr, len);
+#endif
+
+ if (SCARG(uap, flags) & OSF1_MAP_SHARED)
+ SCARG(&a, flags) |= MAP_SHARED;
+ if (SCARG(uap, flags) & OSF1_MAP_PRIVATE)
+ SCARG(&a, flags) |= MAP_PRIVATE;
+
+ switch (SCARG(uap, flags) & OSF1_MAP_TYPE) {
+ case OSF1_MAP_ANONYMOUS:
+ SCARG(&a, flags) |= MAP_ANON;
+ break;
+ case OSF1_MAP_FILE:
+ SCARG(&a, flags) |= MAP_FILE;
+ break;
+ default:
+ return (EINVAL);
+ }
+ if (SCARG(uap, flags) & OSF1_MAP_FIXED)
+ SCARG(&a, flags) |= MAP_FIXED;
+ if (SCARG(uap, flags) & OSF1_MAP_HASSEMAPHORE)
+ SCARG(&a, flags) |= MAP_HASSEMAPHORE;
+ if (SCARG(uap, flags) & OSF1_MAP_INHERIT)
+ SCARG(&a, flags) |= MAP_INHERIT;
+ if (SCARG(uap, flags) & OSF1_MAP_UNALIGNED)
+ return (EINVAL);
+ /*
+ * Emulate an osf/1 bug: Apparently, mmap'ed segments are always
+ * readable even if the user doesn't or in PROT_READ. This causes
+ * some buggy programs to segv.
+ */
+ SCARG(&a, prot) |= PROT_READ;
+
+
+ retval = mmap(p, &a);
+#ifdef DEBUG
+ uprintf(
+ "\nosf1_mmap: addr=%p (%p), len = 0x%lx, prot=0x%x, fd=%d, pad=0, pos=0x%lx",
+ SCARG(uap, addr), SCARG(&a, addr),SCARG(uap, len), SCARG(uap, prot),
+ SCARG(uap, fd), SCARG(uap, pos));
+ printf(" flags = 0x%x\n",SCARG(uap, flags));
+#endif
+ return (retval);
+}
+
+int
+osf1_msync(p, uap)
+ struct proc *p;
+ struct osf1_msync_args *uap;
+{
+ struct msync_args a;
+
+ a.addr = SCARG(uap, addr);
+ a.len = SCARG(uap, len);
+ a.flags = 0;
+ if(SCARG(uap, flags) & OSF1_MS_ASYNC)
+ SCARG(&a, flags) |= MS_ASYNC;
+ if(SCARG(uap, flags) & OSF1_MS_SYNC)
+ SCARG(&a, flags) |= MS_SYNC;
+ if(SCARG(uap, flags) & OSF1_MS_INVALIDATE)
+ SCARG(&a, flags) |= MS_INVALIDATE;
+ return(msync(p, &a));
+}
+
+struct osf1_stat {
+ int32_t st_dev;
+ u_int32_t st_ino;
+ u_int32_t st_mode;
+ u_int16_t st_nlink;
+ u_int32_t st_uid;
+ u_int32_t st_gid;
+ int32_t st_rdev;
+ u_int64_t st_size;
+ int32_t st_atime_sec;
+ int32_t st_spare1;
+ int32_t st_mtime_sec;
+ int32_t st_spare2;
+ int32_t st_ctime_sec;
+ int32_t st_spare3;
+ u_int32_t st_blksize;
+ int32_t st_blocks;
+ u_int32_t st_flags;
+ u_int32_t st_gen;
+};
+
+/*
+ * Get file status; this version follows links.
+ */
+/* ARGSUSED */
+int
+osf1_stat(p, uap)
+ struct proc *p;
+ struct osf1_stat_args *uap;
+{
+ int error;
+ struct stat sb;
+ struct osf1_stat osb;
+ struct nameidata nd;
+ caddr_t sg;
+
+ sg = stackgap_init();
+
+ CHECKALTEXIST(p, &sg, uap->path);
+
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
+ SCARG(uap, path), p);
+ if ((error = namei(&nd)))
+ return (error);
+ error = vn_stat(nd.ni_vp, &sb, p);
+ vput(nd.ni_vp);
+ if (error)
+ return (error);
+ cvtstat2osf1(&sb, &osb);
+ error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
+ return (error);
+}
+
+
+/*
+ * Get file status; this version does not follow links.
+ */
+/* ARGSUSED */
+int
+osf1_lstat(p, uap)
+ struct proc *p;
+ register struct osf1_lstat_args *uap;
+{
+ struct stat sb;
+ struct osf1_stat osb;
+ int error;
+ struct nameidata nd;
+ caddr_t sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, uap->path);
+
+ NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE,
+ SCARG(uap, path), p);
+ if ((error = namei(&nd)))
+ return (error);
+ error = vn_stat(nd.ni_vp, &sb, p);
+ vput(nd.ni_vp);
+ if (error)
+ return (error);
+ cvtstat2osf1(&sb, &osb);
+ error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
+ return (error);
+}
+
+
+/*
+ * Return status information about a file descriptor.
+ */
+int
+osf1_fstat(p, uap)
+ struct proc *p;
+ register struct osf1_fstat_args *uap;
+{
+ register struct filedesc *fdp = p->p_fd;
+ register struct file *fp;
+ struct stat ub;
+ struct osf1_stat oub;
+ int error;
+
+ if ((unsigned)SCARG(uap, fd) >= fdp->fd_nfiles ||
+ (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
+ return (EBADF);
+
+ error = fo_stat(fp, &ub, p);
+ cvtstat2osf1(&ub, &oub);
+ if (error == 0)
+ error = copyout((caddr_t)&oub, (caddr_t)SCARG(uap, sb),
+ sizeof (oub));
+ return (error);
+}
+
+
+#if 1
+#define bsd2osf_dev(dev) (umajor(dev) << 20 | uminor(dev))
+#define osf2bsd_dev(dev) umakedev((umajor(dev) >> 20) & 0xfff, uminor(dev) & 0xfffff)
+#else
+#define minor(x) ((int)((x)&0xffff00ff))
+#define major(x) ((int)(((u_int)(x) >> 8)&0xff))
+#define makedev(x,y) ((dev_t)(((x) << 8) | (y)))
+#define bsd2osf_dev(dev) (major(dev) << 20 | minor(dev))
+#define osf2bsd_dev(dev) makedev(((dev) >> 20) & 0xfff, (dev) & 0xfffff)
+#endif
+/*
+ * Convert from a stat structure to an osf1 stat structure.
+ */
+static void
+cvtstat2osf1(st, ost)
+ struct stat *st;
+ struct osf1_stat *ost;
+{
+
+ ost->st_dev = bsd2osf_dev(st->st_dev);
+ ost->st_ino = st->st_ino;
+ ost->st_mode = st->st_mode;
+ ost->st_nlink = st->st_nlink;
+ ost->st_uid = st->st_uid == -2 ? (u_int16_t) -2 : st->st_uid;
+ ost->st_gid = st->st_gid == -2 ? (u_int16_t) -2 : st->st_gid;
+ ost->st_rdev = bsd2osf_dev(st->st_rdev);
+ ost->st_size = st->st_size;
+ ost->st_atime_sec = st->st_atime;
+ ost->st_spare1 = 0;
+ ost->st_mtime_sec = st->st_mtime;
+ ost->st_spare2 = 0;
+ ost->st_ctime_sec = st->st_ctime;
+ ost->st_spare3 = 0;
+ ost->st_blksize = st->st_blksize;
+ ost->st_blocks = st->st_blocks;
+ ost->st_flags = st->st_flags;
+ ost->st_gen = st->st_gen;
+}
+
+
+int
+osf1_mknod(p, uap)
+ struct proc *p;
+ struct osf1_mknod_args *uap;
+{
+#if notanymore
+ struct mknod_args a;
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, uap->path);
+
+ SCARG(&a, path) = SCARG(uap, path);
+ SCARG(&a, mode) = SCARG(uap, mode);
+ SCARG(&a, dev) = osf2bsd_dev(SCARG(uap, dev));
+
+ return mknod(p, &a);
+#endif
+ printf("osf1_mknod no longer implemented\n");
+ return ENOSYS;
+}
+
+
+int
+osf1_access(p, uap)
+ struct proc *p;
+ struct osf1_access_args *uap;
+{
+ caddr_t sg;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, uap->path);
+
+ return access(p, (struct access_args *)uap);
+}
+
+
+struct osf1_flock {
+ short l_type;
+ short l_whence;
+ off_t l_start;
+ off_t l_len;
+ pid_t l_pid;
+ };
+
+int
+osf1_fcntl(p, uap)
+ struct proc *p;
+ struct osf1_fcntl_args *uap;
+{
+ int error;
+ long tmp;
+ caddr_t oarg, sg;
+ struct fcntl_args a;
+ struct osf1_flock osf_flock;
+ struct flock bsd_flock;
+ struct flock *nflock;
+
+ error = 0;
+
+ switch (SCARG(uap, cmd)) {
+
+ case F_SETFL:
+ SCARG(&a, fd) = SCARG(uap, fd);
+ SCARG(&a, cmd) = F_SETFL;
+ /* need to translate flags here */
+ tmp = 0;
+ if ((long)SCARG(uap, arg) & OSF1_FNONBLOCK)
+ tmp |= FNONBLOCK;
+ if ((long)SCARG(uap, arg) & OSF1_FAPPEND)
+ tmp |= FAPPEND;
+ if ((long)SCARG(uap, arg) & OSF1_FDEFER)
+ tmp |= FDEFER;
+ if ((long)SCARG(uap, arg) & OSF1_FASYNC)
+ tmp |= FASYNC;
+ if ((long)SCARG(uap, arg) & OSF1_FCREAT)
+ tmp |= O_CREAT;
+ if ((long)SCARG(uap, arg) & OSF1_FTRUNC)
+ tmp |= O_TRUNC;
+ if ((long)SCARG(uap, arg) & OSF1_FEXCL)
+ tmp |= O_EXCL;
+ if ((long)SCARG(uap, arg) & OSF1_FNDELAY)
+ tmp |= FNDELAY;
+ if ((long)SCARG(uap, arg) & OSF1_FSYNC)
+ tmp |= FFSYNC;
+ SCARG(&a, arg) = tmp;
+ error = fcntl(p, &a);
+ break;
+
+ case F_SETLK:
+ case F_SETLKW:
+ case F_GETLK:
+ /*
+ * The OSF/1 flock stucture has a different order than
+ * the BSD one, but all else is the same. We must
+ * reorder the one we've gotten so that flock() groks it.
+ */
+ if ((error = copyin(uap->arg, &osf_flock, sizeof(osf_flock))))
+ return error;
+ bsd_flock.l_type = osf_flock.l_type;
+ bsd_flock.l_whence = osf_flock.l_whence;
+ bsd_flock.l_start = osf_flock.l_start;
+ bsd_flock.l_len = osf_flock.l_len;
+ bsd_flock.l_pid = osf_flock.l_pid;
+ sg = stackgap_init();
+ nflock = stackgap_alloc(&sg, sizeof(struct flock));
+ if ((error = copyout(&bsd_flock, nflock, sizeof(bsd_flock))) != 0)
+ return error;
+ oarg = uap->arg;
+ uap->arg = nflock;
+ error = fcntl(p, (struct fcntl_args *) uap);
+/* if (error) {
+ printf("fcntl called with cmd=%d, args=0x%lx\n returns %d\n",uap->cmd,(long)uap->arg,error);
+ printf("bsd_flock.l_type = 0x%x\n", bsd_flock.l_type);
+ printf("bsd_flock.l_whence = 0x%x\n", bsd_flock.l_whence);
+ printf("bsd_flock.l_start = 0x%lx\n", bsd_flock.l_start);
+ printf("bsd_flock.l_len = 0x%lx\n", bsd_flock.l_len);
+ printf("bsd_flock.l_pid = 0x%x\n", bsd_flock.l_pid);
+ }
+*/
+ if ((uap->cmd == F_GETLK) && !error) {
+ osf_flock.l_type = F_UNLCK;
+ if ((error = copyout(&osf_flock, oarg,
+ sizeof(osf_flock))))
+ return error;
+ }
+ break;
+ default:
+ error = fcntl(p, (struct fcntl_args *) uap);
+
+ if ((uap->cmd == OSF1_F_GETFL) && !error ) {
+ tmp = p->p_retval[0] & O_ACCMODE;
+ if (p->p_retval[0] & FNONBLOCK)
+ tmp |= OSF1_FNONBLOCK;
+ if (p->p_retval[0] & FAPPEND)
+ tmp |= OSF1_FAPPEND;
+ if (p->p_retval[0] & FDEFER)
+ tmp |= OSF1_FDEFER;
+ if (p->p_retval[0] & FASYNC)
+ tmp |= OSF1_FASYNC;
+ if (p->p_retval[0] & O_CREAT)
+ tmp |= OSF1_FCREAT;
+ if (p->p_retval[0] & O_TRUNC)
+ tmp |= OSF1_FTRUNC;
+ if (p->p_retval[0] & O_EXCL)
+ tmp |= OSF1_FEXCL;
+ if (p->p_retval[0] & FNDELAY)
+ tmp |= OSF1_FNDELAY;
+ if (p->p_retval[0] & FFSYNC)
+ tmp |= OSF1_FSYNC;
+ p->p_retval[0] = tmp;
+ }
+ }
+
+ return (error);
+}
+
+
+#if 0
+int
+osf1_fcntl(p, uap)
+ struct proc *p;
+ struct osf1_fcntl_args *uap;
+{
+ struct fcntl_args a;
+ long tmp;
+ int error;
+
+ SCARG(&a, fd) = SCARG(uap, fd);
+
+ switch (SCARG(uap, cmd)) {
+
+ case OSF1_F_DUPFD:
+ SCARG(&a, cmd) = F_DUPFD;
+ SCARG(&a, arg) = (long)SCARG(uap, arg);
+ break;
+
+ case OSF1_F_GETFD:
+ SCARG(&a, cmd) = F_GETFD;
+ SCARG(&a, arg) = (long)SCARG(uap, arg);
+ break;
+
+ case OSF1_F_SETFD:
+ SCARG(&a, cmd) = F_SETFD;
+ SCARG(&a, arg) = (long)SCARG(uap, arg);
+ break;
+
+ case OSF1_F_GETFL:
+ SCARG(&a, cmd) = F_GETFL;
+ SCARG(&a, arg) = (long)SCARG(uap, arg); /* ignored */
+ break;
+
+ case OSF1_F_SETFL:
+ SCARG(&a, cmd) = F_SETFL;
+ tmp = 0;
+ if ((long)SCARG(uap, arg) & OSF1_FAPPEND)
+ tmp |= FAPPEND;
+ if ((long)SCARG(uap, arg) & OSF1_FNONBLOCK)
+ tmp |= FNONBLOCK;
+ if ((long)SCARG(uap, arg) & OSF1_FASYNC)
+ tmp |= FASYNC;
+ if ((long)SCARG(uap, arg) & OSF1_FSYNC)
+ tmp |= FFSYNC;
+ SCARG(&a, arg) = tmp;
+ break;
+
+ default: /* XXX other cases */
+ return (EINVAL);
+ }
+
+ error = fcntl(p, &a);
+
+ if (error)
+ return error;
+
+ switch (SCARG(uap, cmd)) {
+ case OSF1_F_GETFL:
+ /* XXX */
+ break;
+ }
+
+ return error;
+}
+#endif
+
+int
+osf1_socket(p, uap)
+ struct proc *p;
+ struct osf1_socket_args *uap;
+{
+ struct socket_args a;
+
+ if (SCARG(uap, type) > AF_LINK)
+ return (EINVAL); /* XXX After AF_LINK, divergence. */
+
+ SCARG(&a, domain) = SCARG(uap, domain);
+ SCARG(&a, type) = SCARG(uap, type);
+ SCARG(&a, protocol) = SCARG(uap, protocol);
+
+ return socket(p, &a);
+}
+
+
+int
+osf1_sendto(p, uap)
+ struct proc *p;
+ register struct osf1_sendto_args *uap;
+{
+ struct sendto_args a;
+
+ if (SCARG(uap, flags) & ~0x7f) /* unsupported flags */
+ return (EINVAL);
+
+ SCARG(&a, s) = SCARG(uap, s);
+ SCARG(&a, buf) = SCARG(uap, buf);
+ SCARG(&a, len) = SCARG(uap, len);
+ SCARG(&a, flags) = SCARG(uap, flags);
+ SCARG(&a, to) = (caddr_t)SCARG(uap, to);
+ SCARG(&a, tolen) = SCARG(uap, tolen);
+
+ return sendto(p, &a);
+}
+
+
+int
+osf1_reboot(p, uap)
+ struct proc *p;
+ struct osf1_reboot_args *uap;
+{
+ struct reboot_args a;
+
+ if (SCARG(uap, opt) & ~OSF1_RB_ALLFLAGS &&
+ SCARG(uap, opt) & (OSF1_RB_ALTBOOT|OSF1_RB_UNIPROC))
+ return (EINVAL);
+
+ SCARG(&a, opt) = 0;
+
+ if (SCARG(uap, opt) & OSF1_RB_ASKNAME)
+ SCARG(&a, opt) |= RB_ASKNAME;
+ if (SCARG(uap, opt) & OSF1_RB_SINGLE)
+ SCARG(&a, opt) |= RB_SINGLE;
+ if (SCARG(uap, opt) & OSF1_RB_NOSYNC)
+ SCARG(&a, opt) |= RB_NOSYNC;
+ if (SCARG(uap, opt) & OSF1_RB_HALT)
+ SCARG(&a, opt) |= RB_HALT;
+ if (SCARG(uap, opt) & OSF1_RB_INITNAME)
+ SCARG(&a, opt) |= RB_INITNAME;
+ if (SCARG(uap, opt) & OSF1_RB_DFLTROOT)
+ SCARG(&a, opt) |= RB_DFLTROOT;
+
+ return reboot(p, &a);
+}
+
+
+int
+osf1_lseek(p, uap)
+ struct proc *p;
+ struct osf1_lseek_args *uap;
+{
+ struct lseek_args a;
+
+ SCARG(&a, fd) = SCARG(uap, fd);
+ SCARG(&a, pad) = 0;
+ SCARG(&a, offset) = SCARG(uap, offset);
+ SCARG(&a, whence) = SCARG(uap, whence);
+
+ return lseek(p, &a);
+}
+
+
+/*
+ * OSF/1 defines _POSIX_SAVED_IDS, which means that our normal
+ * setuid() won't work.
+ *
+ * Instead, by P1003.1b-1993, setuid() is supposed to work like:
+ * If the process has appropriate [super-user] priviledges, the
+ * setuid() function sets the real user ID, effective user
+ * ID, and the saved set-user-ID to uid.
+ * If the process does not have appropriate priviledges, but uid
+ * is equal to the real user ID or the saved set-user-ID, the
+ * setuid() function sets the effective user ID to uid; the
+ * real user ID and saved set-user-ID remain unchanged by
+ * this function call.
+ */
+int
+osf1_setuid(p, uap)
+ struct proc *p;
+ struct osf1_setuid_args *uap;
+{
+ int error;
+ uid_t uid;
+ register struct pcred *pc;
+
+ uid = SCARG(uap, uid);
+ pc = p->p_cred;
+
+ if ((error = suser(p)) != 0 &&
+ uid != pc->p_ruid && uid != pc->p_svuid)
+ return (error);
+
+ pc->pc_ucred = crcopy(pc->pc_ucred);
+ pc->pc_ucred->cr_uid = uid;
+ if (error == 0) {
+ (void)chgproccnt(pc->p_ruid, -1);
+ (void)chgproccnt(uid, 1);
+ pc->p_ruid = uid;
+ pc->p_svuid = uid;
+ }
+ p->p_flag |= P_SUGID;
+ return (0);
+}
+
+
+/*
+ * OSF/1 defines _POSIX_SAVED_IDS, which means that our normal
+ * setgid() won't work.
+ *
+ * If you change "uid" to "gid" in the discussion, above, about
+ * setuid(), you'll get a correct description of setgid().
+ */
+int
+osf1_setgid(p, uap)
+ struct proc *p;
+ struct osf1_setgid_args *uap;
+{
+ int error;
+ gid_t gid;
+ register struct pcred *pc;
+
+ gid = SCARG(uap, gid);
+ pc = p->p_cred;
+
+ if (((error = suser(p)) != 0 ) &&
+ gid != pc->p_rgid && gid != pc->p_svgid)
+ return (error);
+
+ pc->pc_ucred = crcopy(pc->pc_ucred);
+ pc->pc_ucred->cr_gid = gid;
+ if (error == 0) {
+ pc->p_rgid = gid;
+ pc->p_svgid = gid;
+ }
+ p->p_flag |= P_SUGID;
+ return (0);
+}
+
+
+/*
+ * The structures end up being the same... but we can't be sure that
+ * the other word of our iov_len is zero!
+ */
+struct osf1_iovec {
+ char *iov_base;
+ int iov_len;
+};
+#define STACKGAPLEN 400
+int
+osf1_readv(p, uap)
+ struct proc *p;
+ struct osf1_readv_args *uap;
+{
+ int error, osize, nsize, i;
+ caddr_t sg;
+ struct readv_args /* {
+ syscallarg(int) fd;
+ syscallarg(struct iovec *) iovp;
+ syscallarg(u_int) iovcnt;
+ } */ a;
+ struct osf1_iovec *oio;
+ struct iovec *nio;
+
+ sg = stackgap_init();
+
+ if (SCARG(uap, iovcnt) > (STACKGAPLEN / sizeof (struct iovec)))
+ return (EINVAL);
+
+ osize = SCARG(uap, iovcnt) * sizeof (struct osf1_iovec);
+ nsize = SCARG(uap, iovcnt) * sizeof (struct iovec);
+
+ oio = malloc(osize, M_TEMP, M_WAITOK);
+ nio = malloc(nsize, M_TEMP, M_WAITOK);
+
+ error = 0;
+ if ((error = copyin(SCARG(uap, iovp), oio, osize)))
+ goto punt;
+ for (i = 0; i < SCARG(uap, iovcnt); i++) {
+ nio[i].iov_base = oio[i].iov_base;
+ nio[i].iov_len = oio[i].iov_len;
+ }
+
+ SCARG(&a, fd) = SCARG(uap, fd);
+ SCARG(&a, iovp) = stackgap_alloc(&sg, nsize);
+ SCARG(&a, iovcnt) = SCARG(uap, iovcnt);
+
+ if ((error = copyout(nio, (caddr_t)SCARG(&a, iovp), nsize)))
+ goto punt;
+ error = readv(p, &a);
+
+punt:
+ free(oio, M_TEMP);
+ free(nio, M_TEMP);
+ return (error);
+}
+
+
+int
+osf1_writev(p, uap)
+ struct proc *p;
+ struct osf1_writev_args *uap;
+{
+ int error, i, nsize, osize;
+ caddr_t sg;
+ struct writev_args /* {
+ syscallarg(int) fd;
+ syscallarg(struct iovec *) iovp;
+ syscallarg(u_int) iovcnt;
+ } */ a;
+ struct osf1_iovec *oio;
+ struct iovec *nio;
+
+ sg = stackgap_init();
+
+ if (SCARG(uap, iovcnt) > (STACKGAPLEN / sizeof (struct iovec)))
+ return (EINVAL);
+
+ osize = SCARG(uap, iovcnt) * sizeof (struct osf1_iovec);
+ nsize = SCARG(uap, iovcnt) * sizeof (struct iovec);
+
+ oio = malloc(osize, M_TEMP, M_WAITOK);
+ nio = malloc(nsize, M_TEMP, M_WAITOK);
+
+ error = 0;
+ if ((error = copyin(SCARG(uap, iovp), oio, osize)))
+ goto punt;
+ for (i = 0; i < SCARG(uap, iovcnt); i++) {
+ nio[i].iov_base = oio[i].iov_base;
+ nio[i].iov_len = oio[i].iov_len;
+ }
+
+ SCARG(&a, fd) = SCARG(uap, fd);
+ SCARG(&a, iovp) = stackgap_alloc(&sg, nsize);
+ SCARG(&a, iovcnt) = SCARG(uap, iovcnt);
+
+ if ((error = copyout(nio, (caddr_t)SCARG(&a, iovp), nsize)))
+ goto punt;
+ error = writev(p, &a);
+
+punt:
+ free(oio, M_TEMP);
+ free(nio, M_TEMP);
+ return (error);
+}
+
+
+/*
+ * More of the stupid off_t padding!
+ */
+int
+osf1_truncate(p, uap)
+ struct proc *p;
+ struct osf1_truncate_args *uap;
+{
+ caddr_t sg;
+ struct truncate_args a;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, uap->path);
+
+ SCARG(&a, path) = SCARG(uap, path);
+ SCARG(&a, pad) = 0;
+ SCARG(&a, length) = SCARG(uap, length);
+
+ return truncate(p, &a);
+}
+
+
+int
+osf1_ftruncate(p, uap)
+ struct proc *p;
+ struct osf1_ftruncate_args *uap;
+{
+ struct ftruncate_args a;
+
+ SCARG(&a, fd) = SCARG(uap, fd);
+ SCARG(&a, pad) = 0;
+ SCARG(&a, length) = SCARG(uap, length);
+
+ return ftruncate(p, &a);
+}
+
+
+static int
+osf2bsd_pathconf(name)
+ int *name;
+{
+
+ switch (*name) {
+ case _OSF1_PC_LINK_MAX:
+ case _OSF1_PC_MAX_CANON:
+ case _OSF1_PC_MAX_INPUT:
+ case _OSF1_PC_NAME_MAX:
+ *name -= 10;
+ break;
+
+ case _OSF1_PC_PATH_MAX:
+ case _OSF1_PC_PIPE_BUF:
+ *name -= 9;
+
+ case _OSF1_PC_NO_TRUNC:
+ *name = _PC_NO_TRUNC;
+ break;
+
+ case _OSF1_PC_CHOWN_RESTRICTED:
+ *name = _PC_CHOWN_RESTRICTED;
+ break;
+
+ case _OSF1_PC_VDISABLE:
+ *name = _PC_VDISABLE;
+ break;
+
+ default:
+ return (EINVAL);
+ }
+ return 0;
+}
+
+
+int
+osf1_pathconf(p, uap)
+ struct proc *p;
+ struct osf1_pathconf_args *uap;
+{
+
+ if (osf2bsd_pathconf(&uap->name))
+ return (EINVAL);
+ else
+ return (pathconf(p, (void *)uap));
+}
+
+
+int
+osf1_fpathconf(p, uap)
+ struct proc *p;
+ struct osf1_fpathconf_args *uap;
+{
+
+ if (osf2bsd_pathconf(&uap->name))
+ return (EINVAL);
+ else
+ return (fpathconf(p, (void *)uap));
+}
+
+
+int
+osf1_getrusage(p, uap)
+ struct proc *p;
+ struct osf1_getrusage_args *uap;
+{
+ struct rusage *rup;
+ struct osf1_rusage oru;
+
+ switch (uap->who) {
+ case RUSAGE_SELF:
+ rup = &p->p_stats->p_ru;
+ calcru(p, &rup->ru_utime, &rup->ru_stime, NULL);
+ break;
+
+ case RUSAGE_CHILDREN:
+ rup = &p->p_stats->p_cru;
+ break;
+
+ default:
+ return (EINVAL);
+ }
+ TV_CP(rup->ru_utime, oru.ru_utime);
+ TV_CP(rup->ru_stime, oru.ru_stime);
+ bcopy(&(rup->ru_first), &(oru.ru_first),
+ (&(oru.ru_last) - &(oru.ru_first)));
+
+ return (copyout((caddr_t)&oru, (caddr_t)uap->rusage,
+ sizeof (struct osf1_rusage)));
+}
+
+
+int
+osf1_wait4(p, uap)
+ struct proc *p;
+ struct osf1_wait4_args *uap;
+{
+ int error;
+ caddr_t sg;
+ struct osf1_rusage *orusage, oru;
+ struct rusage *rusage, ru;
+
+ sg = stackgap_init();
+ rusage = stackgap_alloc(&sg, sizeof(struct rusage));
+ orusage = SCARG(uap, rusage);
+ SCARG(uap, rusage) = (struct osf1_rusage *)rusage;
+ if ((error = wait4(p, (struct wait_args *)uap) != 0))
+ return error;
+ if (orusage && (error = copyin(rusage, &ru, sizeof(ru)) == 0)){
+ TV_CP(ru.ru_utime, oru.ru_utime);
+ TV_CP(ru.ru_stime, oru.ru_stime);
+ bcopy(&ru.ru_first, &oru.ru_first,
+ (&(oru.ru_last) - &(oru.ru_first)));
+ copyout(&oru, orusage, sizeof (struct osf1_rusage));
+ }
+ return (0);
+}
+
+
+int
+osf1_madvise(p, uap)
+ struct proc *p;
+ struct osf1_madvise_args *uap;
+{
+
+ /* XXX */
+ return EINVAL;
+}
+
+
+int
+osf1_execve(p, uap)
+ struct proc *p;
+ struct osf1_execve_args *uap;
+{
+ caddr_t sg;
+ struct execve_args ap;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(p, &sg, SCARG(uap, path));
+
+ SCARG(&ap, fname) = SCARG(uap, path);
+ SCARG(&ap, argv) = SCARG(uap, argp);
+ SCARG(&ap, envv) = SCARG(uap, envp);
+
+ return execve(p, &ap);
+}
+
+
+int
+osf1_usleep_thread(p, uap)
+ struct proc *p;
+ struct osf1_usleep_thread_args *uap;
+{
+ int error, s, timo;
+ struct osf1_timeval time;
+ struct timeval difftv, endtv, sleeptv, tv;
+
+ if ((error = copyin(SCARG(uap, sleep), &time, sizeof time)))
+ return (error);
+
+ sleeptv.tv_sec = (u_long)time.tv_sec;
+ sleeptv.tv_usec = (u_long)time.tv_usec;
+ timo = tvtohz(&sleeptv);
+
+ /*
+ * Some callers use usleep(0) as a sort of thread-yield so make
+ * sure that the timeout is non-zero.
+ */
+
+ if (timo == 0)
+ timo = 1;
+ s = splclock();
+ microtime(&tv);
+ splx(s);
+
+ tsleep(p, PUSER|PCATCH, "OSF/1", timo);
+
+ if (SCARG(uap, slept) != NULL) {
+ s = splclock();
+ microtime(&endtv);
+ timersub(&time, &endtv, &difftv);
+ splx(s);
+ if (tv.tv_sec < 0 || tv.tv_usec < 0)
+ tv.tv_sec = tv.tv_usec = 0;
+ TV_CP(difftv, time)
+ error = copyout(&time, SCARG(uap, slept), sizeof time);
+ }
+ return (error);
+}
+
+
+int osf1_gettimeofday(p, uap)
+ struct proc *p;
+ register struct osf1_gettimeofday_args *uap;
+{
+ int error;
+ struct timeval atv;
+ struct osf1_timeval otv;
+
+ error = 0;
+
+ if (uap->tp) {
+ microtime(&atv);
+ otv.tv_sec = atv.tv_sec;
+ otv.tv_usec = atv.tv_usec;
+ if ((error = copyout((caddr_t)&otv, (caddr_t)uap->tp,
+ sizeof (otv))))
+ return (error);
+ }
+ if (uap->tzp)
+ error = copyout((caddr_t)&tz, (caddr_t)uap->tzp, sizeof (tz));
+ return (error);
+}
+
+
+int osf1_select(p, uap)
+ struct proc *p;
+ register struct osf1_select_args *uap;
+{
+ if (uap->tv) {
+ int error;
+ caddr_t sg;
+ struct osf1_timeval otv;
+ struct timeval tv;
+
+ sg = stackgap_init();
+
+ if ((error=copyin((caddr_t)uap->tv,(caddr_t)&otv,sizeof(otv))))
+ return(error);
+ TV_CP(otv,tv);
+ uap->tv = stackgap_alloc(&sg, sizeof(struct timeval));
+ if ((error=copyout((caddr_t)&tv, (caddr_t)uap->tv,sizeof(tv))))
+ return(error);
+ }
+ return(select(p, (struct select_args *)uap));
+}
+
+
+int
+osf1_setitimer(p, uap)
+ struct proc *p;
+ struct osf1_setitimer_args *uap;
+{
+
+ int error;
+ caddr_t old_oitv, sg;
+ struct itimerval itv;
+ struct osf1_itimerval otv;
+
+ error = 0;
+ old_oitv = (caddr_t)uap->oitv;
+ sg = stackgap_init();
+
+ if ((error = copyin((caddr_t)uap->itv,(caddr_t)&otv,sizeof(otv)))) {
+ printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
+ return error;
+ }
+ TV_CP(otv.it_interval,itv.it_interval);
+ TV_CP(otv.it_value,itv.it_value);
+ uap->itv = stackgap_alloc(&sg, sizeof(struct itimerval));
+ if ((error = copyout((caddr_t)&itv,(caddr_t)uap->itv,sizeof(itv)))) {
+ printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
+ return error;
+ }
+ uap->oitv = stackgap_alloc(&sg, sizeof(struct itimerval));
+ if ((error = setitimer(p, (struct setitimer_args *)uap))) {
+ printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
+ return error;
+ }
+ if ((error = copyin((caddr_t)uap->oitv,(caddr_t)&itv,sizeof(itv)))) {
+ printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
+ return error;
+ }
+ TV_CP(itv.it_interval,otv.it_interval);
+ TV_CP(itv.it_value,otv.it_value);
+ if (old_oitv
+ && (error = copyout((caddr_t)&otv, old_oitv, sizeof(otv)))) {
+ printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
+ }
+ return error;
+}
+
+
+int
+osf1_getitimer(p, uap)
+ struct proc *p;
+ struct osf1_getitimer_args *uap;
+{
+ int error;
+ caddr_t old_itv, sg;
+ struct itimerval itv;
+ struct osf1_itimerval otv;
+
+ error = 0;
+ old_itv = (caddr_t)uap->itv;
+ sg = stackgap_init();
+
+ uap->itv = stackgap_alloc(&sg, sizeof(struct itimerval));
+ if ((error = getitimer(p, (struct getitimer_args *)uap))) {
+ printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
+ return error;
+ }
+ if ((error = copyin((caddr_t)uap->itv,(caddr_t)&itv,sizeof(itv)))) {
+ printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
+ return error;
+ }
+ TV_CP(itv.it_interval,otv.it_interval);
+ TV_CP(itv.it_value,otv.it_value);
+ if ((error = copyout((caddr_t)&otv, old_itv, sizeof(otv)))) {
+ printf("%s(%d): error = %d\n", __FILE__, __LINE__, error);
+ }
+ return error;
+}
+
+
+int
+osf1_proplist_syscall(p, uap)
+ struct proc *p;
+ struct osf1_proplist_syscall_args *uap;
+{
+
+ return(EOPNOTSUPP);
+}
+
+
+int
+osf1_ntpgettime(p, uap)
+ struct proc *p;
+ struct osf1_ntpgettime_args *uap;
+{
+
+ return(ENOSYS);
+}
+
+
+int
+osf1_ntpadjtime(p, uap)
+ struct proc *p;
+ struct osf1_ntpadjtime_args *uap;
+{
+
+ return(ENOSYS);
+}
+
+
+int
+osf1_setpgrp(p, uap)
+ struct proc *p;
+ struct osf1_setpgrp_args *uap;
+{
+
+ return(setpgid(p, (struct setpgid_args *)uap));
+}
+
+
+int
+osf1_uswitch(p, uap)
+ struct proc *p;
+ struct osf1_uswitch_args *uap;
+{
+ int rv;
+ vm_map_entry_t entry;
+ vm_offset_t zero;
+
+ zero = 0;
+
+ if (uap->cmd == OSF1_USC_GET) {
+ if (vm_map_lookup_entry(&(p->p_vmspace->vm_map),0, &entry))
+ p->p_retval[0] = OSF1_USW_NULLP;
+ else
+ p->p_retval[0] = 0;
+ return(KERN_SUCCESS);
+ } else if (uap->cmd == OSF1_USC_SET)
+ if (uap->mask & OSF1_USW_NULLP) {
+ rv = vm_mmap(&(p->p_vmspace->vm_map), &zero, PAGE_SIZE,
+ VM_PROT_READ, VM_PROT_ALL,
+ MAP_PRIVATE | MAP_FIXED | MAP_ANON, NULL, 0);
+ if (!rv)
+ return(KERN_SUCCESS);
+ else {
+ printf(
+ "osf1_uswitch:vm_mmap of zero page failed with status %d\n",
+ rv);
+ return(rv);
+ }
+ }
+ return(EINVAL);
+}
+
+
+int
+osf1_classcntl(p, uap)
+ struct proc *p;
+ struct osf1_classcntl_args *uap;
+{
+
+ return(EACCES); /* class scheduling not enabled */
+}
+
+
+struct osf1_tbl_loadavg
+{
+ union {
+ long l[3];
+ double d[3];
+ } tl_avenrun;
+ int tl_lscale;
+ long tl_mach_factor[3]; /* ???? */
+};
+
+struct osf1_tbl_sysinfo {
+ long si_user;
+ long si_nice;
+ long si_sys;
+ long si_idle;
+ long si_hz;
+ long si_phz;
+ long si_boottime;
+ long wait;
+};
+
+#define TBL_LOADAVG 3
+#define TBL_SYSINFO 12
+
+int
+osf1_table(p, uap)
+ struct proc *p;
+ struct osf1_table_args /*{
+ long id;
+ long index;
+ void *addr;
+ long nel;
+ u_long lel;
+ }*/ *uap;
+{
+ int retval;
+ struct osf1_tbl_loadavg ld;
+ struct osf1_tbl_sysinfo si;
+
+ retval = 0;
+
+ switch(uap->id) {
+ case TBL_LOADAVG: /* xemacs wants this */
+ if ((uap->index != 0) || (uap->nel != 1))
+ retval = EINVAL;
+ bcopy(&averunnable, &ld, sizeof(averunnable));
+ ld.tl_lscale = (u_int)averunnable.fscale;
+ retval = copyout(&ld, uap->addr, sizeof(ld));
+ break;
+ case TBL_SYSINFO:
+ if ((uap->index != 0) || (uap->nel != 1))
+ retval = EINVAL;
+ bzero(&si, sizeof(si));
+#if 0
+ si.si_user = cp_time[CP_USER];
+ si.si_nice = cp_time[CP_NICE];
+ si.si_sys = cp_time[CP_SYS];
+ si.si_idle = cp_time[CP_IDLE];
+ si.wait = cp_time[CP_INTR];
+#endif
+ si.si_hz = hz;
+ si.si_phz = profhz;
+ si.si_boottime = boottime.tv_sec;
+ retval = copyout(&si, uap->addr, sizeof(si));
+ break;
+ default:
+ printf("osf1_table: %ld, %ld, %p, %ld %ld\n",
+ uap->id, uap->index, uap->addr, uap->nel, uap->lel);
+ retval = EINVAL;
+ }
+ return retval;
+}
+
+
+int
+osf1_sysinfo(p, uap)
+ struct proc *p;
+ struct osf1_sysinfo_args /*{
+ int cmd;
+ char *buf;
+ long count;
+ }*/ *uap;
+{
+ int name[2], retval;
+ size_t bytes, len;
+ char *string;
+
+ string = NULL;
+
+ switch(uap->cmd) {
+ case 1: /* OS */
+ string = "OSF1";
+ break;
+ case 2: /* hostname, from ogethostname */
+ len = uap->count;
+ name[0] = CTL_KERN;
+ name[1] = KERN_HOSTNAME;
+ retval = userland_sysctl(p, name, 2, uap->buf, &len,
+ 1, 0, 0, &bytes);
+ p->p_retval[0] = bytes;
+ return(retval);
+ break;
+ case 3: /* release of osf1 */
+ string = "V4.0";
+ break;
+ case 4: /* minor version of osf1 */
+ string = "878";
+ break;
+ case 5: /* machine or arch */
+ case 6:
+ string = "alpha";
+ break;
+ case 7: /* serial number, real osf1 returns 0! */
+ string = "0";
+ break;
+ case 8: /* HW vendor */
+ string = "Digital";
+ break;
+ case 9: /* dunno, this is what du does.. */
+ return(ENOSYS);
+ break;
+ default:
+ return(EINVAL);
+ }
+ bytes = min(uap->count, strlen(string)+1);
+ copyout(string, uap->buf, bytes);
+ p->p_retval[0] = bytes;
+ return(0);
+}
diff --git a/sys/alpha/osf1/osf1_mount.c b/sys/alpha/osf1/osf1_mount.c
new file mode 100644
index 000000000000..6d3ba9e2eba1
--- /dev/null
+++ b/sys/alpha/osf1/osf1_mount.c
@@ -0,0 +1,391 @@
+/* $NetBSD: osf1_mount.c,v 1.7 1998/05/20 16:34:29 chs Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * Additional Copyright (c) 1999 by Andrew Gallatin
+ * $FreeBSD$
+ */
+
+#include "opt_nfs.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysproto.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/vnode.h>
+#include <sys/malloc.h>
+#include <sys/mount.h>
+#include <sys/proc.h>
+#include <sys/buf.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/domain.h>
+#include <sys/protosw.h>
+#include <sys/namei.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#ifdef ISO
+#include <netiso/iso.h>
+#endif
+#include <nfs/xdr_subs.h>
+#include <nfs/rpcv2.h>
+#include <nfs/nfsproto.h>
+#include <nfs/nfs.h>
+#include <nfs/nfsm_subs.h>
+#include <nfs/nfsrvcache.h>
+#include <nfs/nfsmount.h>
+#include <nfs/nfsnode.h>
+#include <nfs/nqnfs.h>
+#include <nfs/nfsrtt.h>
+
+#include <sys/sysent.h>
+#include <alpha/osf1/osf1_signal.h>
+#include <alpha/osf1/osf1_proto.h>
+#include <alpha/osf1/osf1_syscall.h>
+#include <alpha/osf1/osf1_util.h>
+#include <alpha/osf1/osf1.h>
+
+
+void bsd2osf_statfs __P((struct statfs *, struct osf1_statfs *));
+int osf1_mount_mfs __P((struct proc *, struct osf1_mount_args *,
+ struct mount_args *));
+int osf1_mount_nfs __P((struct proc *, struct osf1_mount_args *,
+ struct mount_args *));
+
+#ifdef notanymore
+static const char *fsnames[OSF1_MOUNT_MAXTYPE+2] = INITMOUNTNAMES;
+#endif
+
+void
+bsd2osf_statfs(bsfs, osfs)
+ struct statfs *bsfs;
+ struct osf1_statfs *osfs;
+{
+
+#ifdef notanymore
+bzero(osfs, sizeof (struct osf1_statfs));
+ if (!strncmp(fsnames[MOUNT_UFS], bsfs->f_fstypename, MFSNAMELEN))
+ osfs->f_type = OSF1_MOUNT_UFS;
+ else if (!strncmp(fsnames[MOUNT_NFS], bsfs->f_fstypename, MFSNAMELEN))
+ osfs->f_type = OSF1_MOUNT_NFS;
+ else if (!strncmp(fsnames[MOUNT_MFS], bsfs->f_fstypename, MFSNAMELEN))
+ osfs->f_type = OSF1_MOUNT_MFS;
+ else
+ /* uh oh... XXX = PC, CDFS, PROCFS, etc. */
+ osfs->f_type = OSF1_MOUNT_ADDON;
+ osfs->f_flags = bsfs->f_flags; /* XXX translate */
+ osfs->f_fsize = bsfs->f_bsize;
+ osfs->f_bsize = bsfs->f_iosize;
+ osfs->f_blocks = bsfs->f_blocks;
+ osfs->f_bfree = bsfs->f_bfree;
+ osfs->f_bavail = bsfs->f_bavail;
+ osfs->f_files = bsfs->f_files;
+ osfs->f_ffree = bsfs->f_ffree;
+ bcopy(&bsfs->f_fsid, &osfs->f_fsid,
+ max(sizeof bsfs->f_fsid, sizeof osfs->f_fsid));
+ /* osfs->f_spare zeroed above */
+ bcopy(bsfs->f_mntonname, osfs->f_mntonname,
+ max(sizeof bsfs->f_mntonname, sizeof osfs->f_mntonname));
+ bcopy(bsfs->f_mntfromname, osfs->f_mntfromname,
+ max(sizeof bsfs->f_mntfromname, sizeof osfs->f_mntfromname));
+ /* XXX osfs->f_xxx should be filled in... */
+#endif
+}
+
+int
+osf1_statfs(p, uap)
+ struct proc *p;
+ struct osf1_statfs_args *uap;
+{
+ int error;
+ struct mount *mp;
+ struct statfs *sp;
+ struct osf1_statfs osfs;
+ struct nameidata nd;
+
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
+ if ((error = namei(&nd)))
+ return (error);
+ mp = nd.ni_vp->v_mount;
+ sp = &mp->mnt_stat;
+ vrele(nd.ni_vp);
+ if ((error = VFS_STATFS(mp, sp, p)))
+ return (error);
+ sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
+ bsd2osf_statfs(sp, &osfs);
+ return copyout(&osfs, SCARG(uap, buf), min(sizeof osfs,
+ SCARG(uap, len)));
+}
+
+int
+osf1_fstatfs(p, uap)
+ struct proc *p;
+ struct osf1_fstatfs_args *uap;
+{
+ int error;
+ struct file *fp;
+ struct mount *mp;
+ struct statfs *sp;
+ struct osf1_statfs osfs;
+
+ if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)))
+ return (error);
+ mp = ((struct vnode *)fp->f_data)->v_mount;
+ sp = &mp->mnt_stat;
+ if ((error = VFS_STATFS(mp, sp, p)))
+ return (error);
+ sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
+ bsd2osf_statfs(sp, &osfs);
+ return copyout(&osfs, SCARG(uap, buf), min(sizeof osfs,
+ SCARG(uap, len)));
+}
+
+int
+osf1_getfsstat(p, uap)
+ struct proc *p;
+ register struct osf1_getfsstat_args *uap;
+{
+ long count, error, maxcount;
+ caddr_t osf_sfsp;
+ struct mount *mp, *nmp;
+ struct statfs *sp;
+ struct osf1_statfs osfs;
+
+ if (SCARG(uap, flags) & ~OSF1_GETFSSTAT_FLAGS)
+ return (EINVAL);
+
+ maxcount = SCARG(uap, bufsize) / sizeof(struct osf1_statfs);
+ osf_sfsp = (caddr_t)SCARG(uap, buf);
+ for (count = 0, mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) {
+ nmp = TAILQ_NEXT(mp, mnt_list);
+ if (osf_sfsp && count < maxcount) {
+ sp = &mp->mnt_stat;
+ /*
+ * If OSF1_MNT_NOWAIT is specified, do not refresh the
+ * fsstat cache. OSF1_MNT_WAIT overrides
+ * OSF1_MNT_NOWAIT.
+ */
+ if (((SCARG(uap, flags) & OSF1_MNT_NOWAIT) == 0 ||
+ (SCARG(uap, flags) & OSF1_MNT_WAIT)) &&
+ (error = VFS_STATFS(mp, sp, p)))
+ continue;
+ sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
+ bsd2osf_statfs(sp, &osfs);
+ if ((error = copyout(&osfs, osf_sfsp,
+ sizeof (struct osf1_statfs))))
+ return (error);
+ osf_sfsp += sizeof (struct osf1_statfs);
+ }
+ count++;
+ }
+ if (osf_sfsp && count > maxcount)
+ p->p_retval[0] = maxcount;
+ else
+ p->p_retval[0] = count;
+
+ return (0);
+}
+
+int
+osf1_unmount(p, uap)
+ struct proc *p;
+ struct osf1_unmount_args *uap;
+{
+ struct unmount_args a;
+
+ SCARG(&a, path) = SCARG(uap, path);
+
+ if (SCARG(uap, flags) & ~OSF1_UNMOUNT_FLAGS)
+ return (EINVAL);
+ SCARG(&a, flags) = 0;
+ if ((SCARG(uap, flags) & OSF1_MNT_FORCE) &&
+ (SCARG(uap, flags) & OSF1_MNT_NOFORCE) == 0)
+ SCARG(&a, flags) |= MNT_FORCE;
+
+ return unmount(p, &a);
+}
+
+int
+osf1_mount(p, uap)
+ struct proc *p;
+ struct osf1_mount_args *uap;
+{
+ int error;
+ struct mount_args a;
+
+ SCARG(&a, path) = SCARG(uap, path);
+
+ if (SCARG(uap, flags) & ~OSF1_MOUNT_FLAGS)
+ return (EINVAL);
+ SCARG(&a, flags) = SCARG(uap, flags); /* XXX - xlate */
+
+ switch (SCARG(uap, type)) {
+ case OSF1_MOUNT_UFS: /* XXX */
+ return (EINVAL);
+ break;
+
+ case OSF1_MOUNT_NFS: /* XXX */
+ if ((error = osf1_mount_nfs(p, uap, &a)))
+ return error;
+ break;
+
+ case OSF1_MOUNT_MFS: /* XXX */
+#ifdef notyet
+ if ((error = osf1_mount_mfs(p, uap, &a)))
+ return error;
+#endif
+ return EINVAL;
+ break;
+
+ case OSF1_MOUNT_CDFS: /* XXX */
+ return (EINVAL);
+ break;
+
+ case OSF1_MOUNT_PROCFS: /* XXX */
+ return (EINVAL);
+ break;
+
+ case OSF1_MOUNT_NONE:
+ case OSF1_MOUNT_PC:
+ case OSF1_MOUNT_S5FS:
+ case OSF1_MOUNT_DFS:
+ case OSF1_MOUNT_EFS:
+ case OSF1_MOUNT_MSFS:
+ case OSF1_MOUNT_FFM:
+ case OSF1_MOUNT_FDFS:
+ case OSF1_MOUNT_ADDON:
+ default:
+ return (EINVAL);
+ }
+
+ return mount(p, &a);
+}
+
+int
+osf1_mount_mfs(p, osf_argp, bsd_argp)
+ struct proc *p;
+ struct osf1_mount_args *osf_argp;
+ struct mount_args *bsd_argp;
+{
+#ifdef notyet
+ int error, len;
+ caddr_t sg;
+ static const char mfs_name[] = "mfs";
+ struct osf1_mfs_args osf_ma;
+ struct mfs_args bsd_ma;
+
+ sg = stackgap_init();
+
+ if ((error = copyin(SCARG(osf_argp, data), &osf_ma, sizeof osf_ma)))
+ return error;
+
+ bzero(&bsd_ma, sizeof bsd_ma);
+ bsd_ma.fspec = osf_ma.name;
+ /* XXX export args */
+ bsd_ma.base = osf_ma.base;
+ bsd_ma.size = osf_ma.size;
+
+ SCARG(bsd_argp, data) = stackgap_alloc(&sg, sizeof bsd_ma);
+ if ((error = copyout(&bsd_ma, SCARG(bsd_argp, data), sizeof bsd_ma)))
+ return error;
+
+ len = strlen(mfs_name) + 1;
+ SCARG(bsd_argp, type) = stackgap_alloc(&sg, len);
+ if ((error = copyout(mfs_name, (void *)SCARG(bsd_argp, type), len)))
+ return error;
+#endif
+ return 0;
+}
+
+int
+osf1_mount_nfs(p, osf_argp, bsd_argp)
+ struct proc *p;
+ struct osf1_mount_args *osf_argp;
+ struct mount_args *bsd_argp;
+{
+ int error, len;
+ caddr_t sg;
+ static const char nfs_name[] = "nfs";
+ struct osf1_nfs_args osf_na;
+ struct nfs_args bsd_na;
+
+ sg = stackgap_init();
+
+ if ((error = copyin(SCARG(osf_argp, data), &osf_na, sizeof osf_na)))
+ return error;
+
+ bzero(&bsd_na, sizeof bsd_na);
+ bsd_na.addr = (struct sockaddr *)osf_na.addr;
+ bsd_na.addrlen = sizeof (struct sockaddr_in);
+ bsd_na.sotype = SOCK_DGRAM;
+ bsd_na.proto = 0;
+ bsd_na.fh = osf_na.fh;
+
+ if (osf_na.flags & ~OSF1_NFSMNT_FLAGS)
+ return EINVAL;
+ if (osf_na.flags & OSF1_NFSMNT_SOFT)
+ bsd_na.flags |= NFSMNT_SOFT;
+ if (osf_na.flags & OSF1_NFSMNT_WSIZE) {
+ bsd_na.wsize = osf_na.wsize;
+ bsd_na.flags |= NFSMNT_WSIZE;
+ }
+ if (osf_na.flags & OSF1_NFSMNT_RSIZE) {
+ bsd_na.rsize = osf_na.rsize;
+ bsd_na.flags |= NFSMNT_RSIZE;
+ }
+ if (osf_na.flags & OSF1_NFSMNT_TIMEO) {
+ bsd_na.timeo = osf_na.timeo;
+ bsd_na.flags |= NFSMNT_TIMEO;
+ }
+ if (osf_na.flags & OSF1_NFSMNT_RETRANS) {
+ bsd_na.retrans = osf_na.retrans;
+ bsd_na.flags |= NFSMNT_RETRANS;
+ }
+ if (osf_na.flags & OSF1_NFSMNT_HOSTNAME)
+ bsd_na.hostname = osf_na.hostname;
+ if (osf_na.flags & OSF1_NFSMNT_INT)
+ bsd_na.flags |= NFSMNT_INT;
+ if (osf_na.flags & OSF1_NFSMNT_NOCONN)
+ bsd_na.flags |= NFSMNT_NOCONN;
+
+ SCARG(bsd_argp, data) = stackgap_alloc(&sg, sizeof bsd_na);
+ if ((error = copyout(&bsd_na, SCARG(bsd_argp, data), sizeof bsd_na)))
+ return error;
+
+ len = strlen(nfs_name) + 1;
+ SCARG(bsd_argp, type) = stackgap_alloc(&sg, len);
+ if ((error = copyout(nfs_name, (void *)SCARG(bsd_argp, type), len)))
+ return error;
+
+ return 0;
+}
diff --git a/sys/alpha/osf1/osf1_signal.c b/sys/alpha/osf1/osf1_signal.c
new file mode 100644
index 000000000000..8766130e64be
--- /dev/null
+++ b/sys/alpha/osf1/osf1_signal.c
@@ -0,0 +1,822 @@
+/* $NetBSD: osf1_signal.c,v 1.4 1998/05/20 16:35:01 chs Exp $
+ */
+
+/*
+ * Copyright (c) 1998-1999 Andrew Gallatin
+ *
+ * Taken from NetBSD's sys/compat/osf1/osf1_signal.c, which at the
+ * time *had no copyright*!
+ *
+ * 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
+ * in this position and unchanged.
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysproto.h>
+#include <sys/signalvar.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/reboot.h>
+#include <sys/buf.h>
+#include <sys/mbuf.h>
+#include <sys/vmmeter.h>
+#include <sys/msgbuf.h>
+#include <sys/exec.h>
+#include <sys/sysctl.h>
+#include <sys/uio.h>
+#include <net/netisr.h>
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_object.h>
+#include <vm/vm_pager.h>
+#include <sys/user.h>
+#include <sys/ptrace.h>
+#include <machine/clock.h>
+#include <machine/md_var.h>
+#include <machine/reg.h>
+#include <machine/pal.h>
+#include <machine/cpuconf.h>
+#include <machine/bootinfo.h>
+#include <machine/rpb.h>
+#include <machine/prom.h>
+#include <machine/chipset.h>
+#include <machine/vmparam.h>
+#include <machine/elf.h>
+#include <ddb/ddb.h>
+#include <alpha/alpha/db_instruction.h>
+#include <sys/vnode.h>
+#include <miscfs/procfs/procfs.h>
+
+#include <alpha/osf1/osf1_signal.h>
+#include <alpha/osf1/osf1_proto.h>
+#include <alpha/osf1/osf1_syscall.h>
+#include <alpha/osf1/osf1_util.h>
+#include <alpha/osf1/osf1.h>
+#include <sys/sysproto.h>
+
+#define DPRINTF uprintf
+int osf1_sigdbg = 0;
+
+static void bsd_to_osf1_sigaction __P((const struct sigaction *bsa,
+ struct osf1_sigaction *osa));
+static void osf1_to_bsd_sigaction __P((const struct osf1_sigaction *osa,
+ struct sigaction *bsa));
+
+#define sigemptyset(s) SIGEMPTYSET(*(s))
+#define sigismember(s, n) SIGISMEMBER(*(s), n)
+#define sigaddset(s, n) SIGADDSET(*(s), n)
+
+#define osf1_sigmask(n) (1 << ((n) - 1))
+#define osf1_sigemptyset(s) memset((s), 0, sizeof(*(s)))
+#define osf1_sigfillset(s) memset((s), 0xffffffff, sizeof(*(s)))
+#define osf1_sigismember(s, n) (*(s) & sigmask(n))
+#define osf1_sigaddset(s, n) (*(s) |= sigmask(n))
+
+int bsd_to_osf1_sig[OSF1_SIGTBLSZ] = {
+ OSF1_SIGHUP, /* 1 */
+ OSF1_SIGINT, /* 2 */
+ OSF1_SIGQUIT, /* 3 */
+ OSF1_SIGILL, /* 4 */
+ OSF1_SIGTRAP, /* 5 */
+ OSF1_SIGABRT, /* 6 */
+ OSF1_SIGEMT, /* 7 */
+ OSF1_SIGFPE, /* 8 */
+ OSF1_SIGKILL, /* 9 */
+ OSF1_SIGBUS, /* 10 */
+ OSF1_SIGSEGV, /* 11 */
+ OSF1_SIGSYS, /* 12 */
+ OSF1_SIGPIPE, /* 13 */
+ OSF1_SIGALRM, /* 14 */
+ OSF1_SIGTERM, /* 15 */
+ OSF1_SIGURG, /* 16 */
+ OSF1_SIGSTOP, /* 17 */
+ OSF1_SIGTSTP, /* 18 */
+ OSF1_SIGCONT, /* 19 */
+ OSF1_SIGCHLD, /* 20 */
+ OSF1_SIGTTIN, /* 21 */
+ OSF1_SIGTTOU, /* 22 */
+ OSF1_SIGIO, /* 23 */
+ OSF1_SIGXCPU, /* 24 */
+ OSF1_SIGXFSZ, /* 25 */
+ OSF1_SIGVTALRM, /* 26 */
+ OSF1_SIGPROF, /* 27 */
+ OSF1_SIGWINCH, /* 28 */
+ OSF1_SIGINFO, /* 29 */
+ OSF1_SIGUSR1, /* 30 */
+ OSF1_SIGUSR2, /* 31 */
+ 0 /* 32 */
+};
+
+int osf1_to_bsd_sig[OSF1_SIGTBLSZ] = {
+ SIGHUP, /* 1 */
+ SIGINT, /* 2 */
+ SIGQUIT, /* 3 */
+ SIGILL, /* 4 */
+ SIGTRAP, /* 5 */
+ SIGABRT, /* 6 */
+ SIGEMT, /* 7 */
+ SIGFPE, /* 8 */
+ SIGKILL, /* 9 */
+ SIGBUS, /* 10 */
+ SIGSEGV, /* 11 */
+ SIGSYS, /* 12 */
+ SIGPIPE, /* 13 */
+ SIGALRM, /* 14 */
+ SIGTERM, /* 15 */
+ SIGURG, /* 16 */
+ SIGSTOP, /* 17 */
+ SIGTSTP, /* 18 */
+ SIGCONT, /* 19 */
+ SIGCHLD, /* 20 */
+ SIGTTIN, /* 21 */
+ SIGTTOU, /* 22 */
+ SIGIO, /* 23 */
+ SIGXCPU, /* 24 */
+ SIGXFSZ, /* 25 */
+ SIGVTALRM, /* 26 */
+ SIGPROF, /* 27 */
+ SIGWINCH, /* 28 */
+ SIGINFO, /* 29 */
+ SIGUSR1, /* 30 */
+ SIGUSR2, /* 31 */
+ 0 /* 32 */
+};
+
+
+void
+osf1_to_bsd_sigset(oss, bss)
+ const osf1_sigset_t *oss;
+ sigset_t *bss;
+{
+ int i, newsig;
+
+ SIGEMPTYSET(*bss);
+ for (i = 1; i <= OSF1_SIGTBLSZ; i++) {
+ if (osf1_sigismember(oss, i)) {
+ newsig = osf1_to_bsd_sig[_SIG_IDX(i)];
+ if (newsig)
+ SIGADDSET(*bss, newsig);
+ }
+ }
+}
+
+void
+bsd_to_osf1_sigset(bss, oss)
+ const sigset_t *bss;
+ osf1_sigset_t *oss;
+{
+ int i, newsig;
+
+ osf1_sigemptyset(oss);
+ for (i = 1; i <= OSF1_SIGTBLSZ; i++) {
+ if (SIGISMEMBER(*bss, i)) {
+ newsig = bsd_to_osf1_sig[_SIG_IDX(i)];
+ if (newsig)
+ osf1_sigaddset(oss, newsig);
+ }
+ }
+
+}
+
+/*
+ * XXX: Only a subset of the flags is currently implemented.
+ */
+void
+osf1_to_bsd_sigaction(osa, bsa)
+ const struct osf1_sigaction *osa;
+ struct sigaction *bsa;
+{
+
+ bsa->sa_handler = osa->osa_handler;
+ if (osf1_sigdbg)
+ uprintf("%s(%d): handler @0x%lx \n", __FILE__, __LINE__,
+ (unsigned long)osa->osa_handler);
+ osf1_to_bsd_sigset(&osa->osa_mask, &bsa->sa_mask);
+ bsa->sa_flags = 0;
+ if ((osa->osa_flags & OSF1_SA_ONSTACK) != 0)
+ bsa->sa_flags |= SA_ONSTACK;
+ if ((osa->osa_flags & OSF1_SA_RESTART) != 0)
+ bsa->sa_flags |= SA_RESTART;
+ if ((osa->osa_flags & OSF1_SA_RESETHAND) != 0)
+ bsa->sa_flags |= SA_RESETHAND;
+ if ((osa->osa_flags & OSF1_SA_NOCLDSTOP) != 0)
+ bsa->sa_flags |= SA_NOCLDSTOP;
+ if ((osa->osa_flags & OSF1_SA_NODEFER) != 0)
+ bsa->sa_flags |= SA_NODEFER;
+}
+
+void
+bsd_to_osf1_sigaction(bsa, osa)
+ const struct sigaction *bsa;
+ struct osf1_sigaction *osa;
+{
+
+ osa->osa_handler = bsa->sa_handler;
+ bsd_to_osf1_sigset(&bsa->sa_mask, &osa->osa_mask);
+ osa->osa_flags = 0;
+ if ((bsa->sa_flags & SA_ONSTACK) != 0)
+ osa->osa_flags |= SA_ONSTACK;
+ if ((bsa->sa_flags & SA_RESTART) != 0)
+ osa->osa_flags |= SA_RESTART;
+ if ((bsa->sa_flags & SA_NOCLDSTOP) != 0)
+ osa->osa_flags |= SA_NOCLDSTOP;
+ if ((bsa->sa_flags & SA_NODEFER) != 0)
+ osa->osa_flags |= SA_NODEFER;
+ if ((bsa->sa_flags & SA_RESETHAND) != 0)
+ osa->osa_flags |= SA_RESETHAND;
+}
+
+void
+osf1_to_bsd_sigaltstack(oss, bss)
+ const struct osf1_sigaltstack *oss;
+ struct sigaltstack *bss;
+{
+
+ bss->ss_sp = oss->ss_sp;
+ bss->ss_size = oss->ss_size;
+ bss->ss_flags = 0;
+
+ if ((oss->ss_flags & OSF1_SS_DISABLE) != 0)
+ bss->ss_flags |= SS_DISABLE;
+ if ((oss->ss_flags & OSF1_SS_ONSTACK) != 0)
+ bss->ss_flags |= SS_ONSTACK;
+}
+
+void
+bsd_to_osf1_sigaltstack(bss, oss)
+ const struct sigaltstack *bss;
+ struct osf1_sigaltstack *oss;
+{
+
+ oss->ss_sp = bss->ss_sp;
+ oss->ss_size = bss->ss_size;
+ oss->ss_flags = 0;
+
+ if ((bss->ss_flags & SS_DISABLE) != 0)
+ oss->ss_flags |= OSF1_SS_DISABLE;
+ if ((bss->ss_flags & SS_ONSTACK) != 0)
+ oss->ss_flags |= OSF1_SS_ONSTACK;
+}
+
+int
+osf1_sigaction(p, uap)
+ struct proc *p;
+ struct osf1_sigaction_args *uap;
+{
+ int error;
+ caddr_t sg;
+ struct osf1_sigaction *nosa, *oosa, tmposa;
+ struct sigaction *nbsa, *obsa, tmpbsa;
+ struct sigaction_args sa;
+
+ sg = stackgap_init();
+ nosa = SCARG(uap, nsa);
+ oosa = SCARG(uap, osa);
+ if (osf1_sigdbg && uap->sigtramp)
+ uprintf("osf1_sigaction: trampoline handler at %p\n",
+ uap->sigtramp);
+ p->p_md.osf_sigtramp = uap->sigtramp;
+ if (oosa != NULL)
+ obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
+ else
+ obsa = NULL;
+ if (nosa != NULL) {
+ nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
+ if ((error = copyin(nosa, &tmposa, sizeof(tmposa))) != 0)
+ return error;
+ osf1_to_bsd_sigaction(&tmposa, &tmpbsa);
+ if ((error = copyout(&tmpbsa, nbsa, sizeof(tmpbsa))) != 0)
+ return error;
+ } else
+ nbsa = NULL;
+
+ SCARG(&sa, sig) = OSF1_OSF12BSD_SIG(SCARG(uap, signum));
+ SCARG(&sa, act) = nbsa;
+ SCARG(&sa, oact) = obsa;
+
+ if ((error = sigaction(p, &sa)) != 0)
+ return error;
+
+ if (oosa != NULL) {
+ if ((error = copyin(obsa, &tmpbsa, sizeof(tmpbsa))) != 0)
+ return error;
+ bsd_to_osf1_sigaction(&tmpbsa, &tmposa);
+ if ((error = copyout(&tmposa, oosa, sizeof(tmposa))) != 0)
+ return error;
+ }
+
+ return 0;
+}
+
+int
+osf1_sigaltstack(p, uap)
+ register struct proc *p;
+ struct osf1_sigaltstack_args *uap;
+{
+ int error;
+ caddr_t sg;
+ struct osf1_sigaltstack *noss, *ooss, tmposs;
+ struct sigaltstack *nbss, *obss, tmpbss;
+ struct sigaltstack_args sa;
+
+ sg = stackgap_init();
+ noss = SCARG(uap, nss);
+ ooss = SCARG(uap, oss);
+
+ if (ooss != NULL)
+ obss = stackgap_alloc(&sg, sizeof(struct sigaltstack));
+ else
+ obss = NULL;
+
+ if (noss != NULL) {
+ nbss = stackgap_alloc(&sg, sizeof(struct sigaltstack));
+ if ((error = copyin(noss, &tmposs, sizeof(tmposs))) != 0)
+ return error;
+ osf1_to_bsd_sigaltstack(&tmposs, &tmpbss);
+ if ((error = copyout(&tmpbss, nbss, sizeof(tmpbss))) != 0)
+ return error;
+ } else
+ nbss = NULL;
+
+ SCARG(&sa, ss) = nbss;
+ SCARG(&sa, oss) = obss;
+
+ if ((error = sigaltstack(p, &sa)) != 0)
+ return error;
+
+ if (obss != NULL) {
+ if ((error = copyin(obss, &tmpbss, sizeof(tmpbss))) != 0)
+ return error;
+ bsd_to_osf1_sigaltstack(&tmpbss, &tmposs);
+ if ((error = copyout(&tmposs, ooss, sizeof(tmposs))) != 0)
+ return error;
+ }
+
+ return 0;
+}
+
+int
+osf1_signal(p, uap)
+ register struct proc *p;
+ struct osf1_signal_args *uap;
+{
+ int error, signum;
+ caddr_t sg;
+
+ sg = stackgap_init();
+
+ signum = OSF1_OSF12BSD_SIG(OSF1_SIGNO(SCARG(uap, signum)));
+ if (signum <= 0 || signum > OSF1_NSIG) {
+ if (OSF1_SIGCALL(SCARG(uap, signum)) == OSF1_SIGNAL_MASK ||
+ OSF1_SIGCALL(SCARG(uap, signum)) == OSF1_SIGDEFER_MASK)
+ p->p_retval[0] = -1;
+ return EINVAL;
+ }
+
+ switch (OSF1_SIGCALL(SCARG(uap, signum))) {
+ case OSF1_SIGDEFER_MASK:
+ /*
+ * sigset is identical to signal() except
+ * that SIG_HOLD is allowed as
+ * an action.
+ */
+ if ((u_long)SCARG(uap, handler) == OSF1_SIG_HOLD) {
+ sigset_t mask;
+ sigset_t *bmask;
+ struct sigprocmask_args sa;
+
+ bmask = stackgap_alloc(&sg, sizeof(sigset_t));
+ SIGEMPTYSET(mask);
+ SIGADDSET(mask, signum);
+ SCARG(&sa, how) = SIG_BLOCK;
+ SCARG(&sa, set) = bmask;
+ SCARG(&sa, oset) = NULL;
+ if ((error = copyout(&mask, bmask, sizeof(mask))) != 0)
+ return (error);
+ return sigprocmask(p, &sa);
+ }
+ /* FALLTHROUGH */
+
+ case OSF1_SIGNAL_MASK:
+ {
+ struct sigaction_args sa_args;
+ struct sigaction *nbsa, *obsa, sa;
+
+ nbsa = stackgap_alloc(&sg, sizeof(struct sigaction));
+ obsa = stackgap_alloc(&sg, sizeof(struct sigaction));
+ SCARG(&sa_args, sig) = signum;
+ SCARG(&sa_args, act) = nbsa;
+ SCARG(&sa_args, oact) = obsa;
+
+ sa.sa_handler = SCARG(uap, handler);
+ SIGEMPTYSET(sa.sa_mask);
+ sa.sa_flags = 0;
+#if 0
+ if (signum != SIGALRM)
+ sa.sa_flags = SA_RESTART;
+#endif
+ if ((error = copyout(&sa, nbsa, sizeof(sa))) != 0)
+ return error;
+ if ((error = sigaction(p, &sa_args)) != 0) {
+ DPRINTF("signal: sigaction failed: %d\n",
+ error);
+ p->p_retval[0] = -1;
+ return error;
+ }
+ if ((error = copyin(obsa, &sa, sizeof(sa))) != 0)
+ return error;
+ p->p_retval[0] = (long)sa.sa_handler;
+ return 0;
+ }
+
+ case OSF1_SIGHOLD_MASK:
+ {
+ struct sigprocmask_args sa;
+ sigset_t set;
+ sigset_t *bset;
+
+ bset = stackgap_alloc(&sg, sizeof(sigset_t));
+ SIGEMPTYSET(set);
+ SIGADDSET(set, signum);
+ SCARG(&sa, how) = SIG_BLOCK;
+ SCARG(&sa, set) = bset;
+ SCARG(&sa, oset) = NULL;
+ if ((error = copyout(&set, bset, sizeof(set))) != 0)
+ return (error);
+ return sigprocmask(p, &sa);
+ }
+
+ case OSF1_SIGRELSE_MASK:
+ {
+ struct sigprocmask_args sa;
+ sigset_t set;
+ sigset_t *bset;
+
+ bset = stackgap_alloc(&sg, sizeof(sigset_t));
+ SIGEMPTYSET(set);
+ SIGADDSET(set, signum);
+ SCARG(&sa, how) = SIG_UNBLOCK;
+ SCARG(&sa, set) = bset;
+ SCARG(&sa, oset) = NULL;
+ if ((error = copyout(&set, bset, sizeof(set))) != 0)
+ return (error);
+ return sigprocmask(p, &sa);
+
+ }
+
+ case OSF1_SIGIGNORE_MASK:
+ {
+ struct sigaction_args sa_args;
+ struct sigaction *bsa, sa;
+
+ bsa = stackgap_alloc(&sg, sizeof(struct sigaction));
+ SCARG(&sa_args, sig) = signum;
+ SCARG(&sa_args, act) = bsa;
+ SCARG(&sa_args, oact) = NULL;
+
+ sa.sa_handler = SIG_IGN;
+ SIGEMPTYSET(sa.sa_mask);
+ sa.sa_flags = 0;
+ if ((error = copyout(&sa, bsa, sizeof(sa))) != 0)
+ return error;
+ if ((error = sigaction(p, &sa_args)) != 0) {
+ DPRINTF(("sigignore: sigaction failed\n"));
+ return error;
+ }
+ return 0;
+ }
+
+ case OSF1_SIGPAUSE_MASK:
+ {
+ struct sigsuspend_args sa;
+ sigset_t set;
+ sigset_t *bmask;
+
+ bmask = stackgap_alloc(&sg, sizeof(sigset_t));
+ set = p->p_sigmask;
+ SIGDELSET(set, signum);
+ SCARG(&sa, sigmask) = bmask;
+ if ((error = copyout(&set, bmask, sizeof(set))) != 0)
+ return (error);
+ return sigsuspend(p, &sa);
+ }
+
+ default:
+ return ENOSYS;
+ }
+}
+
+int
+osf1_sigprocmask(p, uap)
+ register struct proc *p;
+ struct osf1_sigprocmask_args /* {
+ syscallarg(int) how;
+ syscallarg(osf1_sigset_t *) set;
+ } */ *uap;
+{
+ int error;
+ osf1_sigset_t oss;
+ sigset_t bss;
+
+ error = 0;
+ /* Fix the return value first if needed */
+ bsd_to_osf1_sigset(&p->p_sigmask, &oss);
+ p->p_retval[0] = oss;
+
+ osf1_to_bsd_sigset(&uap->mask, &bss);
+
+ (void) splhigh();
+
+ switch (SCARG(uap, how)) {
+ case OSF1_SIG_BLOCK:
+ SIGSETOR(p->p_sigmask, bss);
+ SIG_CANTMASK(p->p_sigmask);
+ break;
+
+ case OSF1_SIG_UNBLOCK:
+ SIGSETNAND(p->p_sigmask, bss);
+ break;
+
+ case OSF1_SIG_SETMASK:
+ p->p_sigmask = bss;
+ SIG_CANTMASK(p->p_sigmask);
+ break;
+
+ default:
+ error = EINVAL;
+ break;
+ }
+
+ (void) spl0();
+
+ return error;
+}
+
+int
+osf1_sigpending(p, uap)
+ register struct proc *p;
+ struct osf1_sigpending_args /* {
+ syscallarg(osf1_sigset_t *) mask;
+ } */ *uap;
+{
+ osf1_sigset_t oss;
+ sigset_t bss;
+
+ bss = p->p_siglist;
+ SIGSETAND(bss, p->p_sigmask);
+ bsd_to_osf1_sigset(&bss, &oss);
+
+ return copyout(&oss, SCARG(uap, mask), sizeof(oss));
+}
+
+int
+osf1_sigsuspend(p, uap)
+ register struct proc *p;
+ struct osf1_sigsuspend_args /* {
+ syscallarg(osf1_sigset_t *) ss;
+ } */ *uap;
+{
+ int error;
+ caddr_t sg;
+ osf1_sigset_t oss;
+ sigset_t bss;
+ sigset_t *bmask;
+ struct sigsuspend_args sa;
+
+ sg = stackgap_init();
+
+ bmask = stackgap_alloc(&sg, sizeof(sigset_t));
+ oss = SCARG(uap, ss);
+ osf1_to_bsd_sigset(&oss, &bss);
+ SCARG(&sa, sigmask) = bmask;
+ if ((error = copyout(&bss, bmask, sizeof(bss))) != 0){
+ return (error);
+ }
+ return sigsuspend(p, &sa);
+}
+
+int
+osf1_kill(p, uap)
+ register struct proc *p;
+ struct osf1_kill_args /* {
+ syscallarg(int) pid;
+ syscallarg(int) signum;
+ } */ *uap;
+{
+ struct kill_args ka;
+
+ SCARG(&ka, pid) = SCARG(uap, pid);
+ SCARG(&ka, signum) = OSF1_OSF12BSD_SIG(SCARG(uap, signum));
+ return kill(p, &ka);
+}
+
+
+/*
+ * Send an interrupt to process.
+ *
+ * Stack is set up to allow sigcode stored at top to call routine,
+ * followed by kcall to sigreturn routine below. After sigreturn resets
+ * the signal mask, the stack, and the frame pointer, it returns to the
+ * user specified pc, psl.
+ */
+
+void
+osf1_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+{
+ int fsize, oonstack, rndfsize;
+ struct proc *p;
+ osiginfo_t *sip, ksi;
+ struct trapframe *frame;
+ struct sigacts *psp;
+
+ p = curproc;
+ psp = p->p_sigacts;
+
+ frame = p->p_md.md_tf;
+ oonstack = p->p_sigstk.ss_flags & SS_ONSTACK;
+ fsize = sizeof ksi;
+ rndfsize = ((fsize + 15) / 16) * 16;
+
+ /*
+ * Allocate and validate space for the signal handler context.
+ * Note that if the stack is in P0 space, the call to grow() is a nop,
+ * and the useracc() check will fail if the process has not already
+ * allocated the space with a `brk'.
+ */
+ if ((p->p_flag & P_ALTSTACK) && !oonstack &&
+ SIGISMEMBER(psp->ps_sigonstack, sig)) {
+ sip = (osiginfo_t *)((caddr_t)p->p_sigstk.ss_sp +
+ p->p_sigstk.ss_size - rndfsize);
+ p->p_sigstk.ss_flags |= SS_ONSTACK;
+ } else
+ sip = (osiginfo_t *)(alpha_pal_rdusp() - rndfsize);
+
+ (void)grow_stack(p, (u_long)sip);
+ if (useracc((caddr_t)sip, fsize, VM_PROT_WRITE) == 0) {
+ /*
+ * Process has trashed its stack; give it an illegal
+ * instruction to halt it in its tracks.
+ */
+ SIGACTION(p, SIGILL) = SIG_DFL;
+ SIGDELSET(p->p_sigignore, SIGILL);
+ SIGDELSET(p->p_sigcatch, SIGILL);
+ SIGDELSET(p->p_sigmask, SIGILL);
+ psignal(p, SIGILL);
+ return;
+ }
+
+ /*
+ * Build the signal context to be used by sigreturn.
+ */
+ ksi.si_sc.sc_onstack = oonstack;
+ SIG2OSIG(*mask, ksi.si_sc.sc_mask);
+ ksi.si_sc.sc_pc = frame->tf_regs[FRAME_PC];
+ ksi.si_sc.sc_ps = frame->tf_regs[FRAME_PS];
+
+ /* copy the registers. */
+ fill_regs(p, (struct reg *)ksi.si_sc.sc_regs);
+ ksi.si_sc.sc_regs[R_ZERO] = 0xACEDBADE; /* magic number */
+ ksi.si_sc.sc_regs[R_SP] = alpha_pal_rdusp();
+
+ /* save the floating-point state, if necessary, then copy it. */
+ alpha_fpstate_save(p, 1); /* XXX maybe write=0 */
+ ksi.si_sc.sc_ownedfp = p->p_md.md_flags & MDP_FPUSED;
+ bcopy(&p->p_addr->u_pcb.pcb_fp, (struct fpreg *)ksi.si_sc.sc_fpregs,
+ sizeof(struct fpreg));
+ ksi.si_sc.sc_fp_control = p->p_addr->u_pcb.pcb_fp_control;
+ bzero(ksi.si_sc.sc_reserved, sizeof ksi.si_sc.sc_reserved); /* XXX */
+ ksi.si_sc.sc_xxx1[0] = 0; /* XXX */
+ ksi.si_sc.sc_xxx1[1] = 0; /* XXX */
+ ksi.si_sc.sc_traparg_a0 = frame->tf_regs[FRAME_TRAPARG_A0];
+ ksi.si_sc.sc_traparg_a1 = frame->tf_regs[FRAME_TRAPARG_A1];
+ ksi.si_sc.sc_traparg_a2 = frame->tf_regs[FRAME_TRAPARG_A2];
+ ksi.si_sc.sc_xxx2[0] = 0; /* XXX */
+ ksi.si_sc.sc_xxx2[1] = 0; /* XXX */
+ ksi.si_sc.sc_xxx2[2] = 0; /* XXX */
+ /* Fill in POSIX parts */
+ ksi.si_signo = sig;
+ ksi.si_code = code;
+ ksi.si_value.sigval_ptr = NULL; /* XXX */
+
+ /*
+ * copy the frame out to userland.
+ */
+ (void) copyout((caddr_t)&ksi, (caddr_t)sip, fsize);
+
+ /*
+ * Set up the registers to return to sigcode.
+ */
+ if (osf1_sigdbg)
+ uprintf("attempting to call osf1 sigtramp\n");
+ frame->tf_regs[FRAME_PC] = (u_int64_t)p->p_md.osf_sigtramp;
+ frame->tf_regs[FRAME_A0] = sig;
+ frame->tf_regs[FRAME_A1] = code;
+ frame->tf_regs[FRAME_A2] = (u_int64_t)sip;
+ frame->tf_regs[FRAME_A3] = (u_int64_t)catcher; /* a3 is pv */
+ alpha_pal_wrusp((unsigned long)sip);
+}
+
+
+/*
+ * System call to cleanup state after a signal has been taken. Reset signal
+ * mask and stack state from context left by sendsig (above). Return to
+ * previous pc and psl as specified by context left by sendsig. Check
+ * carefully to make sure that the user has not modified the state to gain
+ * improper privileges.
+ */
+int
+osf1_sigreturn(struct proc *p,
+ struct osf1_sigreturn_args /* {
+ struct osigcontext *sigcntxp;
+ } */ *uap)
+{
+ struct osigcontext ksc, *scp;
+
+ scp = uap->sigcntxp;
+ if (useracc((caddr_t)scp, sizeof (*scp), VM_PROT_READ) == 0 ) {
+ uprintf("uac fails\n");
+ uprintf("scp: %p\n", scp);
+ }
+ /*
+ * Test and fetch the context structure.
+ * We grab it all at once for speed.
+ */
+ if (useracc((caddr_t)scp, sizeof (*scp), VM_PROT_READ) == 0 ||
+ copyin((caddr_t)scp, (caddr_t)&ksc, sizeof ksc))
+ return (EFAULT);
+
+ /*
+ * Restore the user-supplied information.
+ */
+ if (ksc.sc_onstack)
+ p->p_sigstk.ss_flags |= SS_ONSTACK;
+ else
+ p->p_sigstk.ss_flags &= ~SS_ONSTACK;
+
+ /*
+ * longjmp is still implemented by calling osigreturn. The new
+ * sigmask is stored in sc_reserved, sc_mask is only used for
+ * backward compatibility.
+ */
+ SIGSETOLD(p->p_sigmask, ksc.sc_mask);
+ SIG_CANTMASK(p->p_sigmask);
+
+ set_regs(p, (struct reg *)ksc.sc_regs);
+ p->p_md.md_tf->tf_regs[FRAME_PC] = ksc.sc_pc;
+ p->p_md.md_tf->tf_regs[FRAME_PS] =
+ (ksc.sc_ps | ALPHA_PSL_USERSET) & ~ALPHA_PSL_USERCLR;
+
+ alpha_pal_wrusp(ksc.sc_regs[R_SP]);
+
+ /* XXX ksc.sc_ownedfp ? */
+ alpha_fpstate_drop(p);
+ bcopy((struct fpreg *)ksc.sc_fpregs, &p->p_addr->u_pcb.pcb_fp,
+ sizeof(struct fpreg));
+ p->p_addr->u_pcb.pcb_fp_control = ksc.sc_fp_control;
+ return (EJUSTRETURN);
+}
+
+extern int
+osigstack(struct proc *p, struct osf1_osigstack_args *uap);
+
+int
+osf1_osigstack(p, uap)
+ register struct proc *p;
+ struct osf1_osigstack_args /* {
+ struct sigstack *nss;
+ struct sigstack *oss;
+ } */ *uap;
+{
+
+/* uprintf("osf1_osigstack: oss = %p, nss = %p",uap->oss, uap->nss);
+ uprintf(" stack ptr = %p\n",p->p_sigacts->ps_sigstk.ss_sp);*/
+ return(osigstack(p, uap));
+}
diff --git a/sys/alpha/osf1/osf1_signal.h b/sys/alpha/osf1/osf1_signal.h
new file mode 100644
index 000000000000..7983242f38ad
--- /dev/null
+++ b/sys/alpha/osf1/osf1_signal.h
@@ -0,0 +1,105 @@
+/* $FreeBSD$ */
+
+#ifndef _OSF1_SIGNAL_H
+#define _OSF1_SIGNAL_H
+
+#define OSF1_SIGHUP 1
+#define OSF1_SIGINT 2
+#define OSF1_SIGQUIT 3
+#define OSF1_SIGILL 4
+#define OSF1_SIGTRAP 5
+#define OSF1_SIGABRT 6
+#define OSF1_SIGEMT 7
+#define OSF1_SIGFPE 8
+#define OSF1_SIGKILL 9
+#define OSF1_SIGBUS 10
+#define OSF1_SIGSEGV 11
+#define OSF1_SIGSYS 12
+#define OSF1_SIGPIPE 13
+#define OSF1_SIGALRM 14
+#define OSF1_SIGTERM 15
+#define OSF1_SIGURG 16
+#define OSF1_SIGSTOP 17
+#define OSF1_SIGTSTP 18
+#define OSF1_SIGCONT 19
+#define OSF1_SIGCHLD 20
+#define OSF1_SIGTTIN 21
+#define OSF1_SIGTTOU 22
+#define OSF1_SIGIO 23
+#define OSF1_SIGXCPU 24
+#define OSF1_SIGXFSZ 25
+#define OSF1_SIGVTALRM 26
+#define OSF1_SIGPROF 27
+#define OSF1_SIGWINCH 28
+#define OSF1_SIGINFO 29
+#define OSF1_SIGUSR1 30
+#define OSF1_SIGUSR2 31
+#define OSF1_NSIG 32
+#define OSF1_SIGTBLSZ 32
+
+#define OSF1_SIG_DFL 0
+#define OSF1_SIG_ERR -1
+#define OSF1_SIG_IGN 1
+#define OSF1_SIG_HOLD 2
+
+#define OSF1_SIGNO(a) ((a) & OSF1_SIGNO_MASK)
+#define OSF1_SIGCALL(a) ((a) & ~OSF1_SIGNO_MASK)
+
+#define OSF1_SIG_BLOCK 1
+#define OSF1_SIG_UNBLOCK 2
+#define OSF1_SIG_SETMASK 3
+
+
+#define OSF1_BSD2OSF1_SIG(sig) \
+ (((sig) <= OSF1_SIGTBLSZ) ? bsd_to_osf1_sig[_SIG_IDX(sig)] : sig)
+#define OSF1_OSF12BSD_SIG(sig) \
+ (((sig) <= OSF1_SIGTBLSZ) ? osf1_to_bsd_sig[_SIG_IDX(sig)] : sig)
+
+
+typedef u_long osf1_sigset_t;
+typedef void (*osf1_handler_t) __P((int));
+
+struct osf1_sigaction {
+ osf1_handler_t osa_handler;
+ osf1_sigset_t osa_mask;
+ int osa_flags;
+};
+
+struct osf1_sigaltstack {
+ caddr_t ss_sp;
+ int ss_flags;
+ size_t ss_size;
+};
+
+/* sa_flags */
+#define OSF1_SA_ONSTACK 0x00000001
+#define OSF1_SA_RESTART 0x00000002
+#define OSF1_SA_NOCLDSTOP 0x00000004
+#define OSF1_SA_NODEFER 0x00000008
+#define OSF1_SA_RESETHAND 0x00000010
+#define OSF1_SA_NOCLDWAIT 0x00000020
+#define OSF1_SA_SIGINFO 0x00000040
+
+/* ss_flags */
+#define OSF1_SS_ONSTACK 0x00000001
+#define OSF1_SS_DISABLE 0x00000002
+
+
+#define OSF1_SIGNO_MASK 0x00FF
+#define OSF1_SIGNAL_MASK 0x0000
+#define OSF1_SIGDEFER_MASK 0x0100
+#define OSF1_SIGHOLD_MASK 0x0200
+#define OSF1_SIGRELSE_MASK 0x0400
+#define OSF1_SIGIGNORE_MASK 0x0800
+#define OSF1_SIGPAUSE_MASK 0x1000
+
+
+extern int osf1_to_linux_sig[];
+void bsd_to_osf1_sigaltstack __P((const struct sigaltstack *, struct osf1_sigaltstack *));
+void bsd_to_osf1_sigset __P((const sigset_t *, osf1_sigset_t *));
+void osf1_to_bsd_sigaltstack __P((const struct osf1_sigaltstack *, struct sigaltstack *));
+void osf1_to_bsd_sigset __P((const osf1_sigset_t *, sigset_t *));
+void osf1_sendsig __P((sig_t, int , sigset_t *, u_long ));
+
+
+#endif /* !_OSF1_SIGNAL_H */
diff --git a/sys/alpha/osf1/osf1_sysvec.c b/sys/alpha/osf1/osf1_sysvec.c
new file mode 100644
index 000000000000..71479693437c
--- /dev/null
+++ b/sys/alpha/osf1/osf1_sysvec.c
@@ -0,0 +1,133 @@
+/*-
+ * Copyright (c) 1998-1999 Andrew Gallatin
+ * All rights reserved.
+ *
+ * Based heavily on linux_sysvec.c
+ * Which is Copyright (c) 1994-1996 Søren Schmidt
+ *
+ * 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
+ * in this position and unchanged.
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+/* XXX we use functions that might not exist. */
+#include "opt_compat.h"
+
+#ifndef COMPAT_43
+#error "Unable to compile Osf1-emulator due to missing COMPAT_43 option!"
+#endif
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/sysent.h>
+#include <sys/imgact.h>
+#include <sys/imgact_aout.h>
+#include <sys/imgact_elf.h>
+#include <sys/malloc.h>
+#include <alpha/osf1/exec_ecoff.h>
+#include <alpha/osf1/osf1_signal.h>
+#include <alpha/osf1/osf1_syscall.h>
+#include <alpha/osf1/osf1_util.h>
+#include <alpha/osf1/osf1.h>
+
+int osf1_szsigcode;
+extern char sigcode[];
+static int osf1_freebsd_fixup __P((long **stack_base,
+ struct image_params *imgp));
+
+struct sysentvec osf1_sysvec = {
+ OSF1_SYS_MAXSYSCALL,
+ osf1_sysent,
+ 0x0,
+ NSIG,
+ bsd_to_osf1_sig,
+ 0,
+ 0,
+ 0, /* trap-to-signal translation function */
+ osf1_freebsd_fixup, /* fixup */
+ osf1_sendsig,
+ sigcode, /* use generic trampoline */
+ &osf1_szsigcode, /* use generic trampoline size */
+ 0, /* prepsyscall */
+ "OSF/1 ECOFF",
+ NULL /* we don't have an ECOFF coredump function */
+
+};
+
+/*
+ * Do some magic to setup the stack properly for the osf1 dynamic loader
+ * OSF/1 binaries need an auxargs vector describing the name of the
+ * executable (must be a full path).
+ *
+ * If we're executing a dynamic binary, the loader will expect its
+ * name, /sbin/loader, to be in the auxargs vectore as well.
+ * Bear in mind that when we execute a dynamic binary, we begin by
+ * executing the loader. The loader then takes care of mapping
+ * executable (which is why it needs the full path)
+ * and its requisite shared libs, then it transfers control
+ * to the executable after calling set_program_attributes().
+ */
+
+#define AUXARGS_ENTRY(pos, id, val) {suword(pos++, id); suword(pos++, val);}
+
+static int
+osf1_freebsd_fixup(long **stack_base, struct image_params *imgp)
+{
+ char *destp;
+ int sz;
+ long *pos;
+ struct ps_strings *arginfo;
+ Osf_Auxargs *args;
+
+ args = (Osf_Auxargs *)imgp->auxargs;
+ pos = *stack_base + (imgp->argc + imgp->envc + 2);
+
+ arginfo = (struct ps_strings *)PS_STRINGS;
+
+ sz = *(imgp->proc->p_sysent->sv_szsigcode);
+ destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
+ roundup((ARG_MAX - imgp->stringspace), sizeof(char *));
+
+ destp -= imgp->stringspace;
+
+ destp -= strlen(args->executable)+2;
+ copyout(args->executable, destp, strlen(args->executable)+1);
+
+ AUXARGS_ENTRY(pos, OSF1_EXEC_NAME, (long)destp);
+ if (args->loader) {
+ /* the loader seems to want the name here, then it overwrites it with
+ the FD of the executable. I have NFC what's going on here.. */
+ AUXARGS_ENTRY(pos, OSF1_EXEC_NAME, (long)destp);
+ destp-= (strlen("/sbin/loader")+1);
+ copyout("/sbin/loader", destp, strlen("/sbin/loader")+1);
+ AUXARGS_ENTRY(pos, OSF1_LOADER_NAME, (long)destp);
+ AUXARGS_ENTRY(pos, OSF1_LOADER_FLAGS, 0);
+ }
+ free(imgp->auxargs, M_TEMP);
+ imgp->auxargs = NULL;
+ (*stack_base)--;
+ **stack_base = (long)imgp->argc;
+ return 0;
+}
diff --git a/sys/alpha/osf1/osf1_util.h b/sys/alpha/osf1/osf1_util.h
new file mode 100644
index 000000000000..11eeadeb0e41
--- /dev/null
+++ b/sys/alpha/osf1/osf1_util.h
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (c) 1998-1999 Andrew Gallatin
+ * All rights reserved.
+ *
+ * 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
+ * in this position and unchanged.
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+
+
+#include <sys/exec.h>
+#include <sys/sysent.h>
+#include <sys/cdefs.h>
+
+
+#ifndef SCARG
+#define SCARG(p, x) (p)->x
+#endif
+
+static __inline caddr_t stackgap_init(void);
+static __inline void *stackgap_alloc(caddr_t *, size_t);
+
+static __inline caddr_t
+stackgap_init()
+{
+#define szsigcode (*(curproc->p_sysent->sv_szsigcode))
+ return (caddr_t)(((caddr_t)PS_STRINGS) - szsigcode - SPARE_USRSPACE);
+}
+
+static __inline void *
+stackgap_alloc(sgp, sz)
+ caddr_t *sgp;
+ size_t sz;
+{
+ void *p;
+
+ p = (void *) *sgp;
+ *sgp += ALIGN(sz);
+ return p;
+}
+
+
+extern const char osf1_emul_path[];
+int osf1_emul_find __P((struct proc *, caddr_t *, const char *, char *,
+ char **, int));
+
+#define CHECKALT(p, sgp, path, i) \
+ do { \
+ int _error; \
+ \
+ _error = osf1_emul_find(p, sgp, osf1_emul_path, path, \
+ &path, i); \
+ if (_error == EFAULT) \
+ return (_error); \
+ } while (0)
+
+#define CHECKALTEXIST(p, sgp, path) CHECKALT((p), (sgp), (path), 0)
+#define CHECKALTCREAT(p, sgp, path) CHECKALT((p), (sgp), (path), 1)
diff --git a/sys/alpha/osf1/syscalls.conf b/sys/alpha/osf1/syscalls.conf
new file mode 100644
index 000000000000..8f10864d3be0
--- /dev/null
+++ b/sys/alpha/osf1/syscalls.conf
@@ -0,0 +1,12 @@
+# $FreeBSD$
+sysnames="/dev/null"
+sysproto="osf1_proto.h"
+sysproto_h=_OSF1_SYSPROTO_H_
+syshdr="osf1_syscall.h"
+syssw="osf1_sysent.c"
+sysmk="/dev/null"
+syshide="/dev/null"
+syscallprefix="OSF1_SYS_"
+switchname="osf1_sysent"
+namesname="osf1_syscallnames"
+sysvec="\n"
diff --git a/sys/alpha/osf1/syscalls.master b/sys/alpha/osf1/syscalls.master
new file mode 100644
index 000000000000..416d43ec28d3
--- /dev/null
+++ b/sys/alpha/osf1/syscalls.master
@@ -0,0 +1,392 @@
+; $FreeBSD$
+
+; @(#)syscalls.master 8.1 (Berkeley) 7/19/93
+; System call name/number master file (or rather, slave, from OSF1).
+; Processed to created osf1_sysent.c, osf1_syscalls.c and osf1_syscall.h.
+
+; Columns: number type nargs namespc name alt{name,tag,rtyp}/comments
+; number system call number, must be in order
+; type one of STD, OBSOL, UNIMPL, COMPAT
+; namespc one of POSIX, BSD, STD, NOHIDE (I dont care :-) -Peter
+; name psuedo-prototype of syscall routine
+; If one of the following alts is different, then all appear:
+; altname name of system call if different
+; alttag name of args struct tag if different from [o]`name'"_args"
+; altrtyp return type if not int (bogus - syscalls always return int)
+; for UNIMPL/OBSOL, name continues with comments
+
+; types:
+; STD always included
+; COMPAT included on COMPAT #ifdef
+; LIBCOMPAT included on COMPAT #ifdef, and placed in syscall.h
+; OBSOL obsolete, not included in system, only specifies name
+; UNIMPL not implemented, placeholder only
+
+#include "opt_compat.h"
+#include <sys/param.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
+#include <alpha/osf1/osf1.h>
+#include <alpha/osf1/osf1_signal.h>
+#include <alpha/osf1/osf1_proto.h>
+
+
+0 NOPROTO OSF1 { int nosys(void); }
+1 NOPROTO OSF1 { int exit(int rval); }
+2 NOPROTO OSF1 { int fork(void); }
+3 NOPROTO OSF1 { ssize_t read(int fd, char *buf, ssize_t nbyte); }
+4 NOPROTO OSF1 { ssize_t write(int fd, char *buf, ssize_t nbyte); }
+5 UNIMPL OSF1 old open
+6 NOPROTO OSF1 { int close(int fd); }
+7 STD OSF1 { int osf1_wait4(int pid, int *status, int options, \
+ struct osf1_rusage *rusage); }
+8 UNIMPL OSF1 old creat
+9 NOPROTO OSF1 { int link(char *path, char *link); }
+10 NOPROTO OSF1 { int unlink(char *path); }
+11 UNIMPL OSF1 execv
+12 NOPROTO OSF1 { int chdir(char *path); }
+13 NOPROTO OSF1 { int fchdir(int fd); }
+14 STD OSF1 { int osf1_mknod(char *path, int mode, int dev); }
+15 NOPROTO OSF1 { int chmod(char *path, int mode); }
+16 NOPROTO OSF1 { int chown(char *path, int uid, int gid); }
+17 NOPROTO OSF1 { int obreak(char *nsize); }
+18 STD OSF1 { int osf1_getfsstat(struct osf1_statfs *buf, \
+ long bufsize, int flags); }
+19 STD OSF1 { off_t osf1_lseek(int fd, off_t offset, \
+ int whence); }
+20 NOPROTO OSF1 { pid_t getpid(void); }
+21 STD OSF1 { int osf1_mount(int type, char *path, int flags, \
+ caddr_t data); }
+22 STD OSF1 { int osf1_unmount(char *path, int flags); }
+23 STD OSF1 { int osf1_setuid(uid_t uid); }
+24 NOPROTO OSF1 { uid_t getuid(void); }
+25 UNIMPL OSF1 exec_with_loader
+26 UNIMPL OSF1 ptrace
+27 UNIMPL OSF1 recvmsg
+28 UNIMPL OSF1 sendmsg
+29 NOPROTO OSF1 { int recvfrom(int s, caddr_t buf, size_t len, \
+ int flags, caddr_t from, int *fromlenaddr); }
+30 NOPROTO OSF1 { int accept(int s, caddr_t name, int *anamelen); }
+31 NOPROTO OSF1 { int getpeername(int fdes, caddr_t asa, int *alen); }
+32 NOPROTO OSF1 { int getsockname(int fdes, caddr_t asa, int *alen); }
+33 STD OSF1 { int osf1_access(char *path, int flags); }
+34 UNIMPL OSF1 chflags
+35 UNIMPL OSF1 fchflags
+36 NOPROTO OSF1 { int sync(void); }
+37 STD OSF1 { int osf1_kill(int pid, int signum); }
+38 UNIMPL OSF1 old stat
+39 NOPROTO OSF1 { int setpgid(int pid, int pgid); }
+40 UNIMPL OSF1 old lstat
+41 NOPROTO OSF1 { int dup(u_int fd); }
+42 NOPROTO OSF1 { int pipe(void); }
+43 STD OSF1 { int osf1_set_program_attributes( \
+ vm_offset_t text_start, vm_offset_t text_len,\
+ vm_offset_t bss_start, vm_offset_t bss_len); }
+44 UNIMPL OSF1 profil
+45 STD OSF1 { int osf1_open(char *path, int flags, int mode); }
+46 OBSOL OSF1 sigaction
+47 NOPROTO OSF1 { gid_t getgid(void); }
+48 STD OSF1 { int osf1_sigprocmask(int how, osf1_sigset_t mask); }
+49 NOPROTO OSF1 { int getlogin(char *namebuf, u_int namelen); }
+50 NOPROTO OSF1 { int setlogin(char *namebuf); }
+51 NOPROTO OSF1 { int acct(char *path); }
+52 STD OSF1 { int osf1_sigpending(struct proc *p, \
+ osf1_sigset_t *mask ); }
+53 STD OSF1 { int osf1_classcntl(int opcode, int arg1, \
+ int arg2, int arg3); }
+54 STD OSF1 { int osf1_ioctl(int fd, int com, caddr_t data); }
+55 STD OSF1 { int osf1_reboot(int opt); }
+56 NOPROTO OSF1 { int revoke(char *path); }
+57 NOPROTO OSF1 { int symlink(char *path, char *link); }
+58 NOPROTO OSF1 { int readlink(char *path, char *buf, int count); }
+59 STD OSF1 { int osf1_execve(char *path, char **argp, \
+ char **envp); }
+60 NOPROTO OSF1 { int umask(int newmask); }
+61 NOPROTO OSF1 { int chroot(char *path); }
+62 UNIMPL OSF1 old fstat
+63 NOPROTO OSF1 { int getpgrp(void); }
+64 NOPROTO OSF1 { int ogetpagesize(void); }
+65 UNIMPL OSF1 mremap
+66 NOPROTO OSF1 { int vfork(void); }
+67 STD OSF1 { int osf1_stat(char *path, struct osf1_stat *ub); }
+68 STD OSF1 { int osf1_lstat(char *path, \
+ struct osf1_stat *ub); }
+69 UNIMPL OSF1 sbrk
+70 UNIMPL OSF1 sstk
+71 STD OSF1 { caddr_t osf1_mmap(caddr_t addr, size_t len, \
+ int prot, int flags, int fd, off_t pos); }
+72 UNIMPL OSF1 ovadvise
+73 NOPROTO OSF1 { int munmap(caddr_t addr, size_t len); }
+74 NOPROTO OSF1 { int mprotect(void *addr, size_t len, int prot); }
+; XXX
+75 STD OSF1 { int osf1_madvise(void); }
+76 UNIMPL OSF1 old vhangup
+77 UNIMPL OSF1 kmodcall
+78 UNIMPL OSF1 mincore
+79 NOPROTO OSF1 { int getgroups(u_int gidsetsize, gid_t *gidset); }
+80 NOPROTO OSF1 { int setgroups(u_int gidsetsize, gid_t *gidset); }
+81 UNIMPL OSF1 old getpgrp
+; OSF/1 setpgrp(); identical in function to setpgid(). XXX
+82 STD OSF1 { int osf1_setpgrp(int pid, int pgid); }
+83 STD OSF1 { int osf1_setitimer(u_int which, struct itimerval *itv, \
+ struct itimerval *oitv); }
+84 UNIMPL OSF1 old wait
+85 STD OSF1 { int osf1_table(long id, long index, void *addr, \
+ long nel, u_long lel); }
+86 STD OSF1 { int osf1_getitimer(u_int which, struct itimerval *itv); }
+87 NOPROTO OSF1 { int ogethostname(char *hostname, \
+ u_int len); }
+88 NOPROTO OSF1 { int osethostname(char *hostname, \
+ u_int len); }
+89 NOPROTO OSF1 { int getdtablesize(void); }
+90 NOPROTO OSF1 { int dup2(u_int from, u_int to); }
+91 STD OSF1 { int osf1_fstat(int fd, void *sb); }
+92 STD OSF1 { int osf1_fcntl(int fd, int cmd, void *arg); }
+93 STD OSF1 { int osf1_select(u_int nd, fd_set *in, fd_set *ou, \
+ fd_set *ex, struct timeval *tv); }
+94 NOPROTO OSF1 { int poll(struct pollfd *fds, u_int nfds, \
+ int timeout); }
+95 NOPROTO OSF1 { int fsync(int fd); }
+96 NOPROTO OSF1 { int setpriority(int which, int who, int prio); }
+97 STD OSF1 { int osf1_socket(int domain, int type, \
+ int protocol); }
+98 NOPROTO OSF1 { int connect(int s, caddr_t name, int namelen); }
+99 NOPROTO OSF1 { int oaccept(int s, caddr_t name, int *anamelen); }
+100 NOPROTO OSF1 { int getpriority(int which, int who); }
+101 NOPROTO OSF1 { int osend(int s, caddr_t buf, int len, \
+ int flags); }
+102 NOPROTO OSF1 { int orecv(int s, caddr_t buf, int len, \
+ int flags); }
+103 STD OSF1 { int osf1_sigreturn(struct osigcontext *sigcntxp); }
+104 NOPROTO OSF1 { int bind(int s, caddr_t name, int namelen); }
+105 NOPROTO OSF1 { int setsockopt(int s, int level, int name, \
+ caddr_t val, int valsize); }
+106 NOPROTO OSF1 { int listen(int s, int backlog); }
+107 UNIMPL OSF1 plock
+108 UNIMPL OSF1 old sigvec
+109 UNIMPL OSF1 old sigblock
+110 UNIMPL OSF1 old sigsetmask
+111 STD OSF1 { int osf1_sigsuspend(osf1_sigset_t ss); }
+112 STD OSF1 { int osf1_osigstack(struct sigstack *nss, \
+ struct sigstack *oss); }
+113 UNIMPL OSF1 old recvmsg
+114 UNIMPL OSF1 old sendmsg
+115 UNIMPL OSF1 vtrace
+116 STD OSF1 { int osf1_gettimeofday(struct timeval *tp, \
+ struct timezone *tzp); }
+; XXX
+117 STD OSF1 { int osf1_getrusage(long who, void *rusage); }
+118 NOPROTO OSF1 { int getsockopt(int s, int level, int name, \
+ caddr_t val, int *avalsize); }
+119 UNIMPL OSF1
+120 STD OSF1 { int osf1_readv(int fd, struct osf1_iovec *iovp, \
+ u_int iovcnt); }
+121 STD OSF1 { int osf1_writev(int fd, struct osf1_iovec *iovp, \
+ u_int iovcnt); }
+122 NOPROTO OSF1 { int settimeofday(struct timeval *tv, \
+ struct timezone *tzp); }
+123 NOPROTO OSF1 { int fchown(int fd, int uid, int gid); }
+124 NOPROTO OSF1 { int fchmod(int fd, int mode); }
+125 NOPROTO OSF1 { int orecvfrom(int s, caddr_t buf, \
+ size_t len, int flags, caddr_t from, \
+ int *fromlenaddr); }
+126 NOPROTO OSF1 { int setreuid(int ruid, int euid); }
+127 NOPROTO OSF1 { int setregid(int rgid, int egid); }
+128 NOPROTO OSF1 { int rename(const char *from, \
+ const char *to); }
+129 STD OSF1 { int osf1_truncate(char *path, off_t length); }
+130 STD OSF1 { int osf1_ftruncate(int fd, off_t length); }
+131 NOPROTO OSF1 { int flock(int fd, int how); }
+132 STD OSF1 { int osf1_setgid(gid_t gid); }
+133 STD OSF1 { int osf1_sendto(int s, caddr_t buf, size_t len, \
+ int flags, struct sockaddr *to, int tolen); }
+134 NOPROTO OSF1 { int shutdown(int s, int how); }
+135 UNIMPL OSF1 socketpair
+136 NOPROTO OSF1 { int mkdir(char *path, int mode); }
+137 NOPROTO OSF1 { int rmdir(char *path); }
+138 NOPROTO OSF1 { int utimes(char *path, struct timeval *tptr); }
+139 OBSOL OSF1 4.2 sigreturn
+140 UNIMPL OSF1 adjtime
+141 NOPROTO OSF1 { int ogetpeername(int fdes, caddr_t asa, int *alen); }
+142 NOPROTO OSF1 { int32_t ogethostid(void); }
+143 NOPROTO OSF1 { int osethostid(int32_t hostid); }
+144 STD OSF1 { int osf1_getrlimit(u_int which, \
+ struct rlimit *rlp); }
+145 STD OSF1 { int osf1_setrlimit(u_int which, \
+ struct rlimit *rlp); }
+146 UNIMPL OSF1 old killpg
+147 NOPROTO OSF1 { int setsid(void); }
+148 UNIMPL OSF1 quotactl
+149 NOPROTO OSF1 { int oquota(void); }
+150 NOPROTO OSF1 { int ogetsockname(int fdec, caddr_t asa, int *alen);}
+151 UNIMPL OSF1
+152 UNIMPL OSF1
+153 UNIMPL OSF1
+154 UNIMPL OSF1
+155 UNIMPL OSF1
+156 STD OSF1 { int osf1_sigaction(long signum, \
+ struct osf1_sigaction *nsa, \
+ struct osf1_sigaction *osa, \
+ void *sigtramp); }
+157 UNIMPL OSF1
+158 UNIMPL OSF1 nfssvc
+159 NOPROTO OSF1 { int ogetdirentries(int fd, char *buf, \
+ u_int count, long *basep); }
+160 STD OSF1 { int osf1_statfs(char *path, \
+ struct osf1_statfs *buf, int len); }
+161 STD OSF1 { int osf1_fstatfs(int fd, \
+ struct osf1_statfs *buf, int len); }
+162 UNIMPL OSF1
+163 UNIMPL OSF1 async_daemon
+164 UNIMPL OSF1 getfh
+165 NOPROTO OSF1 { int getdomainname(char *domainname, int len); }
+166 NOPROTO OSF1 { int setdomainname(char *domainname, int len); }
+167 UNIMPL OSF1
+168 UNIMPL OSF1
+169 UNIMPL OSF1 exportfs
+170 UNIMPL OSF1
+171 UNIMPL OSF1
+172 UNIMPL OSF1 alt msgctl
+173 UNIMPL OSF1 alt msgget
+174 UNIMPL OSF1 alt msgrcv
+175 UNIMPL OSF1 alt msgsnd
+176 UNIMPL OSF1 alt semctl
+177 UNIMPL OSF1 alt semget
+178 UNIMPL OSF1 alt semop
+179 UNIMPL OSF1 alt uname
+180 UNIMPL OSF1
+181 UNIMPL OSF1 alt plock
+182 UNIMPL OSF1 lockf
+183 UNIMPL OSF1
+184 UNIMPL OSF1 getmnt
+185 UNIMPL OSF1
+186 UNIMPL OSF1 unmount
+187 UNIMPL OSF1 alt sigpending
+188 UNIMPL OSF1 alt setsid
+189 UNIMPL OSF1
+190 UNIMPL OSF1
+191 UNIMPL OSF1
+192 UNIMPL OSF1
+193 UNIMPL OSF1
+194 UNIMPL OSF1
+195 UNIMPL OSF1
+196 UNIMPL OSF1
+197 UNIMPL OSF1
+198 UNIMPL OSF1
+199 UNIMPL OSF1 swapon
+200 NOPROTO OSF1 { int msgctl(int msqid, int cmd, \
+ struct msqid_ds *buf); }
+201 NOPROTO OSF1 { int msgget(key_t key, int msgflg); }
+202 NOPROTO OSF1 { int msgrcv(int msqid, void *msgp, size_t msgsz, \
+ long msgtyp, int msgflg); }
+203 NOPROTO OSF1 { int msgsnd(int msqid, void *msgp, size_t msgsz, \
+ int msgflg); }
+204 NOPROTO OSF1 { int __semctl(int semid, int semnum, int cmd, \
+ union semun *arg); }
+205 NOPROTO OSF1 { int semget(key_t key, int nsems, int semflg); }
+206 NOPROTO OSF1 { int semop(int semid, struct sembuf *sops, \
+ u_int nsops); }
+207 NOPROTO OSF1 { int uname(struct utsname *name); }
+208 NOPROTO OSF1 { int lchown(char *path, int uid, \
+ int gid); }
+209 NOPROTO OSF1 { int shmat(int shmid, void *shmaddr, int shmflg); }
+210 NOPROTO OSF1 { int shmctl(int shmid, int cmd, \
+ struct shmid_ds *buf); }
+211 NOPROTO OSF1 { int shmdt(void *shmaddr); }
+212 NOPROTO OSF1 { int shmget(key_t key, int size, int shmflg); }
+213 UNIMPL OSF1 mvalid
+214 UNIMPL OSF1 getaddressconf
+215 UNIMPL OSF1 msleep
+216 UNIMPL OSF1 mwakeup
+217 STD OSF1 { int osf1_msync(caddr_t addr, size_t len, \
+ int flags); }
+218 STD OSF1 {int osf1_signal(int signum, void *handler); }
+219 UNIMPL OSF1 utc gettime
+220 UNIMPL OSF1 utc adjtime
+221 UNIMPL OSF1
+222 UNIMPL OSF1 security
+223 UNIMPL OSF1 kloadcall
+224 UNIMPL OSF1
+225 UNIMPL OSF1
+226 UNIMPL OSF1
+227 UNIMPL OSF1
+228 UNIMPL OSF1
+229 UNIMPL OSF1
+230 UNIMPL OSF1
+231 UNIMPL OSF1
+232 UNIMPL OSF1
+233 NOPROTO OSF1 { pid_t getpgid(pid_t pid); }
+234 NOPROTO OSF1 { pid_t getsid(pid_t pid); }
+235 STD OSF1 { int osf1_sigaltstack(struct osf1_sigaltstack *nss, \
+ struct osf1_sigaltstack *oss); }
+236 UNIMPL OSF1 waitid
+237 UNIMPL OSF1 priocntlset
+238 UNIMPL OSF1 sigsendset
+239 UNIMPL OSF1
+240 UNIMPL OSF1 msfs_syscall
+241 STD OSF1 { int osf1_sysinfo(int cmd, char *buf, long count); }
+242 UNIMPL OSF1 uadmin
+243 UNIMPL OSF1 fuser
+244 STD OSF1 { int osf1_proplist_syscall(void); }
+245 STD OSF1 { int osf1_ntpadjtime(void *tp); }
+246 STD OSF1 { int osf1_ntpgettime(void *tp); }
+247 STD OSF1 { int osf1_pathconf(char *path, int name); }
+248 STD OSF1 { int osf1_fpathconf(int fd, int name); }
+249 UNIMPL OSF1
+250 STD OSF1 { int osf1_uswitch(long cmd, long mask); }
+251 STD OSF1 { int osf1_usleep_thread(struct timeval *sleep, \
+ struct timeval *slept); }
+252 UNIMPL OSF1 audcntl
+253 UNIMPL OSF1 audgen
+254 UNIMPL OSF1 sysfs
+255 UNIMPL OSF1
+256 STD OSF1 { int osf1_getsysinfo(u_long op, caddr_t buffer, \
+ u_long nbytes, caddr_t arg, u_long flag); }
+257 STD OSF1 { int osf1_setsysinfo(u_long op, caddr_t buffer, \
+ u_long nbytes, caddr_t arg, u_long flag); }
+258 UNIMPL OSF1 afs_syscall
+259 UNIMPL OSF1 swapctl
+260 UNIMPL OSF1 memcntl
+261 UNIMPL OSF1
+262 UNIMPL OSF1
+263 UNIMPL OSF1
+264 UNIMPL OSF1
+265 UNIMPL OSF1
+266 UNIMPL OSF1
+267 UNIMPL OSF1
+268 UNIMPL OSF1
+269 UNIMPL OSF1
+270 UNIMPL OSF1
+271 UNIMPL OSF1
+272 UNIMPL OSF1
+273 UNIMPL OSF1
+274 UNIMPL OSF1
+275 UNIMPL OSF1
+276 UNIMPL OSF1
+277 UNIMPL OSF1
+278 UNIMPL OSF1
+279 UNIMPL OSF1
+280 UNIMPL OSF1
+281 UNIMPL OSF1
+282 UNIMPL OSF1
+283 UNIMPL OSF1
+284 UNIMPL OSF1
+285 UNIMPL OSF1
+286 UNIMPL OSF1
+287 UNIMPL OSF1
+288 UNIMPL OSF1
+289 UNIMPL OSF1
+290 UNIMPL OSF1
+291 UNIMPL OSF1
+292 UNIMPL OSF1
+293 UNIMPL OSF1
+294 UNIMPL OSF1
+295 UNIMPL OSF1
+296 UNIMPL OSF1
+297 UNIMPL OSF1
+298 UNIMPL OSF1
+299 UNIMPL OSF1
+300 UNIMPL OSF1
+
+
+
diff --git a/sys/modules/osf1/Makefile b/sys/modules/osf1/Makefile
new file mode 100644
index 000000000000..459f4299ebad
--- /dev/null
+++ b/sys/modules/osf1/Makefile
@@ -0,0 +1,26 @@
+# $FreeBSD$
+
+MAINTAINER= gallatin@FreeBSD.org
+
+.PATH: ${.CURDIR}/../../alpha/osf1
+
+KMOD= osf1
+SRCS= osf1_ioctl.c osf1_misc.c osf1_signal.c osf1_sysent.c \
+ osf1_mount.c imgact_osf1.c osf1_sysvec.c opt_compat.h \
+ opt_simos.h opt_nfs.h vnode_if.h
+MAN8= osf1.8
+
+#CFLAGS+= -g
+EXPORT_SYMS= _osf1
+
+opt_compat.h:
+ echo "#define COMPAT_43 1" > ${.TARGET}
+
+opt_osf1.h opt_simos.h opt_nfs.h:
+ touch ${.TARGET}
+
+afterinstall:
+ ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
+ ${.CURDIR}/osf1.sh ${DESTDIR}/usr/bin/osf1
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/osf1/osf1.8 b/sys/modules/osf1/osf1.8
new file mode 100644
index 000000000000..a367dc9be31a
--- /dev/null
+++ b/sys/modules/osf1/osf1.8
@@ -0,0 +1,46 @@
+.\" Copyright (c) 1999
+.\" The FreeBSD Project. All rights reserved.
+.\"
+.\" 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.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd December 31, 1998
+.Dt OSF1 8
+.Os FreeBSD
+.Sh NAME
+.Nm osf1
+.Nd load the OSF/1 emulator kernel module
+.Sh SYNOPSIS
+.Nm osf1
+.Sh DESCRIPTION
+The
+.Nm
+utility loads the OSF/1 image activator kernel module.
+.Sh FILES
+.Bl -tag -width /modules/osf1.ko
+.It Pa /modules/osf1.ko
+OSF/1 image activator loadable kernel module.
+.Sh SEE ALSO
+.Xr kld 4 ,
+.Xr kldload 8 ,
+.Xr kldstat 8 ,
+.Xr kldunload 8
diff --git a/sys/modules/osf1/osf1.sh b/sys/modules/osf1/osf1.sh
new file mode 100644
index 000000000000..b2b4d92f49ac
--- /dev/null
+++ b/sys/modules/osf1/osf1.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# Copyright (c) 1999
+# The FreeBSD Project. All rights reserved.
+#
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``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 DEVELOPERS 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.
+#
+# $FreeBSD$
+#
+
+FOUND=`kldstat -v | egrep 'osf1_ecoff'`
+
+if [ "x$FOUND" != x ] ; then
+ echo Osf1 driver already loaded
+ exit 1
+else
+ kldload osf1
+fi