Revision 5cd4393b

b/linux-user/syscall.c
103 103
extern int flock(int, int);
104 104
extern int setfsuid(int);
105 105
extern int setfsgid(int);
106
extern int setresuid(int,int,int);
107
extern int getresuid(int *,int *,int *);
108
extern int setresgid(int,int,int);
109
extern int getresgid(int *,int *,int *);
106
extern int setresuid(uid_t, uid_t, uid_t);
107
extern int getresuid(uid_t *, uid_t *, uid_t *);
108
extern int setresgid(gid_t, gid_t, gid_t);
109
extern int getresgid(gid_t *, gid_t *, gid_t *);
110 110

  
111 111
static inline long get_errno(long ret)
112 112
{
......
210 210
}
211 211

  
212 212
static inline void target_to_host_timeval(struct timeval *tv, 
213
                                          struct target_timeval *target_tv)
213
                                          const struct target_timeval *target_tv)
214 214
{
215 215
    tv->tv_sec = tswapl(target_tv->tv_sec);
216 216
    tv->tv_usec = tswapl(target_tv->tv_usec);
217 217
}
218 218

  
219 219
static inline void host_to_target_timeval(struct target_timeval *target_tv, 
220
                                          struct timeval *tv)
220
                                          const struct timeval *tv)
221 221
{
222 222
    target_tv->tv_sec = tswapl(tv->tv_sec);
223 223
    target_tv->tv_usec = tswapl(tv->tv_usec);
......
238 238
    efds_ptr = target_to_host_fds(&efds, target_efds, n);
239 239
            
240 240
    if (target_tv) {
241
        tv.tv_sec = tswapl(target_tv->tv_sec);
242
        tv.tv_usec = tswapl(target_tv->tv_usec);
241
        target_to_host_timeval(&tv, target_tv);
243 242
        tv_ptr = &tv;
244 243
    } else {
245 244
        tv_ptr = NULL;
......
251 250
        host_to_target_fds(target_efds, efds_ptr, n);
252 251

  
253 252
        if (target_tv) {
254
            target_tv->tv_sec = tswapl(tv.tv_sec);
255
            target_tv->tv_usec = tswapl(tv.tv_usec);
253
            host_to_target_timeval(target_tv, &tv);
256 254
        }
257 255
    }
258 256
    return ret;
......
755 753
}
756 754

  
757 755
/* specific and weird i386 syscalls */
758
int gemu_modify_ldt(CPUX86State *env, int func, void *ptr, unsigned long bytecount)
756
int do_modify_ldt(CPUX86State *env, int func, void *ptr, unsigned long bytecount)
759 757
{
760 758
    int ret = -ENOSYS;
761 759
    
......
773 771
    return ret;
774 772
}
775 773

  
774
/* vm86 emulation */
775

  
776
#define SAFE_MASK  (0xDD5)
777

  
778
int do_vm86(CPUX86State *env, long subfunction, 
779
            struct target_vm86plus_struct * target_v86)
780
{
781
    TaskState *ts = env->opaque;
782
    int ret;
783
    
784
    switch (subfunction) {
785
    case TARGET_VM86_REQUEST_IRQ:
786
    case TARGET_VM86_FREE_IRQ:
787
    case TARGET_VM86_GET_IRQ_BITS:
788
    case TARGET_VM86_GET_AND_RESET_IRQ:
789
        gemu_log("qemu: unsupported vm86 subfunction (%ld)\n", subfunction);
790
        ret = -EINVAL;
791
        goto out;
792
    case TARGET_VM86_PLUS_INSTALL_CHECK:
793
        /* NOTE: on old vm86 stuff this will return the error
794
           from verify_area(), because the subfunction is
795
           interpreted as (invalid) address to vm86_struct.
796
           So the installation check works.
797
            */
798
        ret = 0;
799
        goto out;
800
    }
801

  
802
    ts->target_v86 = target_v86;
803

  
804
    /* save current CPU regs */
805
    ts->vm86_saved_regs.eax = 0; /* default vm86 syscall return code */
806
    ts->vm86_saved_regs.ebx = env->regs[R_EBX];
807
    ts->vm86_saved_regs.ecx = env->regs[R_ECX];
808
    ts->vm86_saved_regs.edx = env->regs[R_EDX];
809
    ts->vm86_saved_regs.esi = env->regs[R_ESI];
810
    ts->vm86_saved_regs.edi = env->regs[R_EDI];
811
    ts->vm86_saved_regs.ebp = env->regs[R_EBP];
812
    ts->vm86_saved_regs.esp = env->regs[R_ESP];
813
    ts->vm86_saved_regs.eflags = env->eflags;
814
    ts->vm86_saved_regs.eip  = env->eip;
815
    ts->vm86_saved_regs.cs = env->segs[R_CS];
816
    ts->vm86_saved_regs.ss = env->segs[R_SS];
817
    ts->vm86_saved_regs.ds = env->segs[R_DS];
818
    ts->vm86_saved_regs.es = env->segs[R_ES];
819
    ts->vm86_saved_regs.fs = env->segs[R_FS];
820
    ts->vm86_saved_regs.gs = env->segs[R_GS];
821

  
822
    /* build vm86 CPU state */
823
    env->eflags = (env->eflags & ~SAFE_MASK) | 
824
        (tswap32(target_v86->regs.eflags) & SAFE_MASK) | VM_MASK;
825

  
826
    env->regs[R_EBX] = tswap32(target_v86->regs.ebx);
827
    env->regs[R_ECX] = tswap32(target_v86->regs.ecx);
828
    env->regs[R_EDX] = tswap32(target_v86->regs.edx);
829
    env->regs[R_ESI] = tswap32(target_v86->regs.esi);
830
    env->regs[R_EDI] = tswap32(target_v86->regs.edi);
831
    env->regs[R_EBP] = tswap32(target_v86->regs.ebp);
832
    env->regs[R_ESP] = tswap32(target_v86->regs.esp);
833
    env->eip = tswap32(target_v86->regs.eip);
834
    cpu_x86_load_seg(env, R_CS, tswap16(target_v86->regs.cs));
835
    cpu_x86_load_seg(env, R_SS, tswap16(target_v86->regs.ss));
836
    cpu_x86_load_seg(env, R_DS, tswap16(target_v86->regs.ds));
837
    cpu_x86_load_seg(env, R_ES, tswap16(target_v86->regs.es));
838
    cpu_x86_load_seg(env, R_FS, tswap16(target_v86->regs.fs));
839
    cpu_x86_load_seg(env, R_GS, tswap16(target_v86->regs.gs));
840
    ret = tswap32(target_v86->regs.eax); /* eax will be restored at
841
                                            the end of the syscall */
842
    /* now the virtual CPU is ready for vm86 execution ! */
843
 out:
844
    return ret;
845
}
846

  
776 847
/* this stack is the equivalent of the kernel stack associated with a
777 848
   thread/process */
778 849
#define NEW_STACK_SIZE 8192
......
788 859
int do_fork(CPUX86State *env, unsigned int flags, unsigned long newsp)
789 860
{
790 861
    int ret;
862
    TaskState *ts;
791 863
    uint8_t *new_stack;
792 864
    CPUX86State *new_env;
793 865
    
794 866
    if (flags & CLONE_VM) {
795 867
        if (!newsp)
796 868
            newsp = env->regs[R_ESP];
797
        new_stack = malloc(NEW_STACK_SIZE);
798
        
869
        ts = malloc(sizeof(TaskState) + NEW_STACK_SIZE);
870
        memset(ts, 0, sizeof(TaskState));
871
        new_stack = ts->stack;
872
        ts->used = 1;
873
        /* add in task state list */
874
        ts->next = first_task_state;
875
        first_task_state = ts;
799 876
        /* we create a new CPU instance. */
800 877
        new_env = cpu_x86_init();
801 878
        memcpy(new_env, env, sizeof(CPUX86State));
802 879
        new_env->regs[R_ESP] = newsp;
803 880
        new_env->regs[R_EAX] = 0;
881
        new_env->opaque = ts;
804 882
        ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
805 883
    } else {
806 884
        /* if no CLONE_VM, we consider it is a fork */
......
1281 1359
            struct timeval tv;
1282 1360
            ret = get_errno(gettimeofday(&tv, NULL));
1283 1361
            if (!is_error(ret)) {
1284
                target_tv->tv_sec = tswapl(tv.tv_sec);
1285
                target_tv->tv_usec = tswapl(tv.tv_usec);
1362
                host_to_target_timeval(target_tv, &tv);
1286 1363
            }
1287 1364
        }
1288 1365
        break;
......
1290 1367
        {
1291 1368
            struct target_timeval *target_tv = (void *)arg1;
1292 1369
            struct timeval tv;
1293
            tv.tv_sec = tswapl(target_tv->tv_sec);
1294
            tv.tv_usec = tswapl(target_tv->tv_usec);
1370
            target_to_host_timeval(&tv, target_tv);
1295 1371
            ret = get_errno(settimeofday(&tv, NULL));
1296 1372
        }
1297 1373
        break;
......
1487 1563
        break;
1488 1564
    case TARGET_NR_idle:
1489 1565
        goto unimplemented;
1490
    case TARGET_NR_vm86old:
1491
        goto unimplemented;
1492 1566
    case TARGET_NR_wait4:
1493 1567
        {
1494 1568
            int status;
......
1548 1622
        break;
1549 1623
#ifdef TARGET_I386
1550 1624
    case TARGET_NR_modify_ldt:
1551
        ret = get_errno(gemu_modify_ldt(cpu_env, arg1, (void *)arg2, arg3));
1625
        ret = get_errno(do_modify_ldt(cpu_env, arg1, (void *)arg2, arg3));
1626
        break;
1627
    case TARGET_NR_vm86old:
1628
        goto unimplemented;
1629
    case TARGET_NR_vm86:
1630
        ret = do_vm86(cpu_env, arg1, (void *)arg2);
1552 1631
        break;
1553 1632
#endif
1554 1633
    case TARGET_NR_adjtimex:
......
1652 1731

  
1653 1732
            pfd = alloca(sizeof(struct pollfd) * nfds);
1654 1733
            for(i = 0; i < nfds; i++) {
1655
                pfd->fd = tswap32(target_pfd->fd);
1656
                pfd->events = tswap16(target_pfd->events);
1734
                pfd[i].fd = tswap32(target_pfd[i].fd);
1735
                pfd[i].events = tswap16(target_pfd[i].events);
1657 1736
            }
1658 1737
            ret = get_errno(poll(pfd, nfds, timeout));
1659 1738
            if (!is_error(ret)) {
1660 1739
                for(i = 0; i < nfds; i++) {
1661
                    target_pfd->revents = tswap16(pfd->revents);
1740
                    target_pfd[i].revents = tswap16(pfd[i].revents);
1662 1741
                }
1663 1742
            }
1664 1743
        }
......
1702 1781
        ret = get_errno(getsid(arg1));
1703 1782
        break;
1704 1783
    case TARGET_NR_fdatasync:
1705
        goto unimplemented;
1784
        ret = get_errno(fdatasync(arg1));
1785
        break;
1706 1786
    case TARGET_NR__sysctl:
1707 1787
        goto unimplemented;
1708 1788
    case TARGET_NR_sched_setparam:
1709
        goto unimplemented;
1789
        {
1790
            struct sched_param *target_schp = (void *)arg2;
1791
            struct sched_param schp;
1792
            schp.sched_priority = tswap32(target_schp->sched_priority);
1793
            ret = get_errno(sched_setparam(arg1, &schp));
1794
        }
1795
        break;
1710 1796
    case TARGET_NR_sched_getparam:
1711
        goto unimplemented;
1797
        {
1798
            struct sched_param *target_schp = (void *)arg2;
1799
            struct sched_param schp;
1800
            ret = get_errno(sched_getparam(arg1, &schp));
1801
            if (!is_error(ret)) {
1802
                target_schp->sched_priority = tswap32(schp.sched_priority);
1803
            }
1804
        }
1805
        break;
1712 1806
    case TARGET_NR_sched_setscheduler:
1713
        goto unimplemented;
1807
        {
1808
            struct sched_param *target_schp = (void *)arg3;
1809
            struct sched_param schp;
1810
            schp.sched_priority = tswap32(target_schp->sched_priority);
1811
            ret = get_errno(sched_setscheduler(arg1, arg2, &schp));
1812
        }
1813
        break;
1714 1814
    case TARGET_NR_sched_getscheduler:
1715
        goto unimplemented;
1815
        ret = get_errno(sched_getscheduler(arg1));
1816
        break;
1716 1817
    case TARGET_NR_sched_yield:
1717 1818
        ret = get_errno(sched_yield());
1718 1819
        break;
1719 1820
    case TARGET_NR_sched_get_priority_max:
1821
        ret = get_errno(sched_get_priority_max(arg1));
1822
        break;
1720 1823
    case TARGET_NR_sched_get_priority_min:
1824
        ret = get_errno(sched_get_priority_min(arg1));
1825
        break;
1721 1826
    case TARGET_NR_sched_rr_get_interval:
1722
        goto unimplemented;
1723
        
1827
        {
1828
            struct target_timespec *target_ts = (void *)arg2;
1829
            struct timespec ts;
1830
            ret = get_errno(sched_rr_get_interval(arg1, &ts));
1831
            if (!is_error(ret)) {
1832
                target_ts->tv_sec = tswapl(ts.tv_sec);
1833
                target_ts->tv_nsec = tswapl(ts.tv_nsec);
1834
            }
1835
        }
1836
        break;
1724 1837
    case TARGET_NR_nanosleep:
1725 1838
        {
1726 1839
            struct target_timespec *target_req = (void *)arg1;
......
1767 1880
            }
1768 1881
        }
1769 1882
        break;
1770
    case TARGET_NR_vm86:
1771 1883
    case TARGET_NR_query_module:
1884
        goto unimplemented;
1772 1885
    case TARGET_NR_nfsservctl:
1886
        goto unimplemented;
1773 1887
    case TARGET_NR_prctl:
1888
        goto unimplemented;
1774 1889
    case TARGET_NR_pread:
1890
        goto unimplemented;
1775 1891
    case TARGET_NR_pwrite:
1776 1892
        goto unimplemented;
1777 1893
    case TARGET_NR_chown:
......
1781 1897
        ret = get_errno(sys_getcwd1((char *)arg1, arg2));
1782 1898
        break;
1783 1899
    case TARGET_NR_capget:
1900
        goto unimplemented;
1784 1901
    case TARGET_NR_capset:
1902
        goto unimplemented;
1785 1903
    case TARGET_NR_sigaltstack:
1904
        goto unimplemented;
1786 1905
    case TARGET_NR_sendfile:
1906
        goto unimplemented;
1787 1907
    case TARGET_NR_getpmsg:
1908
        goto unimplemented;
1788 1909
    case TARGET_NR_putpmsg:
1910
        goto unimplemented;
1789 1911
    case TARGET_NR_vfork:
1790 1912
        ret = get_errno(do_fork(cpu_env, CLONE_VFORK | CLONE_VM | SIGCHLD, 0));
1791 1913
        break;
1792 1914
    case TARGET_NR_ugetrlimit:
1915
        goto unimplemented;
1793 1916
    case TARGET_NR_truncate64:
1917
        goto unimplemented;
1794 1918
    case TARGET_NR_ftruncate64:
1795 1919
        goto unimplemented;
1796 1920
    case TARGET_NR_stat64:
......
1919 2043
        ret = get_errno(gettid());
1920 2044
        break;
1921 2045
    case TARGET_NR_readahead:
2046
        goto unimplemented;
1922 2047
    case TARGET_NR_setxattr:
1923 2048
    case TARGET_NR_lsetxattr:
1924 2049
    case TARGET_NR_fsetxattr:
......
1931 2056
    case TARGET_NR_removexattr:
1932 2057
    case TARGET_NR_lremovexattr:
1933 2058
    case TARGET_NR_fremovexattr:
1934
        goto unimplemented;
2059
        goto unimplemented_nowarn;
2060
    case TARGET_NR_set_thread_area:
2061
    case TARGET_NR_get_thread_area:
2062
        goto unimplemented_nowarn;
1935 2063
    default:
1936 2064
    unimplemented:
1937
        gemu_log("gemu: Unsupported syscall: %d\n", num);
2065
        gemu_log("qemu: Unsupported syscall: %d\n", num);
2066
    unimplemented_nowarn:
1938 2067
        ret = -ENOSYS;
1939 2068
        break;
1940 2069
    }

Also available in: Unified diff