summaryrefslogtreecommitdiffstats
path: root/sys/alpha/osf1
diff options
context:
space:
mode:
authorgallatin <gallatin@FreeBSD.org>1999-12-14 22:35:36 +0000
committergallatin <gallatin@FreeBSD.org>1999-12-14 22:35:36 +0000
commit1b39d5d377f46180854da60e63f95aa7473d1db6 (patch)
tree0b293aeec2b72f82bb5672fdc41a54e5d8d1b8a6 /sys/alpha/osf1
parenta53726a684bbbe7c65bcfeb9aca85f45a8eaf1e2 (diff)
downloadFreeBSD-src-1b39d5d377f46180854da60e63f95aa7473d1db6.zip
FreeBSD-src-1b39d5d377f46180854da60e63f95aa7473d1db6.tar.gz
Finally add the Alpha OSF/1 compat code. I will add it to the
sys/modules Makefile after completing a buildworld. History: The bulk of this code was obtained from NetBSD approximately one year ago (I have taken care to preserve the original NetBSD copyrights and I thank the authors for their work.) At that time, the OSF/1 code was what was left over from their initial bootstrapping off of OSF/1 and did not provide support for executing shared binaries. I have independently added support for shared libraries, and support for some of the more obscure system calls. This code has been available for testing and comment since January of 1999 and running on production machines here at Duke since April. Known working applications include: - Netscape (all versions I've tried) - Mathematica 3.0.2 - Splus 3.4 - ArcInfo 7.1 - Matlab (version unknown) - SimOS - Atom instrumented binaries (built on a real OSF/1 system) Applications which are known not to work: - All applications linking to libmach - Adobe Acrobat (uses libmach) This has been tested with applications running against shared libraries from OSF/1 (aka Tru64) 4.0D and 4.0F. Reviewed by: marcel, obrien BDE-lint by: obrien Agreed in principal to by: msmith
Diffstat (limited to 'sys/alpha/osf1')
-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
13 files changed, 4755 insertions, 0 deletions
diff --git a/sys/alpha/osf1/Makefile b/sys/alpha/osf1/Makefile
new file mode 100644
index 0000000..a161390
--- /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 0000000..246fa48
--- /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 0000000..f88ab28
--- /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 0000000..0856203
--- /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 0000000..ce362de
--- /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 0000000..4272b52
--- /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 0000000..6d3ba9e
--- /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 0000000..8766130
--- /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 0000000..7983242
--- /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 0000000..7147969
--- /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 0000000..11eeade
--- /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 0000000..8f10864
--- /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 0000000..416d43e
--- /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
+
+
+
OpenPOWER on IntegriCloud