Annotation of qemu/bsd-user/syscall.c, revision 1.1.1.3

1.1       root        1: /*
                      2:  *  BSD syscalls
                      3:  *
                      4:  *  Copyright (c) 2003 - 2008 Fabrice Bellard
                      5:  *
                      6:  *  This program is free software; you can redistribute it and/or modify
                      7:  *  it under the terms of the GNU General Public License as published by
                      8:  *  the Free Software Foundation; either version 2 of the License, or
                      9:  *  (at your option) any later version.
                     10:  *
                     11:  *  This program is distributed in the hope that it will be useful,
                     12:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14:  *  GNU General Public License for more details.
                     15:  *
                     16:  *  You should have received a copy of the GNU General Public License
1.1.1.2   root       17:  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
1.1       root       18:  */
                     19: #include <stdlib.h>
                     20: #include <stdio.h>
                     21: #include <stdint.h>
                     22: #include <stdarg.h>
                     23: #include <string.h>
                     24: #include <errno.h>
                     25: #include <unistd.h>
                     26: #include <fcntl.h>
                     27: #include <time.h>
                     28: #include <limits.h>
                     29: #include <sys/types.h>
                     30: #include <sys/mman.h>
                     31: #include <sys/syscall.h>
1.1.1.3 ! root       32: #include <sys/param.h>
        !            33: #include <sys/sysctl.h>
1.1       root       34: #include <signal.h>
                     35: #include <utime.h>
                     36: 
                     37: #include "qemu.h"
                     38: #include "qemu-common.h"
                     39: 
                     40: //#define DEBUG
                     41: 
                     42: static abi_ulong target_brk;
                     43: static abi_ulong target_original_brk;
                     44: 
1.1.1.3 ! root       45: static inline abi_long get_errno(abi_long ret)
        !            46: {
        !            47:     if (ret == -1)
        !            48:         /* XXX need to translate host -> target errnos here */
        !            49:         return -(errno);
        !            50:     else
        !            51:         return ret;
        !            52: }
        !            53: 
1.1       root       54: #define target_to_host_bitmask(x, tbl) (x)
                     55: 
1.1.1.3 ! root       56: static inline int is_error(abi_long ret)
        !            57: {
        !            58:     return (abi_ulong)ret >= (abi_ulong)(-4096);
        !            59: }
        !            60: 
1.1       root       61: void target_set_brk(abi_ulong new_brk)
                     62: {
                     63:     target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
                     64: }
                     65: 
1.1.1.3 ! root       66: /* do_obreak() must return target errnos. */
        !            67: static abi_long do_obreak(abi_ulong new_brk)
        !            68: {
        !            69:     abi_ulong brk_page;
        !            70:     abi_long mapped_addr;
        !            71:     int new_alloc_size;
        !            72: 
        !            73:     if (!new_brk)
        !            74:         return 0;
        !            75:     if (new_brk < target_original_brk)
        !            76:         return -TARGET_EINVAL;
        !            77: 
        !            78:     brk_page = HOST_PAGE_ALIGN(target_brk);
        !            79: 
        !            80:     /* If the new brk is less than this, set it and we're done... */
        !            81:     if (new_brk < brk_page) {
        !            82:         target_brk = new_brk;
        !            83:         return 0;
        !            84:     }
        !            85: 
        !            86:     /* We need to allocate more memory after the brk... */
        !            87:     new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
        !            88:     mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
        !            89:                                         PROT_READ|PROT_WRITE,
        !            90:                                         MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0));
        !            91: 
        !            92:     if (!is_error(mapped_addr))
        !            93:         target_brk = new_brk;
        !            94:     else
        !            95:         return mapped_addr;
        !            96: 
        !            97:     return 0;
        !            98: }
        !            99: 
        !           100: #if defined(TARGET_I386)
        !           101: static abi_long do_freebsd_sysarch(CPUX86State *env, int op, abi_ulong parms)
        !           102: {
        !           103:     abi_long ret = 0;
        !           104:     abi_ulong val;
        !           105:     int idx;
        !           106: 
        !           107:     switch(op) {
        !           108: #ifdef TARGET_ABI32
        !           109:     case TARGET_FREEBSD_I386_SET_GSBASE:
        !           110:     case TARGET_FREEBSD_I386_SET_FSBASE:
        !           111:         if (op == TARGET_FREEBSD_I386_SET_GSBASE)
        !           112: #else
        !           113:     case TARGET_FREEBSD_AMD64_SET_GSBASE:
        !           114:     case TARGET_FREEBSD_AMD64_SET_FSBASE:
        !           115:         if (op == TARGET_FREEBSD_AMD64_SET_GSBASE)
        !           116: #endif
        !           117:             idx = R_GS;
        !           118:         else
        !           119:             idx = R_FS;
        !           120:         if (get_user(val, parms, abi_ulong))
        !           121:             return -TARGET_EFAULT;
        !           122:         cpu_x86_load_seg(env, idx, 0);
        !           123:         env->segs[idx].base = val;
        !           124:         break;
        !           125: #ifdef TARGET_ABI32
        !           126:     case TARGET_FREEBSD_I386_GET_GSBASE:
        !           127:     case TARGET_FREEBSD_I386_GET_FSBASE:
        !           128:         if (op == TARGET_FREEBSD_I386_GET_GSBASE)
        !           129: #else
        !           130:     case TARGET_FREEBSD_AMD64_GET_GSBASE:
        !           131:     case TARGET_FREEBSD_AMD64_GET_FSBASE:
        !           132:         if (op == TARGET_FREEBSD_AMD64_GET_GSBASE)
        !           133: #endif
        !           134:             idx = R_GS;
        !           135:         else
        !           136:             idx = R_FS;
        !           137:         val = env->segs[idx].base;
        !           138:         if (put_user(val, parms, abi_ulong))
        !           139:             return -TARGET_EFAULT;
        !           140:         break;
        !           141:     /* XXX handle the others... */
        !           142:     default:
        !           143:         ret = -TARGET_EINVAL;
        !           144:         break;
        !           145:     }
        !           146:     return ret;
        !           147: }
        !           148: #endif
        !           149: 
        !           150: #ifdef TARGET_SPARC
        !           151: static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms)
        !           152: {
        !           153:     /* XXX handle
        !           154:      * TARGET_FREEBSD_SPARC_UTRAP_INSTALL,
        !           155:      * TARGET_FREEBSD_SPARC_SIGTRAMP_INSTALL
        !           156:      */
        !           157:     return -TARGET_EINVAL;
        !           158: }
        !           159: #endif
        !           160: 
        !           161: #ifdef __FreeBSD__
        !           162: /*
        !           163:  * XXX this uses the undocumented oidfmt interface to find the kind of
        !           164:  * a requested sysctl, see /sys/kern/kern_sysctl.c:sysctl_sysctl_oidfmt()
        !           165:  * (this is mostly copied from src/sbin/sysctl/sysctl.c)
        !           166:  */
        !           167: static int
        !           168: oidfmt(int *oid, int len, char *fmt, uint32_t *kind)
        !           169: {
        !           170:     int qoid[CTL_MAXNAME+2];
        !           171:     uint8_t buf[BUFSIZ];
        !           172:     int i;
        !           173:     size_t j;
        !           174: 
        !           175:     qoid[0] = 0;
        !           176:     qoid[1] = 4;
        !           177:     memcpy(qoid + 2, oid, len * sizeof(int));
        !           178: 
        !           179:     j = sizeof(buf);
        !           180:     i = sysctl(qoid, len + 2, buf, &j, 0, 0);
        !           181:     if (i)
        !           182:         return i;
        !           183: 
        !           184:     if (kind)
        !           185:         *kind = *(uint32_t *)buf;
        !           186: 
        !           187:     if (fmt)
        !           188:         strcpy(fmt, (char *)(buf + sizeof(uint32_t)));
        !           189:     return (0);
        !           190: }
        !           191: 
        !           192: /*
        !           193:  * try and convert sysctl return data for the target.
        !           194:  * XXX doesn't handle CTLTYPE_OPAQUE and CTLTYPE_STRUCT.
        !           195:  */
        !           196: static int sysctl_oldcvt(void *holdp, size_t holdlen, uint32_t kind)
        !           197: {
        !           198:     switch (kind & CTLTYPE) {
        !           199:     case CTLTYPE_INT:
        !           200:     case CTLTYPE_UINT:
        !           201:         *(uint32_t *)holdp = tswap32(*(uint32_t *)holdp);
        !           202:         break;
        !           203: #ifdef TARGET_ABI32
        !           204:     case CTLTYPE_LONG:
        !           205:     case CTLTYPE_ULONG:
        !           206:         *(uint32_t *)holdp = tswap32(*(long *)holdp);
        !           207:         break;
        !           208: #else
        !           209:     case CTLTYPE_LONG:
        !           210:         *(uint64_t *)holdp = tswap64(*(long *)holdp);
        !           211:     case CTLTYPE_ULONG:
        !           212:         *(uint64_t *)holdp = tswap64(*(unsigned long *)holdp);
        !           213:         break;
        !           214: #endif
        !           215:     case CTLTYPE_QUAD:
        !           216:         *(uint64_t *)holdp = tswap64(*(uint64_t *)holdp);
        !           217:         break;
        !           218:     case CTLTYPE_STRING:
        !           219:         break;
        !           220:     default:
        !           221:         /* XXX unhandled */
        !           222:         return -1;
        !           223:     }
        !           224:     return 0;
        !           225: }
        !           226: 
        !           227: /* XXX this needs to be emulated on non-FreeBSD hosts... */
        !           228: static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong oldp,
        !           229:                           abi_ulong oldlenp, abi_ulong newp, abi_ulong newlen)
        !           230: {
        !           231:     abi_long ret;
        !           232:     void *hnamep, *holdp, *hnewp = NULL;
        !           233:     size_t holdlen;
        !           234:     abi_ulong oldlen = 0;
        !           235:     int32_t *snamep = qemu_malloc(sizeof(int32_t) * namelen), *p, *q, i;
        !           236:     uint32_t kind = 0;
        !           237: 
        !           238:     if (oldlenp)
        !           239:         get_user_ual(oldlen, oldlenp);
        !           240:     if (!(hnamep = lock_user(VERIFY_READ, namep, namelen, 1)))
        !           241:         return -TARGET_EFAULT;
        !           242:     if (newp && !(hnewp = lock_user(VERIFY_READ, newp, newlen, 1)))
        !           243:         return -TARGET_EFAULT;
        !           244:     if (!(holdp = lock_user(VERIFY_WRITE, oldp, oldlen, 0)))
        !           245:         return -TARGET_EFAULT;
        !           246:     holdlen = oldlen;
        !           247:     for (p = hnamep, q = snamep, i = 0; i < namelen; p++, i++)
        !           248:        *q++ = tswap32(*p);
        !           249:     oidfmt(snamep, namelen, NULL, &kind);
        !           250:     /* XXX swap hnewp */
        !           251:     ret = get_errno(sysctl(snamep, namelen, holdp, &holdlen, hnewp, newlen));
        !           252:     if (!ret)
        !           253:         sysctl_oldcvt(holdp, holdlen, kind);
        !           254:     put_user_ual(holdlen, oldlenp);
        !           255:     unlock_user(hnamep, namep, 0);
        !           256:     unlock_user(holdp, oldp, holdlen);
        !           257:     if (hnewp)
        !           258:         unlock_user(hnewp, newp, 0);
        !           259:     qemu_free(snamep);
        !           260:     return ret;
        !           261: }
        !           262: #endif
        !           263: 
        !           264: /* FIXME
        !           265:  * lock_iovec()/unlock_iovec() have a return code of 0 for success where
        !           266:  * other lock functions have a return code of 0 for failure.
        !           267:  */
        !           268: static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
        !           269:                            int count, int copy)
        !           270: {
        !           271:     struct target_iovec *target_vec;
        !           272:     abi_ulong base;
        !           273:     int i;
        !           274: 
        !           275:     target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
        !           276:     if (!target_vec)
        !           277:         return -TARGET_EFAULT;
        !           278:     for(i = 0;i < count; i++) {
        !           279:         base = tswapl(target_vec[i].iov_base);
        !           280:         vec[i].iov_len = tswapl(target_vec[i].iov_len);
        !           281:         if (vec[i].iov_len != 0) {
        !           282:             vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy);
        !           283:             /* Don't check lock_user return value. We must call writev even
        !           284:                if a element has invalid base address. */
        !           285:         } else {
        !           286:             /* zero length pointer is ignored */
        !           287:             vec[i].iov_base = NULL;
        !           288:         }
        !           289:     }
        !           290:     unlock_user (target_vec, target_addr, 0);
        !           291:     return 0;
        !           292: }
        !           293: 
        !           294: static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
        !           295:                              int count, int copy)
        !           296: {
        !           297:     struct target_iovec *target_vec;
        !           298:     abi_ulong base;
        !           299:     int i;
        !           300: 
        !           301:     target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1);
        !           302:     if (!target_vec)
        !           303:         return -TARGET_EFAULT;
        !           304:     for(i = 0;i < count; i++) {
        !           305:         if (target_vec[i].iov_base) {
        !           306:             base = tswapl(target_vec[i].iov_base);
        !           307:             unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0);
        !           308:         }
        !           309:     }
        !           310:     unlock_user (target_vec, target_addr, 0);
        !           311: 
        !           312:     return 0;
        !           313: }
        !           314: 
1.1       root      315: /* do_syscall() should always have a single exit point at the end so
                    316:    that actions, such as logging of syscall results, can be performed.
                    317:    All errnos that do_syscall() returns must be -TARGET_<errcode>. */
                    318: abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
                    319:                             abi_long arg2, abi_long arg3, abi_long arg4,
1.1.1.3 ! root      320:                             abi_long arg5, abi_long arg6, abi_long arg7,
        !           321:                             abi_long arg8)
1.1       root      322: {
                    323:     abi_long ret;
                    324:     void *p;
                    325: 
                    326: #ifdef DEBUG
                    327:     gemu_log("freebsd syscall %d\n", num);
                    328: #endif
                    329:     if(do_strace)
                    330:         print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
                    331: 
                    332:     switch(num) {
                    333:     case TARGET_FREEBSD_NR_exit:
1.1.1.3 ! root      334: #ifdef TARGET_GPROF
1.1       root      335:         _mcleanup();
                    336: #endif
                    337:         gdb_exit(cpu_env, arg1);
                    338:         /* XXX: should free thread stack and CPU env */
                    339:         _exit(arg1);
                    340:         ret = 0; /* avoid warning */
                    341:         break;
                    342:     case TARGET_FREEBSD_NR_read:
                    343:         if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
                    344:             goto efault;
                    345:         ret = get_errno(read(arg1, p, arg3));
                    346:         unlock_user(p, arg2, ret);
                    347:         break;
                    348:     case TARGET_FREEBSD_NR_write:
                    349:         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
                    350:             goto efault;
                    351:         ret = get_errno(write(arg1, p, arg3));
                    352:         unlock_user(p, arg2, 0);
                    353:         break;
1.1.1.3 ! root      354:     case TARGET_FREEBSD_NR_writev:
        !           355:         {
        !           356:             int count = arg3;
        !           357:             struct iovec *vec;
        !           358: 
        !           359:             vec = alloca(count * sizeof(struct iovec));
        !           360:             if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0)
        !           361:                 goto efault;
        !           362:             ret = get_errno(writev(arg1, vec, count));
        !           363:             unlock_iovec(vec, arg2, count, 0);
        !           364:         }
        !           365:         break;
1.1       root      366:     case TARGET_FREEBSD_NR_open:
                    367:         if (!(p = lock_user_string(arg1)))
                    368:             goto efault;
                    369:         ret = get_errno(open(path(p),
                    370:                              target_to_host_bitmask(arg2, fcntl_flags_tbl),
                    371:                              arg3));
                    372:         unlock_user(p, arg1, 0);
                    373:         break;
                    374:     case TARGET_FREEBSD_NR_mmap:
                    375:         ret = get_errno(target_mmap(arg1, arg2, arg3,
                    376:                                     target_to_host_bitmask(arg4, mmap_flags_tbl),
                    377:                                     arg5,
                    378:                                     arg6));
                    379:         break;
                    380:     case TARGET_FREEBSD_NR_mprotect:
                    381:         ret = get_errno(target_mprotect(arg1, arg2, arg3));
                    382:         break;
1.1.1.3 ! root      383:     case TARGET_FREEBSD_NR_break:
        !           384:         ret = do_obreak(arg1);
        !           385:         break;
        !           386: #ifdef __FreeBSD__
        !           387:     case TARGET_FREEBSD_NR___sysctl:
        !           388:         ret = do_freebsd_sysctl(arg1, arg2, arg3, arg4, arg5, arg6);
        !           389:         break;
        !           390: #endif
        !           391:     case TARGET_FREEBSD_NR_sysarch:
        !           392:         ret = do_freebsd_sysarch(cpu_env, arg1, arg2);
        !           393:         break;
1.1       root      394:     case TARGET_FREEBSD_NR_syscall:
                    395:     case TARGET_FREEBSD_NR___syscall:
1.1.1.3 ! root      396:         ret = do_freebsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,arg7,arg8,0);
1.1       root      397:         break;
                    398:     default:
1.1.1.3 ! root      399:         ret = get_errno(syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8));
1.1       root      400:         break;
                    401:     }
                    402:  fail:
                    403: #ifdef DEBUG
                    404:     gemu_log(" = %ld\n", ret);
                    405: #endif
                    406:     if (do_strace)
                    407:         print_freebsd_syscall_ret(num, ret);
                    408:     return ret;
                    409:  efault:
                    410:     ret = -TARGET_EFAULT;
                    411:     goto fail;
                    412: }
                    413: 
                    414: abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1,
                    415:                            abi_long arg2, abi_long arg3, abi_long arg4,
                    416:                            abi_long arg5, abi_long arg6)
                    417: {
                    418:     abi_long ret;
                    419:     void *p;
                    420: 
                    421: #ifdef DEBUG
                    422:     gemu_log("netbsd syscall %d\n", num);
                    423: #endif
                    424:     if(do_strace)
                    425:         print_netbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
                    426: 
                    427:     switch(num) {
                    428:     case TARGET_NETBSD_NR_exit:
1.1.1.3 ! root      429: #ifdef TARGET_GPROF
1.1       root      430:         _mcleanup();
                    431: #endif
                    432:         gdb_exit(cpu_env, arg1);
                    433:         /* XXX: should free thread stack and CPU env */
                    434:         _exit(arg1);
                    435:         ret = 0; /* avoid warning */
                    436:         break;
                    437:     case TARGET_NETBSD_NR_read:
                    438:         if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
                    439:             goto efault;
                    440:         ret = get_errno(read(arg1, p, arg3));
                    441:         unlock_user(p, arg2, ret);
                    442:         break;
                    443:     case TARGET_NETBSD_NR_write:
                    444:         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
                    445:             goto efault;
                    446:         ret = get_errno(write(arg1, p, arg3));
                    447:         unlock_user(p, arg2, 0);
                    448:         break;
                    449:     case TARGET_NETBSD_NR_open:
                    450:         if (!(p = lock_user_string(arg1)))
                    451:             goto efault;
                    452:         ret = get_errno(open(path(p),
                    453:                              target_to_host_bitmask(arg2, fcntl_flags_tbl),
                    454:                              arg3));
                    455:         unlock_user(p, arg1, 0);
                    456:         break;
                    457:     case TARGET_NETBSD_NR_mmap:
                    458:         ret = get_errno(target_mmap(arg1, arg2, arg3,
                    459:                                     target_to_host_bitmask(arg4, mmap_flags_tbl),
                    460:                                     arg5,
                    461:                                     arg6));
                    462:         break;
                    463:     case TARGET_NETBSD_NR_mprotect:
                    464:         ret = get_errno(target_mprotect(arg1, arg2, arg3));
                    465:         break;
                    466:     case TARGET_NETBSD_NR_syscall:
                    467:     case TARGET_NETBSD_NR___syscall:
                    468:         ret = do_netbsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
                    469:         break;
                    470:     default:
                    471:         ret = syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
                    472:         break;
                    473:     }
                    474:  fail:
                    475: #ifdef DEBUG
                    476:     gemu_log(" = %ld\n", ret);
                    477: #endif
                    478:     if (do_strace)
                    479:         print_netbsd_syscall_ret(num, ret);
                    480:     return ret;
                    481:  efault:
                    482:     ret = -TARGET_EFAULT;
                    483:     goto fail;
                    484: }
                    485: 
                    486: abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
                    487:                             abi_long arg2, abi_long arg3, abi_long arg4,
                    488:                             abi_long arg5, abi_long arg6)
                    489: {
                    490:     abi_long ret;
                    491:     void *p;
                    492: 
                    493: #ifdef DEBUG
                    494:     gemu_log("openbsd syscall %d\n", num);
                    495: #endif
                    496:     if(do_strace)
                    497:         print_openbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
                    498: 
                    499:     switch(num) {
                    500:     case TARGET_OPENBSD_NR_exit:
1.1.1.3 ! root      501: #ifdef TARGET_GPROF
1.1       root      502:         _mcleanup();
                    503: #endif
                    504:         gdb_exit(cpu_env, arg1);
                    505:         /* XXX: should free thread stack and CPU env */
                    506:         _exit(arg1);
                    507:         ret = 0; /* avoid warning */
                    508:         break;
                    509:     case TARGET_OPENBSD_NR_read:
                    510:         if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0)))
                    511:             goto efault;
                    512:         ret = get_errno(read(arg1, p, arg3));
                    513:         unlock_user(p, arg2, ret);
                    514:         break;
                    515:     case TARGET_OPENBSD_NR_write:
                    516:         if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1)))
                    517:             goto efault;
                    518:         ret = get_errno(write(arg1, p, arg3));
                    519:         unlock_user(p, arg2, 0);
                    520:         break;
                    521:     case TARGET_OPENBSD_NR_open:
                    522:         if (!(p = lock_user_string(arg1)))
                    523:             goto efault;
                    524:         ret = get_errno(open(path(p),
                    525:                              target_to_host_bitmask(arg2, fcntl_flags_tbl),
                    526:                              arg3));
                    527:         unlock_user(p, arg1, 0);
                    528:         break;
                    529:     case TARGET_OPENBSD_NR_mmap:
                    530:         ret = get_errno(target_mmap(arg1, arg2, arg3,
                    531:                                     target_to_host_bitmask(arg4, mmap_flags_tbl),
                    532:                                     arg5,
                    533:                                     arg6));
                    534:         break;
                    535:     case TARGET_OPENBSD_NR_mprotect:
                    536:         ret = get_errno(target_mprotect(arg1, arg2, arg3));
                    537:         break;
                    538:     case TARGET_OPENBSD_NR_syscall:
                    539:     case TARGET_OPENBSD_NR___syscall:
                    540:         ret = do_openbsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
                    541:         break;
                    542:     default:
                    543:         ret = syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
                    544:         break;
                    545:     }
                    546:  fail:
                    547: #ifdef DEBUG
                    548:     gemu_log(" = %ld\n", ret);
                    549: #endif
                    550:     if (do_strace)
                    551:         print_openbsd_syscall_ret(num, ret);
                    552:     return ret;
                    553:  efault:
                    554:     ret = -TARGET_EFAULT;
                    555:     goto fail;
                    556: }
                    557: 
                    558: void syscall_init(void)
                    559: {
                    560: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.