diff options
| author | fishsoupisgood <github@madingley.org> | 2019-04-29 01:17:54 +0100 | 
|---|---|---|
| committer | fishsoupisgood <github@madingley.org> | 2019-05-27 03:43:43 +0100 | 
| commit | 3f2546b2ef55b661fd8dd69682b38992225e86f6 (patch) | |
| tree | 65ca85f13617aee1dce474596800950f266a456c /bsd-user | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip  | |
Diffstat (limited to 'bsd-user')
| -rw-r--r-- | bsd-user/Makefile.objs | 2 | ||||
| -rw-r--r-- | bsd-user/bsd-mman.h | 121 | ||||
| -rw-r--r-- | bsd-user/bsdload.c | 202 | ||||
| -rw-r--r-- | bsd-user/elfload.c | 1578 | ||||
| -rw-r--r-- | bsd-user/errno_defs.h | 149 | ||||
| -rw-r--r-- | bsd-user/freebsd/strace.list | 231 | ||||
| -rw-r--r-- | bsd-user/freebsd/syscall_nr.h | 450 | ||||
| -rw-r--r-- | bsd-user/i386/syscall.h | 161 | ||||
| -rw-r--r-- | bsd-user/i386/target_signal.h | 20 | ||||
| -rw-r--r-- | bsd-user/main.c | 1139 | ||||
| -rw-r--r-- | bsd-user/mmap.c | 499 | ||||
| -rw-r--r-- | bsd-user/netbsd/strace.list | 145 | ||||
| -rw-r--r-- | bsd-user/netbsd/syscall_nr.h | 373 | ||||
| -rw-r--r-- | bsd-user/openbsd/strace.list | 187 | ||||
| -rw-r--r-- | bsd-user/openbsd/syscall_nr.h | 225 | ||||
| -rw-r--r-- | bsd-user/qemu.h | 421 | ||||
| -rw-r--r-- | bsd-user/signal.c | 38 | ||||
| -rw-r--r-- | bsd-user/sparc/syscall.h | 9 | ||||
| -rw-r--r-- | bsd-user/sparc/target_signal.h | 27 | ||||
| -rw-r--r-- | bsd-user/sparc64/syscall.h | 10 | ||||
| -rw-r--r-- | bsd-user/sparc64/target_signal.h | 27 | ||||
| -rw-r--r-- | bsd-user/strace.c | 242 | ||||
| -rw-r--r-- | bsd-user/syscall.c | 564 | ||||
| -rw-r--r-- | bsd-user/syscall_defs.h | 114 | ||||
| -rw-r--r-- | bsd-user/uaccess.c | 65 | ||||
| -rw-r--r-- | bsd-user/x86_64/syscall.h | 116 | ||||
| -rw-r--r-- | bsd-user/x86_64/target_signal.h | 19 | 
27 files changed, 7134 insertions, 0 deletions
diff --git a/bsd-user/Makefile.objs b/bsd-user/Makefile.objs new file mode 100644 index 00000000..5e77f577 --- /dev/null +++ b/bsd-user/Makefile.objs @@ -0,0 +1,2 @@ +obj-y = main.o bsdload.o elfload.o mmap.o signal.o strace.o syscall.o \ +	        uaccess.o diff --git a/bsd-user/bsd-mman.h b/bsd-user/bsd-mman.h new file mode 100644 index 00000000..910e8c19 --- /dev/null +++ b/bsd-user/bsd-mman.h @@ -0,0 +1,121 @@ +/*- + * Copyright (c) 1982, 1986, 1993 + *      The Regents of the University of California.  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. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + *      @(#)mman.h      8.2 (Berkeley) 1/9/95 + * $FreeBSD: src/sys/sys/mman.h,v 1.42 2008/03/28 04:29:27 ps Exp $ + */ + +#define TARGET_FREEBSD_MAP_RESERVED0080 0x0080  /* previously misimplemented MAP_INHERIT */ +#define TARGET_FREEBSD_MAP_RESERVED0100 0x0100  /* previously unimplemented MAP_NOEXTEND */ +#define TARGET_FREEBSD_MAP_STACK        0x0400  /* region grows down, like a stack */ +#define TARGET_FREEBSD_MAP_NOSYNC       0x0800  /* page to but do not sync underlying file */ + +#define TARGET_FREEBSD_MAP_FLAGMASK     0x1ff7 + +/*      $NetBSD: mman.h,v 1.42 2008/11/18 22:13:49 ad Exp $     */ + +/*- + * Copyright (c) 1982, 1986, 1993 + *      The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + *      @(#)mman.h      8.2 (Berkeley) 1/9/95 + */ +#define TARGET_NETBSD_MAP_INHERIT       0x0080  /* region is retained after exec */ +#define TARGET_NETBSD_MAP_TRYFIXED      0x0400 /* attempt hint address, even within break */ +#define TARGET_NETBSD_MAP_WIRED         0x0800  /* mlock() mapping when it is established */ + +#define TARGET_NETBSD_MAP_STACK         0x2000  /* allocated from memory, swap space (stack) */ + +#define TARGET_NETBSD_MAP_FLAGMASK      0x3ff7 + +/*      $OpenBSD: mman.h,v 1.18 2003/07/21 22:52:19 tedu Exp $  */ +/*      $NetBSD: mman.h,v 1.11 1995/03/26 20:24:23 jtc Exp $    */ + +/*- + * Copyright (c) 1982, 1986, 1993 + *      The Regents of the University of California.  All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + *      @(#)mman.h      8.1 (Berkeley) 6/2/93 + */ + +#define TARGET_OPENBSD_MAP_INHERIT      0x0080  /* region is retained after exec */ +#define TARGET_OPENBSD_MAP_NOEXTEND     0x0100  /* for MAP_FILE, don't change file size */ +#define TARGET_OPENBSD_MAP_TRYFIXED     0x0400  /* attempt hint address, even within heap */ + +#define TARGET_OPENBSD_MAP_FLAGMASK     0x17f7 + +// XXX +#define TARGET_BSD_MAP_FLAGMASK         0x3ff7 diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c new file mode 100644 index 00000000..2abc7136 --- /dev/null +++ b/bsd-user/bsdload.c @@ -0,0 +1,202 @@ +/* Code for loading BSD executables.  Mostly linux kernel code.  */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +#include "qemu.h" + +#define TARGET_NGROUPS 32 + +/* ??? This should really be somewhere else.  */ +abi_long memcpy_to_target(abi_ulong dest, const void *src, +                          unsigned long len) +{ +    void *host_ptr; + +    host_ptr = lock_user(VERIFY_WRITE, dest, len, 0); +    if (!host_ptr) +        return -TARGET_EFAULT; +    memcpy(host_ptr, src, len); +    unlock_user(host_ptr, dest, 1); +    return 0; +} + +static int in_group_p(gid_t g) +{ +    /* return TRUE if we're in the specified group, FALSE otherwise */ +    int         ngroup; +    int         i; +    gid_t       grouplist[TARGET_NGROUPS]; + +    ngroup = getgroups(TARGET_NGROUPS, grouplist); +    for(i = 0; i < ngroup; i++) { +        if(grouplist[i] == g) { +            return 1; +        } +    } +    return 0; +} + +static int count(char ** vec) +{ +    int         i; + +    for(i = 0; *vec; i++) { +        vec++; +    } + +    return(i); +} + +static int prepare_binprm(struct linux_binprm *bprm) +{ +    struct stat         st; +    int mode; +    int retval, id_change; + +    if(fstat(bprm->fd, &st) < 0) { +        return(-errno); +    } + +    mode = st.st_mode; +    if(!S_ISREG(mode)) {        /* Must be regular file */ +        return(-EACCES); +    } +    if(!(mode & 0111)) {        /* Must have at least one execute bit set */ +        return(-EACCES); +    } + +    bprm->e_uid = geteuid(); +    bprm->e_gid = getegid(); +    id_change = 0; + +    /* Set-uid? */ +    if(mode & S_ISUID) { +        bprm->e_uid = st.st_uid; +        if(bprm->e_uid != geteuid()) { +            id_change = 1; +        } +    } + +    /* Set-gid? */ +    /* +     * If setgid is set but no group execute bit then this +     * is a candidate for mandatory locking, not a setgid +     * executable. +     */ +    if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { +        bprm->e_gid = st.st_gid; +        if (!in_group_p(bprm->e_gid)) { +                id_change = 1; +        } +    } + +    memset(bprm->buf, 0, sizeof(bprm->buf)); +    retval = lseek(bprm->fd, 0L, SEEK_SET); +    if(retval >= 0) { +        retval = read(bprm->fd, bprm->buf, 128); +    } +    if(retval < 0) { +        perror("prepare_binprm"); +        exit(-1); +        /* return(-errno); */ +    } +    else { +        return(retval); +    } +} + +/* Construct the envp and argv tables on the target stack.  */ +abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, +                              abi_ulong stringp, int push_ptr) +{ +    int n = sizeof(abi_ulong); +    abi_ulong envp; +    abi_ulong argv; + +    sp -= (envc + 1) * n; +    envp = sp; +    sp -= (argc + 1) * n; +    argv = sp; +    if (push_ptr) { +        /* FIXME - handle put_user() failures */ +        sp -= n; +        put_user_ual(envp, sp); +        sp -= n; +        put_user_ual(argv, sp); +    } +    sp -= n; +    /* FIXME - handle put_user() failures */ +    put_user_ual(argc, sp); + +    while (argc-- > 0) { +        /* FIXME - handle put_user() failures */ +        put_user_ual(stringp, argv); +        argv += n; +        stringp += target_strlen(stringp) + 1; +    } +    /* FIXME - handle put_user() failures */ +    put_user_ual(0, argv); +    while (envc-- > 0) { +        /* FIXME - handle put_user() failures */ +        put_user_ual(stringp, envp); +        envp += n; +        stringp += target_strlen(stringp) + 1; +    } +    /* FIXME - handle put_user() failures */ +    put_user_ual(0, envp); + +    return sp; +} + +int loader_exec(const char * filename, char ** argv, char ** envp, +             struct target_pt_regs * regs, struct image_info *infop) +{ +    struct linux_binprm bprm; +    int retval; +    int i; + +    bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int); +    for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */ +            bprm.page[i] = NULL; +    retval = open(filename, O_RDONLY); +    if (retval < 0) +        return retval; +    bprm.fd = retval; +    bprm.filename = (char *)filename; +    bprm.argc = count(argv); +    bprm.argv = argv; +    bprm.envc = count(envp); +    bprm.envp = envp; + +    retval = prepare_binprm(&bprm); + +    if(retval>=0) { +        if (bprm.buf[0] == 0x7f +                && bprm.buf[1] == 'E' +                && bprm.buf[2] == 'L' +                && bprm.buf[3] == 'F') { +            retval = load_elf_binary(&bprm,regs,infop); +        } else { +            fprintf(stderr, "Unknown binary format\n"); +            return -1; +        } +    } + +    if(retval>=0) { +        /* success.  Initialize important registers */ +        do_init_thread(regs, infop); +        return retval; +    } + +    /* Something went wrong, return the inode and free the argument pages*/ +    for (i=0 ; i<MAX_ARG_PAGES ; i++) { +        g_free(bprm.page[i]); +    } +    return(retval); +} diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c new file mode 100644 index 00000000..2bf57eb1 --- /dev/null +++ b/bsd-user/elfload.c @@ -0,0 +1,1578 @@ +/* This is the Linux kernel elf-loading code, ported into user space */ + +#include <stdio.h> +#include <sys/types.h> +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> +#include <sys/mman.h> +#include <stdlib.h> +#include <string.h> + +#include "qemu.h" +#include "disas/disas.h" + +#ifdef _ARCH_PPC64 +#undef ARCH_DLINFO +#undef ELF_PLATFORM +#undef ELF_HWCAP +#undef ELF_CLASS +#undef ELF_DATA +#undef ELF_ARCH +#endif + +/* from personality.h */ + +/* + * Flags for bug emulation. + * + * These occupy the top three bytes. + */ +enum { +        ADDR_NO_RANDOMIZE =     0x0040000,      /* disable randomization of VA space */ +        FDPIC_FUNCPTRS =        0x0080000,      /* userspace function ptrs point to descriptors +                                                 * (signal handling) +                                                 */ +        MMAP_PAGE_ZERO =        0x0100000, +        ADDR_COMPAT_LAYOUT =    0x0200000, +        READ_IMPLIES_EXEC =     0x0400000, +        ADDR_LIMIT_32BIT =      0x0800000, +        SHORT_INODE =           0x1000000, +        WHOLE_SECONDS =         0x2000000, +        STICKY_TIMEOUTS =       0x4000000, +        ADDR_LIMIT_3GB =        0x8000000, +}; + +/* + * Personality types. + * + * These go in the low byte.  Avoid using the top bit, it will + * conflict with error returns. + */ +enum { +        PER_LINUX =             0x0000, +        PER_LINUX_32BIT =       0x0000 | ADDR_LIMIT_32BIT, +        PER_LINUX_FDPIC =       0x0000 | FDPIC_FUNCPTRS, +        PER_SVR4 =              0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, +        PER_SVR3 =              0x0002 | STICKY_TIMEOUTS | SHORT_INODE, +        PER_SCOSVR3 =           0x0003 | STICKY_TIMEOUTS | +                                         WHOLE_SECONDS | SHORT_INODE, +        PER_OSR5 =              0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS, +        PER_WYSEV386 =          0x0004 | STICKY_TIMEOUTS | SHORT_INODE, +        PER_ISCR4 =             0x0005 | STICKY_TIMEOUTS, +        PER_BSD =               0x0006, +        PER_SUNOS =             0x0006 | STICKY_TIMEOUTS, +        PER_XENIX =             0x0007 | STICKY_TIMEOUTS | SHORT_INODE, +        PER_LINUX32 =           0x0008, +        PER_LINUX32_3GB =       0x0008 | ADDR_LIMIT_3GB, +        PER_IRIX32 =            0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */ +        PER_IRIXN32 =           0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */ +        PER_IRIX64 =            0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */ +        PER_RISCOS =            0x000c, +        PER_SOLARIS =           0x000d | STICKY_TIMEOUTS, +        PER_UW7 =               0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, +        PER_OSF4 =              0x000f,                  /* OSF/1 v4 */ +        PER_HPUX =              0x0010, +        PER_MASK =              0x00ff, +}; + +/* + * Return the base personality without flags. + */ +#define personality(pers)       (pers & PER_MASK) + +/* this flag is uneffective under linux too, should be deleted */ +#ifndef MAP_DENYWRITE +#define MAP_DENYWRITE 0 +#endif + +/* should probably go in elf.h */ +#ifndef ELIBBAD +#define ELIBBAD 80 +#endif + +#ifdef TARGET_I386 + +#define ELF_PLATFORM get_elf_platform() + +static const char *get_elf_platform(void) +{ +    static char elf_platform[] = "i386"; +    int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL); +    if (family > 6) +        family = 6; +    if (family >= 3) +        elf_platform[1] = '0' + family; +    return elf_platform; +} + +#define ELF_HWCAP get_elf_hwcap() + +static uint32_t get_elf_hwcap(void) +{ +    X86CPU *cpu = X86_CPU(thread_cpu); + +    return cpu->env.features[FEAT_1_EDX]; +} + +#ifdef TARGET_X86_64 +#define ELF_START_MMAP 0x2aaaaab000ULL +#define elf_check_arch(x) ( ((x) == ELF_ARCH) ) + +#define ELF_CLASS      ELFCLASS64 +#define ELF_DATA       ELFDATA2LSB +#define ELF_ARCH       EM_X86_64 + +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) +{ +    regs->rax = 0; +    regs->rsp = infop->start_stack; +    regs->rip = infop->entry; +    if (bsd_type == target_freebsd) { +        regs->rdi = infop->start_stack; +    } +} + +#else + +#define ELF_START_MMAP 0x80000000 + +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) ) + +/* + * These are used to set parameters in the core dumps. + */ +#define ELF_CLASS       ELFCLASS32 +#define ELF_DATA        ELFDATA2LSB +#define ELF_ARCH        EM_386 + +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) +{ +    regs->esp = infop->start_stack; +    regs->eip = infop->entry; + +    /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program +       starts %edx contains a pointer to a function which might be +       registered using `atexit'.  This provides a mean for the +       dynamic linker to call DT_FINI functions for shared libraries +       that have been loaded before the code runs. + +       A value of 0 tells we have no such handler.  */ +    regs->edx = 0; +} +#endif + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE       4096 + +#endif + +#ifdef TARGET_ARM + +#define ELF_START_MMAP 0x80000000 + +#define elf_check_arch(x) ( (x) == EM_ARM ) + +#define ELF_CLASS       ELFCLASS32 +#ifdef TARGET_WORDS_BIGENDIAN +#define ELF_DATA        ELFDATA2MSB +#else +#define ELF_DATA        ELFDATA2LSB +#endif +#define ELF_ARCH        EM_ARM + +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) +{ +    abi_long stack = infop->start_stack; +    memset(regs, 0, sizeof(*regs)); +    regs->ARM_cpsr = 0x10; +    if (infop->entry & 1) +      regs->ARM_cpsr |= CPSR_T; +    regs->ARM_pc = infop->entry & 0xfffffffe; +    regs->ARM_sp = infop->start_stack; +    /* FIXME - what to for failure of get_user()? */ +    get_user_ual(regs->ARM_r2, stack + 8); /* envp */ +    get_user_ual(regs->ARM_r1, stack + 4); /* envp */ +    /* XXX: it seems that r0 is zeroed after ! */ +    regs->ARM_r0 = 0; +    /* For uClinux PIC binaries.  */ +    /* XXX: Linux does this only on ARM with no MMU (do we care ?) */ +    regs->ARM_r10 = infop->start_data; +} + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE       4096 + +enum +{ +  ARM_HWCAP_ARM_SWP       = 1 << 0, +  ARM_HWCAP_ARM_HALF      = 1 << 1, +  ARM_HWCAP_ARM_THUMB     = 1 << 2, +  ARM_HWCAP_ARM_26BIT     = 1 << 3, +  ARM_HWCAP_ARM_FAST_MULT = 1 << 4, +  ARM_HWCAP_ARM_FPA       = 1 << 5, +  ARM_HWCAP_ARM_VFP       = 1 << 6, +  ARM_HWCAP_ARM_EDSP      = 1 << 7, +}; + +#define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF              \ +                    | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT     \ +                    | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP) + +#endif + +#ifdef TARGET_SPARC +#ifdef TARGET_SPARC64 + +#define ELF_START_MMAP 0x80000000 + +#ifndef TARGET_ABI32 +#define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS ) +#else +#define elf_check_arch(x) ( (x) == EM_SPARC32PLUS || (x) == EM_SPARC ) +#endif + +#define ELF_CLASS   ELFCLASS64 +#define ELF_DATA    ELFDATA2MSB +#define ELF_ARCH    EM_SPARCV9 + +#define STACK_BIAS              2047 + +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) +{ +#ifndef TARGET_ABI32 +    regs->tstate = 0; +#endif +    regs->pc = infop->entry; +    regs->npc = regs->pc + 4; +    regs->y = 0; +#ifdef TARGET_ABI32 +    regs->u_regs[14] = infop->start_stack - 16 * 4; +#else +    if (personality(infop->personality) == PER_LINUX32) +        regs->u_regs[14] = infop->start_stack - 16 * 4; +    else { +        regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS; +        if (bsd_type == target_freebsd) { +            regs->u_regs[8] = infop->start_stack; +            regs->u_regs[11] = infop->start_stack; +        } +    } +#endif +} + +#else +#define ELF_START_MMAP 0x80000000 + +#define elf_check_arch(x) ( (x) == EM_SPARC ) + +#define ELF_CLASS   ELFCLASS32 +#define ELF_DATA    ELFDATA2MSB +#define ELF_ARCH    EM_SPARC + +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) +{ +    regs->psr = 0; +    regs->pc = infop->entry; +    regs->npc = regs->pc + 4; +    regs->y = 0; +    regs->u_regs[14] = infop->start_stack - 16 * 4; +} + +#endif +#endif + +#ifdef TARGET_PPC + +#define ELF_START_MMAP 0x80000000 + +#if defined(TARGET_PPC64) && !defined(TARGET_ABI32) + +#define elf_check_arch(x) ( (x) == EM_PPC64 ) + +#define ELF_CLASS       ELFCLASS64 + +#else + +#define elf_check_arch(x) ( (x) == EM_PPC ) + +#define ELF_CLASS       ELFCLASS32 + +#endif + +#ifdef TARGET_WORDS_BIGENDIAN +#define ELF_DATA        ELFDATA2MSB +#else +#define ELF_DATA        ELFDATA2LSB +#endif +#define ELF_ARCH        EM_PPC + +/* + * We need to put in some extra aux table entries to tell glibc what + * the cache block size is, so it can use the dcbz instruction safely. + */ +#define AT_DCACHEBSIZE          19 +#define AT_ICACHEBSIZE          20 +#define AT_UCACHEBSIZE          21 +/* A special ignored type value for PPC, for glibc compatibility.  */ +#define AT_IGNOREPPC            22 +/* + * The requirements here are: + * - keep the final alignment of sp (sp & 0xf) + * - make sure the 32-bit value at the first 16 byte aligned position of + *   AUXV is greater than 16 for glibc compatibility. + *   AT_IGNOREPPC is used for that. + * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC, + *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined. + */ +#define DLINFO_ARCH_ITEMS       5 +#define ARCH_DLINFO                                                     \ +do {                                                                    \ +        NEW_AUX_ENT(AT_DCACHEBSIZE, 0x20);                              \ +        NEW_AUX_ENT(AT_ICACHEBSIZE, 0x20);                              \ +        NEW_AUX_ENT(AT_UCACHEBSIZE, 0);                                 \ +        /*                                                              \ +         * Now handle glibc compatibility.                              \ +         */                                                             \ +        NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);                        \ +        NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);                        \ + } while (0) + +static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop) +{ +    abi_ulong pos = infop->start_stack; +    abi_ulong tmp; +#if defined(TARGET_PPC64) && !defined(TARGET_ABI32) +    abi_ulong entry, toc; +#endif + +    _regs->gpr[1] = infop->start_stack; +#if defined(TARGET_PPC64) && !defined(TARGET_ABI32) +    get_user_u64(entry, infop->entry); +    entry += infop->load_addr; +    get_user_u64(toc, infop->entry + 8); +    toc += infop->load_addr; +    _regs->gpr[2] = toc; +    infop->entry = entry; +#endif +    _regs->nip = infop->entry; +    /* Note that isn't exactly what regular kernel does +     * but this is what the ABI wants and is needed to allow +     * execution of PPC BSD programs. +     */ +    /* FIXME - what to for failure of get_user()? */ +    get_user_ual(_regs->gpr[3], pos); +    pos += sizeof(abi_ulong); +    _regs->gpr[4] = pos; +    for (tmp = 1; tmp != 0; pos += sizeof(abi_ulong)) { +        get_user_ual(tmp, pos); +    } +    _regs->gpr[5] = pos; +} + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE       4096 + +#endif + +#ifdef TARGET_MIPS + +#define ELF_START_MMAP 0x80000000 + +#define elf_check_arch(x) ( (x) == EM_MIPS ) + +#ifdef TARGET_MIPS64 +#define ELF_CLASS   ELFCLASS64 +#else +#define ELF_CLASS   ELFCLASS32 +#endif +#ifdef TARGET_WORDS_BIGENDIAN +#define ELF_DATA        ELFDATA2MSB +#else +#define ELF_DATA        ELFDATA2LSB +#endif +#define ELF_ARCH    EM_MIPS + +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) +{ +    regs->cp0_status = 2 << CP0St_KSU; +    regs->cp0_epc = infop->entry; +    regs->regs[29] = infop->start_stack; +} + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE        4096 + +#endif /* TARGET_MIPS */ + +#ifdef TARGET_SH4 + +#define ELF_START_MMAP 0x80000000 + +#define elf_check_arch(x) ( (x) == EM_SH ) + +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA  ELFDATA2LSB +#define ELF_ARCH  EM_SH + +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) +{ +  /* Check other registers XXXXX */ +  regs->pc = infop->entry; +  regs->regs[15] = infop->start_stack; +} + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE        4096 + +#endif + +#ifdef TARGET_CRIS + +#define ELF_START_MMAP 0x80000000 + +#define elf_check_arch(x) ( (x) == EM_CRIS ) + +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA  ELFDATA2LSB +#define ELF_ARCH  EM_CRIS + +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) +{ +  regs->erp = infop->entry; +} + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE        8192 + +#endif + +#ifdef TARGET_M68K + +#define ELF_START_MMAP 0x80000000 + +#define elf_check_arch(x) ( (x) == EM_68K ) + +#define ELF_CLASS       ELFCLASS32 +#define ELF_DATA        ELFDATA2MSB +#define ELF_ARCH        EM_68K + +/* ??? Does this need to do anything? +#define ELF_PLAT_INIT(_r) */ + +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) +{ +    regs->usp = infop->start_stack; +    regs->sr = 0; +    regs->pc = infop->entry; +} + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE       8192 + +#endif + +#ifdef TARGET_ALPHA + +#define ELF_START_MMAP (0x30000000000ULL) + +#define elf_check_arch(x) ( (x) == ELF_ARCH ) + +#define ELF_CLASS      ELFCLASS64 +#define ELF_DATA       ELFDATA2MSB +#define ELF_ARCH       EM_ALPHA + +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) +{ +    regs->pc = infop->entry; +    regs->ps = 8; +    regs->usp = infop->start_stack; +    regs->unique = infop->start_data; /* ? */ +    printf("Set unique value to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n", +           regs->unique, infop->start_data); +} + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE        8192 + +#endif /* TARGET_ALPHA */ + +#ifndef ELF_PLATFORM +#define ELF_PLATFORM (NULL) +#endif + +#ifndef ELF_HWCAP +#define ELF_HWCAP 0 +#endif + +#ifdef TARGET_ABI32 +#undef ELF_CLASS +#define ELF_CLASS ELFCLASS32 +#undef bswaptls +#define bswaptls(ptr) bswap32s(ptr) +#endif + +#include "elf.h" + +struct exec +{ +  unsigned int a_info;   /* Use macros N_MAGIC, etc for access */ +  unsigned int a_text;   /* length of text, in bytes */ +  unsigned int a_data;   /* length of data, in bytes */ +  unsigned int a_bss;    /* length of uninitialized data area, in bytes */ +  unsigned int a_syms;   /* length of symbol table data in file, in bytes */ +  unsigned int a_entry;  /* start address */ +  unsigned int a_trsize; /* length of relocation info for text, in bytes */ +  unsigned int a_drsize; /* length of relocation info for data, in bytes */ +}; + + +#define N_MAGIC(exec) ((exec).a_info & 0xffff) +#define OMAGIC 0407 +#define NMAGIC 0410 +#define ZMAGIC 0413 +#define QMAGIC 0314 + +/* max code+data+bss space allocated to elf interpreter */ +#define INTERP_MAP_SIZE (32 * 1024 * 1024) + +/* max code+data+bss+brk space allocated to ET_DYN executables */ +#define ET_DYN_MAP_SIZE (128 * 1024 * 1024) + +/* Necessary parameters */ +#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE +#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1)) +#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1)) + +#define INTERPRETER_NONE 0 +#define INTERPRETER_AOUT 1 +#define INTERPRETER_ELF 2 + +#define DLINFO_ITEMS 12 + +static inline void memcpy_fromfs(void * to, const void * from, unsigned long n) +{ +        memcpy(to, from, n); +} + +static int load_aout_interp(void * exptr, int interp_fd); + +#ifdef BSWAP_NEEDED +static void bswap_ehdr(struct elfhdr *ehdr) +{ +    bswap16s(&ehdr->e_type);                    /* Object file type */ +    bswap16s(&ehdr->e_machine);         /* Architecture */ +    bswap32s(&ehdr->e_version);         /* Object file version */ +    bswaptls(&ehdr->e_entry);           /* Entry point virtual address */ +    bswaptls(&ehdr->e_phoff);           /* Program header table file offset */ +    bswaptls(&ehdr->e_shoff);           /* Section header table file offset */ +    bswap32s(&ehdr->e_flags);           /* Processor-specific flags */ +    bswap16s(&ehdr->e_ehsize);          /* ELF header size in bytes */ +    bswap16s(&ehdr->e_phentsize);               /* Program header table entry size */ +    bswap16s(&ehdr->e_phnum);           /* Program header table entry count */ +    bswap16s(&ehdr->e_shentsize);               /* Section header table entry size */ +    bswap16s(&ehdr->e_shnum);           /* Section header table entry count */ +    bswap16s(&ehdr->e_shstrndx);                /* Section header string table index */ +} + +static void bswap_phdr(struct elf_phdr *phdr) +{ +    bswap32s(&phdr->p_type);                    /* Segment type */ +    bswaptls(&phdr->p_offset);          /* Segment file offset */ +    bswaptls(&phdr->p_vaddr);           /* Segment virtual address */ +    bswaptls(&phdr->p_paddr);           /* Segment physical address */ +    bswaptls(&phdr->p_filesz);          /* Segment size in file */ +    bswaptls(&phdr->p_memsz);           /* Segment size in memory */ +    bswap32s(&phdr->p_flags);           /* Segment flags */ +    bswaptls(&phdr->p_align);           /* Segment alignment */ +} + +static void bswap_shdr(struct elf_shdr *shdr) +{ +    bswap32s(&shdr->sh_name); +    bswap32s(&shdr->sh_type); +    bswaptls(&shdr->sh_flags); +    bswaptls(&shdr->sh_addr); +    bswaptls(&shdr->sh_offset); +    bswaptls(&shdr->sh_size); +    bswap32s(&shdr->sh_link); +    bswap32s(&shdr->sh_info); +    bswaptls(&shdr->sh_addralign); +    bswaptls(&shdr->sh_entsize); +} + +static void bswap_sym(struct elf_sym *sym) +{ +    bswap32s(&sym->st_name); +    bswaptls(&sym->st_value); +    bswaptls(&sym->st_size); +    bswap16s(&sym->st_shndx); +} +#endif + +/* + * 'copy_elf_strings()' copies argument/envelope strings from user + * memory to free pages in kernel mem. These are in a format ready + * to be put directly into the top of new user memory. + * + */ +static abi_ulong copy_elf_strings(int argc,char ** argv, void **page, +                                  abi_ulong p) +{ +    char *tmp, *tmp1, *pag = NULL; +    int len, offset = 0; + +    if (!p) { +        return 0;       /* bullet-proofing */ +    } +    while (argc-- > 0) { +        tmp = argv[argc]; +        if (!tmp) { +            fprintf(stderr, "VFS: argc is wrong"); +            exit(-1); +        } +        tmp1 = tmp; +        while (*tmp++); +        len = tmp - tmp1; +        if (p < len) {  /* this shouldn't happen - 128kB */ +                return 0; +        } +        while (len) { +            --p; --tmp; --len; +            if (--offset < 0) { +                offset = p % TARGET_PAGE_SIZE; +                pag = (char *)page[p/TARGET_PAGE_SIZE]; +                if (!pag) { +                    pag = g_try_malloc0(TARGET_PAGE_SIZE); +                    page[p/TARGET_PAGE_SIZE] = pag; +                    if (!pag) +                        return 0; +                } +            } +            if (len == 0 || offset == 0) { +                *(pag + offset) = *tmp; +            } +            else { +              int bytes_to_copy = (len > offset) ? offset : len; +              tmp -= bytes_to_copy; +              p -= bytes_to_copy; +              offset -= bytes_to_copy; +              len -= bytes_to_copy; +              memcpy_fromfs(pag + offset, tmp, bytes_to_copy + 1); +            } +        } +    } +    return p; +} + +static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm, +                                 struct image_info *info) +{ +    abi_ulong stack_base, size, error; +    int i; + +    /* Create enough stack to hold everything.  If we don't use +     * it for args, we'll use it for something else... +     */ +    size = x86_stack_size; +    if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) +        size = MAX_ARG_PAGES*TARGET_PAGE_SIZE; +    error = target_mmap(0, +                        size + qemu_host_page_size, +                        PROT_READ | PROT_WRITE, +                        MAP_PRIVATE | MAP_ANON, +                        -1, 0); +    if (error == -1) { +        perror("stk mmap"); +        exit(-1); +    } +    /* we reserve one extra page at the top of the stack as guard */ +    target_mprotect(error + size, qemu_host_page_size, PROT_NONE); + +    stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE; +    p += stack_base; + +    for (i = 0 ; i < MAX_ARG_PAGES ; i++) { +        if (bprm->page[i]) { +            info->rss++; +            /* FIXME - check return value of memcpy_to_target() for failure */ +            memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE); +            g_free(bprm->page[i]); +        } +        stack_base += TARGET_PAGE_SIZE; +    } +    return p; +} + +static void set_brk(abi_ulong start, abi_ulong end) +{ +        /* page-align the start and end addresses... */ +        start = HOST_PAGE_ALIGN(start); +        end = HOST_PAGE_ALIGN(end); +        if (end <= start) +                return; +        if(target_mmap(start, end - start, +                       PROT_READ | PROT_WRITE | PROT_EXEC, +                       MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0) == -1) { +            perror("cannot mmap brk"); +            exit(-1); +        } +} + + +/* We need to explicitly zero any fractional pages after the data +   section (i.e. bss).  This would contain the junk from the file that +   should not be in memory. */ +static void padzero(abi_ulong elf_bss, abi_ulong last_bss) +{ +        abi_ulong nbyte; + +        if (elf_bss >= last_bss) +                return; + +        /* XXX: this is really a hack : if the real host page size is +           smaller than the target page size, some pages after the end +           of the file may not be mapped. A better fix would be to +           patch target_mmap(), but it is more complicated as the file +           size must be known */ +        if (qemu_real_host_page_size < qemu_host_page_size) { +            abi_ulong end_addr, end_addr1; +            end_addr1 = (elf_bss + qemu_real_host_page_size - 1) & +                ~(qemu_real_host_page_size - 1); +            end_addr = HOST_PAGE_ALIGN(elf_bss); +            if (end_addr1 < end_addr) { +                mmap((void *)g2h(end_addr1), end_addr - end_addr1, +                     PROT_READ|PROT_WRITE|PROT_EXEC, +                     MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0); +            } +        } + +        nbyte = elf_bss & (qemu_host_page_size-1); +        if (nbyte) { +            nbyte = qemu_host_page_size - nbyte; +            do { +                /* FIXME - what to do if put_user() fails? */ +                put_user_u8(0, elf_bss); +                elf_bss++; +            } while (--nbyte); +        } +} + + +static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, +                                   struct elfhdr * exec, +                                   abi_ulong load_addr, +                                   abi_ulong load_bias, +                                   abi_ulong interp_load_addr, int ibcs, +                                   struct image_info *info) +{ +        abi_ulong sp; +        int size; +        abi_ulong u_platform; +        const char *k_platform; +        const int n = sizeof(elf_addr_t); + +        sp = p; +        u_platform = 0; +        k_platform = ELF_PLATFORM; +        if (k_platform) { +            size_t len = strlen(k_platform) + 1; +            sp -= (len + n - 1) & ~(n - 1); +            u_platform = sp; +            /* FIXME - check return value of memcpy_to_target() for failure */ +            memcpy_to_target(sp, k_platform, len); +        } +        /* +         * Force 16 byte _final_ alignment here for generality. +         */ +        sp = sp &~ (abi_ulong)15; +        size = (DLINFO_ITEMS + 1) * 2; +        if (k_platform) +          size += 2; +#ifdef DLINFO_ARCH_ITEMS +        size += DLINFO_ARCH_ITEMS * 2; +#endif +        size += envc + argc + 2; +        size += (!ibcs ? 3 : 1);        /* argc itself */ +        size *= n; +        if (size & 15) +            sp -= 16 - (size & 15); + +        /* This is correct because Linux defines +         * elf_addr_t as Elf32_Off / Elf64_Off +         */ +#define NEW_AUX_ENT(id, val) do {               \ +            sp -= n; put_user_ual(val, sp);     \ +            sp -= n; put_user_ual(id, sp);      \ +          } while(0) + +        NEW_AUX_ENT (AT_NULL, 0); + +        /* There must be exactly DLINFO_ITEMS entries here.  */ +        NEW_AUX_ENT(AT_PHDR, (abi_ulong)(load_addr + exec->e_phoff)); +        NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr))); +        NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum)); +        NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(TARGET_PAGE_SIZE)); +        NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_load_addr)); +        NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0); +        NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry); +        NEW_AUX_ENT(AT_UID, (abi_ulong) getuid()); +        NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid()); +        NEW_AUX_ENT(AT_GID, (abi_ulong) getgid()); +        NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid()); +        NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP); +        NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK)); +        if (k_platform) +            NEW_AUX_ENT(AT_PLATFORM, u_platform); +#ifdef ARCH_DLINFO +        /* +         * ARCH_DLINFO must come last so platform specific code can enforce +         * special alignment requirements on the AUXV if necessary (eg. PPC). +         */ +        ARCH_DLINFO; +#endif +#undef NEW_AUX_ENT + +        sp = loader_build_argptr(envc, argc, sp, p, !ibcs); +        return sp; +} + + +static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex, +                                 int interpreter_fd, +                                 abi_ulong *interp_load_addr) +{ +        struct elf_phdr *elf_phdata  =  NULL; +        struct elf_phdr *eppnt; +        abi_ulong load_addr = 0; +        int load_addr_set = 0; +        int retval; +        abi_ulong last_bss, elf_bss; +        abi_ulong error; +        int i; + +        elf_bss = 0; +        last_bss = 0; +        error = 0; + +#ifdef BSWAP_NEEDED +        bswap_ehdr(interp_elf_ex); +#endif +        /* First of all, some simple consistency checks */ +        if ((interp_elf_ex->e_type != ET_EXEC && +             interp_elf_ex->e_type != ET_DYN) || +           !elf_check_arch(interp_elf_ex->e_machine)) { +                return ~((abi_ulong)0UL); +        } + + +        /* Now read in all of the header information */ + +        if (sizeof(struct elf_phdr) * interp_elf_ex->e_phnum > TARGET_PAGE_SIZE) +            return ~(abi_ulong)0UL; + +        elf_phdata =  (struct elf_phdr *) +                malloc(sizeof(struct elf_phdr) * interp_elf_ex->e_phnum); + +        if (!elf_phdata) +          return ~((abi_ulong)0UL); + +        /* +         * If the size of this structure has changed, then punt, since +         * we will be doing the wrong thing. +         */ +        if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) { +            free(elf_phdata); +            return ~((abi_ulong)0UL); +        } + +        retval = lseek(interpreter_fd, interp_elf_ex->e_phoff, SEEK_SET); +        if(retval >= 0) { +            retval = read(interpreter_fd, +                           (char *) elf_phdata, +                           sizeof(struct elf_phdr) * interp_elf_ex->e_phnum); +        } +        if (retval < 0) { +                perror("load_elf_interp"); +                exit(-1); +                free (elf_phdata); +                return retval; +        } +#ifdef BSWAP_NEEDED +        eppnt = elf_phdata; +        for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) { +            bswap_phdr(eppnt); +        } +#endif + +        if (interp_elf_ex->e_type == ET_DYN) { +            /* in order to avoid hardcoding the interpreter load +               address in qemu, we allocate a big enough memory zone */ +            error = target_mmap(0, INTERP_MAP_SIZE, +                                PROT_NONE, MAP_PRIVATE | MAP_ANON, +                                -1, 0); +            if (error == -1) { +                perror("mmap"); +                exit(-1); +            } +            load_addr = error; +            load_addr_set = 1; +        } + +        eppnt = elf_phdata; +        for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) +          if (eppnt->p_type == PT_LOAD) { +            int elf_type = MAP_PRIVATE | MAP_DENYWRITE; +            int elf_prot = 0; +            abi_ulong vaddr = 0; +            abi_ulong k; + +            if (eppnt->p_flags & PF_R) elf_prot =  PROT_READ; +            if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; +            if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC; +            if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) { +                elf_type |= MAP_FIXED; +                vaddr = eppnt->p_vaddr; +            } +            error = target_mmap(load_addr+TARGET_ELF_PAGESTART(vaddr), +                 eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr), +                 elf_prot, +                 elf_type, +                 interpreter_fd, +                 eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr)); + +            if (error == -1) { +              /* Real error */ +              close(interpreter_fd); +              free(elf_phdata); +              return ~((abi_ulong)0UL); +            } + +            if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) { +              load_addr = error; +              load_addr_set = 1; +            } + +            /* +             * Find the end of the file  mapping for this phdr, and keep +             * track of the largest address we see for this. +             */ +            k = load_addr + eppnt->p_vaddr + eppnt->p_filesz; +            if (k > elf_bss) elf_bss = k; + +            /* +             * Do the same thing for the memory mapping - between +             * elf_bss and last_bss is the bss section. +             */ +            k = load_addr + eppnt->p_memsz + eppnt->p_vaddr; +            if (k > last_bss) last_bss = k; +          } + +        /* Now use mmap to map the library into memory. */ + +        close(interpreter_fd); + +        /* +         * Now fill out the bss section.  First pad the last page up +         * to the page boundary, and then perform a mmap to make sure +         * that there are zeromapped pages up to and including the last +         * bss page. +         */ +        padzero(elf_bss, last_bss); +        elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); /* What we have mapped so far */ + +        /* Map the last of the bss segment */ +        if (last_bss > elf_bss) { +            target_mmap(elf_bss, last_bss-elf_bss, +                        PROT_READ|PROT_WRITE|PROT_EXEC, +                        MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0); +        } +        free(elf_phdata); + +        *interp_load_addr = load_addr; +        return ((abi_ulong) interp_elf_ex->e_entry) + load_addr; +} + +static int symfind(const void *s0, const void *s1) +{ +    target_ulong addr = *(target_ulong *)s0; +    struct elf_sym *sym = (struct elf_sym *)s1; +    int result = 0; +    if (addr < sym->st_value) { +        result = -1; +    } else if (addr >= sym->st_value + sym->st_size) { +        result = 1; +    } +    return result; +} + +static const char *lookup_symbolxx(struct syminfo *s, target_ulong orig_addr) +{ +#if ELF_CLASS == ELFCLASS32 +    struct elf_sym *syms = s->disas_symtab.elf32; +#else +    struct elf_sym *syms = s->disas_symtab.elf64; +#endif + +    // binary search +    struct elf_sym *sym; + +    sym = bsearch(&orig_addr, syms, s->disas_num_syms, sizeof(*syms), symfind); +    if (sym != NULL) { +        return s->disas_strtab + sym->st_name; +    } + +    return ""; +} + +/* FIXME: This should use elf_ops.h  */ +static int symcmp(const void *s0, const void *s1) +{ +    struct elf_sym *sym0 = (struct elf_sym *)s0; +    struct elf_sym *sym1 = (struct elf_sym *)s1; +    return (sym0->st_value < sym1->st_value) +        ? -1 +        : ((sym0->st_value > sym1->st_value) ? 1 : 0); +} + +/* Best attempt to load symbols from this ELF object. */ +static void load_symbols(struct elfhdr *hdr, int fd) +{ +    unsigned int i, nsyms; +    struct elf_shdr sechdr, symtab, strtab; +    char *strings; +    struct syminfo *s; +    struct elf_sym *syms, *new_syms; + +    lseek(fd, hdr->e_shoff, SEEK_SET); +    for (i = 0; i < hdr->e_shnum; i++) { +        if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr)) +            return; +#ifdef BSWAP_NEEDED +        bswap_shdr(&sechdr); +#endif +        if (sechdr.sh_type == SHT_SYMTAB) { +            symtab = sechdr; +            lseek(fd, hdr->e_shoff +                  + sizeof(sechdr) * sechdr.sh_link, SEEK_SET); +            if (read(fd, &strtab, sizeof(strtab)) +                != sizeof(strtab)) +                return; +#ifdef BSWAP_NEEDED +            bswap_shdr(&strtab); +#endif +            goto found; +        } +    } +    return; /* Shouldn't happen... */ + + found: +    /* Now know where the strtab and symtab are.  Snarf them. */ +    s = malloc(sizeof(*s)); +    syms = malloc(symtab.sh_size); +    if (!syms) { +        free(s); +        return; +    } +    s->disas_strtab = strings = malloc(strtab.sh_size); +    if (!s->disas_strtab) { +        free(s); +        free(syms); +        return; +    } + +    lseek(fd, symtab.sh_offset, SEEK_SET); +    if (read(fd, syms, symtab.sh_size) != symtab.sh_size) { +        free(s); +        free(syms); +        free(strings); +        return; +    } + +    nsyms = symtab.sh_size / sizeof(struct elf_sym); + +    i = 0; +    while (i < nsyms) { +#ifdef BSWAP_NEEDED +        bswap_sym(syms + i); +#endif +        // Throw away entries which we do not need. +        if (syms[i].st_shndx == SHN_UNDEF || +                syms[i].st_shndx >= SHN_LORESERVE || +                ELF_ST_TYPE(syms[i].st_info) != STT_FUNC) { +            nsyms--; +            if (i < nsyms) { +                syms[i] = syms[nsyms]; +            } +            continue; +        } +#if defined(TARGET_ARM) || defined (TARGET_MIPS) +        /* The bottom address bit marks a Thumb or MIPS16 symbol.  */ +        syms[i].st_value &= ~(target_ulong)1; +#endif +        i++; +    } + +     /* Attempt to free the storage associated with the local symbols +        that we threw away.  Whether or not this has any effect on the +        memory allocation depends on the malloc implementation and how +        many symbols we managed to discard. */ +    new_syms = realloc(syms, nsyms * sizeof(*syms)); +    if (new_syms == NULL) { +        free(s); +        free(syms); +        free(strings); +        return; +    } +    syms = new_syms; + +    qsort(syms, nsyms, sizeof(*syms), symcmp); + +    lseek(fd, strtab.sh_offset, SEEK_SET); +    if (read(fd, strings, strtab.sh_size) != strtab.sh_size) { +        free(s); +        free(syms); +        free(strings); +        return; +    } +    s->disas_num_syms = nsyms; +#if ELF_CLASS == ELFCLASS32 +    s->disas_symtab.elf32 = syms; +    s->lookup_symbol = (lookup_symbol_t)lookup_symbolxx; +#else +    s->disas_symtab.elf64 = syms; +    s->lookup_symbol = (lookup_symbol_t)lookup_symbolxx; +#endif +    s->next = syminfos; +    syminfos = s; +} + +int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, +                    struct image_info * info) +{ +    struct elfhdr elf_ex; +    struct elfhdr interp_elf_ex; +    struct exec interp_ex; +    int interpreter_fd = -1; /* avoid warning */ +    abi_ulong load_addr, load_bias; +    int load_addr_set = 0; +    unsigned int interpreter_type = INTERPRETER_NONE; +    unsigned char ibcs2_interpreter; +    int i; +    abi_ulong mapped_addr; +    struct elf_phdr * elf_ppnt; +    struct elf_phdr *elf_phdata; +    abi_ulong elf_bss, k, elf_brk; +    int retval; +    char * elf_interpreter; +    abi_ulong elf_entry, interp_load_addr = 0; +    int status; +    abi_ulong start_code, end_code, start_data, end_data; +    abi_ulong reloc_func_desc = 0; +    abi_ulong elf_stack; +    char passed_fileno[6]; + +    ibcs2_interpreter = 0; +    status = 0; +    load_addr = 0; +    load_bias = 0; +    elf_ex = *((struct elfhdr *) bprm->buf);          /* exec-header */ +#ifdef BSWAP_NEEDED +    bswap_ehdr(&elf_ex); +#endif + +    /* First of all, some simple consistency checks */ +    if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) || +                                (! elf_check_arch(elf_ex.e_machine))) { +            return -ENOEXEC; +    } + +    bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p); +    bprm->p = copy_elf_strings(bprm->envc,bprm->envp,bprm->page,bprm->p); +    bprm->p = copy_elf_strings(bprm->argc,bprm->argv,bprm->page,bprm->p); +    if (!bprm->p) { +        retval = -E2BIG; +    } + +    /* Now read in all of the header information */ +    elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum); +    if (elf_phdata == NULL) { +        return -ENOMEM; +    } + +    retval = lseek(bprm->fd, elf_ex.e_phoff, SEEK_SET); +    if(retval > 0) { +        retval = read(bprm->fd, (char *) elf_phdata, +                                elf_ex.e_phentsize * elf_ex.e_phnum); +    } + +    if (retval < 0) { +        perror("load_elf_binary"); +        exit(-1); +        free (elf_phdata); +        return -errno; +    } + +#ifdef BSWAP_NEEDED +    elf_ppnt = elf_phdata; +    for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) { +        bswap_phdr(elf_ppnt); +    } +#endif +    elf_ppnt = elf_phdata; + +    elf_bss = 0; +    elf_brk = 0; + + +    elf_stack = ~((abi_ulong)0UL); +    elf_interpreter = NULL; +    start_code = ~((abi_ulong)0UL); +    end_code = 0; +    start_data = 0; +    end_data = 0; +    interp_ex.a_info = 0; + +    for(i=0;i < elf_ex.e_phnum; i++) { +        if (elf_ppnt->p_type == PT_INTERP) { +            if ( elf_interpreter != NULL ) +            { +                free (elf_phdata); +                free(elf_interpreter); +                close(bprm->fd); +                return -EINVAL; +            } + +            /* This is the program interpreter used for +             * shared libraries - for now assume that this +             * is an a.out format binary +             */ + +            elf_interpreter = (char *)malloc(elf_ppnt->p_filesz); + +            if (elf_interpreter == NULL) { +                free (elf_phdata); +                close(bprm->fd); +                return -ENOMEM; +            } + +            retval = lseek(bprm->fd, elf_ppnt->p_offset, SEEK_SET); +            if(retval >= 0) { +                retval = read(bprm->fd, elf_interpreter, elf_ppnt->p_filesz); +            } +            if(retval < 0) { +                perror("load_elf_binary2"); +                exit(-1); +            } + +            /* If the program interpreter is one of these two, +               then assume an iBCS2 image. Otherwise assume +               a native linux image. */ + +            /* JRP - Need to add X86 lib dir stuff here... */ + +            if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 || +                strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) { +              ibcs2_interpreter = 1; +            } + +#if 0 +            printf("Using ELF interpreter %s\n", path(elf_interpreter)); +#endif +            if (retval >= 0) { +                retval = open(path(elf_interpreter), O_RDONLY); +                if(retval >= 0) { +                    interpreter_fd = retval; +                } +                else { +                    perror(elf_interpreter); +                    exit(-1); +                    /* retval = -errno; */ +                } +            } + +            if (retval >= 0) { +                retval = lseek(interpreter_fd, 0, SEEK_SET); +                if(retval >= 0) { +                    retval = read(interpreter_fd,bprm->buf,128); +                } +            } +            if (retval >= 0) { +                interp_ex = *((struct exec *) bprm->buf); /* aout exec-header */ +                interp_elf_ex = *((struct elfhdr *) bprm->buf); /* elf exec-header */ +            } +            if (retval < 0) { +                perror("load_elf_binary3"); +                exit(-1); +                free (elf_phdata); +                free(elf_interpreter); +                close(bprm->fd); +                return retval; +            } +        } +        elf_ppnt++; +    } + +    /* Some simple consistency checks for the interpreter */ +    if (elf_interpreter){ +        interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT; + +        /* Now figure out which format our binary is */ +        if ((N_MAGIC(interp_ex) != OMAGIC) && (N_MAGIC(interp_ex) != ZMAGIC) && +                (N_MAGIC(interp_ex) != QMAGIC)) { +          interpreter_type = INTERPRETER_ELF; +        } + +        if (interp_elf_ex.e_ident[0] != 0x7f || +                strncmp((char *)&interp_elf_ex.e_ident[1], "ELF",3) != 0) { +            interpreter_type &= ~INTERPRETER_ELF; +        } + +        if (!interpreter_type) { +            free(elf_interpreter); +            free(elf_phdata); +            close(bprm->fd); +            return -ELIBBAD; +        } +    } + +    /* OK, we are done with that, now set up the arg stuff, +       and then start this sucker up */ + +    { +        char * passed_p; + +        if (interpreter_type == INTERPRETER_AOUT) { +            snprintf(passed_fileno, sizeof(passed_fileno), "%d", bprm->fd); +            passed_p = passed_fileno; + +            if (elf_interpreter) { +                bprm->p = copy_elf_strings(1,&passed_p,bprm->page,bprm->p); +                bprm->argc++; +            } +        } +        if (!bprm->p) { +            if (elf_interpreter) { +                free(elf_interpreter); +            } +            free (elf_phdata); +            close(bprm->fd); +            return -E2BIG; +        } +    } + +    /* OK, This is the point of no return */ +    info->end_data = 0; +    info->end_code = 0; +    info->start_mmap = (abi_ulong)ELF_START_MMAP; +    info->mmap = 0; +    elf_entry = (abi_ulong) elf_ex.e_entry; + +#if defined(CONFIG_USE_GUEST_BASE) +    /* +     * In case where user has not explicitly set the guest_base, we +     * probe here that should we set it automatically. +     */ +    if (!have_guest_base) { +        /* +         * Go through ELF program header table and find out whether +	 * any of the segments drop below our current mmap_min_addr and +         * in that case set guest_base to corresponding address. +         */ +        for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; +            i++, elf_ppnt++) { +            if (elf_ppnt->p_type != PT_LOAD) +                continue; +            if (HOST_PAGE_ALIGN(elf_ppnt->p_vaddr) < mmap_min_addr) { +                guest_base = HOST_PAGE_ALIGN(mmap_min_addr); +                break; +            } +        } +    } +#endif /* CONFIG_USE_GUEST_BASE */ + +    /* Do this so that we can load the interpreter, if need be.  We will +       change some of these later */ +    info->rss = 0; +    bprm->p = setup_arg_pages(bprm->p, bprm, info); +    info->start_stack = bprm->p; + +    /* Now we do a little grungy work by mmaping the ELF image into +     * the correct location in memory.  At this point, we assume that +     * the image should be loaded at fixed address, not at a variable +     * address. +     */ + +    for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) { +        int elf_prot = 0; +        int elf_flags = 0; +        abi_ulong error; + +        if (elf_ppnt->p_type != PT_LOAD) +            continue; + +        if (elf_ppnt->p_flags & PF_R) elf_prot |= PROT_READ; +        if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; +        if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC; +        elf_flags = MAP_PRIVATE | MAP_DENYWRITE; +        if (elf_ex.e_type == ET_EXEC || load_addr_set) { +            elf_flags |= MAP_FIXED; +        } else if (elf_ex.e_type == ET_DYN) { +            /* Try and get dynamic programs out of the way of the default mmap +               base, as well as whatever program they might try to exec.  This +               is because the brk will follow the loader, and is not movable.  */ +            /* NOTE: for qemu, we do a big mmap to get enough space +               without hardcoding any address */ +            error = target_mmap(0, ET_DYN_MAP_SIZE, +                                PROT_NONE, MAP_PRIVATE | MAP_ANON, +                                -1, 0); +            if (error == -1) { +                perror("mmap"); +                exit(-1); +            } +            load_bias = TARGET_ELF_PAGESTART(error - elf_ppnt->p_vaddr); +        } + +        error = target_mmap(TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr), +                            (elf_ppnt->p_filesz + +                             TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr)), +                            elf_prot, +                            (MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE), +                            bprm->fd, +                            (elf_ppnt->p_offset - +                             TARGET_ELF_PAGEOFFSET(elf_ppnt->p_vaddr))); +        if (error == -1) { +            perror("mmap"); +            exit(-1); +        } + +#ifdef LOW_ELF_STACK +        if (TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr) < elf_stack) +            elf_stack = TARGET_ELF_PAGESTART(elf_ppnt->p_vaddr); +#endif + +        if (!load_addr_set) { +            load_addr_set = 1; +            load_addr = elf_ppnt->p_vaddr - elf_ppnt->p_offset; +            if (elf_ex.e_type == ET_DYN) { +                load_bias += error - +                    TARGET_ELF_PAGESTART(load_bias + elf_ppnt->p_vaddr); +                load_addr += load_bias; +                reloc_func_desc = load_bias; +            } +        } +        k = elf_ppnt->p_vaddr; +        if (k < start_code) +            start_code = k; +        if (start_data < k) +            start_data = k; +        k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz; +        if (k > elf_bss) +            elf_bss = k; +        if ((elf_ppnt->p_flags & PF_X) && end_code <  k) +            end_code = k; +        if (end_data < k) +            end_data = k; +        k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz; +        if (k > elf_brk) elf_brk = k; +    } + +    elf_entry += load_bias; +    elf_bss += load_bias; +    elf_brk += load_bias; +    start_code += load_bias; +    end_code += load_bias; +    start_data += load_bias; +    end_data += load_bias; + +    if (elf_interpreter) { +        if (interpreter_type & 1) { +            elf_entry = load_aout_interp(&interp_ex, interpreter_fd); +        } +        else if (interpreter_type & 2) { +            elf_entry = load_elf_interp(&interp_elf_ex, interpreter_fd, +                                            &interp_load_addr); +        } +        reloc_func_desc = interp_load_addr; + +        close(interpreter_fd); +        free(elf_interpreter); + +        if (elf_entry == ~((abi_ulong)0UL)) { +            printf("Unable to load interpreter\n"); +            free(elf_phdata); +            exit(-1); +            return 0; +        } +    } + +    free(elf_phdata); + +    if (qemu_log_enabled()) +        load_symbols(&elf_ex, bprm->fd); + +    if (interpreter_type != INTERPRETER_AOUT) close(bprm->fd); +    info->personality = (ibcs2_interpreter ? PER_SVR4 : PER_LINUX); + +#ifdef LOW_ELF_STACK +    info->start_stack = bprm->p = elf_stack - 4; +#endif +    bprm->p = create_elf_tables(bprm->p, +                    bprm->argc, +                    bprm->envc, +                    &elf_ex, +                    load_addr, load_bias, +                    interp_load_addr, +                    (interpreter_type == INTERPRETER_AOUT ? 0 : 1), +                    info); +    info->load_addr = reloc_func_desc; +    info->start_brk = info->brk = elf_brk; +    info->end_code = end_code; +    info->start_code = start_code; +    info->start_data = start_data; +    info->end_data = end_data; +    info->start_stack = bprm->p; + +    /* Calling set_brk effectively mmaps the pages that we need for the bss and break +       sections */ +    set_brk(elf_bss, elf_brk); + +    padzero(elf_bss, elf_brk); + +#if 0 +    printf("(start_brk) %x\n" , info->start_brk); +    printf("(end_code) %x\n" , info->end_code); +    printf("(start_code) %x\n" , info->start_code); +    printf("(end_data) %x\n" , info->end_data); +    printf("(start_stack) %x\n" , info->start_stack); +    printf("(brk) %x\n" , info->brk); +#endif + +    if ( info->personality == PER_SVR4 ) +    { +            /* Why this, you ask???  Well SVr4 maps page 0 as read-only, +               and some applications "depend" upon this behavior. +               Since we do not have the power to recompile these, we +               emulate the SVr4 behavior.  Sigh.  */ +            mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC, +                                      MAP_FIXED | MAP_PRIVATE, -1, 0); +    } + +    info->entry = elf_entry; + +    return 0; +} + +static int load_aout_interp(void * exptr, int interp_fd) +{ +    printf("a.out interpreter not yet supported\n"); +    return(0); +} + +void do_init_thread(struct target_pt_regs *regs, struct image_info *infop) +{ +    init_thread(regs, infop); +} diff --git a/bsd-user/errno_defs.h b/bsd-user/errno_defs.h new file mode 100644 index 00000000..1efa502a --- /dev/null +++ b/bsd-user/errno_defs.h @@ -0,0 +1,149 @@ +/*      $OpenBSD: errno.h,v 1.20 2007/09/03 14:37:52 millert Exp $      */ +/*      $NetBSD: errno.h,v 1.10 1996/01/20 01:33:53 jtc Exp $   */ + +/* + * Copyright (c) 1982, 1986, 1989, 1993 + *      The Regents of the University of California.  All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + *      @(#)errno.h     8.5 (Berkeley) 1/21/94 + */ + +#define TARGET_EPERM            1               /* Operation not permitted */ +#define TARGET_ENOENT           2               /* No such file or directory */ +#define TARGET_ESRCH            3               /* No such process */ +#define TARGET_EINTR            4               /* Interrupted system call */ +#define TARGET_EIO              5               /* Input/output error */ +#define TARGET_ENXIO            6               /* Device not configured */ +#define TARGET_E2BIG            7               /* Argument list too long */ +#define TARGET_ENOEXEC          8               /* Exec format error */ +#define TARGET_EBADF            9               /* Bad file descriptor */ +#define TARGET_ECHILD           10              /* No child processes */ +#define TARGET_EDEADLK          11              /* Resource deadlock avoided */ +                                        /* 11 was EAGAIN */ +#define TARGET_ENOMEM           12              /* Cannot allocate memory */ +#define TARGET_EACCES           13              /* Permission denied */ +#define TARGET_EFAULT           14              /* Bad address */ +#define TARGET_ENOTBLK          15              /* Block device required */ +#define TARGET_EBUSY            16              /* Device busy */ +#define TARGET_EEXIST           17              /* File exists */ +#define TARGET_EXDEV            18              /* Cross-device link */ +#define TARGET_ENODEV           19              /* Operation not supported by device */ +#define TARGET_ENOTDIR          20              /* Not a directory */ +#define TARGET_EISDIR           21              /* Is a directory */ +#define TARGET_EINVAL           22              /* Invalid argument */ +#define TARGET_ENFILE           23              /* Too many open files in system */ +#define TARGET_EMFILE           24              /* Too many open files */ +#define TARGET_ENOTTY           25              /* Inappropriate ioctl for device */ +#define TARGET_ETXTBSY          26              /* Text file busy */ +#define TARGET_EFBIG            27              /* File too large */ +#define TARGET_ENOSPC           28              /* No space left on device */ +#define TARGET_ESPIPE           29              /* Illegal seek */ +#define TARGET_EROFS            30              /* Read-only file system */ +#define TARGET_EMLINK           31              /* Too many links */ +#define TARGET_EPIPE            32              /* Broken pipe */ + +/* math software */ +#define TARGET_EDOM             33              /* Numerical argument out of domain */ +#define TARGET_ERANGE           34              /* Result too large */ + +/* non-blocking and interrupt i/o */ +#define TARGET_EAGAIN           35              /* Resource temporarily unavailable */ +#define TARGET_EWOULDBLOCK      EAGAIN          /* Operation would block */ +#define TARGET_EINPROGRESS      36              /* Operation now in progress */ +#define TARGET_EALREADY 37              /* Operation already in progress */ + +/* ipc/network software -- argument errors */ +#define TARGET_ENOTSOCK 38              /* Socket operation on non-socket */ +#define TARGET_EDESTADDRREQ     39              /* Destination address required */ +#define TARGET_EMSGSIZE 40              /* Message too long */ +#define TARGET_EPROTOTYPE       41              /* Protocol wrong type for socket */ +#define TARGET_ENOPROTOOPT      42              /* Protocol not available */ +#define TARGET_EPROTONOSUPPORT  43              /* Protocol not supported */ +#define TARGET_ESOCKTNOSUPPORT  44              /* Socket type not supported */ +#define TARGET_EOPNOTSUPP       45              /* Operation not supported */ +#define TARGET_EPFNOSUPPORT     46              /* Protocol family not supported */ +#define TARGET_EAFNOSUPPORT     47              /* Address family not supported by protocol family */ +#define TARGET_EADDRINUSE       48              /* Address already in use */ +#define TARGET_EADDRNOTAVAIL    49              /* Can't assign requested address */ + +/* ipc/network software -- operational errors */ +#define TARGET_ENETDOWN 50              /* Network is down */ +#define TARGET_ENETUNREACH      51              /* Network is unreachable */ +#define TARGET_ENETRESET        52              /* Network dropped connection on reset */ +#define TARGET_ECONNABORTED     53              /* Software caused connection abort */ +#define TARGET_ECONNRESET       54              /* Connection reset by peer */ +#define TARGET_ENOBUFS          55              /* No buffer space available */ +#define TARGET_EISCONN          56              /* Socket is already connected */ +#define TARGET_ENOTCONN 57              /* Socket is not connected */ +#define TARGET_ESHUTDOWN        58              /* Can't send after socket shutdown */ +#define TARGET_ETOOMANYREFS     59              /* Too many references: can't splice */ +#define TARGET_ETIMEDOUT        60              /* Operation timed out */ +#define TARGET_ECONNREFUSED     61              /* Connection refused */ + +#define TARGET_ELOOP            62              /* Too many levels of symbolic links */ +#define TARGET_ENAMETOOLONG     63              /* File name too long */ + +/* should be rearranged */ +#define TARGET_EHOSTDOWN        64              /* Host is down */ +#define TARGET_EHOSTUNREACH     65              /* No route to host */ +#define TARGET_ENOTEMPTY        66              /* Directory not empty */ + +/* quotas & mush */ +#define TARGET_EPROCLIM 67              /* Too many processes */ +#define TARGET_EUSERS           68              /* Too many users */ +#define TARGET_EDQUOT           69              /* Disk quota exceeded */ + +/* Network File System */ +#define TARGET_ESTALE           70              /* Stale NFS file handle */ +#define TARGET_EREMOTE          71              /* Too many levels of remote in path */ +#define TARGET_EBADRPC          72              /* RPC struct is bad */ +#define TARGET_ERPCMISMATCH     73              /* RPC version wrong */ +#define TARGET_EPROGUNAVAIL     74              /* RPC prog. not avail */ +#define TARGET_EPROGMISMATCH    75              /* Program version wrong */ +#define TARGET_EPROCUNAVAIL     76              /* Bad procedure for program */ + +#define TARGET_ENOLCK           77              /* No locks available */ +#define TARGET_ENOSYS           78              /* Function not implemented */ + +#define TARGET_EFTYPE           79              /* Inappropriate file type or format */ +#define TARGET_EAUTH            80              /* Authentication error */ +#define TARGET_ENEEDAUTH        81              /* Need authenticator */ +#define TARGET_EIPSEC           82              /* IPsec processing failure */ +#define TARGET_ENOATTR          83              /* Attribute not found */ +#define TARGET_EILSEQ           84              /* Illegal byte sequence */ +#define TARGET_ENOMEDIUM        85              /* No medium found */ +#define TARGET_EMEDIUMTYPE      86              /* Wrong Medium Type */ +#define TARGET_EOVERFLOW        87              /* Conversion overflow */ +#define TARGET_ECANCELED        88              /* Operation canceled */ +#define TARGET_EIDRM            89              /* Identifier removed */ +#define TARGET_ENOMSG           90              /* No message of desired type */ +#define TARGET_ELAST            90              /* Must be equal largest errno */ diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list new file mode 100644 index 00000000..2800a2d4 --- /dev/null +++ b/bsd-user/freebsd/strace.list @@ -0,0 +1,231 @@ +/* + *  FreeBSD strace list + * + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +{ TARGET_FREEBSD_NR___acl_aclcheck_fd, "__acl_aclcheck_fd", "%s(%d, %d, %#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR___acl_aclcheck_file, "__acl_aclcheck_file", "%s(\"%s\", %d, %#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR___acl_aclcheck_link, "__acl_aclcheck_link", "%s(\"%s\", %d, %#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR___acl_delete_fd, "__acl_delete_fd", "%s(%d, %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR___acl_delete_file, "__acl_delete_file", "%s(\"%s\", %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR___acl_delete_link, "__acl_delete_link", "%s(\"%s\", %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR___acl_get_fd, "__acl_get_fd", "%s(%d, %d, %#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR___acl_get_file, "__acl_get_file", "%s(\"%s\", %d, %#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR___acl_get_link, "__acl_get_link", "%s(\"%s\", %d, %#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR___acl_set_fd, "__acl_set_fd", "%s(%d, %d, %#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR___acl_set_file, "__acl_set_file", "%s(\"%s\", %d, %#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR___acl_set_link, "__acl_set_link", "%s(\"%s\", %d, %#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR___semctl, "__semctl", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR___syscall, "__syscall", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, print_sysctl, NULL }, +{ TARGET_FREEBSD_NR__umtx_op, "_umtx_op", "%s(%#x, %d, %d, %#x, %#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR_accept, "accept", "%s(%d,%#x,%#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR_access, "access", "%s(\"%s\",%#o)", NULL, NULL }, +{ TARGET_FREEBSD_NR_acct, "acct", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_adjtime, "adjtime", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_bind, "bind", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_break, "break", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_chdir, "chdir", "%s(\"%s\")", NULL, NULL }, +{ TARGET_FREEBSD_NR_chflags, "chflags", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_chmod, "chmod", "%s(\"%s\",%#o)", NULL, NULL }, +{ TARGET_FREEBSD_NR_chown, "chown", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_chroot, "chroot", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_clock_getres, "clock_getres", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_clock_gettime, "clock_gettime", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_clock_settime, "clock_settime", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_close, "close", "%s(%d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_connect, "connect", "%s(%d,%#x,%d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_dup, "dup", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_dup2, "dup2", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_eaccess, "eaccess", "%s(\"%s\",%#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR_execve, "execve", NULL, print_execve, NULL }, +{ TARGET_FREEBSD_NR_exit, "exit", "%s(%d)\n", NULL, NULL }, +{ TARGET_FREEBSD_NR_extattrctl, "extattrctl", "%s(\"%s\", %d, \"%s\", %d, \"%s\"", NULL, NULL }, +{ TARGET_FREEBSD_NR_extattr_delete_fd, "extattr_delete_fd", "%s(%d, %d, \"%s\")", NULL, NULL }, +{ TARGET_FREEBSD_NR_extattr_delete_file, "extattr_delete_file", "%s(\"%s\", %d, \"%s\")", NULL, NULL }, +{ TARGET_FREEBSD_NR_extattr_delete_link, "extattr_delete_link", "%s(\"%s\", %d, \"%s\")", NULL, NULL }, +{ TARGET_FREEBSD_NR_extattr_get_fd, "extattr_get_fd", "%s(%d, %d, \"%s\", %#x, %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_extattr_get_file, "extattr_get_file", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_extattr_get_file, "extattr_get_link", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_extattr_list_fd, "extattr_list_fd", "%s(%d, %d, %#x, %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_extattr_list_file, "extattr_list_file", "%s(\"%s\", %d, %#x, %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_extattr_list_link, "extattr_list_link", "%s(\"%s\", %d, %#x, %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_extattr_set_fd, "extattr_set_fd", "%s(%d, %d, \"%s\", %#x, %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_extattr_set_file, "extattr_set_file", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_extattr_set_link, "extattr_set_link", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_fchdir, "fchdir", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_fchflags, "fchflags", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_fchmod, "fchmod", "%s(%d,%#o)", NULL, NULL }, +{ TARGET_FREEBSD_NR_fchown, "fchown", "%s(%d,%d,%d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_fcntl, "fcntl", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_fexecve, "fexecve", NULL, print_execve, NULL }, +{ TARGET_FREEBSD_NR_fhopen, "fhopen", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_fhstat, "fhstat", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_fhstatfs, "fhstatfs", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_flock, "flock", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_fork, "fork", "%s()", NULL, NULL }, +{ TARGET_FREEBSD_NR_fpathconf, "fpathconf", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_fstat, "fstat", "%s(%d,%#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR_fstatat, "fstatat", "%s(%d,\"%s\", %#x, %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_fstatfs, "fstatfs", "%s(%d,%#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR_fsync, "fsync", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_ftruncate, "ftruncate", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_futimes, "futimes", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_getcontext, "getcontext", "%s(%#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR_getdirentries, "getdirentries", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_freebsd6_mmap, "freebsd6_mmap", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_getegid, "getegid", "%s()", NULL, NULL }, +{ TARGET_FREEBSD_NR_geteuid, "geteuid", "%s()", NULL, NULL }, +{ TARGET_FREEBSD_NR_getfh, "getfh", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_getfsstat, "getfsstat", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_getgid, "getgid", "%s()", NULL, NULL }, +{ TARGET_FREEBSD_NR_getgroups, "getgroups", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_getitimer, "getitimer", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_getlogin, "getlogin", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_getpeername, "getpeername", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_getpgid, "getpgid", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_getpgrp, "getpgrp", "%s()", NULL, NULL }, +{ TARGET_FREEBSD_NR_getpid, "getpid", "%s()", NULL, NULL }, +{ TARGET_FREEBSD_NR_getppid, "getppid", "%s()", NULL, NULL }, +{ TARGET_FREEBSD_NR_getpriority, "getpriority", "%s(%#x,%#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR_getresgid, "getresgid", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_getresuid, "getresuid", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_getrlimit, "getrlimit", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_getrusage, "getrusage", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_getsid, "getsid", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_getsockname, "getsockname", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_getsockopt, "getsockopt", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_gettimeofday, "gettimeofday", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_getuid, "getuid", "%s()", NULL, NULL }, +{ TARGET_FREEBSD_NR_ioctl, "ioctl", NULL, print_ioctl, NULL }, +{ TARGET_FREEBSD_NR_issetugid, "issetugid", "%s()", NULL, NULL }, +{ TARGET_FREEBSD_NR_kevent, "kevent", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_kill, "kill", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_kqueue, "kqueue", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_ktrace, "ktrace", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_lchown, "lchown", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_link, "link", "%s(\"%s\",\"%s\")", NULL, NULL }, +{ TARGET_FREEBSD_NR_listen, "listen", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_lpathconf, "lpathconf", "%s(\"%s\", %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_lseek, "lseek", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_lstat, "lstat", "%s(\"%s\",%p)", NULL, NULL }, +{ TARGET_FREEBSD_NR_madvise, "madvise", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_mincore, "mincore", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_minherit, "minherit", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_mkdir, "mkdir", "%s(\"%s\",%#o)", NULL, NULL }, +{ TARGET_FREEBSD_NR_mkfifo, "mkfifo", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_mknod, "mknod", "%s(\"%s\",%#o,%#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR_mlock, "mlock", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_mlockall, "mlockall", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_mmap, "mmap", NULL, NULL, print_syscall_ret_addr }, +{ TARGET_FREEBSD_NR_mount, "mount", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_mprotect, "mprotect", "%s(%#x,%#x,%d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_msgctl, "msgctl", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_msgget, "msgget", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_msgrcv, "msgrcv", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_msgsnd, "msgsnd", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_msync, "msync", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_munlock, "munlock", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_munlockall, "munlockall", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_munmap, "munmap", "%s(%p,%d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_nanosleep, "nanosleep", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_nfssvc, "nfssvc", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_open, "open", "%s(\"%s\",%#x,%#o)", NULL, NULL }, +{ TARGET_FREEBSD_NR_openat, "openat", "%s(%d, \"%s\",%#x,%#o)", NULL, NULL }, +{ TARGET_FREEBSD_NR_pathconf, "pathconf", "%s(\"%s\", %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_pipe, "pipe", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_poll, "poll", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_pread, "pread", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_preadv, "preadv", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_profil, "profil", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_ptrace, "ptrace", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_pwrite, "pwrite", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_pwritev, "pwritev", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_quotactl, "quotactl", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_read, "read", "%s(%d,%#x,%d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_readlink, "readlink", "%s(\"%s\",%p,%d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_readv, "readv", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_reboot, "reboot", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_recvfrom, "recvfrom", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_recvmsg, "recvmsg", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_rename, "rename", "%s(\"%s\",\"%s\")", NULL, NULL }, +{ TARGET_FREEBSD_NR_revoke, "revoke", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_rfork, "rfork", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_rmdir, "rmdir", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_rtprio_thread, "rtprio_thread", "%s(%d, %d, %p)", NULL, NULL }, +{ TARGET_FREEBSD_NR_sbrk, "sbrk", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_sched_yield, "sched_yield", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_select, "select", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_semget, "semget", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_semop, "semop", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_sendmsg, "sendmsg", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_sendto, "sendto", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_setcontext, "setcontext", "%s(%#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR_setegid, "setegid", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_seteuid, "seteuid", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_setgid, "setgid", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_setgroups, "setgroups", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_setitimer, "setitimer", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_setlogin, "setlogin", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_setpgid, "setpgid", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_setpriority, "setpriority", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_setregid, "setregid", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_setresgid, "setresgid", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_setresuid, "setresuid", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_setreuid, "setreuid", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_setrlimit, "setrlimit", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_setsid, "setsid", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_setsockopt, "setsockopt", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_settimeofday, "settimeofday", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_setuid, "setuid", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_shmat, "shmat", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_shmctl, "shmctl", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_shmdt, "shmdt", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_shmget, "shmget", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_shutdown, "shutdown", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_sigaction, "sigaction", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_sigaltstack, "sigaltstack", "%s(%p,%p)", NULL, NULL }, +{ TARGET_FREEBSD_NR_sigpending, "sigpending", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_sigprocmask, "sigprocmask", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_sigreturn, "sigreturn", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_sigsuspend, "sigsuspend", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_socket, "socket", "%s(%d,%d,%d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_socketpair, "socketpair", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_sstk, "sstk", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_stat, "stat", "%s(\"%s\",%p)", NULL, NULL }, +{ TARGET_FREEBSD_NR_statfs, "statfs", "%s(\"%s\",%p)", NULL, NULL }, +{ TARGET_FREEBSD_NR_symlink, "symlink", "%s(\"%s\",\"%s\")", NULL, NULL }, +{ TARGET_FREEBSD_NR_sync, "sync", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_sysarch, "sysarch", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_syscall, "syscall", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_thr_create, "thr_create", "%s(%#x, %#x, %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_thr_exit, "thr_exit", "%s(%#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR_thr_kill, "thr_kill", "%s(%d, %#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR_thr_kill2, "thr_kill2", "%s(%d, %d, %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_thr_new, "thr_new", "%s(%#x, %d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_thr_self, "thr_self", "%s(%#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR_thr_set_name, "thr_set_name", "%s(%d, \"%s\")", NULL, NULL }, +{ TARGET_FREEBSD_NR_thr_suspend, "thr_suspend", "%s(%d, %#x)", NULL, NULL }, +{ TARGET_FREEBSD_NR_thr_wake, "thr_wake", "%s(%d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_truncate, "truncate", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_umask, "umask", "%s(%#o)", NULL, NULL }, +{ TARGET_FREEBSD_NR_unlink, "unlink", "%s(\"%s\")", NULL, NULL }, +{ TARGET_FREEBSD_NR_unmount, "unmount", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_utimes, "utimes", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_vfork, "vfork", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_wait4, "wait4", NULL, NULL, NULL }, +{ TARGET_FREEBSD_NR_write, "write", "%s(%d,%#x,%d)", NULL, NULL }, +{ TARGET_FREEBSD_NR_writev, "writev", "%s(%d,%p,%#x)", NULL, NULL }, diff --git a/bsd-user/freebsd/syscall_nr.h b/bsd-user/freebsd/syscall_nr.h new file mode 100644 index 00000000..d8490247 --- /dev/null +++ b/bsd-user/freebsd/syscall_nr.h @@ -0,0 +1,450 @@ +/* + * System call numbers. + * + * created from FreeBSD: releng/9.1/sys/kern/syscalls.master 229723 + * 2012-01-06 19:29:16Z jhb + */ + +#define TARGET_FREEBSD_NR_syscall   0 +#define TARGET_FREEBSD_NR_exit  1 +#define TARGET_FREEBSD_NR_fork  2 +#define TARGET_FREEBSD_NR_read  3 +#define TARGET_FREEBSD_NR_write 4 +#define TARGET_FREEBSD_NR_open  5 +#define TARGET_FREEBSD_NR_close 6 +#define TARGET_FREEBSD_NR_wait4 7 +                /* 8 is old creat */ +#define TARGET_FREEBSD_NR_link  9 +#define TARGET_FREEBSD_NR_unlink    10 +                /* 11 is obsolete execv */ +#define TARGET_FREEBSD_NR_chdir 12 +#define TARGET_FREEBSD_NR_fchdir    13 +#define TARGET_FREEBSD_NR_mknod 14 +#define TARGET_FREEBSD_NR_chmod 15 +#define TARGET_FREEBSD_NR_chown 16 +#define TARGET_FREEBSD_NR_break 17 +#define TARGET_FREEBSD_NR_freebsd4_getfsstat    18 +                /* 19 is old lseek */ +#define TARGET_FREEBSD_NR_getpid    20 +#define TARGET_FREEBSD_NR_mount 21 +#define TARGET_FREEBSD_NR_unmount   22 +#define TARGET_FREEBSD_NR_setuid    23 +#define TARGET_FREEBSD_NR_getuid    24 +#define TARGET_FREEBSD_NR_geteuid   25 +#define TARGET_FREEBSD_NR_ptrace    26 +#define TARGET_FREEBSD_NR_recvmsg   27 +#define TARGET_FREEBSD_NR_sendmsg   28 +#define TARGET_FREEBSD_NR_recvfrom  29 +#define TARGET_FREEBSD_NR_accept    30 +#define TARGET_FREEBSD_NR_getpeername   31 +#define TARGET_FREEBSD_NR_getsockname   32 +#define TARGET_FREEBSD_NR_access    33 +#define TARGET_FREEBSD_NR_chflags   34 +#define TARGET_FREEBSD_NR_fchflags  35 +#define TARGET_FREEBSD_NR_sync  36 +#define TARGET_FREEBSD_NR_kill  37 +                /* 38 is old stat */ +#define TARGET_FREEBSD_NR_getppid   39 +                /* 40 is old lstat */ +#define TARGET_FREEBSD_NR_dup   41 +#define TARGET_FREEBSD_NR_pipe  42 +#define TARGET_FREEBSD_NR_getegid   43 +#define TARGET_FREEBSD_NR_profil    44 +#define TARGET_FREEBSD_NR_ktrace    45 +                /* 46 is old sigaction */ +#define TARGET_FREEBSD_NR_getgid    47 +                /* 48 is old sigprocmask */ +#define TARGET_FREEBSD_NR_getlogin  49 +#define TARGET_FREEBSD_NR_setlogin  50 +#define TARGET_FREEBSD_NR_acct  51 +                /* 52 is old sigpending */ +#define TARGET_FREEBSD_NR_sigaltstack   53 +#define TARGET_FREEBSD_NR_ioctl 54 +#define TARGET_FREEBSD_NR_reboot    55 +#define TARGET_FREEBSD_NR_revoke    56 +#define TARGET_FREEBSD_NR_symlink   57 +#define TARGET_FREEBSD_NR_readlink  58 +#define TARGET_FREEBSD_NR_execve    59 +#define TARGET_FREEBSD_NR_umask 60 +#define TARGET_FREEBSD_NR_chroot    61 +                /* 62 is old fstat */ +                /* 63 is old getkerninfo */ +                /* 64 is old getpagesize */ +#define TARGET_FREEBSD_NR_msync 65 +#define TARGET_FREEBSD_NR_vfork 66 +                /* 67 is obsolete vread */ +                /* 68 is obsolete vwrite */ +#define TARGET_FREEBSD_NR_sbrk  69 +#define TARGET_FREEBSD_NR_sstk  70 +                /* 71 is old mmap */ +#define TARGET_FREEBSD_NR_vadvise   72 +#define TARGET_FREEBSD_NR_munmap    73 +#define TARGET_FREEBSD_NR_mprotect  74 +#define TARGET_FREEBSD_NR_madvise   75 +                /* 76 is obsolete vhangup */ +                /* 77 is obsolete vlimit */ +#define TARGET_FREEBSD_NR_mincore   78 +#define TARGET_FREEBSD_NR_getgroups 79 +#define TARGET_FREEBSD_NR_setgroups 80 +#define TARGET_FREEBSD_NR_getpgrp   81 +#define TARGET_FREEBSD_NR_setpgid   82 +#define TARGET_FREEBSD_NR_setitimer 83 +                /* 84 is old wait */ +#define TARGET_FREEBSD_NR_swapon    85 +#define TARGET_FREEBSD_NR_getitimer 86 +                /* 87 is old gethostname */ +                /* 88 is old sethostname */ +#define TARGET_FREEBSD_NR_getdtablesize 89 +#define TARGET_FREEBSD_NR_dup2  90 +#define TARGET_FREEBSD_NR_fcntl 92 +#define TARGET_FREEBSD_NR_select    93 +#define TARGET_FREEBSD_NR_fsync 95 +#define TARGET_FREEBSD_NR_setpriority   96 +#define TARGET_FREEBSD_NR_socket    97 +#define TARGET_FREEBSD_NR_connect   98 +                /* 99 is old accept */ +#define TARGET_FREEBSD_NR_getpriority   100 +                /* 101 is old send */ +                /* 102 is old recv */ +                /* 103 is old sigreturn */ +#define TARGET_FREEBSD_NR_bind  104 +#define TARGET_FREEBSD_NR_setsockopt    105 +#define TARGET_FREEBSD_NR_listen    106 +                /* 107 is obsolete vtimes */ +                /* 108 is old sigvec */ +                /* 109 is old sigblock */ +                /* 110 is old sigsetmask */ +                /* 111 is old sigsuspend */ +                /* 112 is old sigstack */ +                /* 113 is old recvmsg */ +                /* 114 is old sendmsg */ +                /* 115 is obsolete vtrace */ +#define TARGET_FREEBSD_NR_gettimeofday  116 +#define TARGET_FREEBSD_NR_getrusage 117 +#define TARGET_FREEBSD_NR_getsockopt    118 +#define TARGET_FREEBSD_NR_readv 120 +#define TARGET_FREEBSD_NR_writev    121 +#define TARGET_FREEBSD_NR_settimeofday  122 +#define TARGET_FREEBSD_NR_fchown    123 +#define TARGET_FREEBSD_NR_fchmod    124 +                /* 125 is old recvfrom */ +#define TARGET_FREEBSD_NR_setreuid  126 +#define TARGET_FREEBSD_NR_setregid  127 +#define TARGET_FREEBSD_NR_rename    128 +                /* 129 is old truncate */ +                /* 130 is old ftruncate */ +#define TARGET_FREEBSD_NR_flock 131 +#define TARGET_FREEBSD_NR_mkfifo    132 +#define TARGET_FREEBSD_NR_sendto    133 +#define TARGET_FREEBSD_NR_shutdown  134 +#define TARGET_FREEBSD_NR_socketpair    135 +#define TARGET_FREEBSD_NR_mkdir 136 +#define TARGET_FREEBSD_NR_rmdir 137 +#define TARGET_FREEBSD_NR_utimes    138 +                /* 139 is obsolete 4.2 sigreturn */ +#define TARGET_FREEBSD_NR_adjtime   140 +                /* 141 is old getpeername */ +                /* 142 is old gethostid */ +                /* 143 is old sethostid */ +                /* 144 is old getrlimit */ +                /* 145 is old setrlimit */ +                /* 146 is old killpg */ +#define TARGET_FREEBSD_NR_killpg    146 /* COMPAT */ +#define TARGET_FREEBSD_NR_setsid    147 +#define TARGET_FREEBSD_NR_quotactl  148 +                /* 149 is old quota */ +                /* 150 is old getsockname */ +#define TARGET_FREEBSD_NR_nlm_syscall   154 +#define TARGET_FREEBSD_NR_nfssvc    155 +                /* 156 is old getdirentries */ +#define TARGET_FREEBSD_NR_freebsd4_statfs   157 +#define TARGET_FREEBSD_NR_freebsd4_fstatfs  158 +#define TARGET_FREEBSD_NR_lgetfh    160 +#define TARGET_FREEBSD_NR_getfh 161 +#define TARGET_FREEBSD_NR_freebsd4_getdomainname    162 +#define TARGET_FREEBSD_NR_freebsd4_setdomainname    163 +#define TARGET_FREEBSD_NR_freebsd4_uname    164 +#define TARGET_FREEBSD_NR_sysarch   165 +#define TARGET_FREEBSD_NR_rtprio    166 +#define TARGET_FREEBSD_NR_semsys    169 +#define TARGET_FREEBSD_NR_msgsys    170 +#define TARGET_FREEBSD_NR_shmsys    171 +#define TARGET_FREEBSD_NR_freebsd6_pread    173 +#define TARGET_FREEBSD_NR_freebsd6_pwrite   174 +#define TARGET_FREEBSD_NR_setfib    175 +#define TARGET_FREEBSD_NR_ntp_adjtime   176 +#define TARGET_FREEBSD_NR_setgid    181 +#define TARGET_FREEBSD_NR_setegid   182 +#define TARGET_FREEBSD_NR_seteuid   183 +#define TARGET_FREEBSD_NR_stat  188 +#define TARGET_FREEBSD_NR_fstat 189 +#define TARGET_FREEBSD_NR_lstat 190 +#define TARGET_FREEBSD_NR_pathconf  191 +#define TARGET_FREEBSD_NR_fpathconf 192 +#define TARGET_FREEBSD_NR_getrlimit 194 +#define TARGET_FREEBSD_NR_setrlimit 195 +#define TARGET_FREEBSD_NR_getdirentries 196 +#define TARGET_FREEBSD_NR_freebsd6_mmap 197 +#define TARGET_FREEBSD_NR___syscall 198 +#define TARGET_FREEBSD_NR_freebsd6_lseek    199 +#define TARGET_FREEBSD_NR_freebsd6_truncate 200 +#define TARGET_FREEBSD_NR_freebsd6_ftruncate    201 +#define TARGET_FREEBSD_NR___sysctl  202 +#define TARGET_FREEBSD_NR_mlock 203 +#define TARGET_FREEBSD_NR_munlock   204 +#define TARGET_FREEBSD_NR_undelete  205 +#define TARGET_FREEBSD_NR_futimes   206 +#define TARGET_FREEBSD_NR_getpgid   207 +#define TARGET_FREEBSD_NR_poll  209 +#define TARGET_FREEBSD_NR_freebsd7___semctl 220 +#define TARGET_FREEBSD_NR_semget    221 +#define TARGET_FREEBSD_NR_semop 222 +#define TARGET_FREEBSD_NR_freebsd7_msgctl   224 +#define TARGET_FREEBSD_NR_msgget    225 +#define TARGET_FREEBSD_NR_msgsnd    226 +#define TARGET_FREEBSD_NR_msgrcv    227 +#define TARGET_FREEBSD_NR_shmat 228 +#define TARGET_FREEBSD_NR_freebsd7_shmctl   229 +#define TARGET_FREEBSD_NR_shmdt 230 +#define TARGET_FREEBSD_NR_shmget    231 +#define TARGET_FREEBSD_NR_clock_gettime 232 +#define TARGET_FREEBSD_NR_clock_settime 233 +#define TARGET_FREEBSD_NR_clock_getres  234 +#define TARGET_FREEBSD_NR_ktimer_create 235 +#define TARGET_FREEBSD_NR_ktimer_delete 236 +#define TARGET_FREEBSD_NR_ktimer_settime    237 +#define TARGET_FREEBSD_NR_ktimer_gettime    238 +#define TARGET_FREEBSD_NR_ktimer_getoverrun 239 +#define TARGET_FREEBSD_NR_nanosleep 240 +#define TARGET_FREEBSD_NR_ntp_gettime   248 +#define TARGET_FREEBSD_NR_minherit  250 +#define TARGET_FREEBSD_NR_rfork 251 +#define TARGET_FREEBSD_NR_openbsd_poll  252 +#define TARGET_FREEBSD_NR_issetugid 253 +#define TARGET_FREEBSD_NR_lchown    254 +#define TARGET_FREEBSD_NR_aio_read  255 +#define TARGET_FREEBSD_NR_aio_write 256 +#define TARGET_FREEBSD_NR_lio_listio    257 +#define TARGET_FREEBSD_NR_getdents  272 +#define TARGET_FREEBSD_NR_lchmod    274 +#define TARGET_FREEBSD_NR_netbsd_lchown 275 +#define TARGET_FREEBSD_NR_lutimes   276 +#define TARGET_FREEBSD_NR_netbsd_msync  277 +#define TARGET_FREEBSD_NR_nstat 278 +#define TARGET_FREEBSD_NR_nfstat    279 +#define TARGET_FREEBSD_NR_nlstat    280 +#define TARGET_FREEBSD_NR_preadv    289 +#define TARGET_FREEBSD_NR_pwritev   290 +#define TARGET_FREEBSD_NR_freebsd4_fhstatfs 297 +#define TARGET_FREEBSD_NR_fhopen    298 +#define TARGET_FREEBSD_NR_fhstat    299 +#define TARGET_FREEBSD_NR_modnext   300 +#define TARGET_FREEBSD_NR_modstat   301 +#define TARGET_FREEBSD_NR_modfnext  302 +#define TARGET_FREEBSD_NR_modfind   303 +#define TARGET_FREEBSD_NR_kldload   304 +#define TARGET_FREEBSD_NR_kldunload 305 +#define TARGET_FREEBSD_NR_kldfind   306 +#define TARGET_FREEBSD_NR_kldnext   307 +#define TARGET_FREEBSD_NR_kldstat   308 +#define TARGET_FREEBSD_NR_kldfirstmod   309 +#define TARGET_FREEBSD_NR_getsid    310 +#define TARGET_FREEBSD_NR_setresuid 311 +#define TARGET_FREEBSD_NR_setresgid 312 +                /* 313 is obsolete signanosleep */ +#define TARGET_FREEBSD_NR_aio_return    314 +#define TARGET_FREEBSD_NR_aio_suspend   315 +#define TARGET_FREEBSD_NR_aio_cancel    316 +#define TARGET_FREEBSD_NR_aio_error 317 +#define TARGET_FREEBSD_NR_oaio_read 318 +#define TARGET_FREEBSD_NR_oaio_write    319 +#define TARGET_FREEBSD_NR_olio_listio   320 +#define TARGET_FREEBSD_NR_yield 321 +                /* 322 is obsolete thr_sleep */ +                /* 323 is obsolete thr_wakeup */ +#define TARGET_FREEBSD_NR_mlockall  324 +#define TARGET_FREEBSD_NR_munlockall    325 +#define TARGET_FREEBSD_NR___getcwd  326 +#define TARGET_FREEBSD_NR_sched_setparam    327 +#define TARGET_FREEBSD_NR_sched_getparam    328 +#define TARGET_FREEBSD_NR_sched_setscheduler    329 +#define TARGET_FREEBSD_NR_sched_getscheduler    330 +#define TARGET_FREEBSD_NR_sched_yield   331 +#define TARGET_FREEBSD_NR_sched_get_priority_max    332 +#define TARGET_FREEBSD_NR_sched_get_priority_min    333 +#define TARGET_FREEBSD_NR_sched_rr_get_interval 334 +#define TARGET_FREEBSD_NR_utrace    335 +#define TARGET_FREEBSD_NR_freebsd4_sendfile 336 +#define TARGET_FREEBSD_NR_kldsym    337 +#define TARGET_FREEBSD_NR_jail  338 +#define TARGET_FREEBSD_NR_nnpfs_syscall 339 +#define TARGET_FREEBSD_NR_sigprocmask   340 +#define TARGET_FREEBSD_NR_sigsuspend    341 +#define TARGET_FREEBSD_NR_freebsd4_sigaction    342 +#define TARGET_FREEBSD_NR_sigpending    343 +#define TARGET_FREEBSD_NR_freebsd4_sigreturn    344 +#define TARGET_FREEBSD_NR_sigtimedwait  345 +#define TARGET_FREEBSD_NR_sigwaitinfo   346 +#define TARGET_FREEBSD_NR___acl_get_file    347 +#define TARGET_FREEBSD_NR___acl_set_file    348 +#define TARGET_FREEBSD_NR___acl_get_fd  349 +#define TARGET_FREEBSD_NR___acl_set_fd  350 +#define TARGET_FREEBSD_NR___acl_delete_file 351 +#define TARGET_FREEBSD_NR___acl_delete_fd   352 +#define TARGET_FREEBSD_NR___acl_aclcheck_file   353 +#define TARGET_FREEBSD_NR___acl_aclcheck_fd 354 +#define TARGET_FREEBSD_NR_extattrctl    355 +#define TARGET_FREEBSD_NR_extattr_set_file  356 +#define TARGET_FREEBSD_NR_extattr_get_file  357 +#define TARGET_FREEBSD_NR_extattr_delete_file   358 +#define TARGET_FREEBSD_NR_aio_waitcomplete  359 +#define TARGET_FREEBSD_NR_getresuid 360 +#define TARGET_FREEBSD_NR_getresgid 361 +#define TARGET_FREEBSD_NR_kqueue    362 +#define TARGET_FREEBSD_NR_kevent    363 +#define TARGET_FREEBSD_NR_extattr_set_fd    371 +#define TARGET_FREEBSD_NR_extattr_get_fd    372 +#define TARGET_FREEBSD_NR_extattr_delete_fd 373 +#define TARGET_FREEBSD_NR___setugid 374 +#define TARGET_FREEBSD_NR_eaccess   376 +#define TARGET_FREEBSD_NR_afs3_syscall  377 +#define TARGET_FREEBSD_NR_nmount    378 +#define TARGET_FREEBSD_NR___mac_get_proc    384 +#define TARGET_FREEBSD_NR___mac_set_proc    385 +#define TARGET_FREEBSD_NR___mac_get_fd  386 +#define TARGET_FREEBSD_NR___mac_get_file    387 +#define TARGET_FREEBSD_NR___mac_set_fd  388 +#define TARGET_FREEBSD_NR___mac_set_file    389 +#define TARGET_FREEBSD_NR_kenv  390 +#define TARGET_FREEBSD_NR_lchflags  391 +#define TARGET_FREEBSD_NR_uuidgen   392 +#define TARGET_FREEBSD_NR_sendfile  393 +#define TARGET_FREEBSD_NR_mac_syscall   394 +#define TARGET_FREEBSD_NR_getfsstat 395 +#define TARGET_FREEBSD_NR_statfs    396 +#define TARGET_FREEBSD_NR_fstatfs   397 +#define TARGET_FREEBSD_NR_fhstatfs  398 +#define TARGET_FREEBSD_NR_ksem_close    400 +#define TARGET_FREEBSD_NR_ksem_post 401 +#define TARGET_FREEBSD_NR_ksem_wait 402 +#define TARGET_FREEBSD_NR_ksem_trywait  403 +#define TARGET_FREEBSD_NR_ksem_init 404 +#define TARGET_FREEBSD_NR_ksem_open 405 +#define TARGET_FREEBSD_NR_ksem_unlink   406 +#define TARGET_FREEBSD_NR_ksem_getvalue 407 +#define TARGET_FREEBSD_NR_ksem_destroy  408 +#define TARGET_FREEBSD_NR___mac_get_pid 409 +#define TARGET_FREEBSD_NR___mac_get_link    410 +#define TARGET_FREEBSD_NR___mac_set_link    411 +#define TARGET_FREEBSD_NR_extattr_set_link  412 +#define TARGET_FREEBSD_NR_extattr_get_link  413 +#define TARGET_FREEBSD_NR_extattr_delete_link   414 +#define TARGET_FREEBSD_NR___mac_execve  415 +#define TARGET_FREEBSD_NR_sigaction 416 +#define TARGET_FREEBSD_NR_sigreturn 417 +#define TARGET_FREEBSD_NR_getcontext    421 +#define TARGET_FREEBSD_NR_setcontext    422 +#define TARGET_FREEBSD_NR_swapcontext   423 +#define TARGET_FREEBSD_NR_swapoff   424 +#define TARGET_FREEBSD_NR___acl_get_link    425 +#define TARGET_FREEBSD_NR___acl_set_link    426 +#define TARGET_FREEBSD_NR___acl_delete_link 427 +#define TARGET_FREEBSD_NR___acl_aclcheck_link   428 +#define TARGET_FREEBSD_NR_sigwait   429 +#define TARGET_FREEBSD_NR_thr_create    430 +#define TARGET_FREEBSD_NR_thr_exit  431 +#define TARGET_FREEBSD_NR_thr_self  432 +#define TARGET_FREEBSD_NR_thr_kill  433 +#define TARGET_FREEBSD_NR__umtx_lock    434 +#define TARGET_FREEBSD_NR__umtx_unlock  435 +#define TARGET_FREEBSD_NR_jail_attach   436 +#define TARGET_FREEBSD_NR_extattr_list_fd   437 +#define TARGET_FREEBSD_NR_extattr_list_file 438 +#define TARGET_FREEBSD_NR_extattr_list_link 439 +#define TARGET_FREEBSD_NR_ksem_timedwait    441 +#define TARGET_FREEBSD_NR_thr_suspend   442 +#define TARGET_FREEBSD_NR_thr_wake  443 +#define TARGET_FREEBSD_NR_kldunloadf    444 +#define TARGET_FREEBSD_NR_audit 445 +#define TARGET_FREEBSD_NR_auditon   446 +#define TARGET_FREEBSD_NR_getauid   447 +#define TARGET_FREEBSD_NR_setauid   448 +#define TARGET_FREEBSD_NR_getaudit  449 +#define TARGET_FREEBSD_NR_setaudit  450 +#define TARGET_FREEBSD_NR_getaudit_addr 451 +#define TARGET_FREEBSD_NR_setaudit_addr 452 +#define TARGET_FREEBSD_NR_auditctl  453 +#define TARGET_FREEBSD_NR__umtx_op  454 +#define TARGET_FREEBSD_NR_thr_new   455 +#define TARGET_FREEBSD_NR_sigqueue  456 +#define TARGET_FREEBSD_NR_kmq_open  457 +#define TARGET_FREEBSD_NR_kmq_setattr   458 +#define TARGET_FREEBSD_NR_kmq_timedreceive  459 +#define TARGET_FREEBSD_NR_kmq_timedsend 460 +#define TARGET_FREEBSD_NR_kmq_notify    461 +#define TARGET_FREEBSD_NR_kmq_unlink    462 +#define TARGET_FREEBSD_NR_abort2    463 +#define TARGET_FREEBSD_NR_thr_set_name  464 +#define TARGET_FREEBSD_NR_aio_fsync 465 +#define TARGET_FREEBSD_NR_rtprio_thread 466 +#define TARGET_FREEBSD_NR_sctp_peeloff  471 +#define TARGET_FREEBSD_NR_sctp_generic_sendmsg  472 +#define TARGET_FREEBSD_NR_sctp_generic_sendmsg_iov  473 +#define TARGET_FREEBSD_NR_sctp_generic_recvmsg  474 +#define TARGET_FREEBSD_NR_pread 475 +#define TARGET_FREEBSD_NR_pwrite    476 +#define TARGET_FREEBSD_NR_mmap  477 +#define TARGET_FREEBSD_NR_lseek 478 +#define TARGET_FREEBSD_NR_truncate  479 +#define TARGET_FREEBSD_NR_ftruncate 480 +#define TARGET_FREEBSD_NR_thr_kill2 481 +#define TARGET_FREEBSD_NR_shm_open  482 +#define TARGET_FREEBSD_NR_shm_unlink    483 +#define TARGET_FREEBSD_NR_cpuset    484 +#define TARGET_FREEBSD_NR_cpuset_setid  485 +#define TARGET_FREEBSD_NR_cpuset_getid  486 +#define TARGET_FREEBSD_NR_cpuset_getaffinity    487 +#define TARGET_FREEBSD_NR_cpuset_setaffinity    488 +#define TARGET_FREEBSD_NR_faccessat 489 +#define TARGET_FREEBSD_NR_fchmodat  490 +#define TARGET_FREEBSD_NR_fchownat  491 +#define TARGET_FREEBSD_NR_fexecve   492 +#define TARGET_FREEBSD_NR_fstatat   493 +#define TARGET_FREEBSD_NR_futimesat 494 +#define TARGET_FREEBSD_NR_linkat    495 +#define TARGET_FREEBSD_NR_mkdirat   496 +#define TARGET_FREEBSD_NR_mkfifoat  497 +#define TARGET_FREEBSD_NR_mknodat   498 +#define TARGET_FREEBSD_NR_openat    499 +#define TARGET_FREEBSD_NR_readlinkat    500 +#define TARGET_FREEBSD_NR_renameat  501 +#define TARGET_FREEBSD_NR_symlinkat 502 +#define TARGET_FREEBSD_NR_unlinkat  503 +#define TARGET_FREEBSD_NR_posix_openpt  504 +#define TARGET_FREEBSD_NR_gssd_syscall  505 +#define TARGET_FREEBSD_NR_jail_get  506 +#define TARGET_FREEBSD_NR_jail_set  507 +#define TARGET_FREEBSD_NR_jail_remove   508 +#define TARGET_FREEBSD_NR_closefrom 509 +#define TARGET_FREEBSD_NR___semctl  510 +#define TARGET_FREEBSD_NR_msgctl    511 +#define TARGET_FREEBSD_NR_shmctl    512 +#define TARGET_FREEBSD_NR_lpathconf 513 +#define TARGET_FREEBSD_NR_cap_new   514 +#define TARGET_FREEBSD_NR_cap_getrights 515 +#define TARGET_FREEBSD_NR_cap_enter 516 +#define TARGET_FREEBSD_NR_cap_getmode   517 +#define TARGET_FREEBSD_NR_pdfork    518 +#define TARGET_FREEBSD_NR_pdkill    519 +#define TARGET_FREEBSD_NR_pdgetpid  520 +#define TARGET_FREEBSD_NR_pselect   522 +#define TARGET_FREEBSD_NR_getloginclass 523 +#define TARGET_FREEBSD_NR_setloginclass 524 +#define TARGET_FREEBSD_NR_rctl_get_racct    525 +#define TARGET_FREEBSD_NR_rctl_get_rules    526 +#define TARGET_FREEBSD_NR_rctl_get_limits   527 +#define TARGET_FREEBSD_NR_rctl_add_rule 528 +#define TARGET_FREEBSD_NR_rctl_remove_rule  529 +#define TARGET_FREEBSD_NR_posix_fallocate   530 +#define TARGET_FREEBSD_NR_posix_fadvise 531 +#define TARGET_FREEBSD_NR_MAXSYSCALL    532 diff --git a/bsd-user/i386/syscall.h b/bsd-user/i386/syscall.h new file mode 100644 index 00000000..9b34c61b --- /dev/null +++ b/bsd-user/i386/syscall.h @@ -0,0 +1,161 @@ +/* default linux values for the selectors */ +#define __USER_CS	(0x23) +#define __USER_DS	(0x2B) + +struct target_pt_regs { +	long ebx; +	long ecx; +	long edx; +	long esi; +	long edi; +	long ebp; +	long eax; +	int  xds; +	int  xes; +	long orig_eax; +	long eip; +	int  xcs; +	long eflags; +	long esp; +	int  xss; +}; + +/* ioctls */ + +#define TARGET_LDT_ENTRIES      8192 +#define TARGET_LDT_ENTRY_SIZE	8 + +#define TARGET_GDT_ENTRIES             9 +#define TARGET_GDT_ENTRY_TLS_ENTRIES   3 +#define TARGET_GDT_ENTRY_TLS_MIN       6 +#define TARGET_GDT_ENTRY_TLS_MAX       (TARGET_GDT_ENTRY_TLS_MIN + TARGET_GDT_ENTRY_TLS_ENTRIES - 1) + +struct target_modify_ldt_ldt_s { +    unsigned int  entry_number; +    abi_ulong base_addr; +    unsigned int limit; +    unsigned int flags; +}; + +/* vm86 defines */ + +#define TARGET_BIOSSEG		0x0f000 + +#define TARGET_CPU_086		0 +#define TARGET_CPU_186		1 +#define TARGET_CPU_286		2 +#define TARGET_CPU_386		3 +#define TARGET_CPU_486		4 +#define TARGET_CPU_586		5 + +#define TARGET_VM86_SIGNAL	0	/* return due to signal */ +#define TARGET_VM86_UNKNOWN	1	/* unhandled GP fault - IO-instruction or similar */ +#define TARGET_VM86_INTx	2	/* int3/int x instruction (ARG = x) */ +#define TARGET_VM86_STI	3	/* sti/popf/iret instruction enabled virtual interrupts */ + +/* + * Additional return values when invoking new vm86() + */ +#define TARGET_VM86_PICRETURN	4	/* return due to pending PIC request */ +#define TARGET_VM86_TRAP	6	/* return due to DOS-debugger request */ + +/* + * function codes when invoking new vm86() + */ +#define TARGET_VM86_PLUS_INSTALL_CHECK	0 +#define TARGET_VM86_ENTER		1 +#define TARGET_VM86_ENTER_NO_BYPASS	2 +#define	TARGET_VM86_REQUEST_IRQ	3 +#define TARGET_VM86_FREE_IRQ		4 +#define TARGET_VM86_GET_IRQ_BITS	5 +#define TARGET_VM86_GET_AND_RESET_IRQ	6 + +/* + * This is the stack-layout seen by the user space program when we have + * done a translation of "SAVE_ALL" from vm86 mode. The real kernel layout + * is 'kernel_vm86_regs' (see below). + */ + +struct target_vm86_regs { +/* + * normal regs, with special meaning for the segment descriptors.. + */ +	abi_long ebx; +	abi_long ecx; +	abi_long edx; +	abi_long esi; +	abi_long edi; +	abi_long ebp; +	abi_long eax; +	abi_long __null_ds; +	abi_long __null_es; +	abi_long __null_fs; +	abi_long __null_gs; +	abi_long orig_eax; +	abi_long eip; +	unsigned short cs, __csh; +	abi_long eflags; +	abi_long esp; +	unsigned short ss, __ssh; +/* + * these are specific to v86 mode: + */ +	unsigned short es, __esh; +	unsigned short ds, __dsh; +	unsigned short fs, __fsh; +	unsigned short gs, __gsh; +}; + +struct target_revectored_struct { +	abi_ulong __map[8];			/* 256 bits */ +}; + +struct target_vm86_struct { +	struct target_vm86_regs regs; +	abi_ulong flags; +	abi_ulong screen_bitmap; +	abi_ulong cpu_type; +	struct target_revectored_struct int_revectored; +	struct target_revectored_struct int21_revectored; +}; + +/* + * flags masks + */ +#define TARGET_VM86_SCREEN_BITMAP	0x0001 + +struct target_vm86plus_info_struct { +        abi_ulong flags; +#define TARGET_force_return_for_pic (1 << 0) +#define TARGET_vm86dbg_active       (1 << 1)  /* for debugger */ +#define TARGET_vm86dbg_TFpendig     (1 << 2)  /* for debugger */ +#define TARGET_is_vm86pus           (1 << 31) /* for vm86 internal use */ +	unsigned char vm86dbg_intxxtab[32];   /* for debugger */ +}; + +struct target_vm86plus_struct { +	struct target_vm86_regs regs; +	abi_ulong flags; +	abi_ulong screen_bitmap; +	abi_ulong cpu_type; +	struct target_revectored_struct int_revectored; +	struct target_revectored_struct int21_revectored; +	struct target_vm86plus_info_struct vm86plus; +}; + +/* FreeBSD sysarch(2) */ +#define TARGET_FREEBSD_I386_GET_LDT	0 +#define TARGET_FREEBSD_I386_SET_LDT	1 +				/* I386_IOPL */ +#define TARGET_FREEBSD_I386_GET_IOPERM	3 +#define TARGET_FREEBSD_I386_SET_IOPERM	4 +				/* xxxxx */ +#define TARGET_FREEBSD_I386_VM86	6 +#define TARGET_FREEBSD_I386_GET_FSBASE	7 +#define TARGET_FREEBSD_I386_SET_FSBASE	8 +#define TARGET_FREEBSD_I386_GET_GSBASE	9 +#define TARGET_FREEBSD_I386_SET_GSBASE	10 + + +#define UNAME_MACHINE "i386" + diff --git a/bsd-user/i386/target_signal.h b/bsd-user/i386/target_signal.h new file mode 100644 index 00000000..2ef36d1f --- /dev/null +++ b/bsd-user/i386/target_signal.h @@ -0,0 +1,20 @@ +#ifndef TARGET_SIGNAL_H +#define TARGET_SIGNAL_H + +#include "cpu.h" + +/* this struct defines a stack used during syscall handling */ + +typedef struct target_sigaltstack { +	abi_ulong ss_sp; +	abi_long ss_flags; +	abi_ulong ss_size; +} target_stack_t; + + +static inline abi_ulong get_sp_from_cpustate(CPUX86State *state) +{ +    return state->regs[R_ESP]; +} + +#endif /* TARGET_SIGNAL_H */ diff --git a/bsd-user/main.c b/bsd-user/main.c new file mode 100644 index 00000000..ee68daa3 --- /dev/null +++ b/bsd-user/main.c @@ -0,0 +1,1139 @@ +/* + *  qemu user main + * + *  Copyright (c) 2003-2008 Fabrice Bellard + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program; if not, see <http://www.gnu.org/licenses/>. + */ +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <machine/trap.h> +#include <sys/types.h> +#include <sys/mman.h> + +#include "qemu.h" +#include "qemu-common.h" +/* For tb_lock */ +#include "cpu.h" +#include "tcg.h" +#include "qemu/timer.h" +#include "qemu/envlist.h" + +int singlestep; +#if defined(CONFIG_USE_GUEST_BASE) +unsigned long mmap_min_addr; +unsigned long guest_base; +int have_guest_base; +unsigned long reserved_va; +#endif + +static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX; +const char *qemu_uname_release; +extern char **environ; +enum BSDType bsd_type; + +/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so +   we allocate a bigger stack. Need a better solution, for example +   by remapping the process stack directly at the right place */ +unsigned long x86_stack_size = 512 * 1024; + +void gemu_log(const char *fmt, ...) +{ +    va_list ap; + +    va_start(ap, fmt); +    vfprintf(stderr, fmt, ap); +    va_end(ap); +} + +#if defined(TARGET_I386) +int cpu_get_pic_interrupt(CPUX86State *env) +{ +    return -1; +} +#endif + +/* These are no-ops because we are not threadsafe.  */ +static inline void cpu_exec_start(CPUArchState *env) +{ +} + +static inline void cpu_exec_end(CPUArchState *env) +{ +} + +static inline void start_exclusive(void) +{ +} + +static inline void end_exclusive(void) +{ +} + +void fork_start(void) +{ +} + +void fork_end(int child) +{ +    if (child) { +        gdbserver_fork(thread_cpu); +    } +} + +void cpu_list_lock(void) +{ +} + +void cpu_list_unlock(void) +{ +} + +#ifdef TARGET_I386 +/***********************************************************/ +/* CPUX86 core interface */ + +uint64_t cpu_get_tsc(CPUX86State *env) +{ +    return cpu_get_real_ticks(); +} + +static void write_dt(void *ptr, unsigned long addr, unsigned long limit, +                     int flags) +{ +    unsigned int e1, e2; +    uint32_t *p; +    e1 = (addr << 16) | (limit & 0xffff); +    e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000); +    e2 |= flags; +    p = ptr; +    p[0] = tswap32(e1); +    p[1] = tswap32(e2); +} + +static uint64_t *idt_table; +#ifdef TARGET_X86_64 +static void set_gate64(void *ptr, unsigned int type, unsigned int dpl, +                       uint64_t addr, unsigned int sel) +{ +    uint32_t *p, e1, e2; +    e1 = (addr & 0xffff) | (sel << 16); +    e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8); +    p = ptr; +    p[0] = tswap32(e1); +    p[1] = tswap32(e2); +    p[2] = tswap32(addr >> 32); +    p[3] = 0; +} +/* only dpl matters as we do only user space emulation */ +static void set_idt(int n, unsigned int dpl) +{ +    set_gate64(idt_table + n * 2, 0, dpl, 0, 0); +} +#else +static void set_gate(void *ptr, unsigned int type, unsigned int dpl, +                     uint32_t addr, unsigned int sel) +{ +    uint32_t *p, e1, e2; +    e1 = (addr & 0xffff) | (sel << 16); +    e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8); +    p = ptr; +    p[0] = tswap32(e1); +    p[1] = tswap32(e2); +} + +/* only dpl matters as we do only user space emulation */ +static void set_idt(int n, unsigned int dpl) +{ +    set_gate(idt_table + n, 0, dpl, 0, 0); +} +#endif + +void cpu_loop(CPUX86State *env) +{ +    X86CPU *cpu = x86_env_get_cpu(env); +    CPUState *cs = CPU(cpu); +    int trapnr; +    abi_ulong pc; +    //target_siginfo_t info; + +    for(;;) { +        trapnr = cpu_x86_exec(cs); +        switch(trapnr) { +        case 0x80: +            /* syscall from int $0x80 */ +            if (bsd_type == target_freebsd) { +                abi_ulong params = (abi_ulong) env->regs[R_ESP] + +                    sizeof(int32_t); +                int32_t syscall_nr = env->regs[R_EAX]; +                int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8; + +                if (syscall_nr == TARGET_FREEBSD_NR_syscall) { +                    get_user_s32(syscall_nr, params); +                    params += sizeof(int32_t); +                } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) { +                    get_user_s32(syscall_nr, params); +                    params += sizeof(int64_t); +                } +                get_user_s32(arg1, params); +                params += sizeof(int32_t); +                get_user_s32(arg2, params); +                params += sizeof(int32_t); +                get_user_s32(arg3, params); +                params += sizeof(int32_t); +                get_user_s32(arg4, params); +                params += sizeof(int32_t); +                get_user_s32(arg5, params); +                params += sizeof(int32_t); +                get_user_s32(arg6, params); +                params += sizeof(int32_t); +                get_user_s32(arg7, params); +                params += sizeof(int32_t); +                get_user_s32(arg8, params); +                env->regs[R_EAX] = do_freebsd_syscall(env, +                                                      syscall_nr, +                                                      arg1, +                                                      arg2, +                                                      arg3, +                                                      arg4, +                                                      arg5, +                                                      arg6, +                                                      arg7, +                                                      arg8); +            } else { //if (bsd_type == target_openbsd) +                env->regs[R_EAX] = do_openbsd_syscall(env, +                                                      env->regs[R_EAX], +                                                      env->regs[R_EBX], +                                                      env->regs[R_ECX], +                                                      env->regs[R_EDX], +                                                      env->regs[R_ESI], +                                                      env->regs[R_EDI], +                                                      env->regs[R_EBP]); +            } +            if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) { +                env->regs[R_EAX] = -env->regs[R_EAX]; +                env->eflags |= CC_C; +            } else { +                env->eflags &= ~CC_C; +            } +            break; +#ifndef TARGET_ABI32 +        case EXCP_SYSCALL: +            /* syscall from syscall instruction */ +            if (bsd_type == target_freebsd) +                env->regs[R_EAX] = do_freebsd_syscall(env, +                                                      env->regs[R_EAX], +                                                      env->regs[R_EDI], +                                                      env->regs[R_ESI], +                                                      env->regs[R_EDX], +                                                      env->regs[R_ECX], +                                                      env->regs[8], +                                                      env->regs[9], 0, 0); +            else { //if (bsd_type == target_openbsd) +                env->regs[R_EAX] = do_openbsd_syscall(env, +                                                      env->regs[R_EAX], +                                                      env->regs[R_EDI], +                                                      env->regs[R_ESI], +                                                      env->regs[R_EDX], +                                                      env->regs[10], +                                                      env->regs[8], +                                                      env->regs[9]); +            } +            env->eip = env->exception_next_eip; +            if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) { +                env->regs[R_EAX] = -env->regs[R_EAX]; +                env->eflags |= CC_C; +            } else { +                env->eflags &= ~CC_C; +            } +            break; +#endif +#if 0 +        case EXCP0B_NOSEG: +        case EXCP0C_STACK: +            info.si_signo = SIGBUS; +            info.si_errno = 0; +            info.si_code = TARGET_SI_KERNEL; +            info._sifields._sigfault._addr = 0; +            queue_signal(env, info.si_signo, &info); +            break; +        case EXCP0D_GPF: +            /* XXX: potential problem if ABI32 */ +#ifndef TARGET_X86_64 +            if (env->eflags & VM_MASK) { +                handle_vm86_fault(env); +            } else +#endif +            { +                info.si_signo = SIGSEGV; +                info.si_errno = 0; +                info.si_code = TARGET_SI_KERNEL; +                info._sifields._sigfault._addr = 0; +                queue_signal(env, info.si_signo, &info); +            } +            break; +        case EXCP0E_PAGE: +            info.si_signo = SIGSEGV; +            info.si_errno = 0; +            if (!(env->error_code & 1)) +                info.si_code = TARGET_SEGV_MAPERR; +            else +                info.si_code = TARGET_SEGV_ACCERR; +            info._sifields._sigfault._addr = env->cr[2]; +            queue_signal(env, info.si_signo, &info); +            break; +        case EXCP00_DIVZ: +#ifndef TARGET_X86_64 +            if (env->eflags & VM_MASK) { +                handle_vm86_trap(env, trapnr); +            } else +#endif +            { +                /* division by zero */ +                info.si_signo = SIGFPE; +                info.si_errno = 0; +                info.si_code = TARGET_FPE_INTDIV; +                info._sifields._sigfault._addr = env->eip; +                queue_signal(env, info.si_signo, &info); +            } +            break; +        case EXCP01_DB: +        case EXCP03_INT3: +#ifndef TARGET_X86_64 +            if (env->eflags & VM_MASK) { +                handle_vm86_trap(env, trapnr); +            } else +#endif +            { +                info.si_signo = SIGTRAP; +                info.si_errno = 0; +                if (trapnr == EXCP01_DB) { +                    info.si_code = TARGET_TRAP_BRKPT; +                    info._sifields._sigfault._addr = env->eip; +                } else { +                    info.si_code = TARGET_SI_KERNEL; +                    info._sifields._sigfault._addr = 0; +                } +                queue_signal(env, info.si_signo, &info); +            } +            break; +        case EXCP04_INTO: +        case EXCP05_BOUND: +#ifndef TARGET_X86_64 +            if (env->eflags & VM_MASK) { +                handle_vm86_trap(env, trapnr); +            } else +#endif +            { +                info.si_signo = SIGSEGV; +                info.si_errno = 0; +                info.si_code = TARGET_SI_KERNEL; +                info._sifields._sigfault._addr = 0; +                queue_signal(env, info.si_signo, &info); +            } +            break; +        case EXCP06_ILLOP: +            info.si_signo = SIGILL; +            info.si_errno = 0; +            info.si_code = TARGET_ILL_ILLOPN; +            info._sifields._sigfault._addr = env->eip; +            queue_signal(env, info.si_signo, &info); +            break; +#endif +        case EXCP_INTERRUPT: +            /* just indicate that signals should be handled asap */ +            break; +#if 0 +        case EXCP_DEBUG: +            { +                int sig; + +                sig = gdb_handlesig (env, TARGET_SIGTRAP); +                if (sig) +                  { +                    info.si_signo = sig; +                    info.si_errno = 0; +                    info.si_code = TARGET_TRAP_BRKPT; +                    queue_signal(env, info.si_signo, &info); +                  } +            } +            break; +#endif +        default: +            pc = env->segs[R_CS].base + env->eip; +            fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n", +                    (long)pc, trapnr); +            abort(); +        } +        process_pending_signals(env); +    } +} +#endif + +#ifdef TARGET_SPARC +#define SPARC64_STACK_BIAS 2047 + +//#define DEBUG_WIN +/* WARNING: dealing with register windows _is_ complicated. More info +   can be found at http://www.sics.se/~psm/sparcstack.html */ +static inline int get_reg_index(CPUSPARCState *env, int cwp, int index) +{ +    index = (index + cwp * 16) % (16 * env->nwindows); +    /* wrap handling : if cwp is on the last window, then we use the +       registers 'after' the end */ +    if (index < 8 && env->cwp == env->nwindows - 1) +        index += 16 * env->nwindows; +    return index; +} + +/* save the register window 'cwp1' */ +static inline void save_window_offset(CPUSPARCState *env, int cwp1) +{ +    unsigned int i; +    abi_ulong sp_ptr; + +    sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)]; +#ifdef TARGET_SPARC64 +    if (sp_ptr & 3) +        sp_ptr += SPARC64_STACK_BIAS; +#endif +#if defined(DEBUG_WIN) +    printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n", +           sp_ptr, cwp1); +#endif +    for(i = 0; i < 16; i++) { +        /* FIXME - what to do if put_user() fails? */ +        put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr); +        sp_ptr += sizeof(abi_ulong); +    } +} + +static void save_window(CPUSPARCState *env) +{ +#ifndef TARGET_SPARC64 +    unsigned int new_wim; +    new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) & +        ((1LL << env->nwindows) - 1); +    save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2)); +    env->wim = new_wim; +#else +    save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2)); +    env->cansave++; +    env->canrestore--; +#endif +} + +static void restore_window(CPUSPARCState *env) +{ +#ifndef TARGET_SPARC64 +    unsigned int new_wim; +#endif +    unsigned int i, cwp1; +    abi_ulong sp_ptr; + +#ifndef TARGET_SPARC64 +    new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) & +        ((1LL << env->nwindows) - 1); +#endif + +    /* restore the invalid window */ +    cwp1 = cpu_cwp_inc(env, env->cwp + 1); +    sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)]; +#ifdef TARGET_SPARC64 +    if (sp_ptr & 3) +        sp_ptr += SPARC64_STACK_BIAS; +#endif +#if defined(DEBUG_WIN) +    printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n", +           sp_ptr, cwp1); +#endif +    for(i = 0; i < 16; i++) { +        /* FIXME - what to do if get_user() fails? */ +        get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr); +        sp_ptr += sizeof(abi_ulong); +    } +#ifdef TARGET_SPARC64 +    env->canrestore++; +    if (env->cleanwin < env->nwindows - 1) +        env->cleanwin++; +    env->cansave--; +#else +    env->wim = new_wim; +#endif +} + +static void flush_windows(CPUSPARCState *env) +{ +    int offset, cwp1; + +    offset = 1; +    for(;;) { +        /* if restore would invoke restore_window(), then we can stop */ +        cwp1 = cpu_cwp_inc(env, env->cwp + offset); +#ifndef TARGET_SPARC64 +        if (env->wim & (1 << cwp1)) +            break; +#else +        if (env->canrestore == 0) +            break; +        env->cansave++; +        env->canrestore--; +#endif +        save_window_offset(env, cwp1); +        offset++; +    } +    cwp1 = cpu_cwp_inc(env, env->cwp + 1); +#ifndef TARGET_SPARC64 +    /* set wim so that restore will reload the registers */ +    env->wim = 1 << cwp1; +#endif +#if defined(DEBUG_WIN) +    printf("flush_windows: nb=%d\n", offset - 1); +#endif +} + +void cpu_loop(CPUSPARCState *env) +{ +    CPUState *cs = CPU(sparc_env_get_cpu(env)); +    int trapnr, ret, syscall_nr; +    //target_siginfo_t info; + +    while (1) { +        trapnr = cpu_sparc_exec(cs); + +        switch (trapnr) { +#ifndef TARGET_SPARC64 +        case 0x80: +#else +        /* FreeBSD uses 0x141 for syscalls too */ +        case 0x141: +            if (bsd_type != target_freebsd) +                goto badtrap; +        case 0x100: +#endif +            syscall_nr = env->gregs[1]; +            if (bsd_type == target_freebsd) +                ret = do_freebsd_syscall(env, syscall_nr, +                                         env->regwptr[0], env->regwptr[1], +                                         env->regwptr[2], env->regwptr[3], +                                         env->regwptr[4], env->regwptr[5], 0, 0); +            else if (bsd_type == target_netbsd) +                ret = do_netbsd_syscall(env, syscall_nr, +                                        env->regwptr[0], env->regwptr[1], +                                        env->regwptr[2], env->regwptr[3], +                                        env->regwptr[4], env->regwptr[5]); +            else { //if (bsd_type == target_openbsd) +#if defined(TARGET_SPARC64) +                syscall_nr &= ~(TARGET_OPENBSD_SYSCALL_G7RFLAG | +                                TARGET_OPENBSD_SYSCALL_G2RFLAG); +#endif +                ret = do_openbsd_syscall(env, syscall_nr, +                                         env->regwptr[0], env->regwptr[1], +                                         env->regwptr[2], env->regwptr[3], +                                         env->regwptr[4], env->regwptr[5]); +            } +            if ((unsigned int)ret >= (unsigned int)(-515)) { +                ret = -ret; +#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) +                env->xcc |= PSR_CARRY; +#else +                env->psr |= PSR_CARRY; +#endif +            } else { +#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) +                env->xcc &= ~PSR_CARRY; +#else +                env->psr &= ~PSR_CARRY; +#endif +            } +            env->regwptr[0] = ret; +            /* next instruction */ +#if defined(TARGET_SPARC64) +            if (bsd_type == target_openbsd && +                env->gregs[1] & TARGET_OPENBSD_SYSCALL_G2RFLAG) { +                env->pc = env->gregs[2]; +                env->npc = env->pc + 4; +            } else if (bsd_type == target_openbsd && +                       env->gregs[1] & TARGET_OPENBSD_SYSCALL_G7RFLAG) { +                env->pc = env->gregs[7]; +                env->npc = env->pc + 4; +            } else { +                env->pc = env->npc; +                env->npc = env->npc + 4; +            } +#else +            env->pc = env->npc; +            env->npc = env->npc + 4; +#endif +            break; +        case 0x83: /* flush windows */ +#ifdef TARGET_ABI32 +        case 0x103: +#endif +            flush_windows(env); +            /* next instruction */ +            env->pc = env->npc; +            env->npc = env->npc + 4; +            break; +#ifndef TARGET_SPARC64 +        case TT_WIN_OVF: /* window overflow */ +            save_window(env); +            break; +        case TT_WIN_UNF: /* window underflow */ +            restore_window(env); +            break; +        case TT_TFAULT: +        case TT_DFAULT: +#if 0 +            { +                info.si_signo = SIGSEGV; +                info.si_errno = 0; +                /* XXX: check env->error_code */ +                info.si_code = TARGET_SEGV_MAPERR; +                info._sifields._sigfault._addr = env->mmuregs[4]; +                queue_signal(env, info.si_signo, &info); +            } +#endif +            break; +#else +        case TT_SPILL: /* window overflow */ +            save_window(env); +            break; +        case TT_FILL: /* window underflow */ +            restore_window(env); +            break; +        case TT_TFAULT: +        case TT_DFAULT: +#if 0 +            { +                info.si_signo = SIGSEGV; +                info.si_errno = 0; +                /* XXX: check env->error_code */ +                info.si_code = TARGET_SEGV_MAPERR; +                if (trapnr == TT_DFAULT) +                    info._sifields._sigfault._addr = env->dmmuregs[4]; +                else +                    info._sifields._sigfault._addr = env->tsptr->tpc; +                //queue_signal(env, info.si_signo, &info); +            } +#endif +            break; +#endif +        case EXCP_INTERRUPT: +            /* just indicate that signals should be handled asap */ +            break; +        case EXCP_DEBUG: +            { +                int sig; + +                sig = gdb_handlesig(cs, TARGET_SIGTRAP); +#if 0 +                if (sig) +                  { +                    info.si_signo = sig; +                    info.si_errno = 0; +                    info.si_code = TARGET_TRAP_BRKPT; +                    //queue_signal(env, info.si_signo, &info); +                  } +#endif +            } +            break; +        default: +#ifdef TARGET_SPARC64 +        badtrap: +#endif +            printf ("Unhandled trap: 0x%x\n", trapnr); +            cpu_dump_state(cs, stderr, fprintf, 0); +            exit (1); +        } +        process_pending_signals (env); +    } +} + +#endif + +static void usage(void) +{ +    printf("qemu-" TARGET_NAME " version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n" +           "usage: qemu-" TARGET_NAME " [options] program [arguments...]\n" +           "BSD CPU emulator (compiled for %s emulation)\n" +           "\n" +           "Standard options:\n" +           "-h                print this help\n" +           "-g port           wait gdb connection to port\n" +           "-L path           set the elf interpreter prefix (default=%s)\n" +           "-s size           set the stack size in bytes (default=%ld)\n" +           "-cpu model        select CPU (-cpu help for list)\n" +           "-drop-ld-preload  drop LD_PRELOAD for target process\n" +           "-E var=value      sets/modifies targets environment variable(s)\n" +           "-U var            unsets targets environment variable(s)\n" +#if defined(CONFIG_USE_GUEST_BASE) +           "-B address        set guest_base address to address\n" +#endif +           "-bsd type         select emulated BSD type FreeBSD/NetBSD/OpenBSD (default)\n" +           "\n" +           "Debug options:\n" +           "-d item1[,...]    enable logging of specified items\n" +           "                  (use '-d help' for a list of log items)\n" +           "-D logfile        write logs to 'logfile' (default stderr)\n" +           "-p pagesize       set the host page size to 'pagesize'\n" +           "-singlestep       always run in singlestep mode\n" +           "-strace           log system calls\n" +           "\n" +           "Environment variables:\n" +           "QEMU_STRACE       Print system calls and arguments similar to the\n" +           "                  'strace' program.  Enable by setting to any value.\n" +           "You can use -E and -U options to set/unset environment variables\n" +           "for target process.  It is possible to provide several variables\n" +           "by repeating the option.  For example:\n" +           "    -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n" +           "Note that if you provide several changes to single variable\n" +           "last change will stay in effect.\n" +           , +           TARGET_NAME, +           interp_prefix, +           x86_stack_size); +    exit(1); +} + +THREAD CPUState *thread_cpu; + +/* Assumes contents are already zeroed.  */ +void init_task_state(TaskState *ts) +{ +    int i; + +    ts->used = 1; +    ts->first_free = ts->sigqueue_table; +    for (i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) { +        ts->sigqueue_table[i].next = &ts->sigqueue_table[i + 1]; +    } +    ts->sigqueue_table[i].next = NULL; +} + +int main(int argc, char **argv) +{ +    const char *filename; +    const char *cpu_model; +    const char *log_file = NULL; +    const char *log_mask = NULL; +    struct target_pt_regs regs1, *regs = ®s1; +    struct image_info info1, *info = &info1; +    TaskState ts1, *ts = &ts1; +    CPUArchState *env; +    CPUState *cpu; +    int optind; +    const char *r; +    int gdbstub_port = 0; +    char **target_environ, **wrk; +    envlist_t *envlist = NULL; +    bsd_type = target_openbsd; + +    if (argc <= 1) +        usage(); + +    module_call_init(MODULE_INIT_QOM); + +    if ((envlist = envlist_create()) == NULL) { +        (void) fprintf(stderr, "Unable to allocate envlist\n"); +        exit(1); +    } + +    /* add current environment into the list */ +    for (wrk = environ; *wrk != NULL; wrk++) { +        (void) envlist_setenv(envlist, *wrk); +    } + +    cpu_model = NULL; +#if defined(cpudef_setup) +    cpudef_setup(); /* parse cpu definitions in target config file (TBD) */ +#endif + +    optind = 1; +    for(;;) { +        if (optind >= argc) +            break; +        r = argv[optind]; +        if (r[0] != '-') +            break; +        optind++; +        r++; +        if (!strcmp(r, "-")) { +            break; +        } else if (!strcmp(r, "d")) { +            if (optind >= argc) { +                break; +            } +            log_mask = argv[optind++]; +        } else if (!strcmp(r, "D")) { +            if (optind >= argc) { +                break; +            } +            log_file = argv[optind++]; +        } else if (!strcmp(r, "E")) { +            r = argv[optind++]; +            if (envlist_setenv(envlist, r) != 0) +                usage(); +        } else if (!strcmp(r, "ignore-environment")) { +            envlist_free(envlist); +            if ((envlist = envlist_create()) == NULL) { +                (void) fprintf(stderr, "Unable to allocate envlist\n"); +                exit(1); +            } +        } else if (!strcmp(r, "U")) { +            r = argv[optind++]; +            if (envlist_unsetenv(envlist, r) != 0) +                usage(); +        } else if (!strcmp(r, "s")) { +            r = argv[optind++]; +            x86_stack_size = strtol(r, (char **)&r, 0); +            if (x86_stack_size <= 0) +                usage(); +            if (*r == 'M') +                x86_stack_size *= 1024 * 1024; +            else if (*r == 'k' || *r == 'K') +                x86_stack_size *= 1024; +        } else if (!strcmp(r, "L")) { +            interp_prefix = argv[optind++]; +        } else if (!strcmp(r, "p")) { +            qemu_host_page_size = atoi(argv[optind++]); +            if (qemu_host_page_size == 0 || +                (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) { +                fprintf(stderr, "page size must be a power of two\n"); +                exit(1); +            } +        } else if (!strcmp(r, "g")) { +            gdbstub_port = atoi(argv[optind++]); +        } else if (!strcmp(r, "r")) { +            qemu_uname_release = argv[optind++]; +        } else if (!strcmp(r, "cpu")) { +            cpu_model = argv[optind++]; +            if (is_help_option(cpu_model)) { +/* XXX: implement xxx_cpu_list for targets that still miss it */ +#if defined(cpu_list) +                    cpu_list(stdout, &fprintf); +#endif +                exit(1); +            } +#if defined(CONFIG_USE_GUEST_BASE) +        } else if (!strcmp(r, "B")) { +           guest_base = strtol(argv[optind++], NULL, 0); +           have_guest_base = 1; +#endif +        } else if (!strcmp(r, "drop-ld-preload")) { +            (void) envlist_unsetenv(envlist, "LD_PRELOAD"); +        } else if (!strcmp(r, "bsd")) { +            if (!strcasecmp(argv[optind], "freebsd")) { +                bsd_type = target_freebsd; +            } else if (!strcasecmp(argv[optind], "netbsd")) { +                bsd_type = target_netbsd; +            } else if (!strcasecmp(argv[optind], "openbsd")) { +                bsd_type = target_openbsd; +            } else { +                usage(); +            } +            optind++; +        } else if (!strcmp(r, "singlestep")) { +            singlestep = 1; +        } else if (!strcmp(r, "strace")) { +            do_strace = 1; +        } else +        { +            usage(); +        } +    } + +    /* init debug */ +    qemu_set_log_filename(log_file); +    if (log_mask) { +        int mask; + +        mask = qemu_str_to_log_mask(log_mask); +        if (!mask) { +            qemu_print_log_usage(stdout); +            exit(1); +        } +        qemu_set_log(mask); +    } + +    if (optind >= argc) { +        usage(); +    } +    filename = argv[optind]; + +    /* Zero out regs */ +    memset(regs, 0, sizeof(struct target_pt_regs)); + +    /* Zero out image_info */ +    memset(info, 0, sizeof(struct image_info)); + +    /* Scan interp_prefix dir for replacement files. */ +    init_paths(interp_prefix); + +    if (cpu_model == NULL) { +#if defined(TARGET_I386) +#ifdef TARGET_X86_64 +        cpu_model = "qemu64"; +#else +        cpu_model = "qemu32"; +#endif +#elif defined(TARGET_SPARC) +#ifdef TARGET_SPARC64 +        cpu_model = "TI UltraSparc II"; +#else +        cpu_model = "Fujitsu MB86904"; +#endif +#else +        cpu_model = "any"; +#endif +    } +    tcg_exec_init(0); +    /* NOTE: we need to init the CPU at this stage to get +       qemu_host_page_size */ +    cpu = cpu_init(cpu_model); +    if (!cpu) { +        fprintf(stderr, "Unable to find CPU definition\n"); +        exit(1); +    } +    env = cpu->env_ptr; +#if defined(TARGET_SPARC) || defined(TARGET_PPC) +    cpu_reset(cpu); +#endif +    thread_cpu = cpu; + +    if (getenv("QEMU_STRACE")) { +        do_strace = 1; +    } + +    target_environ = envlist_to_environ(envlist, NULL); +    envlist_free(envlist); + +#if defined(CONFIG_USE_GUEST_BASE) +    /* +     * Now that page sizes are configured in cpu_init() we can do +     * proper page alignment for guest_base. +     */ +    guest_base = HOST_PAGE_ALIGN(guest_base); + +    /* +     * Read in mmap_min_addr kernel parameter.  This value is used +     * When loading the ELF image to determine whether guest_base +     * is needed. +     * +     * When user has explicitly set the quest base, we skip this +     * test. +     */ +    if (!have_guest_base) { +        FILE *fp; + +        if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) { +            unsigned long tmp; +            if (fscanf(fp, "%lu", &tmp) == 1) { +                mmap_min_addr = tmp; +                qemu_log("host mmap_min_addr=0x%lx\n", mmap_min_addr); +            } +            fclose(fp); +        } +    } +#endif /* CONFIG_USE_GUEST_BASE */ + +    if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) { +        printf("Error loading %s\n", filename); +        _exit(1); +    } + +    for (wrk = target_environ; *wrk; wrk++) { +        free(*wrk); +    } + +    free(target_environ); + +    if (qemu_log_enabled()) { +#if defined(CONFIG_USE_GUEST_BASE) +        qemu_log("guest_base  0x%lx\n", guest_base); +#endif +        log_page_dump(); + +        qemu_log("start_brk   0x" TARGET_ABI_FMT_lx "\n", info->start_brk); +        qemu_log("end_code    0x" TARGET_ABI_FMT_lx "\n", info->end_code); +        qemu_log("start_code  0x" TARGET_ABI_FMT_lx "\n", +                 info->start_code); +        qemu_log("start_data  0x" TARGET_ABI_FMT_lx "\n", +                 info->start_data); +        qemu_log("end_data    0x" TARGET_ABI_FMT_lx "\n", info->end_data); +        qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n", +                 info->start_stack); +        qemu_log("brk         0x" TARGET_ABI_FMT_lx "\n", info->brk); +        qemu_log("entry       0x" TARGET_ABI_FMT_lx "\n", info->entry); +    } + +    target_set_brk(info->brk); +    syscall_init(); +    signal_init(); + +#if defined(CONFIG_USE_GUEST_BASE) +    /* Now that we've loaded the binary, GUEST_BASE is fixed.  Delay +       generating the prologue until now so that the prologue can take +       the real value of GUEST_BASE into account.  */ +    tcg_prologue_init(&tcg_ctx); +#endif + +    /* build Task State */ +    memset(ts, 0, sizeof(TaskState)); +    init_task_state(ts); +    ts->info = info; +    cpu->opaque = ts; + +#if defined(TARGET_I386) +    env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK; +    env->hflags |= HF_PE_MASK | HF_CPL_MASK; +    if (env->features[FEAT_1_EDX] & CPUID_SSE) { +        env->cr[4] |= CR4_OSFXSR_MASK; +        env->hflags |= HF_OSFXSR_MASK; +    } +#ifndef TARGET_ABI32 +    /* enable 64 bit mode if possible */ +    if (!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) { +        fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n"); +        exit(1); +    } +    env->cr[4] |= CR4_PAE_MASK; +    env->efer |= MSR_EFER_LMA | MSR_EFER_LME; +    env->hflags |= HF_LMA_MASK; +#endif + +    /* flags setup : we activate the IRQs by default as in user mode */ +    env->eflags |= IF_MASK; + +    /* linux register setup */ +#ifndef TARGET_ABI32 +    env->regs[R_EAX] = regs->rax; +    env->regs[R_EBX] = regs->rbx; +    env->regs[R_ECX] = regs->rcx; +    env->regs[R_EDX] = regs->rdx; +    env->regs[R_ESI] = regs->rsi; +    env->regs[R_EDI] = regs->rdi; +    env->regs[R_EBP] = regs->rbp; +    env->regs[R_ESP] = regs->rsp; +    env->eip = regs->rip; +#else +    env->regs[R_EAX] = regs->eax; +    env->regs[R_EBX] = regs->ebx; +    env->regs[R_ECX] = regs->ecx; +    env->regs[R_EDX] = regs->edx; +    env->regs[R_ESI] = regs->esi; +    env->regs[R_EDI] = regs->edi; +    env->regs[R_EBP] = regs->ebp; +    env->regs[R_ESP] = regs->esp; +    env->eip = regs->eip; +#endif + +    /* linux interrupt setup */ +#ifndef TARGET_ABI32 +    env->idt.limit = 511; +#else +    env->idt.limit = 255; +#endif +    env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1), +                                PROT_READ|PROT_WRITE, +                                MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); +    idt_table = g2h(env->idt.base); +    set_idt(0, 0); +    set_idt(1, 0); +    set_idt(2, 0); +    set_idt(3, 3); +    set_idt(4, 3); +    set_idt(5, 0); +    set_idt(6, 0); +    set_idt(7, 0); +    set_idt(8, 0); +    set_idt(9, 0); +    set_idt(10, 0); +    set_idt(11, 0); +    set_idt(12, 0); +    set_idt(13, 0); +    set_idt(14, 0); +    set_idt(15, 0); +    set_idt(16, 0); +    set_idt(17, 0); +    set_idt(18, 0); +    set_idt(19, 0); +    set_idt(0x80, 3); + +    /* linux segment setup */ +    { +        uint64_t *gdt_table; +        env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES, +                                    PROT_READ|PROT_WRITE, +                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); +        env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1; +        gdt_table = g2h(env->gdt.base); +#ifdef TARGET_ABI32 +        write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff, +                 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | +                 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT)); +#else +        /* 64 bit code segment */ +        write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff, +                 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | +                 DESC_L_MASK | +                 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT)); +#endif +        write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff, +                 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | +                 (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT)); +    } + +    cpu_x86_load_seg(env, R_CS, __USER_CS); +    cpu_x86_load_seg(env, R_SS, __USER_DS); +#ifdef TARGET_ABI32 +    cpu_x86_load_seg(env, R_DS, __USER_DS); +    cpu_x86_load_seg(env, R_ES, __USER_DS); +    cpu_x86_load_seg(env, R_FS, __USER_DS); +    cpu_x86_load_seg(env, R_GS, __USER_DS); +    /* This hack makes Wine work... */ +    env->segs[R_FS].selector = 0; +#else +    cpu_x86_load_seg(env, R_DS, 0); +    cpu_x86_load_seg(env, R_ES, 0); +    cpu_x86_load_seg(env, R_FS, 0); +    cpu_x86_load_seg(env, R_GS, 0); +#endif +#elif defined(TARGET_SPARC) +    { +        int i; +        env->pc = regs->pc; +        env->npc = regs->npc; +        env->y = regs->y; +        for(i = 0; i < 8; i++) +            env->gregs[i] = regs->u_regs[i]; +        for(i = 0; i < 8; i++) +            env->regwptr[i] = regs->u_regs[i + 8]; +    } +#else +#error unsupported target CPU +#endif + +    if (gdbstub_port) { +        gdbserver_start (gdbstub_port); +        gdb_handlesig(cpu, 0); +    } +    cpu_loop(env); +    /* never exits */ +    return 0; +} diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c new file mode 100644 index 00000000..092bf7f8 --- /dev/null +++ b/bsd-user/mmap.c @@ -0,0 +1,499 @@ +/* + *  mmap support for qemu + * + *  Copyright (c) 2003 - 2008 Fabrice Bellard + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program; if not, see <http://www.gnu.org/licenses/>. + */ +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <sys/mman.h> + +#include "qemu.h" +#include "qemu-common.h" +#include "bsd-mman.h" + +//#define DEBUG_MMAP + +#if defined(CONFIG_USE_NPTL) +pthread_mutex_t mmap_mutex; +static int __thread mmap_lock_count; + +void mmap_lock(void) +{ +    if (mmap_lock_count++ == 0) { +        pthread_mutex_lock(&mmap_mutex); +    } +} + +void mmap_unlock(void) +{ +    if (--mmap_lock_count == 0) { +        pthread_mutex_unlock(&mmap_mutex); +    } +} + +/* Grab lock to make sure things are in a consistent state after fork().  */ +void mmap_fork_start(void) +{ +    if (mmap_lock_count) +        abort(); +    pthread_mutex_lock(&mmap_mutex); +} + +void mmap_fork_end(int child) +{ +    if (child) +        pthread_mutex_init(&mmap_mutex, NULL); +    else +        pthread_mutex_unlock(&mmap_mutex); +} +#else +/* We aren't threadsafe to start with, so no need to worry about locking.  */ +void mmap_lock(void) +{ +} + +void mmap_unlock(void) +{ +} +#endif + +/* NOTE: all the constants are the HOST ones, but addresses are target. */ +int target_mprotect(abi_ulong start, abi_ulong len, int prot) +{ +    abi_ulong end, host_start, host_end, addr; +    int prot1, ret; + +#ifdef DEBUG_MMAP +    printf("mprotect: start=0x" TARGET_FMT_lx +           " len=0x" TARGET_FMT_lx " prot=%c%c%c\n", start, len, +           prot & PROT_READ ? 'r' : '-', +           prot & PROT_WRITE ? 'w' : '-', +           prot & PROT_EXEC ? 'x' : '-'); +#endif + +    if ((start & ~TARGET_PAGE_MASK) != 0) +        return -EINVAL; +    len = TARGET_PAGE_ALIGN(len); +    end = start + len; +    if (end < start) +        return -EINVAL; +    prot &= PROT_READ | PROT_WRITE | PROT_EXEC; +    if (len == 0) +        return 0; + +    mmap_lock(); +    host_start = start & qemu_host_page_mask; +    host_end = HOST_PAGE_ALIGN(end); +    if (start > host_start) { +        /* handle host page containing start */ +        prot1 = prot; +        for(addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) { +            prot1 |= page_get_flags(addr); +        } +        if (host_end == host_start + qemu_host_page_size) { +            for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { +                prot1 |= page_get_flags(addr); +            } +            end = host_end; +        } +        ret = mprotect(g2h(host_start), qemu_host_page_size, prot1 & PAGE_BITS); +        if (ret != 0) +            goto error; +        host_start += qemu_host_page_size; +    } +    if (end < host_end) { +        prot1 = prot; +        for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { +            prot1 |= page_get_flags(addr); +        } +        ret = mprotect(g2h(host_end - qemu_host_page_size), qemu_host_page_size, +                       prot1 & PAGE_BITS); +        if (ret != 0) +            goto error; +        host_end -= qemu_host_page_size; +    } + +    /* handle the pages in the middle */ +    if (host_start < host_end) { +        ret = mprotect(g2h(host_start), host_end - host_start, prot); +        if (ret != 0) +            goto error; +    } +    page_set_flags(start, start + len, prot | PAGE_VALID); +    mmap_unlock(); +    return 0; +error: +    mmap_unlock(); +    return ret; +} + +/* map an incomplete host page */ +static int mmap_frag(abi_ulong real_start, +                     abi_ulong start, abi_ulong end, +                     int prot, int flags, int fd, abi_ulong offset) +{ +    abi_ulong real_end, addr; +    void *host_start; +    int prot1, prot_new; + +    real_end = real_start + qemu_host_page_size; +    host_start = g2h(real_start); + +    /* get the protection of the target pages outside the mapping */ +    prot1 = 0; +    for(addr = real_start; addr < real_end; addr++) { +        if (addr < start || addr >= end) +            prot1 |= page_get_flags(addr); +    } + +    if (prot1 == 0) { +        /* no page was there, so we allocate one */ +        void *p = mmap(host_start, qemu_host_page_size, prot, +                       flags | MAP_ANON, -1, 0); +        if (p == MAP_FAILED) +            return -1; +        prot1 = prot; +    } +    prot1 &= PAGE_BITS; + +    prot_new = prot | prot1; +    if (!(flags & MAP_ANON)) { +        /* msync() won't work here, so we return an error if write is +           possible while it is a shared mapping */ +        if ((flags & TARGET_BSD_MAP_FLAGMASK) == MAP_SHARED && +            (prot & PROT_WRITE)) +            return -1; + +        /* adjust protection to be able to read */ +        if (!(prot1 & PROT_WRITE)) +            mprotect(host_start, qemu_host_page_size, prot1 | PROT_WRITE); + +        /* read the corresponding file data */ +        pread(fd, g2h(start), end - start, offset); + +        /* put final protection */ +        if (prot_new != (prot1 | PROT_WRITE)) +            mprotect(host_start, qemu_host_page_size, prot_new); +    } else { +        /* just update the protection */ +        if (prot_new != prot1) { +            mprotect(host_start, qemu_host_page_size, prot_new); +        } +    } +    return 0; +} + +#if defined(__CYGWIN__) +/* Cygwin doesn't have a whole lot of address space.  */ +static abi_ulong mmap_next_start = 0x18000000; +#else +static abi_ulong mmap_next_start = 0x40000000; +#endif + +unsigned long last_brk; + +/* find a free memory area of size 'size'. The search starts at +   'start'. If 'start' == 0, then a default start address is used. +   Return -1 if error. +*/ +/* page_init() marks pages used by the host as reserved to be sure not +   to use them. */ +static abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) +{ +    abi_ulong addr, addr1, addr_start; +    int prot; +    unsigned long new_brk; + +    new_brk = (unsigned long)sbrk(0); +    if (last_brk && last_brk < new_brk && last_brk == (target_ulong)last_brk) { +        /* This is a hack to catch the host allocating memory with brk(). +           If it uses mmap then we loose. +           FIXME: We really want to avoid the host allocating memory in +           the first place, and maybe leave some slack to avoid switching +           to mmap.  */ +        page_set_flags(last_brk & TARGET_PAGE_MASK, +                       TARGET_PAGE_ALIGN(new_brk), +                       PAGE_RESERVED); +    } +    last_brk = new_brk; + +    size = HOST_PAGE_ALIGN(size); +    start = start & qemu_host_page_mask; +    addr = start; +    if (addr == 0) +        addr = mmap_next_start; +    addr_start = addr; +    for(;;) { +        prot = 0; +        for(addr1 = addr; addr1 < (addr + size); addr1 += TARGET_PAGE_SIZE) { +            prot |= page_get_flags(addr1); +        } +        if (prot == 0) +            break; +        addr += qemu_host_page_size; +        /* we found nothing */ +        if (addr == addr_start) +            return (abi_ulong)-1; +    } +    if (start == 0) +        mmap_next_start = addr + size; +    return addr; +} + +/* NOTE: all the constants are the HOST ones */ +abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, +                     int flags, int fd, abi_ulong offset) +{ +    abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len; +    unsigned long host_start; + +    mmap_lock(); +#ifdef DEBUG_MMAP +    { +        printf("mmap: start=0x" TARGET_FMT_lx +               " len=0x" TARGET_FMT_lx " prot=%c%c%c flags=", +               start, len, +               prot & PROT_READ ? 'r' : '-', +               prot & PROT_WRITE ? 'w' : '-', +               prot & PROT_EXEC ? 'x' : '-'); +        if (flags & MAP_FIXED) +            printf("MAP_FIXED "); +        if (flags & MAP_ANON) +            printf("MAP_ANON "); +        switch(flags & TARGET_BSD_MAP_FLAGMASK) { +        case MAP_PRIVATE: +            printf("MAP_PRIVATE "); +            break; +        case MAP_SHARED: +            printf("MAP_SHARED "); +            break; +        default: +            printf("[MAP_FLAGMASK=0x%x] ", flags & TARGET_BSD_MAP_FLAGMASK); +            break; +        } +        printf("fd=%d offset=" TARGET_FMT_lx "\n", fd, offset); +    } +#endif + +    if (offset & ~TARGET_PAGE_MASK) { +        errno = EINVAL; +        goto fail; +    } + +    len = TARGET_PAGE_ALIGN(len); +    if (len == 0) +        goto the_end; +    real_start = start & qemu_host_page_mask; + +    if (!(flags & MAP_FIXED)) { +        abi_ulong mmap_start; +        void *p; +        host_offset = offset & qemu_host_page_mask; +        host_len = len + offset - host_offset; +        host_len = HOST_PAGE_ALIGN(host_len); +        mmap_start = mmap_find_vma(real_start, host_len); +        if (mmap_start == (abi_ulong)-1) { +            errno = ENOMEM; +            goto fail; +        } +        /* Note: we prefer to control the mapping address. It is +           especially important if qemu_host_page_size > +           qemu_real_host_page_size */ +        p = mmap(g2h(mmap_start), +                 host_len, prot, flags | MAP_FIXED, fd, host_offset); +        if (p == MAP_FAILED) +            goto fail; +        /* update start so that it points to the file position at 'offset' */ +        host_start = (unsigned long)p; +        if (!(flags & MAP_ANON)) +            host_start += offset - host_offset; +        start = h2g(host_start); +    } else { +        int flg; +        target_ulong addr; + +        if (start & ~TARGET_PAGE_MASK) { +            errno = EINVAL; +            goto fail; +        } +        end = start + len; +        real_end = HOST_PAGE_ALIGN(end); + +        for(addr = real_start; addr < real_end; addr += TARGET_PAGE_SIZE) { +            flg = page_get_flags(addr); +            if (flg & PAGE_RESERVED) { +                errno = ENXIO; +                goto fail; +            } +        } + +        /* worst case: we cannot map the file because the offset is not +           aligned, so we read it */ +        if (!(flags & MAP_ANON) && +            (offset & ~qemu_host_page_mask) != (start & ~qemu_host_page_mask)) { +            /* msync() won't work here, so we return an error if write is +               possible while it is a shared mapping */ +            if ((flags & TARGET_BSD_MAP_FLAGMASK) == MAP_SHARED && +                (prot & PROT_WRITE)) { +                errno = EINVAL; +                goto fail; +            } +            retaddr = target_mmap(start, len, prot | PROT_WRITE, +                                  MAP_FIXED | MAP_PRIVATE | MAP_ANON, +                                  -1, 0); +            if (retaddr == -1) +                goto fail; +            pread(fd, g2h(start), len, offset); +            if (!(prot & PROT_WRITE)) { +                ret = target_mprotect(start, len, prot); +                if (ret != 0) { +                    start = ret; +                    goto the_end; +                } +            } +            goto the_end; +        } + +        /* handle the start of the mapping */ +        if (start > real_start) { +            if (real_end == real_start + qemu_host_page_size) { +                /* one single host page */ +                ret = mmap_frag(real_start, start, end, +                                prot, flags, fd, offset); +                if (ret == -1) +                    goto fail; +                goto the_end1; +            } +            ret = mmap_frag(real_start, start, real_start + qemu_host_page_size, +                            prot, flags, fd, offset); +            if (ret == -1) +                goto fail; +            real_start += qemu_host_page_size; +        } +        /* handle the end of the mapping */ +        if (end < real_end) { +            ret = mmap_frag(real_end - qemu_host_page_size, +                            real_end - qemu_host_page_size, real_end, +                            prot, flags, fd, +                            offset + real_end - qemu_host_page_size - start); +            if (ret == -1) +                goto fail; +            real_end -= qemu_host_page_size; +        } + +        /* map the middle (easier) */ +        if (real_start < real_end) { +            void *p; +            unsigned long offset1; +            if (flags & MAP_ANON) +                offset1 = 0; +            else +                offset1 = offset + real_start - start; +            p = mmap(g2h(real_start), real_end - real_start, +                     prot, flags, fd, offset1); +            if (p == MAP_FAILED) +                goto fail; +        } +    } + the_end1: +    page_set_flags(start, start + len, prot | PAGE_VALID); + the_end: +#ifdef DEBUG_MMAP +    printf("ret=0x" TARGET_FMT_lx "\n", start); +    page_dump(stdout); +    printf("\n"); +#endif +    mmap_unlock(); +    return start; +fail: +    mmap_unlock(); +    return -1; +} + +int target_munmap(abi_ulong start, abi_ulong len) +{ +    abi_ulong end, real_start, real_end, addr; +    int prot, ret; + +#ifdef DEBUG_MMAP +    printf("munmap: start=0x%lx len=0x%lx\n", start, len); +#endif +    if (start & ~TARGET_PAGE_MASK) +        return -EINVAL; +    len = TARGET_PAGE_ALIGN(len); +    if (len == 0) +        return -EINVAL; +    mmap_lock(); +    end = start + len; +    real_start = start & qemu_host_page_mask; +    real_end = HOST_PAGE_ALIGN(end); + +    if (start > real_start) { +        /* handle host page containing start */ +        prot = 0; +        for(addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) { +            prot |= page_get_flags(addr); +        } +        if (real_end == real_start + qemu_host_page_size) { +            for(addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) { +                prot |= page_get_flags(addr); +            } +            end = real_end; +        } +        if (prot != 0) +            real_start += qemu_host_page_size; +    } +    if (end < real_end) { +        prot = 0; +        for(addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) { +            prot |= page_get_flags(addr); +        } +        if (prot != 0) +            real_end -= qemu_host_page_size; +    } + +    ret = 0; +    /* unmap what we can */ +    if (real_start < real_end) { +        ret = munmap(g2h(real_start), real_end - real_start); +    } + +    if (ret == 0) +        page_set_flags(start, start + len, 0); +    mmap_unlock(); +    return ret; +} + +int target_msync(abi_ulong start, abi_ulong len, int flags) +{ +    abi_ulong end; + +    if (start & ~TARGET_PAGE_MASK) +        return -EINVAL; +    len = TARGET_PAGE_ALIGN(len); +    end = start + len; +    if (end < start) +        return -EINVAL; +    if (end == start) +        return 0; + +    start &= qemu_host_page_mask; +    return msync(g2h(start), end - start, flags); +} diff --git a/bsd-user/netbsd/strace.list b/bsd-user/netbsd/strace.list new file mode 100644 index 00000000..5609d70d --- /dev/null +++ b/bsd-user/netbsd/strace.list @@ -0,0 +1,145 @@ +{ TARGET_NETBSD_NR___getcwd, "__getcwd", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR___syscall, "__syscall", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR___sysctl, "__sysctl", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_accept, "accept", "%s(%d,%#x,%#x)", NULL, NULL }, +{ TARGET_NETBSD_NR_access, "access", "%s(\"%s\",%#o)", NULL, NULL }, +{ TARGET_NETBSD_NR_acct, "acct", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_adjtime, "adjtime", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_bind, "bind", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_break, "break", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_chdir, "chdir", "%s(\"%s\")", NULL, NULL }, +{ TARGET_NETBSD_NR_chflags, "chflags", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_chmod, "chmod", "%s(\"%s\",%#o)", NULL, NULL }, +{ TARGET_NETBSD_NR_chown, "chown", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_chroot, "chroot", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_clock_getres, "clock_getres", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_clock_gettime, "clock_gettime", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_clock_settime, "clock_settime", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_close, "close", "%s(%d)", NULL, NULL }, +{ TARGET_NETBSD_NR_connect, "connect", "%s(%d,%#x,%d)", NULL, NULL }, +{ TARGET_NETBSD_NR_dup, "dup", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_dup2, "dup2", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_execve, "execve", NULL, print_execve, NULL }, +{ TARGET_NETBSD_NR_exit, "exit", "%s(%d)\n", NULL, NULL }, +{ TARGET_NETBSD_NR_fchdir, "fchdir", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_fchflags, "fchflags", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_fchmod, "fchmod", "%s(%d,%#o)", NULL, NULL }, +{ TARGET_NETBSD_NR_fchown, "fchown", "%s(\"%s\",%d,%d)", NULL, NULL }, +{ TARGET_NETBSD_NR_fcntl, "fcntl", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_flock, "flock", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_fork, "fork", "%s()", NULL, NULL }, +{ TARGET_NETBSD_NR_fpathconf, "fpathconf", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_fsync, "fsync", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_ftruncate, "ftruncate", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_futimes, "futimes", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_getegid, "getegid", "%s()", NULL, NULL }, +{ TARGET_NETBSD_NR_geteuid, "geteuid", "%s()", NULL, NULL }, +{ TARGET_NETBSD_NR_getgid, "getgid", "%s()", NULL, NULL }, +{ TARGET_NETBSD_NR_getgroups, "getgroups", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_getitimer, "getitimer", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_getpeername, "getpeername", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_getpgid, "getpgid", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_getpgrp, "getpgrp", "%s()", NULL, NULL }, +{ TARGET_NETBSD_NR_getpid, "getpid", "%s()", NULL, NULL }, +{ TARGET_NETBSD_NR_getppid, "getppid", "%s()", NULL, NULL }, +{ TARGET_NETBSD_NR_getpriority, "getpriority", "%s(%#x,%#x)", NULL, NULL }, +{ TARGET_NETBSD_NR_getrlimit, "getrlimit", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_getrusage, "getrusage", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_getsid, "getsid", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_getsockname, "getsockname", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_getsockopt, "getsockopt", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_gettimeofday, "gettimeofday", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_getuid, "getuid", "%s()", NULL, NULL }, +{ TARGET_NETBSD_NR_ioctl, "ioctl", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_issetugid, "issetugid", "%s()", NULL, NULL }, +{ TARGET_NETBSD_NR_kevent, "kevent", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_kill, "kill", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_kqueue, "kqueue", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_ktrace, "ktrace", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_lchown, "lchown", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_lfs_bmapv, "lfs_bmapv", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_lfs_markv, "lfs_markv", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_lfs_segclean, "lfs_segclean", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_lfs_segwait, "lfs_segwait", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_link, "link", "%s(\"%s\",\"%s\")", NULL, NULL }, +{ TARGET_NETBSD_NR_listen, "listen", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_lseek, "lseek", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_madvise, "madvise", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_mincore, "mincore", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_minherit, "minherit", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_mkdir, "mkdir", "%s(\"%s\",%#o)", NULL, NULL }, +{ TARGET_NETBSD_NR_mkfifo, "mkfifo", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_mknod, "mknod", "%s(\"%s\",%#o,%#x)", NULL, NULL }, +{ TARGET_NETBSD_NR_mlock, "mlock", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_mlockall, "mlockall", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_mmap, "mmap", NULL, NULL, print_syscall_ret_addr }, +{ TARGET_NETBSD_NR_mprotect, "mprotect", "%s(%#x,%#x,%d)", NULL, NULL }, +{ TARGET_NETBSD_NR_msgget, "msgget", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_msgrcv, "msgrcv", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_msgsnd, "msgsnd", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_munlock, "munlock", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_munlockall, "munlockall", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_munmap, "munmap", "%s(%p,%d)", NULL, NULL }, +{ TARGET_NETBSD_NR_nanosleep, "nanosleep", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_nfssvc, "nfssvc", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_open, "open", "%s(\"%s\",%#x,%#o)", NULL, NULL }, +{ TARGET_NETBSD_NR_pathconf, "pathconf", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_pipe, "pipe", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_poll, "poll", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_pread, "pread", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_preadv, "preadv", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_profil, "profil", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_ptrace, "ptrace", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_pwrite, "pwrite", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_pwritev, "pwritev", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_quotactl, "quotactl", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_read, "read", "%s(%d,%#x,%d)", NULL, NULL }, +{ TARGET_NETBSD_NR_readlink, "readlink", "%s(\"%s\",%p,%d)", NULL, NULL }, +{ TARGET_NETBSD_NR_readv, "readv", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_reboot, "reboot", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_recvfrom, "recvfrom", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_recvmsg, "recvmsg", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_rename, "rename", "%s(\"%s\",\"%s\")", NULL, NULL }, +{ TARGET_NETBSD_NR_revoke, "revoke", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_rmdir, "rmdir", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_sbrk, "sbrk", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_sched_yield, "sched_yield", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_select, "select", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_semget, "semget", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_semop, "semop", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_sendmsg, "sendmsg", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_sendto, "sendto", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_setegid, "setegid", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_seteuid, "seteuid", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_setgid, "setgid", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_setgroups, "setgroups", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_setitimer, "setitimer", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_setpgid, "setpgid", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_setpriority, "setpriority", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_setregid, "setregid", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_setreuid, "setreuid", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_setrlimit, "setrlimit", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_setsid, "setsid", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_setsockopt, "setsockopt", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_settimeofday, "settimeofday", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_setuid, "setuid", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_shmat, "shmat", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_shmdt, "shmdt", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_shmget, "shmget", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_shutdown, "shutdown", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_socketpair, "socketpair", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_sstk, "sstk", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_swapctl, "swapctl", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_symlink, "symlink", "%s(\"%s\",\"%s\")", NULL, NULL }, +{ TARGET_NETBSD_NR_sync, "sync", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_sysarch, "sysarch", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_syscall, "syscall", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_truncate, "truncate", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_umask, "umask", "%s(%#o)", NULL, NULL }, +{ TARGET_NETBSD_NR_unlink, "unlink", "%s(\"%s\")", NULL, NULL }, +{ TARGET_NETBSD_NR_unmount, "unmount", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_utimes, "utimes", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_vfork, "vfork", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_wait4, "wait4", NULL, NULL, NULL }, +{ TARGET_NETBSD_NR_write, "write", "%s(%d,%#x,%d)", NULL, NULL }, +{ TARGET_NETBSD_NR_writev, "writev", "%s(%d,%p,%#x)", NULL, NULL }, diff --git a/bsd-user/netbsd/syscall_nr.h b/bsd-user/netbsd/syscall_nr.h new file mode 100644 index 00000000..2e9ab537 --- /dev/null +++ b/bsd-user/netbsd/syscall_nr.h @@ -0,0 +1,373 @@ +/* $NetBSD: syscall.h,v 1.215 2008/06/17 16:07:57 tsutsui Exp $ */ + +/* + * System call numbers. + * + * created from	NetBSD: syscalls.master,v 1.204 2008/06/17 16:05:23 tsutsui Exp + */ + +#define TARGET_NETBSD_NR_syscall     0 +#define TARGET_NETBSD_NR_exit        1 +#define TARGET_NETBSD_NR_fork        2 +#define TARGET_NETBSD_NR_read        3 +#define TARGET_NETBSD_NR_write       4 +#define TARGET_NETBSD_NR_open        5 +#define TARGET_NETBSD_NR_close       6 +#define TARGET_NETBSD_NR_wait4       7 +#define TARGET_NETBSD_NR_compat_43_ocreat    8 +#define TARGET_NETBSD_NR_link        9 +#define TARGET_NETBSD_NR_unlink      10 +#define TARGET_NETBSD_NR_chdir       12 +#define TARGET_NETBSD_NR_fchdir      13 +#define TARGET_NETBSD_NR_mknod       14 +#define TARGET_NETBSD_NR_chmod       15 +#define TARGET_NETBSD_NR_chown       16 +#define TARGET_NETBSD_NR_break       17 +#define TARGET_NETBSD_NR_compat_20_getfsstat 18 +#define TARGET_NETBSD_NR_compat_43_olseek    19 +#define TARGET_NETBSD_NR_getpid      20 +#define TARGET_NETBSD_NR_getpid      20 +#define TARGET_NETBSD_NR_compat_40_mount     21 +#define TARGET_NETBSD_NR_unmount     22 +#define TARGET_NETBSD_NR_setuid      23 +#define TARGET_NETBSD_NR_getuid      24 +#define TARGET_NETBSD_NR_getuid      24 +#define TARGET_NETBSD_NR_geteuid     25 +#define TARGET_NETBSD_NR_ptrace      26 +#define TARGET_NETBSD_NR_recvmsg     27 +#define TARGET_NETBSD_NR_sendmsg     28 +#define TARGET_NETBSD_NR_recvfrom    29 +#define TARGET_NETBSD_NR_accept      30 +#define TARGET_NETBSD_NR_getpeername 31 +#define TARGET_NETBSD_NR_getsockname 32 +#define TARGET_NETBSD_NR_access      33 +#define TARGET_NETBSD_NR_chflags     34 +#define TARGET_NETBSD_NR_fchflags    35 +#define TARGET_NETBSD_NR_sync        36 +#define TARGET_NETBSD_NR_kill        37 +#define TARGET_NETBSD_NR_compat_43_stat43    38 +#define TARGET_NETBSD_NR_getppid     39 +#define TARGET_NETBSD_NR_compat_43_lstat43   40 +#define TARGET_NETBSD_NR_dup 41 +#define TARGET_NETBSD_NR_pipe        42 +#define TARGET_NETBSD_NR_getegid     43 +#define TARGET_NETBSD_NR_profil      44 +#define TARGET_NETBSD_NR_ktrace      45 +#define TARGET_NETBSD_NR_compat_13_sigaction13       46 +#define TARGET_NETBSD_NR_getgid      47 +#define TARGET_NETBSD_NR_getgid      47 +#define TARGET_NETBSD_NR_compat_13_sigprocmask13     48 +#define TARGET_NETBSD_NR___getlogin  49 +#define TARGET_NETBSD_NR___setlogin  50 +#define TARGET_NETBSD_NR_acct        51 +#define TARGET_NETBSD_NR_compat_13_sigpending13      52 +#define TARGET_NETBSD_NR_compat_13_sigaltstack13     53 +#define TARGET_NETBSD_NR_ioctl       54 +#define TARGET_NETBSD_NR_compat_12_oreboot   55 +#define TARGET_NETBSD_NR_revoke      56 +#define TARGET_NETBSD_NR_symlink     57 +#define TARGET_NETBSD_NR_readlink    58 +#define TARGET_NETBSD_NR_execve      59 +#define TARGET_NETBSD_NR_umask       60 +#define TARGET_NETBSD_NR_chroot      61 +#define TARGET_NETBSD_NR_compat_43_fstat43   62 +#define TARGET_NETBSD_NR_compat_43_ogetkerninfo      63 +#define TARGET_NETBSD_NR_compat_43_ogetpagesize      64 +#define TARGET_NETBSD_NR_compat_12_msync     65 +#define TARGET_NETBSD_NR_vfork       66 +#define TARGET_NETBSD_NR_sbrk        69 +#define TARGET_NETBSD_NR_sstk        70 +#define TARGET_NETBSD_NR_compat_43_ommap     71 +#define TARGET_NETBSD_NR_vadvise     72 +#define TARGET_NETBSD_NR_munmap      73 +#define TARGET_NETBSD_NR_mprotect    74 +#define TARGET_NETBSD_NR_madvise     75 +#define TARGET_NETBSD_NR_mincore     78 +#define TARGET_NETBSD_NR_getgroups   79 +#define TARGET_NETBSD_NR_setgroups   80 +#define TARGET_NETBSD_NR_getpgrp     81 +#define TARGET_NETBSD_NR_setpgid     82 +#define TARGET_NETBSD_NR_setitimer   83 +#define TARGET_NETBSD_NR_compat_43_owait     84 +#define TARGET_NETBSD_NR_compat_12_oswapon   85 +#define TARGET_NETBSD_NR_getitimer   86 +#define TARGET_NETBSD_NR_compat_43_ogethostname      87 +#define TARGET_NETBSD_NR_compat_43_osethostname      88 +#define TARGET_NETBSD_NR_compat_43_ogetdtablesize    89 +#define TARGET_NETBSD_NR_dup2        90 +#define TARGET_NETBSD_NR_fcntl       92 +#define TARGET_NETBSD_NR_select      93 +#define TARGET_NETBSD_NR_fsync       95 +#define TARGET_NETBSD_NR_setpriority 96 +#define TARGET_NETBSD_NR_compat_30_socket    97 +#define TARGET_NETBSD_NR_connect     98 +#define TARGET_NETBSD_NR_compat_43_oaccept   99 +#define TARGET_NETBSD_NR_getpriority 100 +#define TARGET_NETBSD_NR_compat_43_osend     101 +#define TARGET_NETBSD_NR_compat_43_orecv     102 +#define TARGET_NETBSD_NR_compat_13_sigreturn13       103 +#define TARGET_NETBSD_NR_bind        104 +#define TARGET_NETBSD_NR_setsockopt  105 +#define TARGET_NETBSD_NR_listen      106 +#define TARGET_NETBSD_NR_compat_43_osigvec   108 +#define TARGET_NETBSD_NR_compat_43_osigblock 109 +#define TARGET_NETBSD_NR_compat_43_osigsetmask       110 +#define TARGET_NETBSD_NR_compat_13_sigsuspend13      111 +#define TARGET_NETBSD_NR_compat_43_osigstack 112 +#define TARGET_NETBSD_NR_compat_43_orecvmsg  113 +#define TARGET_NETBSD_NR_compat_43_osendmsg  114 +#define TARGET_NETBSD_NR_gettimeofday        116 +#define TARGET_NETBSD_NR_getrusage   117 +#define TARGET_NETBSD_NR_getsockopt  118 +#define TARGET_NETBSD_NR_readv       120 +#define TARGET_NETBSD_NR_writev      121 +#define TARGET_NETBSD_NR_settimeofday        122 +#define TARGET_NETBSD_NR_fchown      123 +#define TARGET_NETBSD_NR_fchmod      124 +#define TARGET_NETBSD_NR_compat_43_orecvfrom 125 +#define TARGET_NETBSD_NR_setreuid    126 +#define TARGET_NETBSD_NR_setregid    127 +#define TARGET_NETBSD_NR_rename      128 +#define TARGET_NETBSD_NR_compat_43_otruncate 129 +#define TARGET_NETBSD_NR_compat_43_oftruncate        130 +#define TARGET_NETBSD_NR_flock       131 +#define TARGET_NETBSD_NR_mkfifo      132 +#define TARGET_NETBSD_NR_sendto      133 +#define TARGET_NETBSD_NR_shutdown    134 +#define TARGET_NETBSD_NR_socketpair  135 +#define TARGET_NETBSD_NR_mkdir       136 +#define TARGET_NETBSD_NR_rmdir       137 +#define TARGET_NETBSD_NR_utimes      138 +#define TARGET_NETBSD_NR_adjtime     140 +#define TARGET_NETBSD_NR_compat_43_ogetpeername      141 +#define TARGET_NETBSD_NR_compat_43_ogethostid        142 +#define TARGET_NETBSD_NR_compat_43_osethostid        143 +#define TARGET_NETBSD_NR_compat_43_ogetrlimit        144 +#define TARGET_NETBSD_NR_compat_43_osetrlimit        145 +#define TARGET_NETBSD_NR_compat_43_okillpg   146 +#define TARGET_NETBSD_NR_setsid      147 +#define TARGET_NETBSD_NR_quotactl    148 +#define TARGET_NETBSD_NR_compat_43_oquota    149 +#define TARGET_NETBSD_NR_compat_43_ogetsockname      150 +#define TARGET_NETBSD_NR_nfssvc      155 +#define TARGET_NETBSD_NR_compat_43_ogetdirentries    156 +#define TARGET_NETBSD_NR_compat_20_statfs    157 +#define TARGET_NETBSD_NR_compat_20_fstatfs   158 +#define TARGET_NETBSD_NR_compat_30_getfh     161 +#define TARGET_NETBSD_NR_compat_09_ogetdomainname    162 +#define TARGET_NETBSD_NR_compat_09_osetdomainname    163 +#define TARGET_NETBSD_NR_compat_09_ouname    164 +#define TARGET_NETBSD_NR_sysarch     165 +#define TARGET_NETBSD_NR_compat_10_osemsys   169 +#define TARGET_NETBSD_NR_compat_10_omsgsys   170 +#define TARGET_NETBSD_NR_compat_10_oshmsys   171 +#define TARGET_NETBSD_NR_pread       173 +#define TARGET_NETBSD_NR_pwrite      174 +#define TARGET_NETBSD_NR_compat_30_ntp_gettime       175 +#define TARGET_NETBSD_NR_ntp_adjtime 176 +#define TARGET_NETBSD_NR_setgid      181 +#define TARGET_NETBSD_NR_setegid     182 +#define TARGET_NETBSD_NR_seteuid     183 +#define TARGET_NETBSD_NR_lfs_bmapv   184 +#define TARGET_NETBSD_NR_lfs_markv   185 +#define TARGET_NETBSD_NR_lfs_segclean        186 +#define TARGET_NETBSD_NR_lfs_segwait 187 +#define TARGET_NETBSD_NR_compat_12_stat12    188 +#define TARGET_NETBSD_NR_compat_12_fstat12   189 +#define TARGET_NETBSD_NR_compat_12_lstat12   190 +#define TARGET_NETBSD_NR_pathconf    191 +#define TARGET_NETBSD_NR_fpathconf   192 +#define TARGET_NETBSD_NR_getrlimit   194 +#define TARGET_NETBSD_NR_setrlimit   195 +#define TARGET_NETBSD_NR_compat_12_getdirentries     196 +#define TARGET_NETBSD_NR_mmap        197 +#define TARGET_NETBSD_NR___syscall   198 +#define TARGET_NETBSD_NR_lseek       199 +#define TARGET_NETBSD_NR_truncate    200 +#define TARGET_NETBSD_NR_ftruncate   201 +#define TARGET_NETBSD_NR___sysctl    202 +#define TARGET_NETBSD_NR_mlock       203 +#define TARGET_NETBSD_NR_munlock     204 +#define TARGET_NETBSD_NR_undelete    205 +#define TARGET_NETBSD_NR_futimes     206 +#define TARGET_NETBSD_NR_getpgid     207 +#define TARGET_NETBSD_NR_reboot      208 +#define TARGET_NETBSD_NR_poll        209 +#define TARGET_NETBSD_NR_compat_14___semctl  220 +#define TARGET_NETBSD_NR_semget      221 +#define TARGET_NETBSD_NR_semop       222 +#define TARGET_NETBSD_NR_semconfig   223 +#define TARGET_NETBSD_NR_compat_14_msgctl    224 +#define TARGET_NETBSD_NR_msgget      225 +#define TARGET_NETBSD_NR_msgsnd      226 +#define TARGET_NETBSD_NR_msgrcv      227 +#define TARGET_NETBSD_NR_shmat       228 +#define TARGET_NETBSD_NR_compat_14_shmctl    229 +#define TARGET_NETBSD_NR_shmdt       230 +#define TARGET_NETBSD_NR_shmget      231 +#define TARGET_NETBSD_NR_clock_gettime       232 +#define TARGET_NETBSD_NR_clock_settime       233 +#define TARGET_NETBSD_NR_clock_getres        234 +#define TARGET_NETBSD_NR_timer_create        235 +#define TARGET_NETBSD_NR_timer_delete        236 +#define TARGET_NETBSD_NR_timer_settime       237 +#define TARGET_NETBSD_NR_timer_gettime       238 +#define TARGET_NETBSD_NR_timer_getoverrun    239 +#define TARGET_NETBSD_NR_nanosleep   240 +#define TARGET_NETBSD_NR_fdatasync   241 +#define TARGET_NETBSD_NR_mlockall    242 +#define TARGET_NETBSD_NR_munlockall  243 +#define TARGET_NETBSD_NR___sigtimedwait      244 +#define TARGET_NETBSD_NR_modctl      246 +#define TARGET_NETBSD_NR__ksem_init  247 +#define TARGET_NETBSD_NR__ksem_open  248 +#define TARGET_NETBSD_NR__ksem_unlink        249 +#define TARGET_NETBSD_NR__ksem_close 250 +#define TARGET_NETBSD_NR__ksem_post  251 +#define TARGET_NETBSD_NR__ksem_wait  252 +#define TARGET_NETBSD_NR__ksem_trywait       253 +#define TARGET_NETBSD_NR__ksem_getvalue      254 +#define TARGET_NETBSD_NR__ksem_destroy       255 +#define TARGET_NETBSD_NR_mq_open     257 +#define TARGET_NETBSD_NR_mq_close    258 +#define TARGET_NETBSD_NR_mq_unlink   259 +#define TARGET_NETBSD_NR_mq_getattr  260 +#define TARGET_NETBSD_NR_mq_setattr  261 +#define TARGET_NETBSD_NR_mq_notify   262 +#define TARGET_NETBSD_NR_mq_send     263 +#define TARGET_NETBSD_NR_mq_receive  264 +#define TARGET_NETBSD_NR_mq_timedsend        265 +#define TARGET_NETBSD_NR_mq_timedreceive     266 +#define TARGET_NETBSD_NR___posix_rename      270 +#define TARGET_NETBSD_NR_swapctl     271 +#define TARGET_NETBSD_NR_compat_30_getdents  272 +#define TARGET_NETBSD_NR_minherit    273 +#define TARGET_NETBSD_NR_lchmod      274 +#define TARGET_NETBSD_NR_lchown      275 +#define TARGET_NETBSD_NR_lutimes     276 +#define TARGET_NETBSD_NR___msync13   277 +#define TARGET_NETBSD_NR_compat_30___stat13  278 +#define TARGET_NETBSD_NR_compat_30___fstat13 279 +#define TARGET_NETBSD_NR_compat_30___lstat13 280 +#define TARGET_NETBSD_NR___sigaltstack14     281 +#define TARGET_NETBSD_NR___vfork14   282 +#define TARGET_NETBSD_NR___posix_chown       283 +#define TARGET_NETBSD_NR___posix_fchown      284 +#define TARGET_NETBSD_NR___posix_lchown      285 +#define TARGET_NETBSD_NR_getsid      286 +#define TARGET_NETBSD_NR___clone     287 +#define TARGET_NETBSD_NR_fktrace     288 +#define TARGET_NETBSD_NR_preadv      289 +#define TARGET_NETBSD_NR_pwritev     290 +#define TARGET_NETBSD_NR_compat_16___sigaction14     291 +#define TARGET_NETBSD_NR___sigpending14      292 +#define TARGET_NETBSD_NR___sigprocmask14     293 +#define TARGET_NETBSD_NR___sigsuspend14      294 +#define TARGET_NETBSD_NR_compat_16___sigreturn14     295 +#define TARGET_NETBSD_NR___getcwd    296 +#define TARGET_NETBSD_NR_fchroot     297 +#define TARGET_NETBSD_NR_compat_30_fhopen    298 +#define TARGET_NETBSD_NR_compat_30_fhstat    299 +#define TARGET_NETBSD_NR_compat_20_fhstatfs  300 +#define TARGET_NETBSD_NR_____semctl13        301 +#define TARGET_NETBSD_NR___msgctl13  302 +#define TARGET_NETBSD_NR___shmctl13  303 +#define TARGET_NETBSD_NR_lchflags    304 +#define TARGET_NETBSD_NR_issetugid   305 +#define TARGET_NETBSD_NR_utrace      306 +#define TARGET_NETBSD_NR_getcontext  307 +#define TARGET_NETBSD_NR_setcontext  308 +#define TARGET_NETBSD_NR__lwp_create 309 +#define TARGET_NETBSD_NR__lwp_exit   310 +#define TARGET_NETBSD_NR__lwp_self   311 +#define TARGET_NETBSD_NR__lwp_wait   312 +#define TARGET_NETBSD_NR__lwp_suspend        313 +#define TARGET_NETBSD_NR__lwp_continue       314 +#define TARGET_NETBSD_NR__lwp_wakeup 315 +#define TARGET_NETBSD_NR__lwp_getprivate     316 +#define TARGET_NETBSD_NR__lwp_setprivate     317 +#define TARGET_NETBSD_NR__lwp_kill   318 +#define TARGET_NETBSD_NR__lwp_detach 319 +#define TARGET_NETBSD_NR__lwp_park   320 +#define TARGET_NETBSD_NR__lwp_unpark 321 +#define TARGET_NETBSD_NR__lwp_unpark_all     322 +#define TARGET_NETBSD_NR__lwp_setname        323 +#define TARGET_NETBSD_NR__lwp_getname        324 +#define TARGET_NETBSD_NR__lwp_ctl    325 +#define TARGET_NETBSD_NR_sa_register 330 +#define TARGET_NETBSD_NR_sa_stacks   331 +#define TARGET_NETBSD_NR_sa_enable   332 +#define TARGET_NETBSD_NR_sa_setconcurrency   333 +#define TARGET_NETBSD_NR_sa_yield    334 +#define TARGET_NETBSD_NR_sa_preempt  335 +#define TARGET_NETBSD_NR_sa_unblockyield     336 +#define TARGET_NETBSD_NR___sigaction_sigtramp        340 +#define TARGET_NETBSD_NR_pmc_get_info        341 +#define TARGET_NETBSD_NR_pmc_control 342 +#define TARGET_NETBSD_NR_rasctl      343 +#define TARGET_NETBSD_NR_kqueue      344 +#define TARGET_NETBSD_NR_kevent      345 +#define TARGET_NETBSD_NR__sched_setparam     346 +#define TARGET_NETBSD_NR__sched_getparam     347 +#define TARGET_NETBSD_NR__sched_setaffinity  348 +#define TARGET_NETBSD_NR__sched_getaffinity  349 +#define TARGET_NETBSD_NR_sched_yield 350 +#define TARGET_NETBSD_NR_fsync_range 354 +#define TARGET_NETBSD_NR_uuidgen     355 +#define TARGET_NETBSD_NR_getvfsstat  356 +#define TARGET_NETBSD_NR_statvfs1    357 +#define TARGET_NETBSD_NR_fstatvfs1   358 +#define TARGET_NETBSD_NR_compat_30_fhstatvfs1        359 +#define TARGET_NETBSD_NR_extattrctl  360 +#define TARGET_NETBSD_NR_extattr_set_file    361 +#define TARGET_NETBSD_NR_extattr_get_file    362 +#define TARGET_NETBSD_NR_extattr_delete_file 363 +#define TARGET_NETBSD_NR_extattr_set_fd      364 +#define TARGET_NETBSD_NR_extattr_get_fd      365 +#define TARGET_NETBSD_NR_extattr_delete_fd   366 +#define TARGET_NETBSD_NR_extattr_set_link    367 +#define TARGET_NETBSD_NR_extattr_get_link    368 +#define TARGET_NETBSD_NR_extattr_delete_link 369 +#define TARGET_NETBSD_NR_extattr_list_fd     370 +#define TARGET_NETBSD_NR_extattr_list_file   371 +#define TARGET_NETBSD_NR_extattr_list_link   372 +#define TARGET_NETBSD_NR_pselect     373 +#define TARGET_NETBSD_NR_pollts      374 +#define TARGET_NETBSD_NR_setxattr    375 +#define TARGET_NETBSD_NR_lsetxattr   376 +#define TARGET_NETBSD_NR_fsetxattr   377 +#define TARGET_NETBSD_NR_getxattr    378 +#define TARGET_NETBSD_NR_lgetxattr   379 +#define TARGET_NETBSD_NR_fgetxattr   380 +#define TARGET_NETBSD_NR_listxattr   381 +#define TARGET_NETBSD_NR_llistxattr  382 +#define TARGET_NETBSD_NR_flistxattr  383 +#define TARGET_NETBSD_NR_removexattr 384 +#define TARGET_NETBSD_NR_lremovexattr        385 +#define TARGET_NETBSD_NR_fremovexattr        386 +#define TARGET_NETBSD_NR___stat30    387 +#define TARGET_NETBSD_NR___fstat30   388 +#define TARGET_NETBSD_NR___lstat30   389 +#define TARGET_NETBSD_NR___getdents30        390 +#define TARGET_NETBSD_NR_compat_30___fhstat30        392 +#define TARGET_NETBSD_NR___ntp_gettime30     393 +#define TARGET_NETBSD_NR___socket30  394 +#define TARGET_NETBSD_NR___getfh30   395 +#define TARGET_NETBSD_NR___fhopen40  396 +#define TARGET_NETBSD_NR___fhstatvfs140      397 +#define TARGET_NETBSD_NR___fhstat40  398 +#define TARGET_NETBSD_NR_aio_cancel  399 +#define TARGET_NETBSD_NR_aio_error   400 +#define TARGET_NETBSD_NR_aio_fsync   401 +#define TARGET_NETBSD_NR_aio_read    402 +#define TARGET_NETBSD_NR_aio_return  403 +#define TARGET_NETBSD_NR_aio_suspend 404 +#define TARGET_NETBSD_NR_aio_write   405 +#define TARGET_NETBSD_NR_lio_listio  406 +#define TARGET_NETBSD_NR___mount50   410 +#define TARGET_NETBSD_NR_mremap      411 +#define TARGET_NETBSD_NR_pset_create 412 +#define TARGET_NETBSD_NR_pset_destroy        413 +#define TARGET_NETBSD_NR_pset_assign 414 +#define TARGET_NETBSD_NR__pset_bind  415 +#define TARGET_NETBSD_NR___posix_fadvise50   416 diff --git a/bsd-user/openbsd/strace.list b/bsd-user/openbsd/strace.list new file mode 100644 index 00000000..1f0a3316 --- /dev/null +++ b/bsd-user/openbsd/strace.list @@ -0,0 +1,187 @@ +{ TARGET_OPENBSD_NR___getcwd, "__getcwd", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR___semctl, "__semctl", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR___syscall, "__syscall", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR___sysctl, "__sysctl", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_accept, "accept", "%s(%d,%#x,%#x)", NULL, NULL }, +{ TARGET_OPENBSD_NR_access, "access", "%s(\"%s\",%#o)", NULL, NULL }, +{ TARGET_OPENBSD_NR_acct, "acct", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_adjfreq, "adjfreq", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_adjtime, "adjtime", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_bind, "bind", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_break, "break", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_chdir, "chdir", "%s(\"%s\")", NULL, NULL }, +{ TARGET_OPENBSD_NR_chflags, "chflags", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_chmod, "chmod", "%s(\"%s\",%#o)", NULL, NULL }, +{ TARGET_OPENBSD_NR_chown, "chown", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_chroot, "chroot", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_clock_getres, "clock_getres", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_clock_gettime, "clock_gettime", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_clock_settime, "clock_settime", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_close, "close", "%s(%d)", NULL, NULL }, +{ TARGET_OPENBSD_NR_closefrom, "closefrom", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_connect, "connect", "%s(%d,%#x,%d)", NULL, NULL }, +{ TARGET_OPENBSD_NR_dup, "dup", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_dup2, "dup2", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_execve, "execve", NULL, print_execve, NULL }, +{ TARGET_OPENBSD_NR_exit, "exit", "%s(%d)\n", NULL, NULL }, +{ TARGET_OPENBSD_NR_fchdir, "fchdir", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_fchflags, "fchflags", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_fchmod, "fchmod", "%s(%d,%#o)", NULL, NULL }, +{ TARGET_OPENBSD_NR_fchown, "fchown", "%s(\"%s\",%d,%d)", NULL, NULL }, +{ TARGET_OPENBSD_NR_fcntl, "fcntl", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_fhopen, "fhopen", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_fhstat, "fhstat", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_fhstatfs, "fhstatfs", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_flock, "flock", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_fork, "fork", "%s()", NULL, NULL }, +{ TARGET_OPENBSD_NR_fpathconf, "fpathconf", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_fstat, "fstat", "%s(%d,%p)", NULL, NULL }, +{ TARGET_OPENBSD_NR_fstatfs, "fstatfs", "%s(%d,%p)", NULL, NULL }, +{ TARGET_OPENBSD_NR_fsync, "fsync", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_ftruncate, "ftruncate", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_futimes, "futimes", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getdirentries, "getdirentries", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getegid, "getegid", "%s()", NULL, NULL }, +{ TARGET_OPENBSD_NR_geteuid, "geteuid", "%s()", NULL, NULL }, +{ TARGET_OPENBSD_NR_getfh, "getfh", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getfsstat, "getfsstat", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getgid, "getgid", "%s()", NULL, NULL }, +{ TARGET_OPENBSD_NR_getgroups, "getgroups", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getitimer, "getitimer", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getlogin, "getlogin", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getpeereid, "getpeereid", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getpeername, "getpeername", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getpgid, "getpgid", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getpgrp, "getpgrp", "%s()", NULL, NULL }, +{ TARGET_OPENBSD_NR_getpid, "getpid", "%s()", NULL, NULL }, +{ TARGET_OPENBSD_NR_getppid, "getppid", "%s()", NULL, NULL }, +{ TARGET_OPENBSD_NR_getpriority, "getpriority", "%s(%#x,%#x)", NULL, NULL }, +{ TARGET_OPENBSD_NR_getresgid, "getresgid", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getresuid, "getresuid", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getrlimit, "getrlimit", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getrusage, "getrusage", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getsid, "getsid", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getsockname, "getsockname", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getsockopt, "getsockopt", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getthrid, "getthrid", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_gettimeofday, "gettimeofday", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_getuid, "getuid", "%s()", NULL, NULL }, +{ TARGET_OPENBSD_NR_ioctl, "ioctl", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_issetugid, "issetugid", "%s()", NULL, NULL }, +{ TARGET_OPENBSD_NR_kevent, "kevent", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_kill, "kill", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_kqueue, "kqueue", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_ktrace, "ktrace", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_lchown, "lchown", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_lfs_bmapv, "lfs_bmapv", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_lfs_markv, "lfs_markv", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_lfs_segclean, "lfs_segclean", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_lfs_segwait, "lfs_segwait", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_link, "link", "%s(\"%s\",\"%s\")", NULL, NULL }, +{ TARGET_OPENBSD_NR_listen, "listen", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_lseek, "lseek", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_lstat, "lstat", "%s(\"%s\",%p)", NULL, NULL }, +{ TARGET_OPENBSD_NR_madvise, "madvise", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_mincore, "mincore", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_minherit, "minherit", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_mkdir, "mkdir", "%s(\"%s\",%#o)", NULL, NULL }, +{ TARGET_OPENBSD_NR_mkfifo, "mkfifo", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_mknod, "mknod", "%s(\"%s\",%#o,%#x)", NULL, NULL }, +{ TARGET_OPENBSD_NR_mlock, "mlock", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_mlockall, "mlockall", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_mmap, "mmap", NULL, NULL, print_syscall_ret_addr }, +{ TARGET_OPENBSD_NR_mount, "mount", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_mprotect, "mprotect", "%s(%#x,%#x,%d)", NULL, NULL }, +{ TARGET_OPENBSD_NR_mquery, "mquery", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_msgctl, "msgctl", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_msgget, "msgget", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_msgrcv, "msgrcv", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_msgsnd, "msgsnd", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_msync, "msync", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_munlock, "munlock", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_munlockall, "munlockall", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_munmap, "munmap", "%s(%p,%d)", NULL, NULL }, +{ TARGET_OPENBSD_NR_nanosleep, "nanosleep", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_nfssvc, "nfssvc", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_open, "open", "%s(\"%s\",%#x,%#o)", NULL, NULL }, +{ TARGET_OPENBSD_NR_opipe, "opipe", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_osigaltstack, "osigaltstack", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_pathconf, "pathconf", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_pipe, "pipe", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_poll, "poll", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_pread, "pread", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_preadv, "preadv", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_profil, "profil", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_ptrace, "ptrace", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_pwrite, "pwrite", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_pwritev, "pwritev", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_quotactl, "quotactl", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_read, "read", "%s(%d,%#x,%d)", NULL, NULL }, +{ TARGET_OPENBSD_NR_readlink, "readlink", "%s(\"%s\",%p,%d)", NULL, NULL }, +{ TARGET_OPENBSD_NR_readv, "readv", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_reboot, "reboot", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_recvfrom, "recvfrom", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_recvmsg, "recvmsg", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_rename, "rename", "%s(\"%s\",\"%s\")", NULL, NULL }, +{ TARGET_OPENBSD_NR_revoke, "revoke", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_rfork, "rfork", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_rmdir, "rmdir", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_sbrk, "sbrk", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_sched_yield, "sched_yield", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_select, "select", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_semget, "semget", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_semop, "semop", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_sendmsg, "sendmsg", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_sendto, "sendto", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_setegid, "setegid", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_seteuid, "seteuid", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_setgid, "setgid", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_setgroups, "setgroups", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_setitimer, "setitimer", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_setlogin, "setlogin", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_setpgid, "setpgid", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_setpriority, "setpriority", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_setregid, "setregid", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_setresgid, "setresgid", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_setresuid, "setresuid", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_setreuid, "setreuid", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_setrlimit, "setrlimit", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_setsid, "setsid", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_setsockopt, "setsockopt", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_settimeofday, "settimeofday", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_setuid, "setuid", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_shmat, "shmat", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_shmctl, "shmctl", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_shmdt, "shmdt", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_shmget, "shmget", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_shutdown, "shutdown", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_sigaction, "sigaction", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_sigaltstack, "sigaltstack", "%s(%p,%p)", NULL, NULL }, +{ TARGET_OPENBSD_NR_sigpending, "sigpending", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_sigprocmask, "sigprocmask", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_sigreturn, "sigreturn", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_sigsuspend, "sigsuspend", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_socket, "socket", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_socketpair, "socketpair", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_sstk, "sstk", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_stat, "stat", "%s(\"%s\",%p)", NULL, NULL }, +{ TARGET_OPENBSD_NR_statfs, "statfs", "%s(\"%s\",%p)", NULL, NULL }, +{ TARGET_OPENBSD_NR_swapctl, "swapctl", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_symlink, "symlink", "%s(\"%s\",\"%s\")", NULL, NULL }, +{ TARGET_OPENBSD_NR_sync, "sync", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_sysarch, "sysarch", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_syscall, "syscall", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_threxit, "threxit", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_thrsigdivert, "thrsigdivert", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_thrsleep, "thrsleep", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_thrwakeup, "thrwakeup", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_truncate, "truncate", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_umask, "umask", "%s(%#o)", NULL, NULL }, +{ TARGET_OPENBSD_NR_unlink, "unlink", "%s(\"%s\")", NULL, NULL }, +{ TARGET_OPENBSD_NR_unmount, "unmount", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_utimes, "utimes", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_vfork, "vfork", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_wait4, "wait4", NULL, NULL, NULL }, +{ TARGET_OPENBSD_NR_write, "write", "%s(%d,%#x,%d)", NULL, NULL }, +{ TARGET_OPENBSD_NR_writev, "writev", "%s(%d,%p,%#x)", NULL, NULL }, +{ TARGET_OPENBSD_NR_xfspioctl, "xfspioctl", NULL, NULL, NULL }, diff --git a/bsd-user/openbsd/syscall_nr.h b/bsd-user/openbsd/syscall_nr.h new file mode 100644 index 00000000..dececfd9 --- /dev/null +++ b/bsd-user/openbsd/syscall_nr.h @@ -0,0 +1,225 @@ +/*      $OpenBSD: syscall.h,v 1.101 2008/03/16 19:43:41 otto Exp $      */ + +/* + * System call numbers. + * + * created from;        OpenBSD: syscalls.master,v 1.90 2008/03/16 19:42:57 otto Exp + */ + +#define TARGET_OPENBSD_NR_syscall     0 +#define TARGET_OPENBSD_NR_exit        1 +#define TARGET_OPENBSD_NR_fork        2 +#define TARGET_OPENBSD_NR_read        3 +#define TARGET_OPENBSD_NR_write       4 +#define TARGET_OPENBSD_NR_open        5 +#define TARGET_OPENBSD_NR_close       6 +#define TARGET_OPENBSD_NR_wait4       7 +#define TARGET_OPENBSD_NR_link        9 +#define TARGET_OPENBSD_NR_unlink      10 +#define TARGET_OPENBSD_NR_chdir       12 +#define TARGET_OPENBSD_NR_fchdir      13 +#define TARGET_OPENBSD_NR_mknod       14 +#define TARGET_OPENBSD_NR_chmod       15 +#define TARGET_OPENBSD_NR_chown       16 +#define TARGET_OPENBSD_NR_break       17 +#define TARGET_OPENBSD_NR_getpid      20 +#define TARGET_OPENBSD_NR_mount       21 +#define TARGET_OPENBSD_NR_unmount     22 +#define TARGET_OPENBSD_NR_setuid      23 +#define TARGET_OPENBSD_NR_getuid      24 +#define TARGET_OPENBSD_NR_geteuid     25 +#define TARGET_OPENBSD_NR_ptrace      26 +#define TARGET_OPENBSD_NR_recvmsg     27 +#define TARGET_OPENBSD_NR_sendmsg     28 +#define TARGET_OPENBSD_NR_recvfrom    29 +#define TARGET_OPENBSD_NR_accept      30 +#define TARGET_OPENBSD_NR_getpeername 31 +#define TARGET_OPENBSD_NR_getsockname 32 +#define TARGET_OPENBSD_NR_access      33 +#define TARGET_OPENBSD_NR_chflags     34 +#define TARGET_OPENBSD_NR_fchflags    35 +#define TARGET_OPENBSD_NR_sync        36 +#define TARGET_OPENBSD_NR_kill        37 +#define TARGET_OPENBSD_NR_getppid     39 +#define TARGET_OPENBSD_NR_dup 41 +#define TARGET_OPENBSD_NR_opipe       42 +#define TARGET_OPENBSD_NR_getegid     43 +#define TARGET_OPENBSD_NR_profil      44 +#define TARGET_OPENBSD_NR_ktrace      45 +#define TARGET_OPENBSD_NR_sigaction   46 +#define TARGET_OPENBSD_NR_getgid      47 +#define TARGET_OPENBSD_NR_sigprocmask 48 +#define TARGET_OPENBSD_NR_getlogin    49 +#define TARGET_OPENBSD_NR_setlogin    50 +#define TARGET_OPENBSD_NR_acct        51 +#define TARGET_OPENBSD_NR_sigpending  52 +#define TARGET_OPENBSD_NR_osigaltstack        53 +#define TARGET_OPENBSD_NR_ioctl       54 +#define TARGET_OPENBSD_NR_reboot      55 +#define TARGET_OPENBSD_NR_revoke      56 +#define TARGET_OPENBSD_NR_symlink     57 +#define TARGET_OPENBSD_NR_readlink    58 +#define TARGET_OPENBSD_NR_execve      59 +#define TARGET_OPENBSD_NR_umask       60 +#define TARGET_OPENBSD_NR_chroot      61 +#define TARGET_OPENBSD_NR_vfork       66 +#define TARGET_OPENBSD_NR_sbrk        69 +#define TARGET_OPENBSD_NR_sstk        70 +#define TARGET_OPENBSD_NR_munmap      73 +#define TARGET_OPENBSD_NR_mprotect    74 +#define TARGET_OPENBSD_NR_madvise     75 +#define TARGET_OPENBSD_NR_mincore     78 +#define TARGET_OPENBSD_NR_getgroups   79 +#define TARGET_OPENBSD_NR_setgroups   80 +#define TARGET_OPENBSD_NR_getpgrp     81 +#define TARGET_OPENBSD_NR_setpgid     82 +#define TARGET_OPENBSD_NR_setitimer   83 +#define TARGET_OPENBSD_NR_getitimer   86 +#define TARGET_OPENBSD_NR_dup2        90 +#define TARGET_OPENBSD_NR_fcntl       92 +#define TARGET_OPENBSD_NR_select      93 +#define TARGET_OPENBSD_NR_fsync       95 +#define TARGET_OPENBSD_NR_setpriority 96 +#define TARGET_OPENBSD_NR_socket      97 +#define TARGET_OPENBSD_NR_connect     98 +#define TARGET_OPENBSD_NR_getpriority 100 +#define TARGET_OPENBSD_NR_sigreturn   103 +#define TARGET_OPENBSD_NR_bind        104 +#define TARGET_OPENBSD_NR_setsockopt  105 +#define TARGET_OPENBSD_NR_listen      106 +#define TARGET_OPENBSD_NR_sigsuspend  111 +#define TARGET_OPENBSD_NR_gettimeofday        116 +#define TARGET_OPENBSD_NR_getrusage   117 +#define TARGET_OPENBSD_NR_getsockopt  118 +#define TARGET_OPENBSD_NR_readv       120 +#define TARGET_OPENBSD_NR_writev      121 +#define TARGET_OPENBSD_NR_settimeofday        122 +#define TARGET_OPENBSD_NR_fchown      123 +#define TARGET_OPENBSD_NR_fchmod      124 +#define TARGET_OPENBSD_NR_setreuid    126 +#define TARGET_OPENBSD_NR_setregid    127 +#define TARGET_OPENBSD_NR_rename      128 +#define TARGET_OPENBSD_NR_flock       131 +#define TARGET_OPENBSD_NR_mkfifo      132 +#define TARGET_OPENBSD_NR_sendto      133 +#define TARGET_OPENBSD_NR_shutdown    134 +#define TARGET_OPENBSD_NR_socketpair  135 +#define TARGET_OPENBSD_NR_mkdir       136 +#define TARGET_OPENBSD_NR_rmdir       137 +#define TARGET_OPENBSD_NR_utimes      138 +#define TARGET_OPENBSD_NR_adjtime     140 +#define TARGET_OPENBSD_NR_setsid      147 +#define TARGET_OPENBSD_NR_quotactl    148 +#define TARGET_OPENBSD_NR_nfssvc      155 +#define TARGET_OPENBSD_NR_getfh       161 +#define TARGET_OPENBSD_NR_sysarch     165 +#define TARGET_OPENBSD_NR_pread       173 +#define TARGET_OPENBSD_NR_pwrite      174 +#define TARGET_OPENBSD_NR_setgid      181 +#define TARGET_OPENBSD_NR_setegid     182 +#define TARGET_OPENBSD_NR_seteuid     183 +#define TARGET_OPENBSD_NR_lfs_bmapv   184 +#define TARGET_OPENBSD_NR_lfs_markv   185 +#define TARGET_OPENBSD_NR_lfs_segclean        186 +#define TARGET_OPENBSD_NR_lfs_segwait 187 +#define TARGET_OPENBSD_NR_pathconf    191 +#define TARGET_OPENBSD_NR_fpathconf   192 +#define TARGET_OPENBSD_NR_swapctl     193 +#define TARGET_OPENBSD_NR_getrlimit   194 +#define TARGET_OPENBSD_NR_setrlimit   195 +#define TARGET_OPENBSD_NR_getdirentries       196 +#define TARGET_OPENBSD_NR_mmap        197 +#define TARGET_OPENBSD_NR___syscall   198 +#define TARGET_OPENBSD_NR_lseek       199 +#define TARGET_OPENBSD_NR_truncate    200 +#define TARGET_OPENBSD_NR_ftruncate   201 +#define TARGET_OPENBSD_NR___sysctl    202 +#define TARGET_OPENBSD_NR_mlock       203 +#define TARGET_OPENBSD_NR_munlock     204 +#define TARGET_OPENBSD_NR_futimes     206 +#define TARGET_OPENBSD_NR_getpgid     207 +#define TARGET_OPENBSD_NR_xfspioctl   208 +#define TARGET_OPENBSD_NR_semget      221 +#define TARGET_OPENBSD_NR_msgget      225 +#define TARGET_OPENBSD_NR_msgsnd      226 +#define TARGET_OPENBSD_NR_msgrcv      227 +#define TARGET_OPENBSD_NR_shmat       228 +#define TARGET_OPENBSD_NR_shmdt       230 +#define TARGET_OPENBSD_NR_clock_gettime       232 +#define TARGET_OPENBSD_NR_clock_settime       233 +#define TARGET_OPENBSD_NR_clock_getres        234 +#define TARGET_OPENBSD_NR_nanosleep   240 +#define TARGET_OPENBSD_NR_minherit    250 +#define TARGET_OPENBSD_NR_rfork       251 +#define TARGET_OPENBSD_NR_poll        252 +#define TARGET_OPENBSD_NR_issetugid   253 +#define TARGET_OPENBSD_NR_lchown      254 +#define TARGET_OPENBSD_NR_getsid      255 +#define TARGET_OPENBSD_NR_msync       256 +#define TARGET_OPENBSD_NR_pipe        263 +#define TARGET_OPENBSD_NR_fhopen      264 +#define TARGET_OPENBSD_NR_preadv      267 +#define TARGET_OPENBSD_NR_pwritev     268 +#define TARGET_OPENBSD_NR_kqueue      269 +#define TARGET_OPENBSD_NR_kevent      270 +#define TARGET_OPENBSD_NR_mlockall    271 +#define TARGET_OPENBSD_NR_munlockall  272 +#define TARGET_OPENBSD_NR_getpeereid  273 +#define TARGET_OPENBSD_NR_getresuid   281 +#define TARGET_OPENBSD_NR_setresuid   282 +#define TARGET_OPENBSD_NR_getresgid   283 +#define TARGET_OPENBSD_NR_setresgid   284 +#define TARGET_OPENBSD_NR_mquery      286 +#define TARGET_OPENBSD_NR_closefrom   287 +#define TARGET_OPENBSD_NR_sigaltstack 288 +#define TARGET_OPENBSD_NR_shmget      289 +#define TARGET_OPENBSD_NR_semop       290 +#define TARGET_OPENBSD_NR_stat        291 +#define TARGET_OPENBSD_NR_fstat       292 +#define TARGET_OPENBSD_NR_lstat       293 +#define TARGET_OPENBSD_NR_fhstat      294 +#define TARGET_OPENBSD_NR___semctl    295 +#define TARGET_OPENBSD_NR_shmctl      296 +#define TARGET_OPENBSD_NR_msgctl      297 +#define TARGET_OPENBSD_NR_sched_yield 298 +#define TARGET_OPENBSD_NR_getthrid    299 +#define TARGET_OPENBSD_NR_thrsleep    300 +#define TARGET_OPENBSD_NR_thrwakeup   301 +#define TARGET_OPENBSD_NR_threxit     302 +#define TARGET_OPENBSD_NR_thrsigdivert        303 +#define TARGET_OPENBSD_NR___getcwd    304 +#define TARGET_OPENBSD_NR_adjfreq     305 +#define TARGET_OPENBSD_NR_getfsstat   306 +#define TARGET_OPENBSD_NR_statfs      307 +#define TARGET_OPENBSD_NR_fstatfs     308 +#define TARGET_OPENBSD_NR_fhstatfs    309 + +/* syscall flags from machine/trap.h */ + +/*      $OpenBSD: trap.h,v 1.4 2008/07/04 22:04:37 kettenis Exp $       */ +/*      $NetBSD: trap.h,v 1.4 1999/06/07 05:28:04 eeh Exp $ */ + +/* + * Copyright (c) 1996-1999 Eduardo Horvath + * + * 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. + * + * 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. + * + */ +#define TARGET_OPENBSD_SYSCALL_G2RFLAG 0x400   /* on success, return to %g2 rather than npc */ +#define TARGET_OPENBSD_SYSCALL_G7RFLAG 0x800   /* use %g7 as above (deprecated) */ diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h new file mode 100644 index 00000000..5362297f --- /dev/null +++ b/bsd-user/qemu.h @@ -0,0 +1,421 @@ +/* + *  qemu bsd user mode definition + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program; if not, see <http://www.gnu.org/licenses/>. + */ +#ifndef QEMU_H +#define QEMU_H + +#include <signal.h> +#include <string.h> + +#include "cpu.h" +#include "exec/cpu_ldst.h" + +#undef DEBUG_REMAP +#ifdef DEBUG_REMAP +#include <stdlib.h> +#endif /* DEBUG_REMAP */ + +#include "exec/user/abitypes.h" + +enum BSDType { +    target_freebsd, +    target_netbsd, +    target_openbsd, +}; +extern enum BSDType bsd_type; + +#include "syscall_defs.h" +#include "syscall.h" +#include "target_signal.h" +#include "exec/gdbstub.h" + +#if defined(CONFIG_USE_NPTL) +#define THREAD __thread +#else +#define THREAD +#endif + +/* This struct is used to hold certain information about the image. + * Basically, it replicates in user space what would be certain + * task_struct fields in the kernel + */ +struct image_info { +    abi_ulong load_addr; +    abi_ulong start_code; +    abi_ulong end_code; +    abi_ulong start_data; +    abi_ulong end_data; +    abi_ulong start_brk; +    abi_ulong brk; +    abi_ulong start_mmap; +    abi_ulong mmap; +    abi_ulong rss; +    abi_ulong start_stack; +    abi_ulong entry; +    abi_ulong code_offset; +    abi_ulong data_offset; +    int       personality; +}; + +#define MAX_SIGQUEUE_SIZE 1024 + +struct sigqueue { +    struct sigqueue *next; +    //target_siginfo_t info; +}; + +struct emulated_sigtable { +    int pending; /* true if signal is pending */ +    struct sigqueue *first; +    struct sigqueue info; /* in order to always have memory for the +                             first signal, we put it here */ +}; + +/* NOTE: we force a big alignment so that the stack stored after is +   aligned too */ +typedef struct TaskState { +    struct TaskState *next; +    int used; /* non zero if used */ +    struct image_info *info; + +    struct emulated_sigtable sigtab[TARGET_NSIG]; +    struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */ +    struct sigqueue *first_free; /* first free siginfo queue entry */ +    int signal_pending; /* non zero if a signal may be pending */ + +    uint8_t stack[0]; +} __attribute__((aligned(16))) TaskState; + +void init_task_state(TaskState *ts); +extern const char *qemu_uname_release; +#if defined(CONFIG_USE_GUEST_BASE) +extern unsigned long mmap_min_addr; +#endif + +/* ??? See if we can avoid exposing so much of the loader internals.  */ +/* + * MAX_ARG_PAGES defines the number of pages allocated for arguments + * and envelope for the new program. 32 should suffice, this gives + * a maximum env+arg of 128kB w/4KB pages! + */ +#define MAX_ARG_PAGES 32 + +/* + * This structure is used to hold the arguments that are + * used when loading binaries. + */ +struct linux_binprm { +        char buf[128]; +        void *page[MAX_ARG_PAGES]; +        abi_ulong p; +        int fd; +        int e_uid, e_gid; +        int argc, envc; +        char **argv; +        char **envp; +        char * filename;        /* Name of binary */ +}; + +void do_init_thread(struct target_pt_regs *regs, struct image_info *infop); +abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp, +                              abi_ulong stringp, int push_ptr); +int loader_exec(const char * filename, char ** argv, char ** envp, +             struct target_pt_regs * regs, struct image_info *infop); + +int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, +                    struct image_info * info); +int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, +                    struct image_info * info); + +abi_long memcpy_to_target(abi_ulong dest, const void *src, +                          unsigned long len); +void target_set_brk(abi_ulong new_brk); +abi_long do_brk(abi_ulong new_brk); +void syscall_init(void); +abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, +                            abi_long arg2, abi_long arg3, abi_long arg4, +                            abi_long arg5, abi_long arg6, abi_long arg7, +                            abi_long arg8); +abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1, +                           abi_long arg2, abi_long arg3, abi_long arg4, +                           abi_long arg5, abi_long arg6); +abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1, +                            abi_long arg2, abi_long arg3, abi_long arg4, +                            abi_long arg5, abi_long arg6); +void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2); +extern THREAD CPUState *thread_cpu; +void cpu_loop(CPUArchState *env); +char *target_strerror(int err); +int get_osversion(void); +void fork_start(void); +void fork_end(int child); + +#include "qemu/log.h" + +/* strace.c */ +struct syscallname { +    int nr; +    const char *name; +    const char *format; +    void (*call)(const struct syscallname *, +                 abi_long, abi_long, abi_long, +                 abi_long, abi_long, abi_long); +    void (*result)(const struct syscallname *, abi_long); +}; + +void +print_freebsd_syscall(int num, +                      abi_long arg1, abi_long arg2, abi_long arg3, +                      abi_long arg4, abi_long arg5, abi_long arg6); +void print_freebsd_syscall_ret(int num, abi_long ret); +void +print_netbsd_syscall(int num, +                     abi_long arg1, abi_long arg2, abi_long arg3, +                     abi_long arg4, abi_long arg5, abi_long arg6); +void print_netbsd_syscall_ret(int num, abi_long ret); +void +print_openbsd_syscall(int num, +                      abi_long arg1, abi_long arg2, abi_long arg3, +                      abi_long arg4, abi_long arg5, abi_long arg6); +void print_openbsd_syscall_ret(int num, abi_long ret); +extern int do_strace; + +/* signal.c */ +void process_pending_signals(CPUArchState *cpu_env); +void signal_init(void); +//int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info); +//void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info); +//void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo); +long do_sigreturn(CPUArchState *env); +long do_rt_sigreturn(CPUArchState *env); +abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp); + +/* mmap.c */ +int target_mprotect(abi_ulong start, abi_ulong len, int prot); +abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, +                     int flags, int fd, abi_ulong offset); +int target_munmap(abi_ulong start, abi_ulong len); +abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, +                       abi_ulong new_size, unsigned long flags, +                       abi_ulong new_addr); +int target_msync(abi_ulong start, abi_ulong len, int flags); +extern unsigned long last_brk; +void mmap_lock(void); +void mmap_unlock(void); +void cpu_list_lock(void); +void cpu_list_unlock(void); +#if defined(CONFIG_USE_NPTL) +void mmap_fork_start(void); +void mmap_fork_end(int child); +#endif + +/* main.c */ +extern unsigned long x86_stack_size; + +/* user access */ + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 /* implies read access */ + +static inline int access_ok(int type, abi_ulong addr, abi_ulong size) +{ +    return page_check_range((target_ulong)addr, size, +                            (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0; +} + +/* NOTE __get_user and __put_user use host pointers and don't check access. */ +/* These are usually used to access struct data members once the + * struct has been locked - usually with lock_user_struct(). + */ +#define __put_user(x, hptr)\ +({\ +    int size = sizeof(*hptr);\ +    switch(size) {\ +    case 1:\ +        *(uint8_t *)(hptr) = (uint8_t)(typeof(*hptr))(x);\ +        break;\ +    case 2:\ +        *(uint16_t *)(hptr) = tswap16((typeof(*hptr))(x));\ +        break;\ +    case 4:\ +        *(uint32_t *)(hptr) = tswap32((typeof(*hptr))(x));\ +        break;\ +    case 8:\ +        *(uint64_t *)(hptr) = tswap64((typeof(*hptr))(x));\ +        break;\ +    default:\ +        abort();\ +    }\ +    0;\ +}) + +#define __get_user(x, hptr) \ +({\ +    int size = sizeof(*hptr);\ +    switch(size) {\ +    case 1:\ +        x = (typeof(*hptr))*(uint8_t *)(hptr);\ +        break;\ +    case 2:\ +        x = (typeof(*hptr))tswap16(*(uint16_t *)(hptr));\ +        break;\ +    case 4:\ +        x = (typeof(*hptr))tswap32(*(uint32_t *)(hptr));\ +        break;\ +    case 8:\ +        x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\ +        break;\ +    default:\ +        /* avoid warning */\ +        x = 0;\ +        abort();\ +    }\ +    0;\ +}) + +/* put_user()/get_user() take a guest address and check access */ +/* These are usually used to access an atomic data type, such as an int, + * that has been passed by address.  These internally perform locking + * and unlocking on the data type. + */ +#define put_user(x, gaddr, target_type)                                 \ +({                                                                      \ +    abi_ulong __gaddr = (gaddr);                                        \ +    target_type *__hptr;                                                \ +    abi_long __ret;                                                     \ +    if ((__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0))) { \ +        __ret = __put_user((x), __hptr);                                \ +        unlock_user(__hptr, __gaddr, sizeof(target_type));              \ +    } else                                                              \ +        __ret = -TARGET_EFAULT;                                         \ +    __ret;                                                              \ +}) + +#define get_user(x, gaddr, target_type)                                 \ +({                                                                      \ +    abi_ulong __gaddr = (gaddr);                                        \ +    target_type *__hptr;                                                \ +    abi_long __ret;                                                     \ +    if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1))) { \ +        __ret = __get_user((x), __hptr);                                \ +        unlock_user(__hptr, __gaddr, 0);                                \ +    } else {                                                            \ +        /* avoid warning */                                             \ +        (x) = 0;                                                        \ +        __ret = -TARGET_EFAULT;                                         \ +    }                                                                   \ +    __ret;                                                              \ +}) + +#define put_user_ual(x, gaddr) put_user((x), (gaddr), abi_ulong) +#define put_user_sal(x, gaddr) put_user((x), (gaddr), abi_long) +#define put_user_u64(x, gaddr) put_user((x), (gaddr), uint64_t) +#define put_user_s64(x, gaddr) put_user((x), (gaddr), int64_t) +#define put_user_u32(x, gaddr) put_user((x), (gaddr), uint32_t) +#define put_user_s32(x, gaddr) put_user((x), (gaddr), int32_t) +#define put_user_u16(x, gaddr) put_user((x), (gaddr), uint16_t) +#define put_user_s16(x, gaddr) put_user((x), (gaddr), int16_t) +#define put_user_u8(x, gaddr)  put_user((x), (gaddr), uint8_t) +#define put_user_s8(x, gaddr)  put_user((x), (gaddr), int8_t) + +#define get_user_ual(x, gaddr) get_user((x), (gaddr), abi_ulong) +#define get_user_sal(x, gaddr) get_user((x), (gaddr), abi_long) +#define get_user_u64(x, gaddr) get_user((x), (gaddr), uint64_t) +#define get_user_s64(x, gaddr) get_user((x), (gaddr), int64_t) +#define get_user_u32(x, gaddr) get_user((x), (gaddr), uint32_t) +#define get_user_s32(x, gaddr) get_user((x), (gaddr), int32_t) +#define get_user_u16(x, gaddr) get_user((x), (gaddr), uint16_t) +#define get_user_s16(x, gaddr) get_user((x), (gaddr), int16_t) +#define get_user_u8(x, gaddr)  get_user((x), (gaddr), uint8_t) +#define get_user_s8(x, gaddr)  get_user((x), (gaddr), int8_t) + +/* copy_from_user() and copy_to_user() are usually used to copy data + * buffers between the target and host.  These internally perform + * locking/unlocking of the memory. + */ +abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len); +abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len); + +/* Functions for accessing guest memory.  The tget and tput functions +   read/write single values, byteswapping as necessary.  The lock_user function +   gets a pointer to a contiguous area of guest memory, but does not perform +   any byteswapping.  lock_user may return either a pointer to the guest +   memory, or a temporary buffer.  */ + +/* Lock an area of guest memory into the host.  If copy is true then the +   host area will have the same contents as the guest.  */ +static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy) +{ +    if (!access_ok(type, guest_addr, len)) +        return NULL; +#ifdef DEBUG_REMAP +    { +        void *addr; +        addr = malloc(len); +        if (copy) +            memcpy(addr, g2h(guest_addr), len); +        else +            memset(addr, 0, len); +        return addr; +    } +#else +    return g2h(guest_addr); +#endif +} + +/* Unlock an area of guest memory.  The first LEN bytes must be +   flushed back to guest memory. host_ptr = NULL is explicitly +   allowed and does nothing. */ +static inline void unlock_user(void *host_ptr, abi_ulong guest_addr, +                               long len) +{ + +#ifdef DEBUG_REMAP +    if (!host_ptr) +        return; +    if (host_ptr == g2h(guest_addr)) +        return; +    if (len > 0) +        memcpy(g2h(guest_addr), host_ptr, len); +    free(host_ptr); +#endif +} + +/* Return the length of a string in target memory or -TARGET_EFAULT if +   access error. */ +abi_long target_strlen(abi_ulong gaddr); + +/* Like lock_user but for null terminated strings.  */ +static inline void *lock_user_string(abi_ulong guest_addr) +{ +    abi_long len; +    len = target_strlen(guest_addr); +    if (len < 0) +        return NULL; +    return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1); +} + +/* Helper macros for locking/unlocking a target struct.  */ +#define lock_user_struct(type, host_ptr, guest_addr, copy)      \ +    (host_ptr = lock_user(type, guest_addr, sizeof(*host_ptr), copy)) +#define unlock_user_struct(host_ptr, guest_addr, copy)          \ +    unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0) + +#if defined(CONFIG_USE_NPTL) +#include <pthread.h> +#endif + +#endif /* QEMU_H */ diff --git a/bsd-user/signal.c b/bsd-user/signal.c new file mode 100644 index 00000000..445f69e8 --- /dev/null +++ b/bsd-user/signal.c @@ -0,0 +1,38 @@ +/* + *  Emulation of BSD signals + * + *  Copyright (c) 2003 - 2008 Fabrice Bellard + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program; if not, see <http://www.gnu.org/licenses/>. + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <unistd.h> +#include <signal.h> +#include <errno.h> + +#include "qemu.h" +#include "target_signal.h" + +//#define DEBUG_SIGNAL + +void signal_init(void) +{ +} + +void process_pending_signals(CPUArchState *cpu_env) +{ +} diff --git a/bsd-user/sparc/syscall.h b/bsd-user/sparc/syscall.h new file mode 100644 index 00000000..5a9bb7e5 --- /dev/null +++ b/bsd-user/sparc/syscall.h @@ -0,0 +1,9 @@ +struct target_pt_regs { +	abi_ulong psr; +	abi_ulong pc; +	abi_ulong npc; +	abi_ulong y; +	abi_ulong u_regs[16]; +}; + +#define UNAME_MACHINE "sun4" diff --git a/bsd-user/sparc/target_signal.h b/bsd-user/sparc/target_signal.h new file mode 100644 index 00000000..5b2abba4 --- /dev/null +++ b/bsd-user/sparc/target_signal.h @@ -0,0 +1,27 @@ +#ifndef TARGET_SIGNAL_H +#define TARGET_SIGNAL_H + +#include "cpu.h" + +/* this struct defines a stack used during syscall handling */ + +typedef struct target_sigaltstack { +	abi_ulong ss_sp; +	abi_long ss_flags; +	abi_ulong ss_size; +} target_stack_t; + + +#ifndef UREG_I6 +#define UREG_I6        6 +#endif +#ifndef UREG_FP +#define UREG_FP        UREG_I6 +#endif + +static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state) +{ +    return state->regwptr[UREG_FP]; +} + +#endif /* TARGET_SIGNAL_H */ diff --git a/bsd-user/sparc64/syscall.h b/bsd-user/sparc64/syscall.h new file mode 100644 index 00000000..81a816de --- /dev/null +++ b/bsd-user/sparc64/syscall.h @@ -0,0 +1,10 @@ +struct target_pt_regs { +	abi_ulong u_regs[16]; +	abi_ulong tstate; +	abi_ulong pc; +	abi_ulong npc; +	abi_ulong y; +	abi_ulong fprs; +}; + +#define UNAME_MACHINE "sun4u" diff --git a/bsd-user/sparc64/target_signal.h b/bsd-user/sparc64/target_signal.h new file mode 100644 index 00000000..5b2abba4 --- /dev/null +++ b/bsd-user/sparc64/target_signal.h @@ -0,0 +1,27 @@ +#ifndef TARGET_SIGNAL_H +#define TARGET_SIGNAL_H + +#include "cpu.h" + +/* this struct defines a stack used during syscall handling */ + +typedef struct target_sigaltstack { +	abi_ulong ss_sp; +	abi_long ss_flags; +	abi_ulong ss_size; +} target_stack_t; + + +#ifndef UREG_I6 +#define UREG_I6        6 +#endif +#ifndef UREG_FP +#define UREG_FP        UREG_I6 +#endif + +static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state) +{ +    return state->regwptr[UREG_FP]; +} + +#endif /* TARGET_SIGNAL_H */ diff --git a/bsd-user/strace.c b/bsd-user/strace.c new file mode 100644 index 00000000..e33dd4d4 --- /dev/null +++ b/bsd-user/strace.c @@ -0,0 +1,242 @@ +/* + *  System call tracing and debugging + * + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include <errno.h> +#include <sys/select.h> +#include <sys/types.h> +#include <unistd.h> +#include <sys/syscall.h> +#include <sys/ioccom.h> +#include <ctype.h> + +#include "qemu.h" + +int do_strace; + +/* + * Utility functions + */ + +static void print_sysctl(const struct syscallname *name, abi_long arg1, +        abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, +        abi_long arg6) +{ +    uint32_t i; +    int32_t *namep; + +    gemu_log("%s({ ", name->name); +    namep = lock_user(VERIFY_READ, arg1, sizeof(int32_t) * arg2, 1); +    if (namep) { +        int32_t *p = namep; + +        for (i = 0; i < (uint32_t)arg2; i++) { +            gemu_log("%d ", tswap32(*p++)); +        } +        unlock_user(namep, arg1, 0); +    } +    gemu_log("}, %u, 0x" TARGET_ABI_FMT_lx ", 0x" TARGET_ABI_FMT_lx ", 0x" +        TARGET_ABI_FMT_lx ", 0x" TARGET_ABI_FMT_lx ")", +        (uint32_t)arg2, arg3, arg4, arg5, arg6); +} + +static void print_execve(const struct syscallname *name, abi_long arg1, +        abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, +        abi_long arg6) +{ +    abi_ulong arg_ptr_addr; +    char *s; + +    s = lock_user_string(arg1); +    if (s == NULL) { +        return; +    } +    gemu_log("%s(\"%s\",{", name->name, s); +    unlock_user(s, arg1, 0); + +    for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(abi_ulong)) { +        abi_ulong *arg_ptr, arg_addr; + +        arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1); +        if (!arg_ptr) { +            return; +        } +        arg_addr = tswapl(*arg_ptr); +        unlock_user(arg_ptr, arg_ptr_addr, 0); +        if (!arg_addr) { +            break; +        } +        if ((s = lock_user_string(arg_addr))) { +            gemu_log("\"%s\",", s); +            unlock_user(s, arg_addr, 0); +        } +    } +    gemu_log("NULL})"); +} + +static void print_ioctl(const struct syscallname *name, +        abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, +        abi_long arg5, abi_long arg6) +{ +    /* Decode the ioctl request */ +    gemu_log("%s(%d, 0x%0lx { IO%s%s GRP:0x%x('%c') CMD:%d LEN:%d }, 0x" +            TARGET_ABI_FMT_lx ", ...)", +            name->name, +            (int)arg1, +            (unsigned long)arg2, +            arg2 & IOC_OUT ? "R" : "", +            arg2 & IOC_IN ? "W" : "", +            (unsigned)IOCGROUP(arg2), +            isprint(IOCGROUP(arg2)) ? (char)IOCGROUP(arg2) : '?', +            (int)arg2 & 0xFF, +            (int)IOCPARM_LEN(arg2), +            arg3); +} + +/* + * Variants for the return value output function + */ + +static void print_syscall_ret_addr(const struct syscallname *name, abi_long ret) +{ +    if (ret == -1) { +        gemu_log(" = -1 errno=%d (%s)\n", errno, strerror(errno)); +    } else { +        gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret); +    } +} + +#if 0 /* currently unused */ +static void +print_syscall_ret_raw(struct syscallname *name, abi_long ret) +{ +        gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret); +} +#endif + +/* + * An array of all of the syscalls we know about + */ + +static const struct syscallname freebsd_scnames[] = { +#include "freebsd/strace.list" +}; +static const struct syscallname netbsd_scnames[] = { +#include "netbsd/strace.list" +}; +static const struct syscallname openbsd_scnames[] = { +#include "openbsd/strace.list" +}; + +static void print_syscall(int num, const struct syscallname *scnames, +        unsigned int nscnames, abi_long arg1, abi_long arg2, abi_long arg3, +        abi_long arg4, abi_long arg5, abi_long arg6) +{ +    unsigned int i; +    const char *format="%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," +        TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," +        TARGET_ABI_FMT_ld ")"; + +    gemu_log("%d ", getpid() ); + +    for (i = 0; i < nscnames; i++) { +        if (scnames[i].nr == num) { +            if (scnames[i].call != NULL) { +                scnames[i].call(&scnames[i], arg1, arg2, arg3, arg4, arg5, +                        arg6); +            } else { +                /* XXX: this format system is broken because it uses +                   host types and host pointers for strings */ +                if (scnames[i].format != NULL) { +                    format = scnames[i].format; +                } +                gemu_log(format, scnames[i].name, arg1, arg2, arg3, arg4, arg5, +                        arg6); +            } +            return; +        } +    } +    gemu_log("Unknown syscall %d\n", num); +} + +static void print_syscall_ret(int num, abi_long ret, +        const struct syscallname *scnames, unsigned int nscnames) +{ +    unsigned int i; + +    for (i = 0; i < nscnames; i++) { +        if (scnames[i].nr == num) { +            if (scnames[i].result != NULL) { +                scnames[i].result(&scnames[i], ret); +            } else { +                if (ret < 0) { +                    gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", -ret, +                             strerror(-ret)); +                } else { +                    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret); +                } +            } +            break; +        } +    } +} + +/* + * The public interface to this module. + */ +void print_freebsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3, +        abi_long arg4, abi_long arg5, abi_long arg6) +{ + +    print_syscall(num, freebsd_scnames, ARRAY_SIZE(freebsd_scnames), arg1, arg2, +            arg3, arg4, arg5, arg6); +} + +void print_freebsd_syscall_ret(int num, abi_long ret) +{ + +    print_syscall_ret(num, ret, freebsd_scnames, ARRAY_SIZE(freebsd_scnames)); +} + +void print_netbsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3, +        abi_long arg4, abi_long arg5, abi_long arg6) +{ + +    print_syscall(num, netbsd_scnames, ARRAY_SIZE(netbsd_scnames), +                  arg1, arg2, arg3, arg4, arg5, arg6); +} + +void print_netbsd_syscall_ret(int num, abi_long ret) +{ + +    print_syscall_ret(num, ret, netbsd_scnames, ARRAY_SIZE(netbsd_scnames)); +} + +void print_openbsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3, +        abi_long arg4, abi_long arg5, abi_long arg6) +{ + +    print_syscall(num, openbsd_scnames, ARRAY_SIZE(openbsd_scnames), arg1, arg2, +            arg3, arg4, arg5, arg6); +} + +void print_openbsd_syscall_ret(int num, abi_long ret) +{ + +    print_syscall_ret(num, ret, openbsd_scnames, ARRAY_SIZE(openbsd_scnames)); +} diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c new file mode 100644 index 00000000..a4d1583f --- /dev/null +++ b/bsd-user/syscall.c @@ -0,0 +1,564 @@ +/* + *  BSD syscalls + * + *  Copyright (c) 2003 - 2008 Fabrice Bellard + * + *  This program is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 2 of the License, or + *  (at your option) any later version. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with this program; if not, see <http://www.gnu.org/licenses/>. + */ +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <stdarg.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <time.h> +#include <limits.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/syscall.h> +#include <sys/param.h> +#include <sys/sysctl.h> +#include <utime.h> + +#include "qemu.h" +#include "qemu-common.h" + +//#define DEBUG + +static abi_ulong target_brk; +static abi_ulong target_original_brk; + +static inline abi_long get_errno(abi_long ret) +{ +    if (ret == -1) +        /* XXX need to translate host -> target errnos here */ +        return -(errno); +    else +        return ret; +} + +#define target_to_host_bitmask(x, tbl) (x) + +static inline int is_error(abi_long ret) +{ +    return (abi_ulong)ret >= (abi_ulong)(-4096); +} + +void target_set_brk(abi_ulong new_brk) +{ +    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk); +} + +/* do_obreak() must return target errnos. */ +static abi_long do_obreak(abi_ulong new_brk) +{ +    abi_ulong brk_page; +    abi_long mapped_addr; +    int new_alloc_size; + +    if (!new_brk) +        return 0; +    if (new_brk < target_original_brk) +        return -TARGET_EINVAL; + +    brk_page = HOST_PAGE_ALIGN(target_brk); + +    /* If the new brk is less than this, set it and we're done... */ +    if (new_brk < brk_page) { +        target_brk = new_brk; +        return 0; +    } + +    /* We need to allocate more memory after the brk... */ +    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1); +    mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, +                                        PROT_READ|PROT_WRITE, +                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0)); + +    if (!is_error(mapped_addr)) +        target_brk = new_brk; +    else +        return mapped_addr; + +    return 0; +} + +#if defined(TARGET_I386) +static abi_long do_freebsd_sysarch(CPUX86State *env, int op, abi_ulong parms) +{ +    abi_long ret = 0; +    abi_ulong val; +    int idx; + +    switch(op) { +#ifdef TARGET_ABI32 +    case TARGET_FREEBSD_I386_SET_GSBASE: +    case TARGET_FREEBSD_I386_SET_FSBASE: +        if (op == TARGET_FREEBSD_I386_SET_GSBASE) +#else +    case TARGET_FREEBSD_AMD64_SET_GSBASE: +    case TARGET_FREEBSD_AMD64_SET_FSBASE: +        if (op == TARGET_FREEBSD_AMD64_SET_GSBASE) +#endif +            idx = R_GS; +        else +            idx = R_FS; +        if (get_user(val, parms, abi_ulong)) +            return -TARGET_EFAULT; +        cpu_x86_load_seg(env, idx, 0); +        env->segs[idx].base = val; +        break; +#ifdef TARGET_ABI32 +    case TARGET_FREEBSD_I386_GET_GSBASE: +    case TARGET_FREEBSD_I386_GET_FSBASE: +        if (op == TARGET_FREEBSD_I386_GET_GSBASE) +#else +    case TARGET_FREEBSD_AMD64_GET_GSBASE: +    case TARGET_FREEBSD_AMD64_GET_FSBASE: +        if (op == TARGET_FREEBSD_AMD64_GET_GSBASE) +#endif +            idx = R_GS; +        else +            idx = R_FS; +        val = env->segs[idx].base; +        if (put_user(val, parms, abi_ulong)) +            return -TARGET_EFAULT; +        break; +    /* XXX handle the others... */ +    default: +        ret = -TARGET_EINVAL; +        break; +    } +    return ret; +} +#endif + +#ifdef TARGET_SPARC +static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms) +{ +    /* XXX handle +     * TARGET_FREEBSD_SPARC_UTRAP_INSTALL, +     * TARGET_FREEBSD_SPARC_SIGTRAMP_INSTALL +     */ +    return -TARGET_EINVAL; +} +#endif + +#ifdef __FreeBSD__ +/* + * XXX this uses the undocumented oidfmt interface to find the kind of + * a requested sysctl, see /sys/kern/kern_sysctl.c:sysctl_sysctl_oidfmt() + * (this is mostly copied from src/sbin/sysctl/sysctl.c) + */ +static int +oidfmt(int *oid, int len, char *fmt, uint32_t *kind) +{ +    int qoid[CTL_MAXNAME+2]; +    uint8_t buf[BUFSIZ]; +    int i; +    size_t j; + +    qoid[0] = 0; +    qoid[1] = 4; +    memcpy(qoid + 2, oid, len * sizeof(int)); + +    j = sizeof(buf); +    i = sysctl(qoid, len + 2, buf, &j, 0, 0); +    if (i) +        return i; + +    if (kind) +        *kind = *(uint32_t *)buf; + +    if (fmt) +        strcpy(fmt, (char *)(buf + sizeof(uint32_t))); +    return (0); +} + +/* + * try and convert sysctl return data for the target. + * XXX doesn't handle CTLTYPE_OPAQUE and CTLTYPE_STRUCT. + */ +static int sysctl_oldcvt(void *holdp, size_t holdlen, uint32_t kind) +{ +    switch (kind & CTLTYPE) { +    case CTLTYPE_INT: +    case CTLTYPE_UINT: +        *(uint32_t *)holdp = tswap32(*(uint32_t *)holdp); +        break; +#ifdef TARGET_ABI32 +    case CTLTYPE_LONG: +    case CTLTYPE_ULONG: +        *(uint32_t *)holdp = tswap32(*(long *)holdp); +        break; +#else +    case CTLTYPE_LONG: +        *(uint64_t *)holdp = tswap64(*(long *)holdp); +    case CTLTYPE_ULONG: +        *(uint64_t *)holdp = tswap64(*(unsigned long *)holdp); +        break; +#endif +#ifdef CTLTYPE_U64 +    case CTLTYPE_S64: +    case CTLTYPE_U64: +#else +    case CTLTYPE_QUAD: +#endif +        *(uint64_t *)holdp = tswap64(*(uint64_t *)holdp); +        break; +    case CTLTYPE_STRING: +        break; +    default: +        /* XXX unhandled */ +        return -1; +    } +    return 0; +} + +/* XXX this needs to be emulated on non-FreeBSD hosts... */ +static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong oldp, +                          abi_ulong oldlenp, abi_ulong newp, abi_ulong newlen) +{ +    abi_long ret; +    void *hnamep, *holdp, *hnewp = NULL; +    size_t holdlen; +    abi_ulong oldlen = 0; +    int32_t *snamep = g_malloc(sizeof(int32_t) * namelen), *p, *q, i; +    uint32_t kind = 0; + +    if (oldlenp) +        get_user_ual(oldlen, oldlenp); +    if (!(hnamep = lock_user(VERIFY_READ, namep, namelen, 1))) +        return -TARGET_EFAULT; +    if (newp && !(hnewp = lock_user(VERIFY_READ, newp, newlen, 1))) +        return -TARGET_EFAULT; +    if (!(holdp = lock_user(VERIFY_WRITE, oldp, oldlen, 0))) +        return -TARGET_EFAULT; +    holdlen = oldlen; +    for (p = hnamep, q = snamep, i = 0; i < namelen; p++, i++) +       *q++ = tswap32(*p); +    oidfmt(snamep, namelen, NULL, &kind); +    /* XXX swap hnewp */ +    ret = get_errno(sysctl(snamep, namelen, holdp, &holdlen, hnewp, newlen)); +    if (!ret) +        sysctl_oldcvt(holdp, holdlen, kind); +    put_user_ual(holdlen, oldlenp); +    unlock_user(hnamep, namep, 0); +    unlock_user(holdp, oldp, holdlen); +    if (hnewp) +        unlock_user(hnewp, newp, 0); +    g_free(snamep); +    return ret; +} +#endif + +/* FIXME + * lock_iovec()/unlock_iovec() have a return code of 0 for success where + * other lock functions have a return code of 0 for failure. + */ +static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr, +                           int count, int copy) +{ +    struct target_iovec *target_vec; +    abi_ulong base; +    int i; + +    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1); +    if (!target_vec) +        return -TARGET_EFAULT; +    for(i = 0;i < count; i++) { +        base = tswapl(target_vec[i].iov_base); +        vec[i].iov_len = tswapl(target_vec[i].iov_len); +        if (vec[i].iov_len != 0) { +            vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy); +            /* Don't check lock_user return value. We must call writev even +               if a element has invalid base address. */ +        } else { +            /* zero length pointer is ignored */ +            vec[i].iov_base = NULL; +        } +    } +    unlock_user (target_vec, target_addr, 0); +    return 0; +} + +static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr, +                             int count, int copy) +{ +    struct target_iovec *target_vec; +    abi_ulong base; +    int i; + +    target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1); +    if (!target_vec) +        return -TARGET_EFAULT; +    for(i = 0;i < count; i++) { +        if (target_vec[i].iov_base) { +            base = tswapl(target_vec[i].iov_base); +            unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); +        } +    } +    unlock_user (target_vec, target_addr, 0); + +    return 0; +} + +/* do_syscall() should always have a single exit point at the end so +   that actions, such as logging of syscall results, can be performed. +   All errnos that do_syscall() returns must be -TARGET_<errcode>. */ +abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, +                            abi_long arg2, abi_long arg3, abi_long arg4, +                            abi_long arg5, abi_long arg6, abi_long arg7, +                            abi_long arg8) +{ +    abi_long ret; +    void *p; + +#ifdef DEBUG +    gemu_log("freebsd syscall %d\n", num); +#endif +    if(do_strace) +        print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); + +    switch(num) { +    case TARGET_FREEBSD_NR_exit: +#ifdef TARGET_GPROF +        _mcleanup(); +#endif +        gdb_exit(cpu_env, arg1); +        /* XXX: should free thread stack and CPU env */ +        _exit(arg1); +        ret = 0; /* avoid warning */ +        break; +    case TARGET_FREEBSD_NR_read: +        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) +            goto efault; +        ret = get_errno(read(arg1, p, arg3)); +        unlock_user(p, arg2, ret); +        break; +    case TARGET_FREEBSD_NR_write: +        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) +            goto efault; +        ret = get_errno(write(arg1, p, arg3)); +        unlock_user(p, arg2, 0); +        break; +    case TARGET_FREEBSD_NR_writev: +        { +            int count = arg3; +            struct iovec *vec; + +            vec = alloca(count * sizeof(struct iovec)); +            if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) +                goto efault; +            ret = get_errno(writev(arg1, vec, count)); +            unlock_iovec(vec, arg2, count, 0); +        } +        break; +    case TARGET_FREEBSD_NR_open: +        if (!(p = lock_user_string(arg1))) +            goto efault; +        ret = get_errno(open(path(p), +                             target_to_host_bitmask(arg2, fcntl_flags_tbl), +                             arg3)); +        unlock_user(p, arg1, 0); +        break; +    case TARGET_FREEBSD_NR_mmap: +        ret = get_errno(target_mmap(arg1, arg2, arg3, +                                    target_to_host_bitmask(arg4, mmap_flags_tbl), +                                    arg5, +                                    arg6)); +        break; +    case TARGET_FREEBSD_NR_mprotect: +        ret = get_errno(target_mprotect(arg1, arg2, arg3)); +        break; +    case TARGET_FREEBSD_NR_break: +        ret = do_obreak(arg1); +        break; +#ifdef __FreeBSD__ +    case TARGET_FREEBSD_NR___sysctl: +        ret = do_freebsd_sysctl(arg1, arg2, arg3, arg4, arg5, arg6); +        break; +#endif +    case TARGET_FREEBSD_NR_sysarch: +        ret = do_freebsd_sysarch(cpu_env, arg1, arg2); +        break; +    case TARGET_FREEBSD_NR_syscall: +    case TARGET_FREEBSD_NR___syscall: +        ret = do_freebsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,arg7,arg8,0); +        break; +    default: +        ret = get_errno(syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)); +        break; +    } + fail: +#ifdef DEBUG +    gemu_log(" = %ld\n", ret); +#endif +    if (do_strace) +        print_freebsd_syscall_ret(num, ret); +    return ret; + efault: +    ret = -TARGET_EFAULT; +    goto fail; +} + +abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1, +                           abi_long arg2, abi_long arg3, abi_long arg4, +                           abi_long arg5, abi_long arg6) +{ +    abi_long ret; +    void *p; + +#ifdef DEBUG +    gemu_log("netbsd syscall %d\n", num); +#endif +    if(do_strace) +        print_netbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); + +    switch(num) { +    case TARGET_NETBSD_NR_exit: +#ifdef TARGET_GPROF +        _mcleanup(); +#endif +        gdb_exit(cpu_env, arg1); +        /* XXX: should free thread stack and CPU env */ +        _exit(arg1); +        ret = 0; /* avoid warning */ +        break; +    case TARGET_NETBSD_NR_read: +        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) +            goto efault; +        ret = get_errno(read(arg1, p, arg3)); +        unlock_user(p, arg2, ret); +        break; +    case TARGET_NETBSD_NR_write: +        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) +            goto efault; +        ret = get_errno(write(arg1, p, arg3)); +        unlock_user(p, arg2, 0); +        break; +    case TARGET_NETBSD_NR_open: +        if (!(p = lock_user_string(arg1))) +            goto efault; +        ret = get_errno(open(path(p), +                             target_to_host_bitmask(arg2, fcntl_flags_tbl), +                             arg3)); +        unlock_user(p, arg1, 0); +        break; +    case TARGET_NETBSD_NR_mmap: +        ret = get_errno(target_mmap(arg1, arg2, arg3, +                                    target_to_host_bitmask(arg4, mmap_flags_tbl), +                                    arg5, +                                    arg6)); +        break; +    case TARGET_NETBSD_NR_mprotect: +        ret = get_errno(target_mprotect(arg1, arg2, arg3)); +        break; +    case TARGET_NETBSD_NR_syscall: +    case TARGET_NETBSD_NR___syscall: +        ret = do_netbsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0); +        break; +    default: +        ret = syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); +        break; +    } + fail: +#ifdef DEBUG +    gemu_log(" = %ld\n", ret); +#endif +    if (do_strace) +        print_netbsd_syscall_ret(num, ret); +    return ret; + efault: +    ret = -TARGET_EFAULT; +    goto fail; +} + +abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1, +                            abi_long arg2, abi_long arg3, abi_long arg4, +                            abi_long arg5, abi_long arg6) +{ +    abi_long ret; +    void *p; + +#ifdef DEBUG +    gemu_log("openbsd syscall %d\n", num); +#endif +    if(do_strace) +        print_openbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); + +    switch(num) { +    case TARGET_OPENBSD_NR_exit: +#ifdef TARGET_GPROF +        _mcleanup(); +#endif +        gdb_exit(cpu_env, arg1); +        /* XXX: should free thread stack and CPU env */ +        _exit(arg1); +        ret = 0; /* avoid warning */ +        break; +    case TARGET_OPENBSD_NR_read: +        if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) +            goto efault; +        ret = get_errno(read(arg1, p, arg3)); +        unlock_user(p, arg2, ret); +        break; +    case TARGET_OPENBSD_NR_write: +        if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) +            goto efault; +        ret = get_errno(write(arg1, p, arg3)); +        unlock_user(p, arg2, 0); +        break; +    case TARGET_OPENBSD_NR_open: +        if (!(p = lock_user_string(arg1))) +            goto efault; +        ret = get_errno(open(path(p), +                             target_to_host_bitmask(arg2, fcntl_flags_tbl), +                             arg3)); +        unlock_user(p, arg1, 0); +        break; +    case TARGET_OPENBSD_NR_mmap: +        ret = get_errno(target_mmap(arg1, arg2, arg3, +                                    target_to_host_bitmask(arg4, mmap_flags_tbl), +                                    arg5, +                                    arg6)); +        break; +    case TARGET_OPENBSD_NR_mprotect: +        ret = get_errno(target_mprotect(arg1, arg2, arg3)); +        break; +    case TARGET_OPENBSD_NR_syscall: +    case TARGET_OPENBSD_NR___syscall: +        ret = do_openbsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0); +        break; +    default: +        ret = syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); +        break; +    } + fail: +#ifdef DEBUG +    gemu_log(" = %ld\n", ret); +#endif +    if (do_strace) +        print_openbsd_syscall_ret(num, ret); +    return ret; + efault: +    ret = -TARGET_EFAULT; +    goto fail; +} + +void syscall_init(void) +{ +} diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h new file mode 100644 index 00000000..207ddeec --- /dev/null +++ b/bsd-user/syscall_defs.h @@ -0,0 +1,114 @@ +/*      $OpenBSD: signal.h,v 1.19 2006/01/08 14:20:16 millert Exp $     */ +/*      $NetBSD: signal.h,v 1.21 1996/02/09 18:25:32 christos Exp $     */ + +/* + * Copyright (c) 1982, 1986, 1989, 1991, 1993 + *      The Regents of the University of California.  All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + * + *      @(#)signal.h    8.2 (Berkeley) 1/21/94 + */ + +#define TARGET_NSIG     32              /* counting 0; could be 33 (mask is 1-32) */ + +#define TARGET_SIGHUP  1       /* hangup */ +#define TARGET_SIGINT  2       /* interrupt */ +#define TARGET_SIGQUIT 3       /* quit */ +#define TARGET_SIGILL  4       /* illegal instruction (not reset when caught) */ +#define TARGET_SIGTRAP 5       /* trace trap (not reset when caught) */ +#define TARGET_SIGABRT 6       /* abort() */ +#define TARGET_SIGIOT  SIGABRT /* compatibility */ +#define TARGET_SIGEMT  7       /* EMT instruction */ +#define TARGET_SIGFPE  8       /* floating point exception */ +#define TARGET_SIGKILL 9       /* kill (cannot be caught or ignored) */ +#define TARGET_SIGBUS  10      /* bus error */ +#define TARGET_SIGSEGV 11      /* segmentation violation */ +#define TARGET_SIGSYS  12      /* bad argument to system call */ +#define TARGET_SIGPIPE 13      /* write on a pipe with no one to read it */ +#define TARGET_SIGALRM 14      /* alarm clock */ +#define TARGET_SIGTERM 15      /* software termination signal from kill */ +#define TARGET_SIGURG  16      /* urgent condition on IO channel */ +#define TARGET_SIGSTOP 17      /* sendable stop signal not from tty */ +#define TARGET_SIGTSTP 18      /* stop signal from tty */ +#define TARGET_SIGCONT 19      /* continue a stopped process */ +#define TARGET_SIGCHLD 20      /* to parent on child stop or exit */ +#define TARGET_SIGTTIN 21      /* to readers pgrp upon background tty read */ +#define TARGET_SIGTTOU 22      /* like TTIN for output if (tp->t_local<OSTOP) */ +#define TARGET_SIGIO   23      /* input/output possible signal */ +#define TARGET_SIGXCPU 24      /* exceeded CPU time limit */ +#define TARGET_SIGXFSZ 25      /* exceeded file size limit */ +#define TARGET_SIGVTALRM 26    /* virtual time alarm */ +#define TARGET_SIGPROF 27      /* profiling time alarm */ +#define TARGET_SIGWINCH 28      /* window size changes */ +#define TARGET_SIGINFO  29      /* information request */ +#define TARGET_SIGUSR1 30       /* user defined signal 1 */ +#define TARGET_SIGUSR2 31       /* user defined signal 2 */ + +/* + * Language spec says we must list exactly one parameter, even though we + * actually supply three.  Ugh! + */ +#define TARGET_SIG_DFL         (void (*)(int))0 +#define TARGET_SIG_IGN         (void (*)(int))1 +#define TARGET_SIG_ERR         (void (*)(int))-1 + +#define TARGET_SA_ONSTACK       0x0001  /* take signal on signal stack */ +#define TARGET_SA_RESTART       0x0002  /* restart system on signal return */ +#define TARGET_SA_RESETHAND     0x0004  /* reset to SIG_DFL when taking signal */ +#define TARGET_SA_NODEFER       0x0010  /* don't mask the signal we're delivering */ +#define TARGET_SA_NOCLDWAIT     0x0020  /* don't create zombies (assign to pid 1) */ +#define TARGET_SA_USERTRAMP    0x0100  /* do not bounce off kernel's sigtramp */ +#define TARGET_SA_NOCLDSTOP     0x0008  /* do not generate SIGCHLD on child stop */ +#define TARGET_SA_SIGINFO       0x0040  /* generate siginfo_t */ + +/* + * Flags for sigprocmask: + */ +#define TARGET_SIG_BLOCK       1       /* block specified signal set */ +#define TARGET_SIG_UNBLOCK     2       /* unblock specified signal set */ +#define TARGET_SIG_SETMASK     3       /* set specified signal set */ + +#define TARGET_BADSIG          SIG_ERR + +#define TARGET_SS_ONSTACK       0x0001  /* take signals on alternate stack */ +#define TARGET_SS_DISABLE       0x0004  /* disable taking signals on alternate stack */ + +#include "errno_defs.h" + +#include "freebsd/syscall_nr.h" +#include "netbsd/syscall_nr.h" +#include "openbsd/syscall_nr.h" + +struct target_iovec { +    abi_long iov_base;   /* Starting address */ +    abi_long iov_len;   /* Number of bytes */ +}; + diff --git a/bsd-user/uaccess.c b/bsd-user/uaccess.c new file mode 100644 index 00000000..677f19c2 --- /dev/null +++ b/bsd-user/uaccess.c @@ -0,0 +1,65 @@ +/* User memory access */ +#include <stdio.h> +#include <string.h> + +#include "qemu.h" + +/* copy_from_user() and copy_to_user() are usually used to copy data + * buffers between the target and host.  These internally perform + * locking/unlocking of the memory. + */ +abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len) +{ +    abi_long ret = 0; +    void *ghptr; + +    if ((ghptr = lock_user(VERIFY_READ, gaddr, len, 1))) { +        memcpy(hptr, ghptr, len); +        unlock_user(ghptr, gaddr, 0); +    } else +        ret = -TARGET_EFAULT; + +    return ret; +} + + +abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len) +{ +    abi_long ret = 0; +    void *ghptr; + +    if ((ghptr = lock_user(VERIFY_WRITE, gaddr, len, 0))) { +        memcpy(ghptr, hptr, len); +        unlock_user(ghptr, gaddr, len); +    } else +        ret = -TARGET_EFAULT; + +    return ret; +} + +/* Return the length of a string in target memory or -TARGET_EFAULT if +   access error  */ +abi_long target_strlen(abi_ulong guest_addr1) +{ +    uint8_t *ptr; +    abi_ulong guest_addr; +    int max_len, len; + +    guest_addr = guest_addr1; +    for(;;) { +        max_len = TARGET_PAGE_SIZE - (guest_addr & ~TARGET_PAGE_MASK); +        ptr = lock_user(VERIFY_READ, guest_addr, max_len, 1); +        if (!ptr) +            return -TARGET_EFAULT; +        len = qemu_strnlen((char *)ptr, max_len); +        unlock_user(ptr, guest_addr, 0); +        guest_addr += len; +        /* we don't allow wrapping or integer overflow */ +        if (guest_addr == 0 || +            (guest_addr - guest_addr1) > 0x7fffffff) +            return -TARGET_EFAULT; +        if (len != max_len) +            break; +    } +    return guest_addr - guest_addr1; +} diff --git a/bsd-user/x86_64/syscall.h b/bsd-user/x86_64/syscall.h new file mode 100644 index 00000000..630514a9 --- /dev/null +++ b/bsd-user/x86_64/syscall.h @@ -0,0 +1,116 @@ +#define __USER_CS	(0x33) +#define __USER_DS	(0x2B) + +struct target_pt_regs { +	abi_ulong r15; +	abi_ulong r14; +	abi_ulong r13; +	abi_ulong r12; +	abi_ulong rbp; +	abi_ulong rbx; +/* arguments: non interrupts/non tracing syscalls only save up to here */ + 	abi_ulong r11; +	abi_ulong r10; +	abi_ulong r9; +	abi_ulong r8; +	abi_ulong rax; +	abi_ulong rcx; +	abi_ulong rdx; +	abi_ulong rsi; +	abi_ulong rdi; +	abi_ulong orig_rax; +/* end of arguments */ +/* cpu exception frame or undefined */ +	abi_ulong rip; +	abi_ulong cs; +	abi_ulong eflags; +	abi_ulong rsp; +	abi_ulong ss; +/* top of stack page */ +}; + +/* Maximum number of LDT entries supported. */ +#define TARGET_LDT_ENTRIES	8192 +/* The size of each LDT entry. */ +#define TARGET_LDT_ENTRY_SIZE	8 + +#define TARGET_GDT_ENTRIES 16 +#define TARGET_GDT_ENTRY_TLS_ENTRIES 3 +#define TARGET_GDT_ENTRY_TLS_MIN 12 +#define TARGET_GDT_ENTRY_TLS_MAX 14 + +#if 0 // Redefine this +struct target_modify_ldt_ldt_s { +	unsigned int  entry_number; +        abi_ulong     base_addr; +	unsigned int  limit; +	unsigned int  seg_32bit:1; +	unsigned int  contents:2; +	unsigned int  read_exec_only:1; +	unsigned int  limit_in_pages:1; +	unsigned int  seg_not_present:1; +	unsigned int  useable:1; +	unsigned int  lm:1; +}; +#else +struct target_modify_ldt_ldt_s { +	unsigned int  entry_number; +        abi_ulong     base_addr; +	unsigned int  limit; +        unsigned int flags; +}; +#endif + +struct target_ipc64_perm +{ +	int		key; +	uint32_t	uid; +	uint32_t	gid; +	uint32_t	cuid; +	uint32_t	cgid; +	unsigned short		mode; +	unsigned short		__pad1; +	unsigned short		seq; +	unsigned short		__pad2; +	abi_ulong		__unused1; +	abi_ulong		__unused2; +}; + +struct target_msqid64_ds { +	struct target_ipc64_perm msg_perm; +	unsigned int msg_stime;	/* last msgsnd time */ +	unsigned int msg_rtime;	/* last msgrcv time */ +	unsigned int msg_ctime;	/* last change time */ +	abi_ulong  msg_cbytes;	/* current number of bytes on queue */ +	abi_ulong  msg_qnum;	/* number of messages in queue */ +	abi_ulong  msg_qbytes;	/* max number of bytes on queue */ +	unsigned int msg_lspid;	/* pid of last msgsnd */ +	unsigned int msg_lrpid;	/* last receive pid */ +	abi_ulong  __unused4; +	abi_ulong  __unused5; +}; + +/* FreeBSD sysarch(2) */ +#define TARGET_FREEBSD_I386_GET_LDT	0 +#define TARGET_FREEBSD_I386_SET_LDT	1 +				/* I386_IOPL */ +#define TARGET_FREEBSD_I386_GET_IOPERM	3 +#define TARGET_FREEBSD_I386_SET_IOPERM	4 +				/* xxxxx */ +#define TARGET_FREEBSD_I386_GET_FSBASE	7 +#define TARGET_FREEBSD_I386_SET_FSBASE	8 +#define TARGET_FREEBSD_I386_GET_GSBASE	9 +#define TARGET_FREEBSD_I386_SET_GSBASE	10 + +#define TARGET_FREEBSD_AMD64_GET_FSBASE	128 +#define TARGET_FREEBSD_AMD64_SET_FSBASE	129 +#define TARGET_FREEBSD_AMD64_GET_GSBASE	130 +#define TARGET_FREEBSD_AMD64_SET_GSBASE	131 + + +#define UNAME_MACHINE "x86_64" + +#define TARGET_ARCH_SET_GS 0x1001 +#define TARGET_ARCH_SET_FS 0x1002 +#define TARGET_ARCH_GET_FS 0x1003 +#define TARGET_ARCH_GET_GS 0x1004 diff --git a/bsd-user/x86_64/target_signal.h b/bsd-user/x86_64/target_signal.h new file mode 100644 index 00000000..659cd401 --- /dev/null +++ b/bsd-user/x86_64/target_signal.h @@ -0,0 +1,19 @@ +#ifndef TARGET_SIGNAL_H +#define TARGET_SIGNAL_H + +#include "cpu.h" + +/* this struct defines a stack used during syscall handling */ + +typedef struct target_sigaltstack { +	abi_ulong ss_sp; +	abi_long ss_flags; +	abi_ulong ss_size; +} target_stack_t; + +static inline abi_ulong get_sp_from_cpustate(CPUX86State *state) +{ +    return state->regs[R_ESP]; +} + +#endif /* TARGET_SIGNAL_H */  | 
