-------- Forwarded Message -------- > From: Jocelyn Mayer <[EMAIL PROTECTED]> > Reply-To: [EMAIL PROTECTED], qemu-devel@nongnu.org > To: qemu-devel@nongnu.org > Subject: Re: [Fwd: [Qemu-devel] RFC: linux user problems] > Date: Wed, 19 Sep 2007 11:23:03 +0200 > > On Wed, 2007-09-19 at 10:07 +0100, Thiemo Seufer wrote: > > J. Mayer wrote: > > > Following my previous message, I did a patch that makes syscalls take > > > target_long/target_ulong argument and return target_long value instead > > > of long/unsigned long. > > > I also included the #ifdef protection for do_socketcall and do_ipc to > > > avoid compilation warnings. > > > And I also converted the fd given to do_ioctl to be an int. > > > > > > In addition to my previous remarks, I noticed some other things while > > > reading the code: > > > - the do_msgctl function seems very strange to me. It looks like half of > > > the code is missing in the switch... > > > - do_ipc directly uses pointers from the emulated environment without > > > using lock_user related functions like it seems to be done everywhere > > > else. > > > - there are at least two problems in IPCOP_shmat: > > > * the returned address could not fit in the target address space when > > > emulating a 32 bits > > > target on a 64 bits host > > > * the returned address is always casted into a 32 bits value. I changed > > > this to be target_ulong. > > > - I also noticed some suspicious warnings (cast between pointer and > > > integer of different size) that may hide other problems: > > > * target_to_host_cmsg:567 > > > * host_to_target_cmsg:612 > > > * do_ipc:1608 > > > * do_ipc: 1620 > > > * do_ipc: 1644 > > > * do_ipc: 1654 > > > * do_ipc: 1676 (multiple times) > > > * do_ipc: 1688 > > > * do_ipc: 1710 > > > * write_ldt:2009 > > > * do_syscall:2684 > > > * do_syscall: 3901 > > > * do_syscall: 3902 > > > * do_syscall: 4669 > > > > > > May someone take a look at my patch and say if it seems reasonable to > > > include this in the repository ? > > > > Looks reasonable, but introduces new compiler warnings > > (on a ppc32/Linux host):
The reported warnings have been fixed. There are still a lot of warnings related to 32/64 bits invalid casts on 64 bits hosts (see above) which will need to be fixed once. I also changed some parameters of do_ipc from long to int (instead of target_long), following the do_ipc man page specification, and reported this change in child functions. There may be more to do... Please comment... -- J. Mayer <[EMAIL PROTECTED]> Never organized
Index: linux-user/qemu.h =================================================================== RCS file: /sources/qemu/qemu/linux-user/qemu.h,v retrieving revision 1.33 diff -u -d -d -p -r1.33 qemu.h --- linux-user/qemu.h 16 Sep 2007 21:07:58 -0000 1.33 +++ linux-user/qemu.h 21 Sep 2007 06:11:03 -0000 @@ -126,10 +127,11 @@ int load_flt_binary(struct linux_binprm void memcpy_to_target(target_ulong dest, const void *src, unsigned long len); void target_set_brk(target_ulong new_brk); -long do_brk(target_ulong new_brk); +target_long do_brk(target_ulong new_brk); void syscall_init(void); -long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, - long arg4, long arg5, long arg6); +target_long do_syscall(void *cpu_env, int num, target_long arg1, + target_long arg2, target_long arg3, target_long arg4, + target_long arg5, target_long arg6); void gemu_log(const char *fmt, ...) __attribute__((format(printf,1,2))); extern CPUState *global_env; void cpu_loop(CPUState *env); Index: linux-user/syscall.c =================================================================== RCS file: /sources/qemu/qemu/linux-user/syscall.c,v retrieving revision 1.121 diff -u -d -d -p -r1.121 syscall.c --- linux-user/syscall.c 17 Sep 2007 08:09:50 -0000 1.121 +++ linux-user/syscall.c 21 Sep 2007 06:11:03 -0000 @@ -310,7 +310,7 @@ static inline int host_to_target_errno(i return err; } -static inline long get_errno(long ret) +static inline target_long get_errno(target_long ret) { if (ret == -1) return -host_to_target_errno(errno); @@ -318,9 +318,9 @@ static inline long get_errno(long ret) return ret; } -static inline int is_error(long ret) +static inline int is_error(target_long ret) { - return (unsigned long)ret >= (unsigned long)(-4096); + return (target_ulong)ret >= (target_ulong)(-4096); } static target_ulong target_brk; @@ -331,10 +331,10 @@ void target_set_brk(target_ulong new_brk target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk); } -long do_brk(target_ulong new_brk) +target_long do_brk(target_ulong new_brk) { target_ulong brk_page; - long mapped_addr; + target_long mapped_addr; int new_alloc_size; if (!new_brk) @@ -415,7 +415,7 @@ static inline void host_to_target_fds(ta #define HOST_HZ 100 #endif -static inline long host_to_target_clock_t(long ticks) +static inline target_long host_to_target_clock_t(long ticks) { #if HOST_HZ == TARGET_HZ return ticks; @@ -474,15 +474,15 @@ static inline void host_to_target_timeva } -static long do_select(long n, - target_ulong rfd_p, target_ulong wfd_p, - target_ulong efd_p, target_ulong target_tv) +static target_long do_select(target_long n, + target_ulong rfd_p, target_ulong wfd_p, + target_ulong efd_p, target_ulong target_tv) { fd_set rfds, wfds, efds; fd_set *rfds_ptr, *wfds_ptr, *efds_ptr; target_long *target_rfds, *target_wfds, *target_efds; struct timeval tv, *tv_ptr; - long ret; + target_long ret; int ok; if (rfd_p) { @@ -648,10 +648,11 @@ static inline void host_to_target_cmsg(s msgh->msg_controllen = tswapl(space); } -static long do_setsockopt(int sockfd, int level, int optname, - target_ulong optval, socklen_t optlen) +static target_long do_setsockopt(int sockfd, int level, int optname, + target_ulong optval, socklen_t optlen) { - int val, ret; + target_long ret; + int val; switch(level) { case SOL_TCP: @@ -768,10 +769,11 @@ static long do_setsockopt(int sockfd, in return ret; } -static long do_getsockopt(int sockfd, int level, int optname, - target_ulong optval, target_ulong optlen) +static target_long do_getsockopt(int sockfd, int level, int optname, + target_ulong optval, target_ulong optlen) { - int len, lv, val, ret; + target_long ret; + int len, lv, val; switch(level) { case TARGET_SOL_SOCKET: @@ -887,7 +889,7 @@ static void unlock_iovec(struct iovec *v unlock_user (target_vec, target_addr, 0); } -static long do_socket(int domain, int type, int protocol) +static target_long do_socket(int domain, int type, int protocol) { #if defined(TARGET_MIPS) switch(type) { @@ -914,8 +916,8 @@ static long do_socket(int domain, int ty return get_errno(socket(domain, type, protocol)); } -static long do_bind(int sockfd, target_ulong target_addr, - socklen_t addrlen) +static target_long do_bind(int sockfd, target_ulong target_addr, + socklen_t addrlen) { void *addr = alloca(addrlen); @@ -923,8 +925,8 @@ static long do_bind(int sockfd, target_u return get_errno(bind(sockfd, addr, addrlen)); } -static long do_connect(int sockfd, target_ulong target_addr, - socklen_t addrlen) +static target_long do_connect(int sockfd, target_ulong target_addr, + socklen_t addrlen) { void *addr = alloca(addrlen); @@ -932,10 +934,10 @@ static long do_connect(int sockfd, targe return get_errno(connect(sockfd, addr, addrlen)); } -static long do_sendrecvmsg(int fd, target_ulong target_msg, - int flags, int send) +static target_long do_sendrecvmsg(int fd, target_ulong target_msg, + int flags, int send) { - long ret; + target_long ret; struct target_msghdr *msgp; struct msghdr msg; int count; @@ -975,12 +977,12 @@ static long do_sendrecvmsg(int fd, targe return ret; } -static long do_accept(int fd, target_ulong target_addr, - target_ulong target_addrlen) +static target_long do_accept(int fd, target_ulong target_addr, + target_ulong target_addrlen) { socklen_t addrlen = tget32(target_addrlen); void *addr = alloca(addrlen); - long ret; + target_long ret; ret = get_errno(accept(fd, addr, &addrlen)); if (!is_error(ret)) { @@ -990,12 +992,12 @@ static long do_accept(int fd, target_ulo return ret; } -static long do_getpeername(int fd, target_ulong target_addr, - target_ulong target_addrlen) +static target_long do_getpeername(int fd, target_ulong target_addr, + target_ulong target_addrlen) { socklen_t addrlen = tget32(target_addrlen); void *addr = alloca(addrlen); - long ret; + target_long ret; ret = get_errno(getpeername(fd, addr, &addrlen)); if (!is_error(ret)) { @@ -1005,12 +1007,12 @@ static long do_getpeername(int fd, targe return ret; } -static long do_getsockname(int fd, target_ulong target_addr, - target_ulong target_addrlen) +static target_long do_getsockname(int fd, target_ulong target_addr, + target_ulong target_addrlen) { socklen_t addrlen = tget32(target_addrlen); void *addr = alloca(addrlen); - long ret; + target_long ret; ret = get_errno(getsockname(fd, addr, &addrlen)); if (!is_error(ret)) { @@ -1020,11 +1022,11 @@ static long do_getsockname(int fd, targe return ret; } -static long do_socketpair(int domain, int type, int protocol, - target_ulong target_tab) +static target_long do_socketpair(int domain, int type, int protocol, + target_ulong target_tab) { int tab[2]; - long ret; + target_long ret; ret = get_errno(socketpair(domain, type, protocol, tab)); if (!is_error(ret)) { @@ -1034,12 +1036,12 @@ static long do_socketpair(int domain, in return ret; } -static long do_sendto(int fd, target_ulong msg, size_t len, int flags, - target_ulong target_addr, socklen_t addrlen) +static target_long do_sendto(int fd, target_ulong msg, size_t len, int flags, + target_ulong target_addr, socklen_t addrlen) { void *addr; void *host_msg; - long ret; + target_long ret; host_msg = lock_user(msg, len, 1); if (target_addr) { @@ -1053,13 +1055,14 @@ static long do_sendto(int fd, target_ulo return ret; } -static long do_recvfrom(int fd, target_ulong msg, size_t len, int flags, - target_ulong target_addr, target_ulong target_addrlen) +static target_long do_recvfrom(int fd, target_ulong msg, size_t len, int flags, + target_ulong target_addr, + target_ulong target_addrlen) { socklen_t addrlen; void *addr; void *host_msg; - long ret; + target_long ret; host_msg = lock_user(msg, len, 0); if (target_addr) { @@ -1082,9 +1085,10 @@ static long do_recvfrom(int fd, target_u return ret; } -static long do_socketcall(int num, target_ulong vptr) +#ifdef TARGET_NR_socketcall +static target_long do_socketcall(int num, target_ulong vptr) { - long ret; + target_long ret; const int n = sizeof(target_ulong); switch(num) { @@ -1244,7 +1248,9 @@ static long do_socketcall(int num, targe } return ret; } +#endif +#ifdef TARGET_NR_ipc #define N_SHM_REGIONS 32 static struct shm_region { @@ -1351,7 +1360,7 @@ union target_semun { unsigned short int *array; }; -static inline void target_to_host_semun(unsigned long cmd, +static inline void target_to_host_semun(int cmd, union semun *host_su, target_ulong target_addr, struct semid_ds *ds) @@ -1383,7 +1392,7 @@ static inline void target_to_host_semun( } } -static inline void host_to_target_semun(unsigned long cmd, +static inline void host_to_target_semun(int cmd, target_ulong target_addr, union semun *host_su, struct semid_ds *ds) @@ -1414,12 +1423,13 @@ static inline void host_to_target_semun( } } -static inline long do_semctl(long first, long second, long third, long ptr) +static inline target_long do_semctl(int first, int second, int third, + target_long ptr) { union semun arg; struct semid_ds dsarg; int cmd = third&0xff; - long ret = 0; + target_long ret = 0; switch( cmd ) { case GETVAL: @@ -1476,7 +1488,7 @@ struct target_msqid_ds }; static inline void target_to_host_msqid_ds(struct msqid_ds *host_md, - target_ulong target_addr) + target_ulong target_addr) { struct target_msqid_ds *target_md; @@ -1513,11 +1526,11 @@ static inline void host_to_target_msqid_ unlock_user_struct(target_md, target_addr, 1); } -static inline long do_msgctl(long first, long second, long ptr) +static inline target_long do_msgctl(int first, int second, target_long ptr) { struct msqid_ds dsarg; int cmd = second&0xff; - long ret = 0; + target_long ret = 0; switch( cmd ) { case IPC_STAT: case IPC_SET: @@ -1530,11 +1543,12 @@ static inline long do_msgctl(long first, char mtext[1]; }; -static inline long do_msgsnd(long msqid, long msgp, long msgsz, long msgflg) +static inline target_long do_msgsnd(int msqid, target_long msgp, + unsigned int msgsz, int msgflg) { struct target_msgbuf *target_mb; struct msgbuf *host_mb; - long ret = 0; + target_long ret = 0; lock_user_struct(target_mb,msgp,0); host_mb = malloc(msgsz+sizeof(long)); @@ -1552,11 +1569,13 @@ static inline long do_msgsnd(long msqid, return ret; } -static inline long do_msgrcv(long msqid, long msgp, long msgsz, long msgtype, long msgflg) +static inline target_long do_msgrcv(int msqid, target_long msgp, + unsigned int msgsz, int msgtype, + int msgflg) { struct target_msgbuf *target_mb; struct msgbuf *host_mb; - long ret = 0; + target_long ret = 0; lock_user_struct(target_mb, msgp, 0); host_mb = malloc(msgsz+sizeof(long)); @@ -1571,11 +1590,12 @@ static inline long do_msgrcv(long msqid, } /* ??? This only works with linear mappings. */ -static long do_ipc(long call, long first, long second, long third, - long ptr, long fifth) +static target_long do_ipc(unsigned int call, int first, + int second, int third, + target_long ptr, target_long fifth) { int version; - long ret = 0; + target_long ret = 0; unsigned long raddr; struct shmid_ds shm_info; int i; @@ -1597,7 +1617,7 @@ static long do_ipc(long call, long first break; case IPCOP_semtimedop: - gemu_log("Unsupported ipc call: %ld (version %d)\n", call, version); + gemu_log("Unsupported ipc call: %d (version %d)\n", call, version); ret = -ENOSYS; break; @@ -1653,7 +1673,7 @@ static long do_ipc(long call, long first break; } } - if (put_user(raddr, (uint32_t *)third)) + if (put_user(raddr, (target_ulong *)third)) return -EFAULT; ret = 0; break; @@ -1687,12 +1707,13 @@ static long do_ipc(long call, long first break; default: unimplemented: - gemu_log("Unsupported ipc call: %ld (version %d)\n", call, version); + gemu_log("Unsupported ipc call: %d (version %d)\n", call, version); ret = -ENOSYS; break; } return ret; } +#endif /* kernel structure types definitions */ #define IFNAMSIZ 16 @@ -1733,11 +1754,11 @@ IOCTLEntry ioctl_entries[] = { }; /* ??? Implement proper locking for ioctls. */ -static long do_ioctl(long fd, long cmd, long arg) +static target_long do_ioctl(int fd, target_long cmd, target_long arg) { const IOCTLEntry *ie; const argtype *arg_type; - long ret; + target_long ret; uint8_t buf_temp[MAX_STRUCT_SIZE]; int target_size; void *argptr; @@ -1745,7 +1766,7 @@ static long do_ioctl(long fd, long cmd, ie = ioctl_entries; for(;;) { if (ie->target_cmd == 0) { - gemu_log("Unsupported ioctl: cmd=0x%04lx\n", cmd); + gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd); return -ENOSYS; } if (ie->target_cmd == cmd) @@ -1754,7 +1775,7 @@ static long do_ioctl(long fd, long cmd, } arg_type = ie->arg_type; #if defined(DEBUG) - gemu_log("ioctl: cmd=0x%04lx (%s)\n", cmd, ie->name); + gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name); #endif switch(arg_type[0]) { case TYPE_NULL: @@ -1799,7 +1820,8 @@ static long do_ioctl(long fd, long cmd, } break; default: - gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", cmd, arg_type[0]); + gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", + (long)cmd, arg_type[0]); ret = -ENOSYS; break; } @@ -2149,7 +2171,7 @@ static int clone_func(void *arg) return 0; } -int do_fork(CPUState *env, unsigned int flags, unsigned long newsp) +int do_fork(CPUState *env, unsigned int flags, target_ulong newsp) { int ret; TaskState *ts; @@ -2235,13 +2257,13 @@ int do_fork(CPUState *env, unsigned int return ret; } -static long do_fcntl(int fd, int cmd, target_ulong arg) +static target_long do_fcntl(int fd, int cmd, target_ulong arg) { struct flock fl; struct target_flock *target_fl; struct flock64 fl64; struct target_flock64 *target_fl64; - long ret; + target_long ret; switch(cmd) { case TARGET_F_GETLK: @@ -2400,6 +2422,7 @@ void syscall_init(void) } } +#if TARGET_LONG_BITS == 32 static inline uint64_t target_offset64(uint32_t word0, uint32_t word1) { #ifdef TARGET_WORDS_BIG_ENDIAN @@ -2408,10 +2431,18 @@ static inline uint64_t target_offset64(u return ((uint64_t)word1 << 32) | word0; #endif } +#else /* TARGET_LONG_BITS == 32 */ +static inline uint64_t target_offset64(uint64_t word0, uint64_t word1) +{ + return word0; +} +#endif /* TARGET_LONG_BITS != 32 */ #ifdef TARGET_NR_truncate64 -static inline long target_truncate64(void *cpu_env, const char *arg1, - long arg2, long arg3, long arg4) +static inline target_long target_truncate64(void *cpu_env, const char *arg1, + target_long arg2, + target_long arg3, + target_long arg4) { #ifdef TARGET_ARM if (((CPUARMState *)cpu_env)->eabi) @@ -2425,8 +2456,10 @@ static inline long target_truncate64(voi #endif #ifdef TARGET_NR_ftruncate64 -static inline long target_ftruncate64(void *cpu_env, long arg1, long arg2, - long arg3, long arg4) +static inline target_long target_ftruncate64(void *cpu_env, target_long arg1, + target_long arg2, + target_long arg3, + target_long arg4) { #ifdef TARGET_ARM if (((CPUARMState *)cpu_env)->eabi) @@ -2461,10 +2494,11 @@ static inline void host_to_target_timesp unlock_user_struct(target_ts, target_addr, 1); } -long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, - long arg4, long arg5, long arg6) +target_long do_syscall(void *cpu_env, int num, target_long arg1, + target_long arg2, target_long arg3, target_long arg4, + target_long arg5, target_long arg6) { - long ret; + target_long ret; struct stat st; struct statfs stfs; void *p; @@ -3781,7 +3815,7 @@ long do_syscall(void *cpu_env, int num, { struct target_dirent *target_dirp; struct dirent *dirp; - long count = arg3; + target_long count = arg3; dirp = malloc(count); if (!dirp) @@ -3823,7 +3857,7 @@ long do_syscall(void *cpu_env, int num, #else { struct dirent *dirp; - long count = arg3; + target_long count = arg3; dirp = lock_user(arg2, count, 0); ret = get_errno(sys_getdents(arg1, dirp, count)); @@ -3851,7 +3885,7 @@ long do_syscall(void *cpu_env, int num, case TARGET_NR_getdents64: { struct dirent64 *dirp; - long count = arg3; + target_long count = arg3; dirp = lock_user(arg2, count, 0); ret = get_errno(sys_getdents64(arg1, dirp, count)); if (!is_error(ret)) { @@ -4668,4 +4702,3 @@ long do_syscall(void *cpu_env, int num, #endif return ret; } -