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