diff options
author | peter <peter@FreeBSD.org> | 2002-07-20 02:56:12 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2002-07-20 02:56:12 +0000 |
commit | cc7b2e42482d2eb35468c5dd11903248b12692b2 (patch) | |
tree | 442882c197085f1177ad99039e6387b24c60e44a /sys/compat | |
parent | c458732bcf221adf5c81f68d8d9044444c901a54 (diff) | |
download | FreeBSD-src-cc7b2e42482d2eb35468c5dd11903248b12692b2.zip FreeBSD-src-cc7b2e42482d2eb35468c5dd11903248b12692b2.tar.gz |
Infrastructure tweaks to allow having both an Elf32 and an Elf64 executable
handler in the kernel at the same time. Also, allow for the
exec_new_vmspace() code to build a different sized vmspace depending on
the executable environment. This is a big help for execing i386 binaries
on ia64. The ELF exec code grows the ability to map partial pages when
there is a page size difference, eg: emulating 4K pages on 8K or 16K
hardware pages.
Flesh out the i386 emulation support for ia64. At this point, the only
binary that I know of that fails is cvsup, because the cvsup runtime
tries to execute code in pages not marked executable.
Obtained from: dfr (mostly, many tweaks from me).
Diffstat (limited to 'sys/compat')
-rw-r--r-- | sys/compat/freebsd32/freebsd32.h | 103 | ||||
-rw-r--r-- | sys/compat/freebsd32/freebsd32_misc.c | 1339 | ||||
-rw-r--r-- | sys/compat/freebsd32/freebsd32_util.h | 94 | ||||
-rw-r--r-- | sys/compat/freebsd32/syscalls.master | 659 | ||||
-rw-r--r-- | sys/compat/ia32/ia32_sysvec.c | 365 | ||||
-rw-r--r-- | sys/compat/ia32/ia32_util.h | 94 | ||||
-rw-r--r-- | sys/compat/pecoff/imgact_pecoff.c | 2 | ||||
-rw-r--r-- | sys/compat/svr4/imgact_svr4.c | 2 | ||||
-rw-r--r-- | sys/compat/svr4/svr4_sysvec.c | 9 |
9 files changed, 2332 insertions, 335 deletions
diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h new file mode 100644 index 0000000..943b24c --- /dev/null +++ b/sys/compat/freebsd32/freebsd32.h @@ -0,0 +1,103 @@ +/*- + * Copyright (c) 2001 Doug Rabson + * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _IA64_IA32_IA32_H_ +#define _IA64_IA32_IA32_H_ + +#define PTRIN(v) (void *)(uintptr_t) (v) +#define PTROUT(v) (u_int32_t)(uintptr_t) (v) + +#define CP(src,dst,fld) do { (dst).fld = (src).fld; } while (0) +#define PTRIN_CP(src,dst,fld) \ + do { (dst).fld = PTRIN((src).fld); } while (0) +#define PTROUT_CP(src,dst,fld) \ + do { (dst).fld = PTROUT((src).fld); } while (0) + +struct timeval32 { + int32_t tv_sec; + int32_t tv_usec; +}; +#define TV_CP(src,dst,fld) do { \ + CP((src).fld,(dst).fld,tv_sec); \ + CP((src).fld,(dst).fld,tv_usec); \ +} while (0); + +struct timespec32 { + u_int32_t tv_sec; + u_int32_t tv_nsec; +}; +#define TS_CP(src,dst,fld) do { \ + CP((src).fld,(dst).fld,tv_sec); \ + CP((src).fld,(dst).fld,tv_nsec); \ +} while (0); + +struct rusage32 { + struct timeval32 ru_utime; + struct timeval32 ru_stime; + int32_t ru_maxrss; + int32_t ru_ixrss; + int32_t ru_idrss; + int32_t ru_isrss; + int32_t ru_minflt; + int32_t ru_majflt; + int32_t ru_nswap; + int32_t ru_inblock; + int32_t ru_oublock; + int32_t ru_msgsnd; + int32_t ru_msgrcv; + int32_t ru_nsignals; + int32_t ru_nvcsw; + int32_t ru_nivcsw; +}; + +struct statfs32 { + int32_t f_spare2; + int32_t f_bsize; + int32_t f_iosize; + int32_t f_blocks; + int32_t f_bfree; + int32_t f_bavail; + int32_t f_files; + int32_t f_ffree; + fsid_t f_fsid; + uid_t f_owner; + int32_t f_type; + int32_t f_flags; + int32_t f_syncwrites; + int32_t f_asyncwrites; + char f_fstypename[MFSNAMELEN]; + char f_mntonname[MNAMELEN]; + int32_t f_syncreads; + int32_t f_asyncreads; + int16_t f_spares1; + char f_mntfromname[MNAMELEN]; + int16_t f_spares2; + int32_t f_spare[2]; +}; + +#endif /* !_IA64_IA32_IA32_H_ */ diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c new file mode 100644 index 0000000..8b28bce --- /dev/null +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -0,0 +1,1339 @@ +/*- + * Copyright (c) 2002 Doug Rabson + * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/dkstat.h> +#include <sys/exec.h> +#include <sys/fcntl.h> +#include <sys/filedesc.h> +#include <sys/imgact.h> +#include <sys/kernel.h> +#include <sys/lock.h> +#include <sys/malloc.h> +#include <sys/file.h> /* Must come after sys/malloc.h */ +#include <sys/mman.h> +#include <sys/module.h> +#include <sys/mount.h> +#include <sys/mutex.h> +#include <sys/namei.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/reboot.h> +#include <sys/resource.h> +#include <sys/resourcevar.h> +#include <sys/selinfo.h> +#include <sys/pipe.h> /* Must come after sys/selinfo.h */ +#include <sys/signal.h> +#include <sys/signalvar.h> +#include <sys/socket.h> +#include <sys/socketvar.h> +#include <sys/stat.h> +#include <sys/sysctl.h> +#include <sys/sysent.h> +#include <sys/sysproto.h> +#include <sys/systm.h> +#include <sys/unistd.h> +#include <sys/user.h> +#include <sys/utsname.h> +#include <sys/vnode.h> + +#include <vm/vm.h> +#include <vm/vm_kern.h> +#include <vm/vm_param.h> +#include <vm/pmap.h> +#include <vm/vm_map.h> +#include <vm/vm_object.h> +#include <vm/vm_extern.h> + +#include <ia64/ia32/ia32_util.h> +#include <ia64/ia32/ia32.h> +#include <ia64/ia32/ia32_proto.h> + +static const char ia32_emul_path[] = "/compat/ia32"; +/* + * [ taken from the linux emulator ] + * Search an alternate path before passing pathname arguments on + * to system calls. Useful for keeping a separate '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 +ia32_emul_find(td, sgp, prefix, path, pbuf, cflag) + struct thread *td; + 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 ucred *ucred; + 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, td); + + if ((error = namei(&nd)) != 0) { + free(buf, M_TEMP); + return error; + } + + *cp = '/'; + } else { + NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); + + if ((error = namei(&nd)) != 0) { + free(buf, M_TEMP); + return error; + } + + /* + * We now compare the vnode of the ia32_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, ia32_emul_path, + td); + + if ((error = namei(&ndroot)) != 0) { + /* Cannot happen! */ + free(buf, M_TEMP); + vrele(nd.ni_vp); + return error; + } + + ucred = td->td_ucred; + if ((error = VOP_GETATTR(nd.ni_vp, &vat, ucred, td)) != 0) { + goto bad; + } + + if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, ucred, + td)) != 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 +ia32_open(struct thread *td, struct ia32_open_args *uap) +{ + caddr_t sg; + + sg = stackgap_init(); + CHECKALTEXIST(td, &sg, uap->path); + + return open(td, (struct open_args *) uap); +} + +int +ia32_wait4(struct thread *td, struct ia32_wait4_args *uap) +{ + int error; + caddr_t sg; + struct rusage32 *rusage32, ru32; + struct rusage *rusage = NULL, ru; + + rusage32 = SCARG(uap, rusage); + if (rusage32) { + sg = stackgap_init(); + rusage = stackgap_alloc(&sg, sizeof(struct rusage)); + SCARG(uap, rusage) = (struct rusage32 *)rusage; + } + error = wait4(td, (struct wait_args *)uap); + if (error) + return (error); + if (rusage32 && (error = copyin(rusage, &ru, sizeof(ru)) == 0)) { + TV_CP(ru, ru32, ru_utime); + TV_CP(ru, ru32, ru_stime); + CP(ru, ru32, ru_maxrss); + CP(ru, ru32, ru_ixrss); + CP(ru, ru32, ru_idrss); + CP(ru, ru32, ru_isrss); + CP(ru, ru32, ru_minflt); + CP(ru, ru32, ru_majflt); + CP(ru, ru32, ru_nswap); + CP(ru, ru32, ru_inblock); + CP(ru, ru32, ru_oublock); + CP(ru, ru32, ru_msgsnd); + CP(ru, ru32, ru_msgrcv); + CP(ru, ru32, ru_nsignals); + CP(ru, ru32, ru_nvcsw); + CP(ru, ru32, ru_nivcsw); + error = copyout(&ru32, rusage32, sizeof(ru32)); + } + return (error); +} + +static void +copy_statfs(struct statfs *in, struct statfs32 *out) +{ + CP(*in, *out, f_bsize); + CP(*in, *out, f_iosize); + CP(*in, *out, f_blocks); + CP(*in, *out, f_bfree); + CP(*in, *out, f_bavail); + CP(*in, *out, f_files); + CP(*in, *out, f_ffree); + CP(*in, *out, f_fsid); + CP(*in, *out, f_owner); + CP(*in, *out, f_type); + CP(*in, *out, f_flags); + CP(*in, *out, f_flags); + CP(*in, *out, f_syncwrites); + CP(*in, *out, f_asyncwrites); + bcopy(in->f_fstypename, + out->f_fstypename, MFSNAMELEN); + bcopy(in->f_mntonname, + out->f_mntonname, MNAMELEN); + CP(*in, *out, f_syncreads); + CP(*in, *out, f_asyncreads); + bcopy(in->f_mntfromname, + out->f_mntfromname, MNAMELEN); +} + +int +ia32_getfsstat(struct thread *td, struct ia32_getfsstat_args *uap) +{ + int error; + caddr_t sg; + struct statfs32 *sp32, stat32; + struct statfs *sp = NULL, stat; + int maxcount, count, i; + + sp32 = SCARG(uap, buf); + maxcount = SCARG(uap, bufsize) / sizeof(struct statfs32); + + if (sp32) { + sg = stackgap_init(); + sp = stackgap_alloc(&sg, sizeof(struct statfs) * maxcount); + SCARG(uap, buf) = (struct statfs32 *)sp; + } + error = getfsstat(td, (struct getfsstat_args *) uap); + if (sp32 && !error) { + count = td->td_retval[0]; + for (i = 0; i < count; i++) { + error = copyin(&sp[i], &stat, sizeof(stat)); + if (error) + return (error); + copy_statfs(&stat, &stat32); + error = copyout(&stat32, &sp32[i], sizeof(stat32)); + if (error) + return (error); + } + } + return (error); +} + +int +ia32_access(struct thread *td, struct ia32_access_args *uap) +{ + caddr_t sg; + + sg = stackgap_init(); + CHECKALTEXIST(td, &sg, uap->path); + + return access(td, (struct access_args *)uap); +} + +int +ia32_chflags(struct thread *td, struct ia32_chflags_args *uap) +{ + caddr_t sg; + + sg = stackgap_init(); + CHECKALTEXIST(td, &sg, uap->path); + + return chflags(td, (struct chflags_args *)uap); +} + +struct sigaltstack32 { + u_int32_t ss_sp; + u_int32_t ss_size; + int ss_flags; +}; + +int +ia32_sigaltstack(struct thread *td, struct ia32_sigaltstack_args *uap) +{ + int error; + caddr_t sg; + struct sigaltstack32 *p32, *op32, s32; + struct sigaltstack *p = NULL, *op = NULL, s; + + p32 = SCARG(uap, ss); + if (p32) { + sg = stackgap_init(); + p = stackgap_alloc(&sg, sizeof(struct sigaltstack)); + SCARG(uap, ss) = (struct sigaltstack32 *)p; + error = copyin(p32, &s32, sizeof(s32)); + if (error) + return (error); + PTRIN_CP(s32, s, ss_sp); + CP(s32, s, ss_size); + CP(s32, s, ss_flags); + error = copyout(&s, p, sizeof(s)); + if (error) + return (error); + } + op32 = SCARG(uap, oss); + if (op32) { + sg = stackgap_init(); + op = stackgap_alloc(&sg, sizeof(struct sigaltstack)); + SCARG(uap, oss) = (struct sigaltstack32 *)op; + } + error = sigaltstack(td, (struct sigaltstack_args *) uap); + if (error) + return (error); + if (op32) { + error = copyin(op, &s, sizeof(s)); + if (error) + return (error); + PTROUT_CP(s, s32, ss_sp); + CP(s, s32, ss_size); + CP(s, s32, ss_flags); + error = copyout(&s32, op32, sizeof(s32)); + } + return (error); +} + +int +ia32_execve(struct thread *td, struct ia32_execve_args *uap) +{ + int error; + caddr_t sg; + struct execve_args ap; + u_int32_t *p32, arg; + char **p; + int count; + + sg = stackgap_init(); + CHECKALTEXIST(td, &sg, SCARG(uap, fname)); + SCARG(&ap, fname) = SCARG(uap, fname); + + if (SCARG(uap, argv)) { + count = 0; + p32 = SCARG(uap, argv); + do { + error = copyin(p32++, &arg, sizeof(arg)); + if (error) + return error; + count++; + } while (arg != 0); + p = stackgap_alloc(&sg, count * sizeof(char *)); + SCARG(&ap, argv) = p; + p32 = SCARG(uap, argv); + do { + error = copyin(p32++, &arg, sizeof(arg)); + if (error) + return error; + *p++ = PTRIN(arg); + } while (arg != 0); + } + if (SCARG(uap, envv)) { + count = 0; + p32 = SCARG(uap, envv); + do { + error = copyin(p32++, &arg, sizeof(arg)); + if (error) + return error; + count++; + } while (arg != 0); + p = stackgap_alloc(&sg, count * sizeof(char *)); + SCARG(&ap, envv) = p; + p32 = SCARG(uap, envv); + do { + error = copyin(p32++, &arg, sizeof(arg)); + if (error) + return error; + *p++ = PTRIN(arg); + } while (arg != 0); + } + + return execve(td, &ap); +} + +static int +ia32_mmap_partial(struct thread *td, vm_offset_t start, vm_offset_t end, + int prot, int fd, off_t pos) +{ + vm_map_t map; + vm_map_entry_t entry; + int rv; + + map = &td->td_proc->p_vmspace->vm_map; + if (fd != -1) + prot |= VM_PROT_WRITE; + + if (vm_map_lookup_entry(map, start, &entry)) { + if ((entry->protection & prot) != prot) { + rv = vm_map_protect(map, + trunc_page(start), + round_page(end), + entry->protection | prot, + FALSE); + if (rv != KERN_SUCCESS) + return (EINVAL); + } + } else { + vm_offset_t addr = trunc_page(start); + rv = vm_map_find(map, 0, 0, + &addr, PAGE_SIZE, FALSE, prot, + VM_PROT_ALL, 0); + if (rv != KERN_SUCCESS) + return (EINVAL); + } + + if (fd != -1) { + struct pread_args r; + SCARG(&r, fd) = fd; + SCARG(&r, buf) = (void *) start; + SCARG(&r, nbyte) = end - start; + SCARG(&r, offset) = pos; + return (pread(td, &r)); + } else { + while (start < end) { + subyte((void *) start, 0); + start++; + } + return (0); + } +} + +int +ia32_mmap(struct thread *td, struct ia32_mmap_args *uap) +{ + struct mmap_args ap; + vm_offset_t addr = (vm_offset_t) SCARG(uap, addr); + vm_size_t len = SCARG(uap, len); + int prot = SCARG(uap, prot); + int flags = SCARG(uap, flags); + int fd = SCARG(uap, fd); + off_t pos = (SCARG(uap, poslo) + | ((off_t)SCARG(uap, poshi) << 32)); + vm_size_t pageoff; + int error; + + /* + * Attempt to handle page size hassles. + */ + pageoff = (pos & PAGE_MASK); + if (flags & MAP_FIXED) { + vm_offset_t start, end; + start = addr; + end = addr + len; + + if (start != trunc_page(start)) { + error = ia32_mmap_partial(td, start, round_page(start), + prot, fd, pos); + if (fd != -1) + pos += round_page(start) - start; + start = round_page(start); + } + if (end != round_page(end)) { + vm_offset_t t = trunc_page(end); + error = ia32_mmap_partial(td, t, end, + prot, fd, + pos + t - start); + end = trunc_page(end); + } + if (end > start && fd != -1 && (pos & PAGE_MASK)) { + /* + * We can't map this region at all. The specified + * address doesn't have the same alignment as the file + * position. Fake the mapping by simply reading the + * entire region into memory. First we need to make + * sure the region exists. + */ + vm_map_t map; + struct pread_args r; + int rv; + + prot |= VM_PROT_WRITE; + map = &td->td_proc->p_vmspace->vm_map; + rv = vm_map_remove(map, start, end); + if (rv != KERN_SUCCESS) + return (EINVAL); + rv = vm_map_find(map, 0, 0, + &start, end - start, FALSE, + prot, VM_PROT_ALL, 0); + if (rv != KERN_SUCCESS) + return (EINVAL); + SCARG(&r, fd) = fd; + SCARG(&r, buf) = (void *) start; + SCARG(&r, nbyte) = end - start; + SCARG(&r, offset) = pos; + error = pread(td, &r); + if (error) + return (error); + + td->td_retval[0] = addr; + return (0); + } + if (end == start) { + /* + * After dealing with the ragged ends, there + * might be none left. + */ + td->td_retval[0] = addr; + return (0); + } + addr = start; + len = end - start; + } + + SCARG(&ap, addr) = (void *) addr; + SCARG(&ap, len) = len; + SCARG(&ap, prot) = prot; + SCARG(&ap, flags) = flags; + SCARG(&ap, fd) = fd; + SCARG(&ap, pos) = pos; + + return (mmap(td, &ap)); +} + +struct itimerval32 { + struct timeval32 it_interval; + struct timeval32 it_value; +}; + +int +ia32_setitimer(struct thread *td, struct ia32_setitimer_args *uap) +{ + int error; + caddr_t sg; + struct itimerval32 *p32, *op32, s32; + struct itimerval *p = NULL, *op = NULL, s; + + p32 = SCARG(uap, itv); + if (p32) { + sg = stackgap_init(); + p = stackgap_alloc(&sg, sizeof(struct itimerval)); + SCARG(uap, itv) = (struct itimerval32 *)p; + error = copyin(p32, &s32, sizeof(s32)); + if (error) + return (error); + TV_CP(s32, s, it_interval); + TV_CP(s32, s, it_value); + error = copyout(&s, p, sizeof(s)); + if (error) + return (error); + } + op32 = SCARG(uap, oitv); + if (op32) { + sg = stackgap_init(); + op = stackgap_alloc(&sg, sizeof(struct itimerval)); + SCARG(uap, oitv) = (struct itimerval32 *)op; + } + error = setitimer(td, (struct setitimer_args *) uap); + if (error) + return (error); + if (op32) { + error = copyin(op, &s, sizeof(s)); + if (error) + return (error); + TV_CP(s, s32, it_interval); + TV_CP(s, s32, it_value); + error = copyout(&s32, op32, sizeof(s32)); + } + return (error); +} + +int +ia32_select(struct thread *td, struct ia32_select_args *uap) +{ + int error; + caddr_t sg; + struct timeval32 *p32, s32; + struct timeval *p = NULL, s; + + p32 = SCARG(uap, tv); + if (p32) { + sg = stackgap_init(); + p = stackgap_alloc(&sg, sizeof(struct timeval)); + SCARG(uap, tv) = (struct timeval32 *)p; + error = copyin(p32, &s32, sizeof(s32)); + if (error) + return (error); + CP(s32, s, tv_sec); + CP(s32, s, tv_usec); + error = copyout(&s, p, sizeof(s)); + if (error) + return (error); + } + /* + * XXX big-endian needs to convert the fd_sets too. + */ + return (select(td, (struct select_args *) uap)); +} + +int +ia32_gettimeofday(struct thread *td, struct ia32_gettimeofday_args *uap) +{ + int error; + caddr_t sg; + struct timeval32 *p32, s32; + struct timeval *p = NULL, s; + + p32 = SCARG(uap, tp); + if (p32) { + sg = stackgap_init(); + p = stackgap_alloc(&sg, sizeof(struct timeval)); + SCARG(uap, tp) = (struct timeval32 *)p; + } + error = gettimeofday(td, (struct gettimeofday_args *) uap); + if (error) + return (error); + if (p32) { + error = copyin(p, &s, sizeof(s)); + if (error) + return (error); + CP(s, s32, tv_sec); + CP(s, s32, tv_usec); + error = copyout(&s32, p32, sizeof(s32)); + if (error) + return (error); + } + return (error); +} + +int +ia32_getrusage(struct thread *td, struct ia32_getrusage_args *uap) +{ + int error; + caddr_t sg; + struct rusage32 *p32, s32; + struct rusage *p = NULL, s; + + p32 = SCARG(uap, rusage); + if (p32) { + sg = stackgap_init(); + p = stackgap_alloc(&sg, sizeof(struct rusage)); + SCARG(uap, rusage) = (struct rusage32 *)p; + } + error = getrusage(td, (struct getrusage_args *) uap); + if (error) + return (error); + if (p32) { + error = copyin(p, &s, sizeof(s)); + if (error) + return (error); + TV_CP(s, s32, ru_utime); + TV_CP(s, s32, ru_stime); + CP(s, s32, ru_maxrss); + CP(s, s32, ru_ixrss); + CP(s, s32, ru_idrss); + CP(s, s32, ru_isrss); + CP(s, s32, ru_minflt); + CP(s, s32, ru_majflt); + CP(s, s32, ru_nswap); + CP(s, s32, ru_inblock); + CP(s, s32, ru_oublock); + CP(s, s32, ru_msgsnd); + CP(s, s32, ru_msgrcv); + CP(s, s32, ru_nsignals); + CP(s, s32, ru_nvcsw); + CP(s, s32, ru_nivcsw); + error = copyout(&s32, p32, sizeof(s32)); + } + return (error); +} + +struct iovec32 { + u_int32_t iov_base; + int iov_len; +}; +#define STACKGAPLEN 400 + +int +ia32_readv(struct thread *td, struct ia32_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 iovec32 *oio; + struct iovec *nio; + + sg = stackgap_init(); + + if (SCARG(uap, iovcnt) > (STACKGAPLEN / sizeof (struct iovec))) + return (EINVAL); + + osize = SCARG(uap, iovcnt) * sizeof (struct iovec32); + 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 = PTRIN(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(td, &a); + +punt: + free(oio, M_TEMP); + free(nio, M_TEMP); + return (error); +} + +int +ia32_writev(struct thread *td, struct ia32_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 iovec32 *oio; + struct iovec *nio; + + sg = stackgap_init(); + + if (SCARG(uap, iovcnt) > (STACKGAPLEN / sizeof (struct iovec))) + return (EINVAL); + + osize = SCARG(uap, iovcnt) * sizeof (struct iovec32); + 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 = PTRIN(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(td, &a); + +punt: + free(oio, M_TEMP); + free(nio, M_TEMP); + return (error); +} + +int +ia32_settimeofday(struct thread *td, struct ia32_settimeofday_args *uap) +{ + int error; + caddr_t sg; + struct timeval32 *p32, s32; + struct timeval *p = NULL, s; + + p32 = SCARG(uap, tv); + if (p32) { + sg = stackgap_init(); + p = stackgap_alloc(&sg, sizeof(struct timeval)); + SCARG(uap, tv) = (struct timeval32 *)p; + error = copyin(p32, &s32, sizeof(s32)); + if (error) + return (error); + CP(s32, s, tv_sec); + CP(s32, s, tv_usec); + error = copyout(&s, p, sizeof(s)); + if (error) + return (error); + } + return (settimeofday(td, (struct settimeofday_args *) uap)); +} + +int +ia32_utimes(struct thread *td, struct ia32_utimes_args *uap) +{ + int error; + caddr_t sg; + struct timeval32 *p32, s32[2]; + struct timeval *p = NULL, s[2]; + + p32 = SCARG(uap, tptr); + if (p32) { + sg = stackgap_init(); + p = stackgap_alloc(&sg, 2*sizeof(struct timeval)); + SCARG(uap, tptr) = (struct timeval32 *)p; + error = copyin(p32, s32, sizeof(s32)); + if (error) + return (error); + CP(s32[0], s[0], tv_sec); + CP(s32[0], s[0], tv_usec); + CP(s32[1], s[1], tv_sec); + CP(s32[1], s[1], tv_usec); + error = copyout(s, p, sizeof(s)); + if (error) + return (error); + } + return (utimes(td, (struct utimes_args *) uap)); +} + +int +ia32_adjtime(struct thread *td, struct ia32_adjtime_args *uap) +{ + int error; + caddr_t sg; + struct timeval32 *p32, *op32, s32; + struct timeval *p = NULL, *op = NULL, s; + + p32 = SCARG(uap, delta); + if (p32) { + sg = stackgap_init(); + p = stackgap_alloc(&sg, sizeof(struct timeval)); + SCARG(uap, delta) = (struct timeval32 *)p; + error = copyin(p32, &s32, sizeof(s32)); + if (error) + return (error); + CP(s32, s, tv_sec); + CP(s32, s, tv_usec); + error = copyout(&s, p, sizeof(s)); + if (error) + return (error); + } + op32 = SCARG(uap, olddelta); + if (op32) { + sg = stackgap_init(); + op = stackgap_alloc(&sg, sizeof(struct timeval)); + SCARG(uap, olddelta) = (struct timeval32 *)op; + } + error = utimes(td, (struct utimes_args *) uap); + if (error) + return error; + if (op32) { + error = copyin(op, &s, sizeof(s)); + if (error) + return (error); + CP(s, s32, tv_sec); + CP(s, s32, tv_usec); + error = copyout(&s32, op32, sizeof(s32)); + } + return (error); +} + +int +ia32_statfs(struct thread *td, struct ia32_statfs_args *uap) +{ + int error; + caddr_t sg; + struct statfs32 *p32, s32; + struct statfs *p = NULL, s; + + p32 = SCARG(uap, buf); + if (p32) { + sg = stackgap_init(); + p = stackgap_alloc(&sg, sizeof(struct statfs)); + SCARG(uap, buf) = (struct statfs32 *)p; + } + error = statfs(td, (struct statfs_args *) uap); + if (error) + return (error); + if (p32) { + error = copyin(p, &s, sizeof(s)); + if (error) + return (error); + copy_statfs(&s, &s32); + error = copyout(&s32, p32, sizeof(s32)); + } + return (error); +} + +int +ia32_fstatfs(struct thread *td, struct ia32_fstatfs_args *uap) +{ + int error; + caddr_t sg; + struct statfs32 *p32, s32; + struct statfs *p = NULL, s; + + p32 = SCARG(uap, buf); + if (p32) { + sg = stackgap_init(); + p = stackgap_alloc(&sg, sizeof(struct statfs)); + SCARG(uap, buf) = (struct statfs32 *)p; + } + error = fstatfs(td, (struct fstatfs_args *) uap); + if (error) + return (error); + if (p32) { + error = copyin(p, &s, sizeof(s)); + if (error) + return (error); + copy_statfs(&s, &s32); + error = copyout(&s32, p32, sizeof(s32)); + } + return (error); +} + +int +ia32_semsys(struct thread *td, struct ia32_semsys_args *uap) +{ + /* + * Vector through to semsys if it is loaded. + */ + return sysent[169].sy_call(td, uap); +} + +int +ia32_msgsys(struct thread *td, struct ia32_msgsys_args *uap) +{ + /* + * Vector through to msgsys if it is loaded. + */ + return sysent[170].sy_call(td, uap); +} + +int +ia32_shmsys(struct thread *td, struct ia32_shmsys_args *uap) +{ + /* + * Vector through to shmsys if it is loaded. + */ + return sysent[171].sy_call(td, uap); +} + +int +ia32_pread(struct thread *td, struct ia32_pread_args *uap) +{ + struct pread_args ap; + + SCARG(&ap, fd) = SCARG(uap, fd); + SCARG(&ap, buf) = SCARG(uap, buf); + SCARG(&ap, nbyte) = SCARG(uap, nbyte); + SCARG(&ap, offset) = (SCARG(uap, offsetlo) + | ((off_t)SCARG(uap, offsethi) << 32)); + return (pread(td, &ap)); +} + +int +ia32_pwrite(struct thread *td, struct ia32_pwrite_args *uap) +{ + struct pwrite_args ap; + + SCARG(&ap, fd) = SCARG(uap, fd); + SCARG(&ap, buf) = SCARG(uap, buf); + SCARG(&ap, nbyte) = SCARG(uap, nbyte); + SCARG(&ap, offset) = (SCARG(uap, offsetlo) + | ((off_t)SCARG(uap, offsethi) << 32)); + return (pwrite(td, &ap)); +} + +int +ia32_lseek(struct thread *td, struct ia32_lseek_args *uap) +{ + int error; + struct lseek_args ap; + off_t pos; + + SCARG(&ap, fd) = SCARG(uap, fd); + SCARG(&ap, offset) = (SCARG(uap, offsetlo) + | ((off_t)SCARG(uap, offsethi) << 32)); + SCARG(&ap, whence) = SCARG(uap, whence); + error = lseek(td, &ap); + /* Expand the quad return into two parts for eax and edx */ + pos = *(off_t *)(td->td_retval); + td->td_retval[0] = pos & 0xffffffff; /* %eax */ + td->td_retval[1] = pos >> 32; /* %edx */ + return error; +} + +int +ia32_truncate(struct thread *td, struct ia32_truncate_args *uap) +{ + struct truncate_args ap; + + SCARG(&ap, path) = SCARG(uap, path); + SCARG(&ap, length) = (SCARG(uap, lengthlo) + | ((off_t)SCARG(uap, lengthhi) << 32)); + return (truncate(td, &ap)); +} + +int +ia32_ftruncate(struct thread *td, struct ia32_ftruncate_args *uap) +{ + struct ftruncate_args ap; + + SCARG(&ap, fd) = SCARG(uap, fd); + SCARG(&ap, length) = (SCARG(uap, lengthlo) + | ((off_t)SCARG(uap, lengthhi) << 32)); + return (ftruncate(td, &ap)); +} + +int +ia32_sendfile(struct thread *td, struct ia32_sendfile_args *uap) +{ + struct sendfile_args ap; + + SCARG(&ap, fd) = SCARG(uap, fd); + SCARG(&ap, s) = SCARG(uap, s); + SCARG(&ap, offset) = (SCARG(uap, offsetlo) + | ((off_t)SCARG(uap, offsethi) << 32)); + SCARG(&ap, nbytes) = SCARG(uap, nbytes); /* XXX check */ + SCARG(&ap, hdtr) = SCARG(uap, hdtr); /* XXX check */ + SCARG(&ap, sbytes) = SCARG(uap, sbytes); /* XXX FIXME!! */ + SCARG(&ap, flags) = SCARG(uap, flags); + return (sendfile(td, &ap)); +} + +struct stat32 { + udev_t st_dev; + ino_t st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + udev_t st_rdev; + struct timespec32 st_atimespec; + struct timespec32 st_mtimespec; + struct timespec32 st_ctimespec; + off_t st_size; + int64_t st_blocks; + u_int32_t st_blksize; + u_int32_t st_flags; + u_int32_t st_gen; +}; + +static void +copy_stat( struct stat *in, struct stat32 *out) +{ + CP(*in, *out, st_dev); + CP(*in, *out, st_ino); + CP(*in, *out, st_mode); + CP(*in, *out, st_nlink); + CP(*in, *out, st_uid); + CP(*in, *out, st_gid); + CP(*in, *out, st_rdev); + TS_CP(*in, *out, st_atimespec); + TS_CP(*in, *out, st_mtimespec); + TS_CP(*in, *out, st_ctimespec); + CP(*in, *out, st_size); + CP(*in, *out, st_blocks); + CP(*in, *out, st_blksize); + CP(*in, *out, st_flags); + CP(*in, *out, st_gen); +} + +int +ia32_stat(struct thread *td, struct ia32_stat_args *uap) +{ + int error; + caddr_t sg; + struct stat32 *p32, s32; + struct stat *p = NULL, s; + + p32 = SCARG(uap, ub); + if (p32) { + sg = stackgap_init(); + p = stackgap_alloc(&sg, sizeof(struct stat)); + SCARG(uap, ub) = (struct stat32 *)p; + } + error = stat(td, (struct stat_args *) uap); + if (error) + return (error); + if (p32) { + error = copyin(p, &s, sizeof(s)); + if (error) + return (error); + copy_stat(&s, &s32); + error = copyout(&s32, p32, sizeof(s32)); + } + return (error); +} + +int +ia32_fstat(struct thread *td, struct ia32_fstat_args *uap) +{ + int error; + caddr_t sg; + struct stat32 *p32, s32; + struct stat *p = NULL, s; + + p32 = SCARG(uap, ub); + if (p32) { + sg = stackgap_init(); + p = stackgap_alloc(&sg, sizeof(struct stat)); + SCARG(uap, ub) = (struct stat32 *)p; + } + error = fstat(td, (struct fstat_args *) uap); + if (error) + return (error); + if (p32) { + error = copyin(p, &s, sizeof(s)); + if (error) + return (error); + copy_stat(&s, &s32); + error = copyout(&s32, p32, sizeof(s32)); + } + return (error); +} + +int +ia32_lstat(struct thread *td, struct ia32_lstat_args *uap) +{ + int error; + caddr_t sg; + struct stat32 *p32, s32; + struct stat *p = NULL, s; + + p32 = SCARG(uap, ub); + if (p32) { + sg = stackgap_init(); + p = stackgap_alloc(&sg, sizeof(struct stat)); + SCARG(uap, ub) = (struct stat32 *)p; + } + error = lstat(td, (struct lstat_args *) uap); + if (error) + return (error); + if (p32) { + error = copyin(p, &s, sizeof(s)); + if (error) + return (error); + copy_stat(&s, &s32); + error = copyout(&s32, p32, sizeof(s32)); + } + return (error); +} + +/* + * MPSAFE + */ +int +ia32_sysctl(struct thread *td, struct ia32_sysctl_args *uap) +{ + int error, name[CTL_MAXNAME]; + size_t j, oldlen; + + if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) + return (EINVAL); + + error = copyin(uap->name, &name, uap->namelen * sizeof(int)); + if (error) + return (error); + + mtx_lock(&Giant); + + if (uap->oldlenp) + oldlen = fuword32(uap->oldlenp); + else + oldlen = 0; + error = userland_sysctl(td, name, uap->namelen, + uap->old, &oldlen, 1, + uap->new, uap->newlen, &j); + if (error && error != ENOMEM) + goto done2; + if (uap->oldlenp) { + suword32(uap->oldlenp, j); + } +done2: + mtx_unlock(&Giant); + return (error); +} + +struct sigaction32 { + u_int32_t sa_u; + int sa_flags; + sigset_t sa_mask; +}; + +int +ia32_sigaction(struct thread *td, struct ia32_sigaction_args *uap) +{ + int error; + caddr_t sg; + struct sigaction32 *p32, *op32, s32; + struct sigaction *p = NULL, *op = NULL, s; + + p32 = SCARG(uap, act); + if (p32) { + sg = stackgap_init(); + p = stackgap_alloc(&sg, sizeof(struct sigaction)); + SCARG(uap, act) = (struct sigaction32 *)p; + error = copyin(p32, &s32, sizeof(s32)); + if (error) + return (error); + s.sa_handler = PTRIN(s32.sa_u); + CP(s32, s, sa_flags); + CP(s32, s, sa_mask); + error = copyout(&s, p, sizeof(s)); + if (error) + return (error); + } + op32 = SCARG(uap, oact); + if (op32) { + sg = stackgap_init(); + op = stackgap_alloc(&sg, sizeof(struct sigaction)); + SCARG(uap, oact) = (struct sigaction32 *)op; + } + error = sigaction(td, (struct sigaction_args *) uap); + if (error) + return (error); + if (op32) { + error = copyin(op, &s, sizeof(s)); + if (error) + return (error); + s32.sa_u = PTROUT(s.sa_handler); + CP(s, s32, sa_flags); + CP(s, s32, sa_mask); + error = copyout(&s32, op32, sizeof(s32)); + } + return (error); +} + +#if 0 + +int +ia32_xxx(struct thread *td, struct ia32_xxx_args *uap) +{ + int error; + caddr_t sg; + struct yyy32 *p32, s32; + struct yyy *p = NULL, s; + + p32 = SCARG(uap, zzz); + if (p32) { + sg = stackgap_init(); + p = stackgap_alloc(&sg, sizeof(struct yyy)); + SCARG(uap, zzz) = (struct yyy32 *)p; + error = copyin(p32, &s32, sizeof(s32)); + if (error) + return (error); + /* translate in */ + error = copyout(&s, p, sizeof(s)); + if (error) + return (error); + } + error = xxx(td, (struct xxx_args *) uap); + if (error) + return (error); + if (p32) { + error = copyin(p, &s, sizeof(s)); + if (error) + return (error); + /* translate out */ + error = copyout(&s32, p32, sizeof(s32)); + } + return (error); +} + +#endif diff --git a/sys/compat/freebsd32/freebsd32_util.h b/sys/compat/freebsd32/freebsd32_util.h new file mode 100644 index 0000000..b9e0a7c --- /dev/null +++ b/sys/compat/freebsd32/freebsd32_util.h @@ -0,0 +1,94 @@ +/*- + * Copyright (c) 1998-1999 Andrew Gallatin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <vm/vm.h> +#include <vm/vm_param.h> +#include <vm/pmap.h> + + +#include <sys/exec.h> +#include <sys/sysent.h> +#include <sys/cdefs.h> + + +#ifndef SCARG +#define SCARG(p, x) (p)->x +#endif + +struct ia32_ps_strings { + u_int32_t ps_argvstr; /* first of 0 or more argument strings */ + int ps_nargvstr; /* the number of argument strings */ + u_int32_t ps_envstr; /* first of 0 or more environment strings */ + int ps_nenvstr; /* the number of environment strings */ +}; + +#define IA32_USRSTACK (4L*1024*1024*1024 - PAGE_SIZE) +#define IA32_PS_STRINGS (IA32_USRSTACK - sizeof(struct ia32_ps_strings)) + +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)IA32_PS_STRINGS) - szsigcode - SPARE_USRSPACE); +#undef szsigcode +} + +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 ia32_emul_path[]; +int ia32_emul_find(struct thread *, caddr_t *, const char *, char *, + char **, int); + +#define CHECKALT(p, sgp, path, i) \ + do { \ + int _error; \ + \ + _error = ia32_emul_find(p, sgp, ia32_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/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index 347196a..6de1c57 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -36,6 +36,9 @@ #include <sys/param.h> #include <sys/sysent.h> #include <sys/sysproto.h> +#include <sys/mount.h> +#include <ia64/ia32/ia32.h> +#include <ia64/ia32/ia32_proto.h> ; Reserved/unimplemented system calls in the range 0-150 inclusive ; are reserved for use in future Berkeley releases. @@ -43,200 +46,189 @@ ; redistributions should be placed in the reserved range at the end ; of the current calls. -0 STD NOHIDE { int nosys(void); } syscall nosys_args int -1 MSTD NOHIDE { void sys_exit(int rval); } exit sys_exit_args void -2 MSTD POSIX { int fork(void); } -3 MSTD POSIX { ssize_t read(int fd, void *buf, size_t nbyte); } -4 MSTD POSIX { ssize_t write(int fd, const void *buf, size_t nbyte); } -5 STD POSIX { int open(char *path, int flags, int mode); } +0 MNOPROTO NOHIDE { int nosys(void); } syscall nosys_args int +1 MNOPROTO NOHIDE { void sys_exit(int rval); } exit sys_exit_args void +2 MNOPROTO POSIX { int fork(void); } +3 MNOPROTO POSIX { ssize_t read(int fd, void *buf, size_t nbyte); } +4 MNOPROTO POSIX { ssize_t write(int fd, const void *buf, size_t nbyte); } +5 STD POSIX { int ia32_open(char *path, int flags, int mode); } ; XXX should be { int open(const char *path, int flags, ...); } ; but we're not ready for `const' or varargs. ; XXX man page says `mode_t mode'. -6 MSTD POSIX { int close(int fd); } -7 MSTD BSD { int wait4(int pid, int *status, int options, \ - struct rusage *rusage); } wait4 wait_args int -8 COMPAT BSD { int creat(char *path, int mode); } -9 STD POSIX { int link(char *path, char *link); } -10 STD POSIX { int unlink(char *path); } +6 MNOPROTO POSIX { int close(int fd); } +7 MSTD BSD { int ia32_wait4(int pid, int *status, int options, \ + struct rusage32 *rusage); } +8 OBSOL BSD old creat +9 NOPROTO POSIX { int link(char *path, char *link); } +10 NOPROTO POSIX { int unlink(char *path); } 11 OBSOL NOHIDE execv -12 STD POSIX { int chdir(char *path); } -13 STD BSD { int fchdir(int fd); } -14 STD POSIX { int mknod(char *path, int mode, int dev); } -15 STD POSIX { int chmod(char *path, int mode); } -16 STD POSIX { int chown(char *path, int uid, int gid); } -17 MSTD BSD { int obreak(char *nsize); } break obreak_args int -18 STD BSD { int getfsstat(struct statfs *buf, long bufsize, \ - int flags); } -19 COMPAT POSIX { long lseek(int fd, long offset, int whence); } -20 MSTD POSIX { pid_t getpid(void); } -21 STD BSD { int mount(char *type, char *path, int flags, \ +12 NOPROTO POSIX { int chdir(char *path); } +13 NOPROTO BSD { int fchdir(int fd); } +14 NOPROTO POSIX { int mknod(char *path, int mode, int dev); } +15 NOPROTO POSIX { int chmod(char *path, int mode); } +16 NOPROTO POSIX { int chown(char *path, int uid, int gid); } +17 MNOPROTO BSD { int obreak(char *nsize); } break obreak_args int +18 STD BSD { int ia32_getfsstat(struct statfs32 *buf, \ + long bufsize, int flags); } +19 OBSOL POSIX olseek +20 MNOPROTO POSIX { pid_t getpid(void); } +21 NOPROTO BSD { int mount(char *type, char *path, int flags, \ caddr_t data); } ; XXX `path' should have type `const char *' but we're not ready for that. -22 STD BSD { int unmount(char *path, int flags); } -23 MSTD POSIX { int setuid(uid_t uid); } -24 MSTD POSIX { uid_t getuid(void); } -25 MSTD POSIX { uid_t geteuid(void); } -26 STD BSD { int ptrace(int req, pid_t pid, caddr_t addr, \ +22 NOPROTO BSD { int unmount(char *path, int flags); } +23 MNOPROTO POSIX { int setuid(uid_t uid); } +24 MNOPROTO POSIX { uid_t getuid(void); } +25 MNOPROTO POSIX { uid_t geteuid(void); } +26 NOPROTO BSD { int ptrace(int req, pid_t pid, caddr_t addr, \ int data); } -27 MSTD BSD { int recvmsg(int s, struct msghdr *msg, int flags); } -28 MSTD BSD { int sendmsg(int s, caddr_t msg, int flags); } -29 MSTD BSD { int recvfrom(int s, caddr_t buf, size_t len, \ +27 UNIMPL BSD recvmsg +28 MNOPROTO BSD { int sendmsg(int s, caddr_t msg, int flags); } +29 MNOPROTO BSD { int recvfrom(int s, caddr_t buf, size_t len, \ int flags, caddr_t from, int *fromlenaddr); } -30 MSTD BSD { int accept(int s, caddr_t name, int *anamelen); } -31 MSTD BSD { int getpeername(int fdes, caddr_t asa, int *alen); } -32 MSTD BSD { int getsockname(int fdes, caddr_t asa, int *alen); } -33 STD POSIX { int access(char *path, int flags); } -34 STD BSD { int chflags(char *path, int flags); } -35 STD BSD { int fchflags(int fd, int flags); } -36 STD BSD { int sync(void); } -37 MSTD POSIX { int kill(int pid, int signum); } -38 COMPAT POSIX { int stat(char *path, struct ostat *ub); } -39 MSTD POSIX { pid_t getppid(void); } -40 COMPAT POSIX { int lstat(char *path, struct ostat *ub); } -41 STD POSIX { int dup(u_int fd); } -42 STD POSIX { int pipe(void); } -43 MSTD POSIX { gid_t getegid(void); } -44 MSTD BSD { int profil(caddr_t samples, size_t size, \ +30 MNOPROTO BSD { int accept(int s, caddr_t name, int *anamelen); } +31 MNOPROTO BSD { int getpeername(int fdes, caddr_t asa, int *alen); } +32 MNOPROTO BSD { int getsockname(int fdes, caddr_t asa, int *alen); } +33 STD POSIX { int ia32_access(char *path, int flags); } +34 STD BSD { int ia32_chflags(char *path, int flags); } +35 NOPROTO BSD { int fchflags(int fd, int flags); } +36 NOPROTO BSD { int sync(void); } +37 MNOPROTO POSIX { int kill(int pid, int signum); } +38 UNIMPL POSIX ostat +39 MNOPROTO POSIX { pid_t getppid(void); } +40 UNIMPL POSIX olstat +41 NOPROTO POSIX { int dup(u_int fd); } +42 NOPROTO POSIX { int pipe(void); } +43 MNOPROTO POSIX { gid_t getegid(void); } +44 MNOPROTO BSD { int profil(caddr_t samples, size_t size, \ size_t offset, u_int scale); } -45 STD BSD { int ktrace(const char *fname, int ops, int facs, \ +45 NOPROTO BSD { int ktrace(const char *fname, int ops, int facs, \ int pid); } -46 MCOMPAT POSIX { int sigaction(int signum, struct osigaction *nsa, \ - struct osigaction *osa); } -47 MSTD POSIX { gid_t getgid(void); } -48 MCOMPAT POSIX { int sigprocmask(int how, osigset_t mask); } -; XXX note nonstandard (bogus) calling convention - the libc stub passes -; us the mask, not a pointer to it, and we return the old mask as the -; (int) return value. -49 MSTD BSD { int getlogin(char *namebuf, u_int namelen); } -50 MSTD BSD { int setlogin(char *namebuf); } -51 MSTD BSD { int acct(char *path); } -52 MCOMPAT POSIX { int sigpending(void); } -53 MSTD BSD { int sigaltstack(stack_t *ss, stack_t *oss); } -54 MSTD POSIX { int ioctl(int fd, u_long com, caddr_t data); } -55 MSTD BSD { int reboot(int opt); } -56 STD POSIX { int revoke(char *path); } -57 STD POSIX { int symlink(char *path, char *link); } -58 STD POSIX { int readlink(char *path, char *buf, int count); } -59 MSTD POSIX { int execve(char *fname, char **argv, char **envv); } -60 MSTD POSIX { int umask(int newmask); } umask umask_args int -61 STD BSD { int chroot(char *path); } -62 MCOMPAT POSIX { int fstat(int fd, struct ostat *sb); } -63 MCOMPAT BSD { int getkerninfo(int op, char *where, size_t *size, \ - int arg); } getkerninfo getkerninfo_args int -64 MCOMPAT BSD { int getpagesize(void); } \ - getpagesize getpagesize_args int -65 STD BSD { int msync(void *addr, size_t len, int flags); } -66 MSTD BSD { int vfork(void); } +46 UNIMPL POSIX osigaction +47 MNOPROTO POSIX { gid_t getgid(void); } +48 UNIMPL POSIX osigprocmask +49 MNOPROTO BSD { int getlogin(char *namebuf, u_int namelen); } +50 MNOPROTO BSD { int setlogin(char *namebuf); } +51 MNOPROTO BSD { int acct(char *path); } +52 MNOPROTO POSIX { int sigpending(void); } +53 STD BSD { int ia32_sigaltstack(struct sigaltstack32 *ss, struct sigaltstack32 *oss); } +54 MNOPROTO POSIX { int ioctl(int fd, u_long com, caddr_t data); } +55 MNOPROTO BSD { int reboot(int opt); } +56 NOPROTO POSIX { int revoke(char *path); } +57 NOPROTO POSIX { int symlink(char *path, char *link); } +58 NOPROTO POSIX { int readlink(char *path, char *buf, int count); } +59 STD POSIX { int ia32_execve(char *fname, u_int32_t *argv, u_int32_t *envv); } +60 MNOPROTO POSIX { int umask(int newmask); } umask umask_args int +61 NOPROTO BSD { int chroot(char *path); } +62 OBSOL POSIX ofstat +63 OBSOL BSD ogetkerninfo +64 OBSOL BSD ogetpagesize +65 OBSOL BSD omsync +66 OBSOL BSD ovfork 67 OBSOL NOHIDE vread 68 OBSOL NOHIDE vwrite -69 MSTD BSD { int sbrk(int incr); } -70 MSTD BSD { int sstk(int incr); } -71 MCOMPAT BSD { int mmap(void *addr, int len, int prot, \ - int flags, int fd, long pos); } -72 MSTD BSD { int ovadvise(int anom); } vadvise ovadvise_args int -73 MSTD BSD { int munmap(void *addr, size_t len); } -74 MSTD BSD { int mprotect(const void *addr, size_t len, int prot); } -75 MSTD BSD { int madvise(void *addr, size_t len, int behav); } +69 MNOPROTO BSD { int sbrk(int incr); } +70 MNOPROTO BSD { int sstk(int incr); } +71 OBSOL BSD ommap +72 MNOPROTO BSD { int ovadvise(int anom); } vadvise ovadvise_args int +73 MNOPROTO BSD { int munmap(void *addr, size_t len); } +74 MNOPROTO BSD { int mprotect(const void *addr, size_t len, int prot); } +75 MNOPROTO BSD { int madvise(void *addr, size_t len, int behav); } 76 OBSOL NOHIDE vhangup 77 OBSOL NOHIDE vlimit -78 MSTD BSD { int mincore(const void *addr, size_t len, \ +78 MNOPROTO BSD { int mincore(const void *addr, size_t len, \ char *vec); } -79 MSTD POSIX { int getgroups(u_int gidsetsize, gid_t *gidset); } -80 MSTD POSIX { int setgroups(u_int gidsetsize, gid_t *gidset); } -81 MSTD POSIX { int getpgrp(void); } -82 MSTD POSIX { int setpgid(int pid, int pgid); } -83 MSTD BSD { int setitimer(u_int which, struct itimerval *itv, \ - struct itimerval *oitv); } -84 MCOMPAT BSD { int wait(void); } -85 MSTD BSD { int swapon(char *name); } -86 MSTD BSD { int getitimer(u_int which, struct itimerval *itv); } -87 MCOMPAT BSD { int gethostname(char *hostname, u_int len); } \ - gethostname gethostname_args int -88 MCOMPAT BSD { int sethostname(char *hostname, u_int len); } \ - sethostname sethostname_args int -89 MSTD BSD { int getdtablesize(void); } -90 MSTD POSIX { int dup2(u_int from, u_int to); } +79 MNOPROTO POSIX { int getgroups(u_int gidsetsize, gid_t *gidset); } +80 MNOPROTO POSIX { int setgroups(u_int gidsetsize, gid_t *gidset); } +81 MNOPROTO POSIX { int getpgrp(void); } +82 MNOPROTO POSIX { int setpgid(int pid, int pgid); } +83 STD BSD { int ia32_setitimer(u_int which, \ + struct itimerval32 *itv, \ + struct itimerval32 *oitv); } +84 OBSOL BSD owait +85 OBSOL BSD oswapon +86 OBSOL BSD ogetitimer +87 OBSOL BSD ogethostname +88 OBSOL BSD osethostname +89 MNOPROTO BSD { int getdtablesize(void); } +90 MNOPROTO POSIX { int dup2(u_int from, u_int to); } 91 UNIMPL BSD getdopt -92 MSTD POSIX { int fcntl(int fd, int cmd, long arg); } +92 MNOPROTO POSIX { int fcntl(int fd, int cmd, long arg); } ; XXX should be { int fcntl(int fd, int cmd, ...); } ; but we're not ready for varargs. ; XXX man page says `int arg' too. -93 MSTD BSD { int select(int nd, fd_set *in, fd_set *ou, \ - fd_set *ex, struct timeval *tv); } +93 STD BSD { int ia32_select(int nd, fd_set *in, fd_set *ou, \ + fd_set *ex, struct timeval32 *tv); } +; XXX need to override for big-endian - little-endian should work fine. 94 UNIMPL BSD setdopt -95 STD POSIX { int fsync(int fd); } -96 MSTD BSD { int setpriority(int which, int who, int prio); } -97 MSTD BSD { int socket(int domain, int type, int protocol); } -98 MSTD BSD { int connect(int s, caddr_t name, int namelen); } -99 MCPT_NOA BSD { int accept(int s, caddr_t name, int *anamelen); } \ +95 NOPROTO POSIX { int fsync(int fd); } +96 MNOPROTO BSD { int setpriority(int which, int who, int prio); } +97 MNOPROTO BSD { int socket(int domain, int type, int protocol); } +98 MNOPROTO BSD { int connect(int s, caddr_t name, int namelen); } +99 MNOPROTO BSD { int accept(int s, caddr_t name, int *anamelen); } \ accept accept_args int -100 MSTD BSD { int getpriority(int which, int who); } -101 MCOMPAT BSD { int send(int s, caddr_t buf, int len, int flags); } -102 MCOMPAT BSD { int recv(int s, caddr_t buf, int len, int flags); } -103 STD BSD { int osigreturn(struct osigcontext *sigcntxp); } -104 MSTD BSD { int bind(int s, caddr_t name, int namelen); } -105 MSTD BSD { int setsockopt(int s, int level, int name, \ +100 MNOPROTO BSD { int getpriority(int which, int who); } +101 OBSOL BSD osend +102 OBSOL BSD orecv +103 OBSOL BSD osigreturn +104 MNOPROTO BSD { int bind(int s, caddr_t name, int namelen); } +105 MNOPROTO BSD { int setsockopt(int s, int level, int name, \ caddr_t val, int valsize); } -106 MSTD BSD { int listen(int s, int backlog); } +106 MNOPROTO BSD { int listen(int s, int backlog); } 107 OBSOL NOHIDE vtimes -108 MCOMPAT BSD { int sigvec(int signum, struct sigvec *nsv, \ - struct sigvec *osv); } -109 MCOMPAT BSD { int sigblock(int mask); } -110 MCOMPAT BSD { int sigsetmask(int mask); } -111 MCOMPAT POSIX { int sigsuspend(osigset_t mask); } -; XXX note nonstandard (bogus) calling convention - the libc stub passes -; us the mask, not a pointer to it. -112 MCOMPAT BSD { int sigstack(struct sigstack *nss, \ - struct sigstack *oss); } -113 MCOMPAT BSD { int recvmsg(int s, struct omsghdr *msg, int flags); } -114 MCOMPAT BSD { int sendmsg(int s, caddr_t msg, int flags); } +108 OBSOL BSD osigvec +109 OBSOL BSD osigblock +110 OBSOL BSD osigsetmask +111 OBSOL POSIX osigsuspend +112 OBSOL BSD osigstack +113 OBSOL BSD orecvmsg +114 OBSOL BSD osendmsg 115 OBSOL NOHIDE vtrace -116 MSTD BSD { int gettimeofday(struct timeval *tp, \ +116 STD BSD { int ia32_gettimeofday(struct timeval32 *tp, \ struct timezone *tzp); } -117 MSTD BSD { int getrusage(int who, struct rusage *rusage); } -118 MSTD BSD { int getsockopt(int s, int level, int name, \ +117 STD BSD { int ia32_getrusage(int who, struct rusage32 *rusage); } +118 MNOPROTO BSD { int getsockopt(int s, int level, int name, \ caddr_t val, int *avalsize); } 119 UNIMPL NOHIDE resuba (BSD/OS 2.x) -120 MSTD BSD { int readv(int fd, struct iovec *iovp, u_int iovcnt); } -121 MSTD BSD { int writev(int fd, struct iovec *iovp, \ +120 STD BSD { int ia32_readv(int fd, struct iovec32 *iovp, u_int iovcnt); } +121 STD BSD { int ia32_writev(int fd, struct iovec32 *iovp, \ u_int iovcnt); } -122 MSTD BSD { int settimeofday(struct timeval *tv, \ +122 STD BSD { int ia32_settimeofday(struct timeval32 *tv, \ struct timezone *tzp); } -123 STD BSD { int fchown(int fd, int uid, int gid); } -124 STD BSD { int fchmod(int fd, int mode); } -125 MCPT_NOA BSD { int recvfrom(int s, caddr_t buf, size_t len, \ +123 NOPROTO BSD { int fchown(int fd, int uid, int gid); } +124 NOPROTO BSD { int fchmod(int fd, int mode); } +125 MNOPROTO BSD { int recvfrom(int s, caddr_t buf, size_t len, \ int flags, caddr_t from, int *fromlenaddr); } \ recvfrom recvfrom_args int -126 MSTD BSD { int setreuid(int ruid, int euid); } -127 MSTD BSD { int setregid(int rgid, int egid); } -128 STD POSIX { int rename(char *from, char *to); } -129 COMPAT BSD { int truncate(char *path, long length); } -130 COMPAT BSD { int ftruncate(int fd, long length); } -131 MSTD BSD { int flock(int fd, int how); } -132 STD POSIX { int mkfifo(char *path, int mode); } -133 MSTD BSD { int sendto(int s, caddr_t buf, size_t len, \ +126 MNOPROTO BSD { int setreuid(int ruid, int euid); } +127 MNOPROTO BSD { int setregid(int rgid, int egid); } +128 NOPROTO POSIX { int rename(char *from, char *to); } +129 OBSOL BSD otruncate +130 OBSOL BSD ftruncate +131 MNOPROTO BSD { int flock(int fd, int how); } +132 NOPROTO POSIX { int mkfifo(char *path, int mode); } +133 MNOPROTO BSD { int sendto(int s, caddr_t buf, size_t len, \ int flags, caddr_t to, int tolen); } -134 MSTD BSD { int shutdown(int s, int how); } -135 MSTD BSD { int socketpair(int domain, int type, int protocol, \ +134 MNOPROTO BSD { int shutdown(int s, int how); } +135 MNOPROTO BSD { int socketpair(int domain, int type, int protocol, \ int *rsv); } -136 STD POSIX { int mkdir(char *path, int mode); } -137 STD POSIX { int rmdir(char *path); } -138 STD BSD { int utimes(char *path, struct timeval *tptr); } +136 NOPROTO POSIX { int mkdir(char *path, int mode); } +137 NOPROTO POSIX { int rmdir(char *path); } +138 STD BSD { int ia32_utimes(char *path, \ + struct timeval32 *tptr); } 139 OBSOL NOHIDE 4.2 sigreturn -140 MSTD BSD { int adjtime(struct timeval *delta, \ - struct timeval *olddelta); } -141 MCOMPAT BSD { int getpeername(int fdes, caddr_t asa, int *alen); } -142 MCOMPAT BSD { long gethostid(void); } -143 MCOMPAT BSD { int sethostid(long hostid); } -144 MCOMPAT BSD { int getrlimit(u_int which, struct orlimit *rlp); } -145 MCOMPAT BSD { int setrlimit(u_int which, struct orlimit *rlp); } -146 MCOMPAT BSD { int killpg(int pgid, int signum); } -147 MSTD POSIX { int setsid(void); } -148 STD BSD { int quotactl(char *path, int cmd, int uid, \ +140 STD BSD { int ia32_adjtime(struct timeval32 *delta, \ + struct timeval32 *olddelta); } +141 OBSOL BSD ogetpeername +142 OBSOL BSD ogethostid +143 OBSOL BSD sethostid +144 OBSOL BSD getrlimit +145 OBSOL BSD setrlimit +146 OBSOL BSD killpg +147 MNOPROTO POSIX { int setsid(void); } +148 NOPROTO BSD { int quotactl(char *path, int cmd, int uid, \ caddr_t arg); } -149 MCOMPAT BSD { int quota(void); } -150 MCPT_NOA BSD { int getsockname(int fdec, caddr_t asa, int *alen); }\ - getsockname getsockname_args int +149 OBSOL BSD oquota +150 OBSOL BSD ogetsockname ; Syscalls 151-180 inclusive are reserved for vendor-specific ; system calls. (This includes various calls added for compatibity @@ -247,136 +239,138 @@ 153 UNIMPL NOHIDE asyncdaemon (BSD/OS 2.x) 154 UNIMPL NOHIDE nosys ; 155 is initialized by the NFS code, if present. -155 MNOIMPL BSD { int nfssvc(int flag, caddr_t argp); } -156 COMPAT BSD { int getdirentries(int fd, char *buf, u_int count, \ +155 UNIMPL NOHIDE nfssvc +156 NOPROTO BSD { int getdirentries(int fd, char *buf, u_int count, \ long *basep); } -157 STD BSD { int statfs(char *path, struct statfs *buf); } -158 STD BSD { int fstatfs(int fd, struct statfs *buf); } +157 STD BSD { int ia32_statfs(char *path, struct statfs32 *buf); } +158 STD BSD { int ia32_fstatfs(int fd, struct statfs32 *buf); } 159 UNIMPL NOHIDE nosys 160 UNIMPL NOHIDE nosys -161 STD BSD { int getfh(char *fname, struct fhandle *fhp); } -162 MSTD BSD { int getdomainname(char *domainname, int len); } -163 MSTD BSD { int setdomainname(char *domainname, int len); } -164 MSTD BSD { int uname(struct utsname *name); } -165 STD BSD { int sysarch(int op, char *parms); } -166 MSTD BSD { int rtprio(int function, pid_t pid, \ +161 NOPROTO BSD { int getfh(char *fname, struct fhandle *fhp); } +162 MNOPROTO BSD { int getdomainname(char *domainname, int len); } +163 MNOPROTO BSD { int setdomainname(char *domainname, int len); } +164 MNOPROTO BSD { int uname(struct utsname *name); } +165 NOPROTO BSD { int sysarch(int op, char *parms); } +166 MNOPROTO BSD { int rtprio(int function, pid_t pid, \ struct rtprio *rtp); } 167 UNIMPL NOHIDE nosys 168 UNIMPL NOHIDE nosys -; 169 is initialized by the SYSVSEM code if present or loaded -169 MNOSTD BSD { int semsys(int which, int a2, int a3, int a4, \ +169 STD BSD { int ia32_semsys(int which, int a2, int a3, int a4, \ int a5); } -; 169 is initialized by the SYSVMSG code if present or loaded -; XXX should be { int semsys(int which, ...); } -170 MNOSTD BSD { int msgsys(int which, int a2, int a3, int a4, \ +170 STD BSD { int ia32_msgsys(int which, int a2, int a3, int a4, \ int a5, int a6); } -; 169 is initialized by the SYSVSHM code if present or loaded -; XXX should be { int msgsys(int which, ...); } -171 MNOSTD BSD { int shmsys(int which, int a2, int a3, int a4); } -; XXX should be { int shmsys(int which, ...); } +171 STD BSD { int ia32_shmsys(int which, int a2, int a3, int a4); } 172 UNIMPL NOHIDE nosys -173 MSTD POSIX { ssize_t pread(int fd, void *buf, size_t nbyte, \ - int pad, off_t offset); } -174 MSTD POSIX { ssize_t pwrite(int fd, const void *buf, \ - size_t nbyte, int pad, off_t offset); } +173 STD POSIX { ssize_t ia32_pread(int fd, void *buf, size_t nbyte, \ + int pad, u_int32_t offsetlo, u_int32_t offsethi); } +; XXX note - bigendian is different +174 STD POSIX { ssize_t ia32_pwrite(int fd, const void *buf, \ + size_t nbyte, int pad, u_int32_t offsetlo, \ + u_int32_t offsethi); } +; XXX note - bigendian is different 175 UNIMPL NOHIDE nosys -176 MSTD BSD { int ntp_adjtime(struct timex *tp); } +176 MNOPROTO BSD { int ntp_adjtime(struct timex *tp); } 177 UNIMPL NOHIDE sfork (BSD/OS 2.x) 178 UNIMPL NOHIDE getdescriptor (BSD/OS 2.x) 179 UNIMPL NOHIDE setdescriptor (BSD/OS 2.x) 180 UNIMPL NOHIDE nosys ; Syscalls 181-199 are used by/reserved for BSD -181 MSTD POSIX { int setgid(gid_t gid); } -182 MSTD BSD { int setegid(gid_t egid); } -183 MSTD BSD { int seteuid(uid_t euid); } +181 MNOPROTO POSIX { int setgid(gid_t gid); } +182 MNOPROTO BSD { int setegid(gid_t egid); } +183 MNOPROTO BSD { int seteuid(uid_t euid); } 184 UNIMPL BSD lfs_bmapv 185 UNIMPL BSD lfs_markv 186 UNIMPL BSD lfs_segclean 187 UNIMPL BSD lfs_segwait -188 STD POSIX { int stat(char *path, struct stat *ub); } -189 MSTD POSIX { int fstat(int fd, struct stat *sb); } -190 STD POSIX { int lstat(char *path, struct stat *ub); } -191 STD POSIX { int pathconf(char *path, int name); } -192 MSTD POSIX { int fpathconf(int fd, int name); } +188 STD POSIX { int ia32_stat(char *path, struct stat32 *ub); } +189 STD POSIX { int ia32_fstat(int fd, struct stat32 *ub); } +190 STD POSIX { int ia32_lstat(char *path, struct stat32 *ub); } +191 NOPROTO POSIX { int pathconf(char *path, int name); } +192 MNOPROTO POSIX { int fpathconf(int fd, int name); } 193 UNIMPL NOHIDE nosys -194 MSTD BSD { int getrlimit(u_int which, \ +194 MNOPROTO BSD { int getrlimit(u_int which, \ struct rlimit *rlp); } \ getrlimit __getrlimit_args int -195 MSTD BSD { int setrlimit(u_int which, \ +195 MNOPROTO BSD { int setrlimit(u_int which, \ struct rlimit *rlp); } \ setrlimit __setrlimit_args int -196 STD BSD { int getdirentries(int fd, char *buf, u_int count, \ +196 NOPROTO BSD { int getdirentries(int fd, char *buf, u_int count, \ long *basep); } -197 MSTD BSD { caddr_t mmap(caddr_t addr, size_t len, int prot, \ - int flags, int fd, int pad, off_t pos); } -198 STD NOHIDE { int nosys(void); } __syscall __syscall_args int -199 STD POSIX { off_t lseek(int fd, int pad, off_t offset, \ +197 STD BSD { caddr_t ia32_mmap(caddr_t addr, size_t len, \ + int prot, int flags, int fd, int pad, \ + u_int32_t poslo, u_int32_t poshi); } +198 NOPROTO NOHIDE { int nosys(void); } __syscall __syscall_args int +; XXX note - bigendian is different +199 STD POSIX { off_t ia32_lseek(int fd, int pad, \ + u_int32_t offsetlo, u_int32_t offsethi, \ int whence); } -200 STD BSD { int truncate(char *path, int pad, off_t length); } -201 STD BSD { int ftruncate(int fd, int pad, off_t length); } -202 MSTD BSD { int __sysctl(int *name, u_int namelen, void *old, \ - size_t *oldlenp, void *new, size_t newlen); } \ - __sysctl sysctl_args int -; properly, __sysctl should be a NOHIDE, but making an exception -; here allows to avoid one in libc/sys/Makefile.inc. -203 MSTD BSD { int mlock(const void *addr, size_t len); } -204 MSTD BSD { int munlock(const void *addr, size_t len); } -205 STD BSD { int undelete(char *path); } -206 STD BSD { int futimes(int fd, struct timeval *tptr); } -207 MSTD BSD { int getpgid(pid_t pid); } +; XXX note - bigendian is different +200 STD BSD { int ia32_truncate(char *path, int pad, \ + u_int32_t lengthlo, u_int32_t lengthhi); } +; XXX note - bigendian is different +201 STD BSD { int ia32_ftruncate(int fd, int pad, \ + u_int32_t lengthlo, u_int32_t lengthhi); } +202 MSTD BSD { int ia32_sysctl(int *name, u_int namelen, \ + void *old, u_int32_t *oldlenp, void *new, \ + u_int32_t newlen); } +203 MNOPROTO BSD { int mlock(const void *addr, size_t len); } +204 MNOPROTO BSD { int munlock(const void *addr, size_t len); } +205 NOPROTO BSD { int undelete(char *path); } +206 NOPROTO BSD { int futimes(int fd, struct timeval *tptr); } +207 MNOPROTO BSD { int getpgid(pid_t pid); } 208 UNIMPL NOHIDE newreboot (NetBSD) -209 MSTD BSD { int poll(struct pollfd *fds, u_int nfds, \ +209 MNOPROTO BSD { int poll(struct pollfd *fds, u_int nfds, \ int timeout); } ; ; The following are reserved for loadable syscalls ; -210 NODEF NOHIDE lkmnosys lkmnosys nosys_args int -211 NODEF NOHIDE lkmnosys lkmnosys nosys_args int -212 NODEF NOHIDE lkmnosys lkmnosys nosys_args int -213 NODEF NOHIDE lkmnosys lkmnosys nosys_args int -214 NODEF NOHIDE lkmnosys lkmnosys nosys_args int -215 NODEF NOHIDE lkmnosys lkmnosys nosys_args int -216 NODEF NOHIDE lkmnosys lkmnosys nosys_args int -217 NODEF NOHIDE lkmnosys lkmnosys nosys_args int -218 NODEF NOHIDE lkmnosys lkmnosys nosys_args int -219 NODEF NOHIDE lkmnosys lkmnosys nosys_args int +210 UNIMPL NOHIDE +211 UNIMPL NOHIDE +212 UNIMPL NOHIDE +213 UNIMPL NOHIDE +214 UNIMPL NOHIDE +215 UNIMPL NOHIDE +216 UNIMPL NOHIDE +217 UNIMPL NOHIDE +218 UNIMPL NOHIDE +219 UNIMPL NOHIDE ; ; The following were introduced with NetBSD/4.4Lite-2 ; They are initialized by thier respective modules/sysinits -220 MNOSTD BSD { int __semctl(int semid, int semnum, int cmd, \ +220 MNOPROTO BSD { int __semctl(int semid, int semnum, int cmd, \ union semun *arg); } -221 MNOSTD BSD { int semget(key_t key, int nsems, int semflg); } -222 MNOSTD BSD { int semop(int semid, struct sembuf *sops, \ +221 MNOPROTO BSD { int semget(key_t key, int nsems, int semflg); } +222 MNOPROTO BSD { int semop(int semid, struct sembuf *sops, \ u_int nsops); } 223 UNIMPL NOHIDE semconfig -224 MNOSTD BSD { int msgctl(int msqid, int cmd, \ +224 MNOPROTO BSD { int msgctl(int msqid, int cmd, \ struct msqid_ds *buf); } -225 MNOSTD BSD { int msgget(key_t key, int msgflg); } -226 MNOSTD BSD { int msgsnd(int msqid, void *msgp, size_t msgsz, \ +225 MNOPROTO BSD { int msgget(key_t key, int msgflg); } +226 MNOPROTO BSD { int msgsnd(int msqid, void *msgp, size_t msgsz, \ int msgflg); } -227 MNOSTD BSD { int msgrcv(int msqid, void *msgp, size_t msgsz, \ +227 MNOPROTO BSD { int msgrcv(int msqid, void *msgp, size_t msgsz, \ long msgtyp, int msgflg); } -228 MNOSTD BSD { int shmat(int shmid, void *shmaddr, int shmflg); } -229 MNOSTD BSD { int shmctl(int shmid, int cmd, \ +228 MNOPROTO BSD { int shmat(int shmid, void *shmaddr, int shmflg); } +229 MNOPROTO BSD { int shmctl(int shmid, int cmd, \ struct shmid_ds *buf); } -230 MNOSTD BSD { int shmdt(void *shmaddr); } -231 MNOSTD BSD { int shmget(key_t key, int size, int shmflg); } +230 MNOPROTO BSD { int shmdt(void *shmaddr); } +231 MNOPROTO BSD { int shmget(key_t key, int size, int shmflg); } ; -232 MSTD POSIX { int clock_gettime(clockid_t clock_id, \ +232 MNOPROTO POSIX { int clock_gettime(clockid_t clock_id, \ struct timespec *tp); } -233 MSTD POSIX { int clock_settime(clockid_t clock_id, \ +233 MNOPROTO POSIX { int clock_settime(clockid_t clock_id, \ const struct timespec *tp); } -234 MSTD POSIX { int clock_getres(clockid_t clock_id, \ +234 MNOPROTO POSIX { int clock_getres(clockid_t clock_id, \ struct timespec *tp); } 235 UNIMPL NOHIDE timer_create 236 UNIMPL NOHIDE timer_delete 237 UNIMPL NOHIDE timer_settime 238 UNIMPL NOHIDE timer_gettime 239 UNIMPL NOHIDE timer_getoverrun -240 MSTD POSIX { int nanosleep(const struct timespec *rqtp, \ +240 MNOPROTO POSIX { int nanosleep(const struct timespec *rqtp, \ struct timespec *rmtp); } 241 UNIMPL NOHIDE nosys 242 UNIMPL NOHIDE nosys @@ -388,12 +382,12 @@ 248 UNIMPL NOHIDE nosys 249 UNIMPL NOHIDE nosys ; syscall numbers initially used in OpenBSD -250 MSTD BSD { int minherit(void *addr, size_t len, int inherit); } -251 MSTD BSD { int rfork(int flags); } -252 MSTD BSD { int openbsd_poll(struct pollfd *fds, u_int nfds, \ +250 MNOPROTO BSD { int minherit(void *addr, size_t len, int inherit); } +251 MNOPROTO BSD { int rfork(int flags); } +252 MNOPROTO BSD { int openbsd_poll(struct pollfd *fds, u_int nfds, \ int timeout); } -253 STD BSD { int issetugid(void); } -254 STD BSD { int lchown(char *path, int uid, int gid); } +253 NOPROTO BSD { int issetugid(void); } +254 NOPROTO BSD { int lchown(char *path, int uid, int gid); } 255 UNIMPL NOHIDE nosys 256 UNIMPL NOHIDE nosys 257 UNIMPL NOHIDE nosys @@ -411,15 +405,15 @@ 269 UNIMPL NOHIDE nosys 270 UNIMPL NOHIDE nosys 271 UNIMPL NOHIDE nosys -272 STD BSD { int getdents(int fd, char *buf, size_t count); } +272 NOPROTO BSD { int getdents(int fd, char *buf, size_t count); } 273 UNIMPL NOHIDE nosys -274 STD BSD { int lchmod(char *path, mode_t mode); } +274 NOPROTO BSD { int lchmod(char *path, mode_t mode); } 275 NOPROTO BSD { int lchown(char *path, uid_t uid, gid_t gid); } netbsd_lchown lchown_args int -276 STD BSD { int lutimes(char *path, struct timeval *tptr); } +276 NOPROTO BSD { int lutimes(char *path, struct timeval *tptr); } 277 MNOPROTO BSD { int msync(void *addr, size_t len, int flags); } netbsd_msync msync_args int -278 STD BSD { int nstat(char *path, struct nstat *ub); } -279 MSTD BSD { int nfstat(int fd, struct nstat *sb); } -280 STD BSD { int nlstat(char *path, struct nstat *ub); } +278 NOPROTO BSD { int nstat(char *path, struct nstat *ub); } +279 MNOPROTO BSD { int nfstat(int fd, struct nstat *sb); } +280 NOPROTO BSD { int nlstat(char *path, struct nstat *ub); } 281 UNIMPL NOHIDE nosys 282 UNIMPL NOHIDE nosys 283 UNIMPL NOHIDE nosys @@ -437,126 +431,133 @@ 295 UNIMPL NOHIDE nosys 296 UNIMPL NOHIDE nosys ; XXX 297 is 300 in NetBSD -297 STD BSD { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); } -298 STD BSD { int fhopen(const struct fhandle *u_fhp, int flags); } -299 STD BSD { int fhstat(const struct fhandle *u_fhp, struct stat *sb); } +297 NOPROTO BSD { int fhstatfs(const struct fhandle *u_fhp, struct statfs *buf); } +298 NOPROTO BSD { int fhopen(const struct fhandle *u_fhp, int flags); } +299 NOPROTO BSD { int fhstat(const struct fhandle *u_fhp, struct stat *sb); } ; syscall numbers for FreeBSD -300 MSTD BSD { int modnext(int modid); } -301 MSTD BSD { int modstat(int modid, struct module_stat* stat); } -302 MSTD BSD { int modfnext(int modid); } -303 MSTD BSD { int modfind(const char *name); } -304 MSTD BSD { int kldload(const char *file); } -305 MSTD BSD { int kldunload(int fileid); } -306 MSTD BSD { int kldfind(const char *file); } -307 MSTD BSD { int kldnext(int fileid); } -308 MSTD BSD { int kldstat(int fileid, struct kld_file_stat* stat); } -309 MSTD BSD { int kldfirstmod(int fileid); } -310 MSTD BSD { int getsid(pid_t pid); } -311 MSTD BSD { int setresuid(uid_t ruid, uid_t euid, uid_t suid); } -312 MSTD BSD { int setresgid(gid_t rgid, gid_t egid, gid_t sgid); } +300 MNOPROTO BSD { int modnext(int modid); } +301 MNOPROTO BSD { int modstat(int modid, struct module_stat* stat); } +302 MNOPROTO BSD { int modfnext(int modid); } +303 MNOPROTO BSD { int modfind(const char *name); } +304 MNOPROTO BSD { int kldload(const char *file); } +305 MNOPROTO BSD { int kldunload(int fileid); } +306 MNOPROTO BSD { int kldfind(const char *file); } +307 MNOPROTO BSD { int kldnext(int fileid); } +308 MNOPROTO BSD { int kldstat(int fileid, struct kld_file_stat* stat); } +309 MNOPROTO BSD { int kldfirstmod(int fileid); } +310 MNOPROTO BSD { int getsid(pid_t pid); } +311 MNOPROTO BSD { int setresuid(uid_t ruid, uid_t euid, uid_t suid); } +312 MNOPROTO BSD { int setresgid(gid_t rgid, gid_t egid, gid_t sgid); } 313 OBSOL NOHIDE signanosleep -314 NOSTD BSD { int aio_return(struct aiocb *aiocbp); } -315 NOSTD BSD { int aio_suspend(struct aiocb * const * aiocbp, int nent, const struct timespec *timeout); } -316 NOSTD BSD { int aio_cancel(int fd, struct aiocb *aiocbp); } -317 NOSTD BSD { int aio_error(struct aiocb *aiocbp); } -318 NOSTD BSD { int aio_read(struct aiocb *aiocbp); } -319 NOSTD BSD { int aio_write(struct aiocb *aiocbp); } -320 NOSTD BSD { int lio_listio(int mode, struct aiocb * const *acb_list, int nent, struct sigevent *sig); } -321 MSTD BSD { int yield(void); } +314 UNIMPL NOHIDE aio_return +315 UNIMPL NOHIDE aio_suspend +316 UNIMPL NOHIDE aio_cancel +317 UNIMPL NOHIDE aio_error +318 UNIMPL NOHIDE aio_read +319 UNIMPL NOHIDE aio_write +320 UNIMPL NOHIDE lio_listio +321 MNOPROTO BSD { int yield(void); } 322 OBSOL NOHIDE thr_sleep 323 OBSOL NOHIDE thr_wakeup -324 MSTD BSD { int mlockall(int how); } -325 MSTD BSD { int munlockall(void); } -326 STD BSD { int __getcwd(u_char *buf, u_int buflen); } +324 MNOPROTO BSD { int mlockall(int how); } +325 MNOPROTO BSD { int munlockall(void); } +326 NOPROTO BSD { int __getcwd(u_char *buf, u_int buflen); } -327 MSTD POSIX { int sched_setparam (pid_t pid, const struct sched_param *param); } -328 MSTD POSIX { int sched_getparam (pid_t pid, struct sched_param *param); } +327 MNOPROTO POSIX { int sched_setparam (pid_t pid, const struct sched_param *param); } +328 MNOPROTO POSIX { int sched_getparam (pid_t pid, struct sched_param *param); } -329 MSTD POSIX { int sched_setscheduler (pid_t pid, int policy, const struct sched_param *param); } -330 MSTD POSIX { int sched_getscheduler (pid_t pid); } +329 MNOPROTO POSIX { int sched_setscheduler (pid_t pid, int policy, const struct sched_param *param); } +330 MNOPROTO POSIX { int sched_getscheduler (pid_t pid); } -331 MSTD POSIX { int sched_yield (void); } -332 MSTD POSIX { int sched_get_priority_max (int policy); } -333 MSTD POSIX { int sched_get_priority_min (int policy); } -334 MSTD POSIX { int sched_rr_get_interval (pid_t pid, struct timespec *interval); } -335 STD BSD { int utrace(const void *addr, size_t len); } -336 MSTD BSD { int sendfile(int fd, int s, off_t offset, size_t nbytes, \ - struct sf_hdtr *hdtr, off_t *sbytes, int flags); } -337 STD BSD { int kldsym(int fileid, int cmd, void *data); } -338 MSTD BSD { int jail(struct jail *jail); } +331 MNOPROTO POSIX { int sched_yield (void); } +332 MNOPROTO POSIX { int sched_get_priority_max (int policy); } +333 MNOPROTO POSIX { int sched_get_priority_min (int policy); } +334 MNOPROTO POSIX { int sched_rr_get_interval (pid_t pid, struct timespec *interval); } +335 NOPROTO BSD { int utrace(const void *addr, size_t len); } +; XXX note - bigendian is different +336 MSTD BSD { int ia32_sendfile(int fd, int s, u_int32_t offsetlo, \ + u_int32_t offsethi, size_t nbytes, \ + struct sf_hdtr *hdtr, off_t *sbytes, int flags); } +337 NOPROTO BSD { int kldsym(int fileid, int cmd, void *data); } +338 MNOPROTO BSD { int jail(struct jail *jail); } 339 UNIMPL BSD pioctl -340 MSTD POSIX { int sigprocmask(int how, const sigset_t *set, \ +340 MNOPROTO POSIX { int sigprocmask(int how, const sigset_t *set, \ sigset_t *oset); } -341 MSTD POSIX { int sigsuspend(const sigset_t *sigmask); } -342 MSTD POSIX { int sigaction(int sig, const struct sigaction *act, \ - struct sigaction *oact); } -343 MSTD POSIX { int sigpending(sigset_t *set); } -344 STD BSD { int sigreturn(const struct __ucontext *sigcntxp); } +341 MNOPROTO POSIX { int sigsuspend(const sigset_t *sigmask); } +342 STD POSIX { int ia32_sigaction(int sig, \ + struct sigaction32 *act, \ + struct sigaction32 *oact); } +343 MNOPROTO POSIX { int sigpending(sigset_t *set); } +344 MNOPROTO BSD { int sigreturn(const struct __ucontext *sigcntxp); } 345 UNIMPL NOHIDE sigtimedwait 346 UNIMPL NOHIDE sigwaitinfo -347 MSTD BSD { int __acl_get_file(const char *path, \ +347 MNOPROTO BSD { int __acl_get_file(const char *path, \ acl_type_t type, struct acl *aclp); } -348 MSTD BSD { int __acl_set_file(const char *path, \ +348 MNOPROTO BSD { int __acl_set_file(const char *path, \ acl_type_t type, struct acl *aclp); } -349 MSTD BSD { int __acl_get_fd(int filedes, acl_type_t type, \ +349 MNOPROTO BSD { int __acl_get_fd(int filedes, acl_type_t type, \ struct acl *aclp); } -350 MSTD BSD { int __acl_set_fd(int filedes, acl_type_t type, \ +350 MNOPROTO BSD { int __acl_set_fd(int filedes, acl_type_t type, \ struct acl *aclp); } -351 MSTD BSD { int __acl_delete_file(const char *path, \ +351 MNOPROTO BSD { int __acl_delete_file(const char *path, \ acl_type_t type); } -352 MSTD BSD { int __acl_delete_fd(int filedes, acl_type_t type); } -353 MSTD BSD { int __acl_aclcheck_file(const char *path, \ +352 MNOPROTO BSD { int __acl_delete_fd(int filedes, acl_type_t type); } +353 MNOPROTO BSD { int __acl_aclcheck_file(const char *path, \ acl_type_t type, struct acl *aclp); } -354 MSTD BSD { int __acl_aclcheck_fd(int filedes, acl_type_t type, \ +354 MNOPROTO BSD { int __acl_aclcheck_fd(int filedes, acl_type_t type, \ struct acl *aclp); } -355 STD BSD { int extattrctl(const char *path, int cmd, \ +355 NOPROTO BSD { int extattrctl(const char *path, int cmd, \ const char *filename, int attrnamespace, \ const char *attrname); } -356 STD BSD { int extattr_set_file(const char *path, \ +356 NOPROTO BSD { int extattr_set_file(const char *path, \ int attrnamespace, const char *attrname, \ void *data, size_t nbytes); } -357 STD BSD { ssize_t extattr_get_file(const char *path, \ +357 NOPROTO BSD { ssize_t extattr_get_file(const char *path, \ int attrnamespace, const char *attrname, \ void *data, size_t nbytes); } -358 STD BSD { int extattr_delete_file(const char *path, \ +358 NOPROTO BSD { int extattr_delete_file(const char *path, \ int attrnamespace, const char *attrname); } -359 NOSTD BSD { int aio_waitcomplete(struct aiocb **aiocbp, struct timespec *timeout); } -360 MSTD BSD { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); } -361 MSTD BSD { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); } -362 MSTD BSD { int kqueue(void); } -363 MSTD BSD { int kevent(int fd, \ +359 UNIMPL NOHIDE aio_waitcomplete +360 MNOPROTO BSD { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); } +361 MNOPROTO BSD { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); } +362 MNOPROTO BSD { int kqueue(void); } +363 MNOPROTO BSD { int kevent(int fd, \ const struct kevent *changelist, int nchanges, \ struct kevent *eventlist, int nevents, \ const struct timespec *timeout); } -364 STD BSD { int __cap_get_proc(struct cap *cap_p); } -365 STD BSD { int __cap_set_proc(struct cap *cap_p); } -366 STD BSD { int __cap_get_fd(int fd, struct cap *cap_p); } -367 STD BSD { int __cap_get_file(const char *path_p, struct cap *cap_p); } -368 STD BSD { int __cap_set_fd(int fd, struct cap *cap_p); } -369 STD BSD { int __cap_set_file(const char *path_p, struct cap *cap_p); } -370 NODEF NOHIDE lkmressys lkmressys nosys_args int -371 STD BSD { int extattr_set_fd(int fd, int attrnamespace, \ +364 UNIMPL NOHIDE __cap_get_proc +365 UNIMPL NOHIDE __cap_set_proc +366 UNIMPL NOHIDE __cap_get_fd +367 UNIMPL NOHIDE __cap_get_file +368 UNIMPL NOHIDE __cap_set_fd +369 UNIMPL NOHIDE __cap_set_file +370 UNIMPL NOHIDE lkmressys +371 NOPROTO BSD { int extattr_set_fd(int fd, int attrnamespace, \ const char *attrname, void *data, \ size_t nbytes); } -372 STD BSD { ssize_t extattr_get_fd(int fd, int attrnamespace, \ +372 NOPROTO BSD { ssize_t extattr_get_fd(int fd, int attrnamespace, \ const char *attrname, void *data, size_t nbytes); } -373 STD BSD { int extattr_delete_fd(int fd, int attrnamespace, \ +373 NOPROTO BSD { int extattr_delete_fd(int fd, int attrnamespace, \ const char *attrname); } -374 MSTD BSD { int __setugid(int flag); } -375 NOIMPL BSD { int nfsclnt(int flag, caddr_t argp); } -376 STD BSD { int eaccess(char *path, int flags); } +374 MNOPROTO BSD { int __setugid(int flag); } +375 UNIMPL BSD nfsclnt +376 NOPROTO BSD { int eaccess(char *path, int flags); } 377 UNIMPL BSD afs_syscall -378 STD BSD { int nmount(struct iovec *iovp, unsigned int iovcnt, \ +378 NOPROTO BSD { int nmount(struct iovec *iovp, unsigned int iovcnt, \ int flags); } -379 STD BSD { int kse_exit(void); } -380 STD BSD { int kse_wakeup(void); } -381 STD BSD { int kse_new(struct kse_mailbox * mbx, \ +379 NOPROTO BSD { int kse_exit(void); } +380 NOPROTO BSD { int kse_wakeup(void); } +381 NOPROTO BSD { int kse_new(struct kse_mailbox * mbx, \ int new_grp_flag); } -382 STD BSD { int thread_wakeup(struct thread_mailbox *tmbx); } -383 STD BSD { int kse_yield(void); } +382 NOPROTO BSD { int thread_wakeup(struct thread_mailbox *tmbx); } +383 NOPROTO BSD { int kse_yield(void); } 384 UNIMPL BSD __mac_get_proc 385 UNIMPL BSD __mac_set_proc 386 UNIMPL BSD __mac_get_fd 387 UNIMPL BSD __mac_get_file 388 UNIMPL BSD __mac_set_fd 389 UNIMPL BSD __mac_set_file +390 NOPROTO BSD { int kenv(int what, const char *name, char *value, \ + int len); } +391 NOPROTO BSD { int lchflags(const char *path, int flags); } +392 NOPROTO BSD { int uuidgen(struct uuid *store, int count); } diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c new file mode 100644 index 0000000..06e6505 --- /dev/null +++ b/sys/compat/ia32/ia32_sysvec.c @@ -0,0 +1,365 @@ +/*- + * Copyright (c) 2002 Doug Rabson + * 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#define __ELF_WORD_SIZE 32 + +#include <sys/param.h> +#include <sys/exec.h> +#include <sys/fcntl.h> +#include <sys/imgact.h> +#include <sys/kernel.h> +#include <sys/lock.h> +#include <sys/malloc.h> +#include <sys/mutex.h> +#include <sys/mman.h> +#include <sys/namei.h> +#include <sys/pioctl.h> +#include <sys/proc.h> +#include <sys/procfs.h> +#include <sys/resourcevar.h> +#include <sys/systm.h> +#include <sys/signalvar.h> +#include <sys/stat.h> +#include <sys/sx.h> +#include <sys/syscall.h> +#include <sys/sysctl.h> +#include <sys/sysent.h> +#include <sys/vnode.h> +#include <sys/imgact_elf.h> + +#include <vm/vm.h> +#include <vm/vm_kern.h> +#include <vm/vm_param.h> +#include <vm/pmap.h> +#include <vm/vm_map.h> +#include <vm/vm_object.h> +#include <vm/vm_extern.h> + +#include <ia64/ia32/ia32_util.h> +#include <i386/include/psl.h> +#include <i386/include/segments.h> +#include <i386/include/specialreg.h> +#include <machine/frame.h> +#include <machine/md_var.h> + +static register_t *ia32_copyout_strings(struct image_params *imgp); +static void ia32_setregs(struct thread *td, u_long entry, u_long stack, + u_long ps_strings); + +extern struct sysent ia32_sysent[]; + +static char ia32_sigcode[] = { + 0xff, 0x54, 0x24, 0x10, /* call *SIGF_HANDLER(%esp) */ + 0x8d, 0x44, 0x24, 0x14, /* lea SIGF_UC(%esp),%eax */ + 0x50, /* pushl %eax */ + 0xf7, 0x40, 0x54, 0x00, 0x00, 0x02, 0x02, /* testl $PSL_VM,UC_EFLAGS(%eax) */ + 0x75, 0x03, /* jne 9f */ + 0x8e, 0x68, 0x14, /* movl UC_GS(%eax),%gs */ + 0xb8, 0x57, 0x01, 0x00, 0x00, /* 9: movl $SYS_sigreturn,%eax */ + 0x50, /* pushl %eax */ + 0xcd, 0x80, /* int $0x80 */ + 0xeb, 0xfe, /* 0: jmp 0b */ + 0, 0, 0, 0 +}; +static int ia32_szsigcode = sizeof(ia32_sigcode) & ~3; + +struct sysentvec ia32_freebsd_sysvec = { + SYS_MAXSYSCALL, + ia32_sysent, + 0, + 0, + 0, + 0, + 0, + 0, + elf32_freebsd_fixup, + sendsig, + ia32_sigcode, + &ia32_szsigcode, + 0, + "FreeBSD ELF", + elf32_coredump, + NULL, + MINSIGSTKSZ, + 4096, + IA32_USRSTACK, + IA32_USRSTACK, + ia32_copyout_strings, + ia32_setregs +}; + +static Elf32_Brandinfo ia32_brand_info = { + ELFOSABI_FREEBSD, + EM_386, + "FreeBSD", + "/compat/ia32", + "/usr/libexec/ld-elf.so.1", + &ia32_freebsd_sysvec + }; + +SYSINIT(ia32, SI_SUB_EXEC, SI_ORDER_ANY, + (sysinit_cfunc_t) elf32_insert_brand_entry, + &ia32_brand_info); + +static register_t * +ia32_copyout_strings(struct image_params *imgp) +{ + int argc, envc; + u_int32_t *vectp; + char *stringp, *destp; + u_int32_t *stack_base; + struct ia32_ps_strings *arginfo; + int szsigcode; + + /* + * Calculate string base and vector table pointers. + * Also deal with signal trampoline code for this exec type. + */ + arginfo = (struct ia32_ps_strings *)IA32_PS_STRINGS; + szsigcode = *(imgp->proc->p_sysent->sv_szsigcode); + destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE - + roundup((ARG_MAX - imgp->stringspace), sizeof(char *)); + + /* + * install sigcode + */ + if (szsigcode) + copyout(imgp->proc->p_sysent->sv_sigcode, + ((caddr_t)arginfo - szsigcode), szsigcode); + + /* + * If we have a valid auxargs ptr, prepare some room + * on the stack. + */ + if (imgp->auxargs) { + /* + * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for + * lower compatibility. + */ + imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size + : (AT_COUNT * 2); + /* + * The '+ 2' is for the null pointers at the end of each of + * the arg and env vector sets,and imgp->auxarg_size is room + * for argument of Runtime loader. + */ + vectp = (u_int32_t *) (destp - (imgp->argc + imgp->envc + 2 + + imgp->auxarg_size) * sizeof(u_int32_t)); + + } else + /* + * The '+ 2' is for the null pointers at the end of each of + * the arg and env vector sets + */ + vectp = (u_int32_t *) + (destp - (imgp->argc + imgp->envc + 2) * sizeof(u_int32_t)); + + /* + * vectp also becomes our initial stack base + */ + stack_base = vectp; + + stringp = imgp->stringbase; + argc = imgp->argc; + envc = imgp->envc; + + /* + * Copy out strings - arguments and environment. + */ + copyout(stringp, destp, ARG_MAX - imgp->stringspace); + + /* + * Fill in "ps_strings" struct for ps, w, etc. + */ + suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp); + suword32(&arginfo->ps_nargvstr, argc); + + /* + * Fill in argument portion of vector table. + */ + for (; argc > 0; --argc) { + suword32(vectp++, (u_int32_t)(intptr_t)destp); + while (*stringp++ != 0) + destp++; + destp++; + } + + /* a null vector table pointer separates the argp's from the envp's */ + suword32(vectp++, 0); + + suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp); + suword32(&arginfo->ps_nenvstr, envc); + + /* + * Fill in environment portion of vector table. + */ + for (; envc > 0; --envc) { + suword32(vectp++, (u_int32_t)(intptr_t)destp); + while (*stringp++ != 0) + destp++; + destp++; + } + + /* end of vector table is a null pointer */ + suword32(vectp, 0); + + return ((register_t *)stack_base); +} + +static void +ia32_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) +{ + struct trapframe *frame = td->td_frame; + vm_offset_t gdt, ldt; + u_int64_t codesel, datasel, ldtsel; + u_int64_t codeseg, dataseg, gdtseg, ldtseg; + struct segment_descriptor desc; + struct vmspace *vmspace = td->td_proc->p_vmspace; + + /* + * Make sure that we restore the entire trapframe after an + * execve. + */ + frame->tf_flags &= ~FRAME_SYSCALL; + + bzero(frame->tf_r, sizeof(frame->tf_r)); + bzero(frame->tf_f, sizeof(frame->tf_f)); + + frame->tf_cr_iip = entry; + frame->tf_cr_ipsr = (IA64_PSR_IC + | IA64_PSR_I + | IA64_PSR_IT + | IA64_PSR_DT + | IA64_PSR_RT + | IA64_PSR_DFH + | IA64_PSR_IS + | IA64_PSR_BN + | IA64_PSR_CPL_USER); + frame->tf_r[FRAME_R12] = stack; + + codesel = LSEL(LUCODE_SEL, SEL_UPL); + datasel = LSEL(LUDATA_SEL, SEL_UPL); + ldtsel = GSEL(GLDT_SEL, SEL_UPL); + +#if 1 + frame->tf_r[FRAME_R16] = (datasel << 48) | (datasel << 32) + | (datasel << 16) | datasel; + frame->tf_r[FRAME_R17] = (ldtsel << 32) | (datasel << 16) | codesel; +#else + frame->tf_r[FRAME_R16] = datasel; + frame->tf_r[FRAME_R17] = codesel; + frame->tf_r[FRAME_R18] = datasel; + frame->tf_r[FRAME_R19] = datasel; + frame->tf_r[FRAME_R20] = datasel; + frame->tf_r[FRAME_R21] = datasel; + frame->tf_r[FRAME_R22] = ldtsel; +#endif + + /* + * Build the GDT and LDT. + */ + gdt = IA32_USRSTACK; + vm_map_find(&vmspace->vm_map, 0, 0, + &gdt, PAGE_SIZE, 0, + VM_PROT_ALL, VM_PROT_ALL, 0); + ldt = gdt + 4096; + + desc.sd_lolimit = 8*NLDT-1; + desc.sd_lobase = ldt & 0xffffff; + desc.sd_type = SDT_SYSLDT; + desc.sd_dpl = SEL_UPL; + desc.sd_p = 1; + desc.sd_hilimit = 0; + desc.sd_def32 = 0; + desc.sd_gran = 0; + desc.sd_hibase = ldt >> 24; + copyout(&desc, (caddr_t) gdt + 8*GLDT_SEL, sizeof(desc)); + + desc.sd_lolimit = ((IA32_USRSTACK >> 12) - 1) & 0xffff; + desc.sd_lobase = 0; + desc.sd_type = SDT_MEMERA; + desc.sd_dpl = SEL_UPL; + desc.sd_p = 1; + desc.sd_hilimit = ((IA32_USRSTACK >> 12) - 1) >> 16; + desc.sd_def32 = 1; + desc.sd_gran = 1; + desc.sd_hibase = 0; + copyout(&desc, (caddr_t) ldt + 8*LUCODE_SEL, sizeof(desc)); + desc.sd_type = SDT_MEMRWA; + copyout(&desc, (caddr_t) ldt + 8*LUDATA_SEL, sizeof(desc)); + + codeseg = 0 /* base */ + + (((IA32_USRSTACK >> 12) - 1) << 32) /* limit */ + + ((long)SDT_MEMERA << 52) + + ((long)SEL_UPL << 57) + + (1L << 59) /* present */ + + (1L << 62) /* 32 bits */ + + (1L << 63); /* page granularity */ + dataseg = 0 /* base */ + + (((IA32_USRSTACK >> 12) - 1) << 32) /* limit */ + + ((long)SDT_MEMRWA << 52) + + ((long)SEL_UPL << 57) + + (1L << 59) /* present */ + + (1L << 62) /* 32 bits */ + + (1L << 63); /* page granularity */ + ia64_set_csd(codeseg); + ia64_set_ssd(dataseg); + frame->tf_r[FRAME_R24] = dataseg; /* ESD */ + frame->tf_r[FRAME_R27] = dataseg; /* DSD */ + frame->tf_r[FRAME_R28] = dataseg; /* FSD */ + frame->tf_r[FRAME_R29] = dataseg; /* GSD */ + + gdtseg = gdt /* base */ + + ((8L*NGDT - 1) << 32) /* limit */ + + ((long)SDT_SYSNULL << 52) + + ((long)SEL_UPL << 57) + + (1L << 59) /* present */ + + (0L << 62) /* 16 bits */ + + (0L << 63); /* byte granularity */ + ldtseg = ldt /* base */ + + ((8L*NLDT - 1) << 32) /* limit */ + + ((long)SDT_SYSLDT << 52) + + ((long)SEL_UPL << 57) + + (1L << 59) /* present */ + + (0L << 62) /* 16 bits */ + + (0L << 63); /* byte granularity */ + frame->tf_r[FRAME_R30] = ldtseg; /* LDTD */ + frame->tf_r[FRAME_R31] = gdtseg; /* GDTD */ + + ia64_set_eflag(PSL_USER); + + /* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */ + frame->tf_r[FRAME_R11] = IA32_PS_STRINGS; + + /* + * XXX - Linux emulator + * Make sure sure edx is 0x0 on entry. Linux binaries depend + * on it. + */ + td->td_retval[1] = 0; +} diff --git a/sys/compat/ia32/ia32_util.h b/sys/compat/ia32/ia32_util.h new file mode 100644 index 0000000..b9e0a7c --- /dev/null +++ b/sys/compat/ia32/ia32_util.h @@ -0,0 +1,94 @@ +/*- + * Copyright (c) 1998-1999 Andrew Gallatin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <vm/vm.h> +#include <vm/vm_param.h> +#include <vm/pmap.h> + + +#include <sys/exec.h> +#include <sys/sysent.h> +#include <sys/cdefs.h> + + +#ifndef SCARG +#define SCARG(p, x) (p)->x +#endif + +struct ia32_ps_strings { + u_int32_t ps_argvstr; /* first of 0 or more argument strings */ + int ps_nargvstr; /* the number of argument strings */ + u_int32_t ps_envstr; /* first of 0 or more environment strings */ + int ps_nenvstr; /* the number of environment strings */ +}; + +#define IA32_USRSTACK (4L*1024*1024*1024 - PAGE_SIZE) +#define IA32_PS_STRINGS (IA32_USRSTACK - sizeof(struct ia32_ps_strings)) + +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)IA32_PS_STRINGS) - szsigcode - SPARE_USRSPACE); +#undef szsigcode +} + +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 ia32_emul_path[]; +int ia32_emul_find(struct thread *, caddr_t *, const char *, char *, + char **, int); + +#define CHECKALT(p, sgp, path, i) \ + do { \ + int _error; \ + \ + _error = ia32_emul_find(p, sgp, ia32_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/compat/pecoff/imgact_pecoff.c b/sys/compat/pecoff/imgact_pecoff.c index 8196aa1..2d4691d 100644 --- a/sys/compat/pecoff/imgact_pecoff.c +++ b/sys/compat/pecoff/imgact_pecoff.c @@ -465,7 +465,7 @@ exec_pecoff_coff_prep_zmagic(struct image_params * imgp, peofs + PECOFF_HDR_SIZE, (caddr_t) sh, scnsiz); if ((error = exec_extract_strings(imgp)) != 0) goto fail; - exec_new_vmspace(imgp); + exec_new_vmspace(imgp, VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS, USRSTACK); vmspace = imgp->proc->p_vmspace; for (i = 0; i < fp->f_nscns; i++) { prot = VM_PROT_WRITE; /* XXX for relocation? */ diff --git a/sys/compat/svr4/imgact_svr4.c b/sys/compat/svr4/imgact_svr4.c index 43b71be..ad72929 100644 --- a/sys/compat/svr4/imgact_svr4.c +++ b/sys/compat/svr4/imgact_svr4.c @@ -119,7 +119,7 @@ exec_svr4_imgact(imgp) /* * Destroy old process VM and create a new one (with a new stack) */ - exec_new_vmspace(imgp); + exec_new_vmspace(imgp, VM_MIN_ADDRESS, VM_MAXUSER_ADDRESS, USRSTACK); vmspace = imgp->proc->p_vmspace; /* diff --git a/sys/compat/svr4/svr4_sysvec.c b/sys/compat/svr4/svr4_sysvec.c index 1c37adb..c7d67ff 100644 --- a/sys/compat/svr4/svr4_sysvec.c +++ b/sys/compat/svr4/svr4_sysvec.c @@ -179,13 +179,14 @@ struct sysentvec svr4_sysvec = { &svr4_szsigcode, NULL, "SVR4", - elf_coredump, + elf32_coredump, NULL, SVR4_MINSIGSTKSZ }; Elf32_Brandinfo svr4_brand = { ELFOSABI_SYSV, + EM_386, /* XXX only implemented for x86 so far. */ "SVR4", svr4_emul_path, "/lib/libc.so.1", @@ -376,7 +377,7 @@ svr4_elf_modevent(module_t mod, int type, void *data) switch(type) { case MOD_LOAD: - if (elf_insert_brand_entry(&svr4_brand) < 0) + if (elf32_insert_brand_entry(&svr4_brand) < 0) error = EINVAL; if (error) printf("cannot insert svr4 elf brand handler\n"); @@ -385,9 +386,9 @@ svr4_elf_modevent(module_t mod, int type, void *data) break; case MOD_UNLOAD: /* Only allow the emulator to be removed if it isn't in use. */ - if (elf_brand_inuse(&svr4_brand) != 0) { + if (elf32_brand_inuse(&svr4_brand) != 0) { error = EBUSY; - } else if (elf_remove_brand_entry(&svr4_brand) < 0) { + } else if (elf32_remove_brand_entry(&svr4_brand) < 0) { error = EINVAL; } |