mirror of
https://github.com/qemu/qemu.git
synced 2024-11-24 11:23:43 +08:00
Merge branch 'linux-user-for-upstream' of git://gitorious.org/qemu-maemo/qemu
* 'linux-user-for-upstream' of git://gitorious.org/qemu-maemo/qemu: linux-user: untie syscalls from UID16 linux-user: add s390x to llseek list linux-user: add ioctl(SIOCGIWNAME, ...) support. linux-user: convert ioctl(SIOCGIFCONF, ...) result. linux-user: improve traces [v2] linux-user: bigger default stack
This commit is contained in:
commit
1a924df620
@ -412,10 +412,3 @@
|
||||
#define TARGET_NR_timerfd 477
|
||||
#define TARGET_NR_eventfd 478
|
||||
|
||||
/* The following aliases are defined in order to match up with the
|
||||
standard i386 syscalls implemented in syscalls.c. */
|
||||
#define TARGET_NR_chown32 TARGET_NR_chown
|
||||
#define TARGET_NR_setuid32 TARGET_NR_setuid
|
||||
#define TARGET_NR_setgid32 TARGET_NR_setgid
|
||||
#define TARGET_NR_setfsuid32 TARGET_NR_setfsuid
|
||||
#define TARGET_NR_setfsgid32 TARGET_NR_setfsgid
|
||||
|
@ -112,7 +112,8 @@
|
||||
IOCTL(SIOCADDMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||
IOCTL(SIOCDELMULTI, IOC_W, MK_PTR(MK_STRUCT(STRUCT_sockaddr_ifreq)))
|
||||
IOCTL(SIOCSIFLINK, 0, TYPE_NULL)
|
||||
IOCTL(SIOCGIFCONF, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_ifconf)))
|
||||
IOCTL_SPECIAL(SIOCGIFCONF, IOC_W | IOC_R, do_ioctl_ifconf,
|
||||
MK_PTR(MK_STRUCT(STRUCT_ifconf)))
|
||||
IOCTL(SIOCGIFENCAP, IOC_RW, MK_PTR(TYPE_INT))
|
||||
IOCTL(SIOCSIFENCAP, IOC_W, MK_PTR(TYPE_INT))
|
||||
IOCTL(SIOCDARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||
@ -121,6 +122,7 @@
|
||||
IOCTL(SIOCDRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||
IOCTL(SIOCSRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||
IOCTL(SIOCGRARP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
|
||||
IOCTL(SIOCGIWNAME, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_char_ifreq)))
|
||||
|
||||
IOCTL(CDROMPAUSE, 0, TYPE_NULL)
|
||||
IOCTL(CDROMSTART, 0, TYPE_NULL)
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <sys/mount.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
#include "qemu.h"
|
||||
|
||||
int do_strace=0;
|
||||
@ -63,6 +64,7 @@ UNUSED static void print_string(abi_long, int);
|
||||
UNUSED static void print_raw_param(const char *, abi_long, int);
|
||||
UNUSED static void print_timeval(abi_ulong, int);
|
||||
UNUSED static void print_number(abi_long, int);
|
||||
UNUSED static void print_signal(abi_ulong, int);
|
||||
|
||||
/*
|
||||
* Utility functions
|
||||
@ -117,6 +119,37 @@ if( cmd == val ) { \
|
||||
gemu_log("%d",cmd);
|
||||
}
|
||||
|
||||
static void
|
||||
print_signal(abi_ulong arg, int last)
|
||||
{
|
||||
const char *signal_name = NULL;
|
||||
switch(arg) {
|
||||
case TARGET_SIGHUP: signal_name = "SIGHUP"; break;
|
||||
case TARGET_SIGINT: signal_name = "SIGINT"; break;
|
||||
case TARGET_SIGQUIT: signal_name = "SIGQUIT"; break;
|
||||
case TARGET_SIGILL: signal_name = "SIGILL"; break;
|
||||
case TARGET_SIGABRT: signal_name = "SIGABRT"; break;
|
||||
case TARGET_SIGFPE: signal_name = "SIGFPE"; break;
|
||||
case TARGET_SIGKILL: signal_name = "SIGKILL"; break;
|
||||
case TARGET_SIGSEGV: signal_name = "SIGSEGV"; break;
|
||||
case TARGET_SIGPIPE: signal_name = "SIGPIPE"; break;
|
||||
case TARGET_SIGALRM: signal_name = "SIGALRM"; break;
|
||||
case TARGET_SIGTERM: signal_name = "SIGTERM"; break;
|
||||
case TARGET_SIGUSR1: signal_name = "SIGUSR1"; break;
|
||||
case TARGET_SIGUSR2: signal_name = "SIGUSR2"; break;
|
||||
case TARGET_SIGCHLD: signal_name = "SIGCHLD"; break;
|
||||
case TARGET_SIGCONT: signal_name = "SIGCONT"; break;
|
||||
case TARGET_SIGSTOP: signal_name = "SIGSTOP"; break;
|
||||
case TARGET_SIGTTIN: signal_name = "SIGTTIN"; break;
|
||||
case TARGET_SIGTTOU: signal_name = "SIGTTOU"; break;
|
||||
}
|
||||
if (signal_name == NULL) {
|
||||
print_raw_param("%ld", arg, 1);
|
||||
return;
|
||||
}
|
||||
gemu_log("%s%s", signal_name, get_comma(last));
|
||||
}
|
||||
|
||||
#ifdef TARGET_NR__newselect
|
||||
static void
|
||||
print_fdset(int n, abi_ulong target_fds_addr)
|
||||
@ -427,6 +460,32 @@ UNUSED static struct flags fcntl_flags[] = {
|
||||
FLAG_END,
|
||||
};
|
||||
|
||||
UNUSED static struct flags clone_flags[] = {
|
||||
FLAG_GENERIC(CLONE_VM),
|
||||
FLAG_GENERIC(CLONE_FS),
|
||||
FLAG_GENERIC(CLONE_FILES),
|
||||
FLAG_GENERIC(CLONE_SIGHAND),
|
||||
FLAG_GENERIC(CLONE_PTRACE),
|
||||
FLAG_GENERIC(CLONE_VFORK),
|
||||
FLAG_GENERIC(CLONE_PARENT),
|
||||
FLAG_GENERIC(CLONE_THREAD),
|
||||
FLAG_GENERIC(CLONE_NEWNS),
|
||||
FLAG_GENERIC(CLONE_SYSVSEM),
|
||||
FLAG_GENERIC(CLONE_SETTLS),
|
||||
FLAG_GENERIC(CLONE_PARENT_SETTID),
|
||||
FLAG_GENERIC(CLONE_CHILD_CLEARTID),
|
||||
FLAG_GENERIC(CLONE_DETACHED),
|
||||
FLAG_GENERIC(CLONE_UNTRACED),
|
||||
FLAG_GENERIC(CLONE_CHILD_SETTID),
|
||||
FLAG_GENERIC(CLONE_NEWUTS),
|
||||
FLAG_GENERIC(CLONE_NEWIPC),
|
||||
FLAG_GENERIC(CLONE_NEWUSER),
|
||||
FLAG_GENERIC(CLONE_NEWPID),
|
||||
FLAG_GENERIC(CLONE_NEWNET),
|
||||
FLAG_GENERIC(CLONE_IO),
|
||||
FLAG_END,
|
||||
};
|
||||
|
||||
/*
|
||||
* print_xxx utility functions. These are used to print syscall
|
||||
* parameters in certain format. All of these have parameter
|
||||
@ -669,6 +728,39 @@ print_chmod(const struct syscallname *name,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_NR_clone
|
||||
static void
|
||||
print_clone(const struct syscallname *name,
|
||||
abi_long arg0, abi_long arg1, abi_long arg2,
|
||||
abi_long arg3, abi_long arg4, abi_long arg5)
|
||||
{
|
||||
print_syscall_prologue(name);
|
||||
#if defined(TARGET_M68K)
|
||||
print_flags(clone_flags, arg0, 0);
|
||||
print_raw_param("newsp=0x" TARGET_ABI_FMT_lx, arg1, 1);
|
||||
#elif defined(TARGET_SH4) || defined(TARGET_ALPHA)
|
||||
print_flags(clone_flags, arg0, 0);
|
||||
print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg1, 0);
|
||||
print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
|
||||
print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg3, 0);
|
||||
print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg4, 1);
|
||||
#elif defined(TARGET_CRIS)
|
||||
print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg0, 0);
|
||||
print_flags(clone_flags, arg1, 0);
|
||||
print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
|
||||
print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg3, 0);
|
||||
print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg4, 1);
|
||||
#else
|
||||
print_flags(clone_flags, arg0, 0);
|
||||
print_raw_param("child_stack=0x" TARGET_ABI_FMT_lx, arg1, 0);
|
||||
print_raw_param("parent_tidptr=0x" TARGET_ABI_FMT_lx, arg2, 0);
|
||||
print_raw_param("tls=0x" TARGET_ABI_FMT_lx, arg3, 0);
|
||||
print_raw_param("child_tidptr=0x" TARGET_ABI_FMT_lx, arg4, 1);
|
||||
#endif
|
||||
print_syscall_epilogue(name);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_NR_creat
|
||||
static void
|
||||
print_creat(const struct syscallname *name,
|
||||
@ -805,6 +897,28 @@ print_linkat(const struct syscallname *name,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_NR__llseek
|
||||
static void
|
||||
print__llseek(const struct syscallname *name,
|
||||
abi_long arg0, abi_long arg1, abi_long arg2,
|
||||
abi_long arg3, abi_long arg4, abi_long arg5)
|
||||
{
|
||||
const char *whence = "UNKNOWN";
|
||||
print_syscall_prologue(name);
|
||||
print_raw_param("%d", arg0, 0);
|
||||
print_raw_param("%ld", arg1, 0);
|
||||
print_raw_param("%ld", arg2, 0);
|
||||
print_pointer(arg3, 0);
|
||||
switch(arg4) {
|
||||
case SEEK_SET: whence = "SEEK_SET"; break;
|
||||
case SEEK_CUR: whence = "SEEK_CUR"; break;
|
||||
case SEEK_END: whence = "SEEK_END"; break;
|
||||
}
|
||||
gemu_log("%s",whence);
|
||||
print_syscall_epilogue(name);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) || \
|
||||
defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64)
|
||||
static void
|
||||
@ -875,6 +989,40 @@ print_rmdir(const struct syscallname *name,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_NR_rt_sigaction
|
||||
static void
|
||||
print_rt_sigaction(const struct syscallname *name,
|
||||
abi_long arg0, abi_long arg1, abi_long arg2,
|
||||
abi_long arg3, abi_long arg4, abi_long arg5)
|
||||
{
|
||||
print_syscall_prologue(name);
|
||||
print_signal(arg0, 0);
|
||||
print_pointer(arg1, 0);
|
||||
print_pointer(arg2, 1);
|
||||
print_syscall_epilogue(name);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_NR_rt_sigprocmask
|
||||
static void
|
||||
print_rt_sigprocmask(const struct syscallname *name,
|
||||
abi_long arg0, abi_long arg1, abi_long arg2,
|
||||
abi_long arg3, abi_long arg4, abi_long arg5)
|
||||
{
|
||||
const char *how = "UNKNOWN";
|
||||
print_syscall_prologue(name);
|
||||
switch(arg0) {
|
||||
case TARGET_SIG_BLOCK: how = "SIG_BLOCK"; break;
|
||||
case TARGET_SIG_UNBLOCK: how = "SIG_UNBLOCK"; break;
|
||||
case TARGET_SIG_SETMASK: how = "SIG_SETMASK"; break;
|
||||
}
|
||||
gemu_log("%s,",how);
|
||||
print_pointer(arg1, 0);
|
||||
print_pointer(arg2, 1);
|
||||
print_syscall_epilogue(name);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_NR_mknod
|
||||
static void
|
||||
print_mknod(const struct syscallname *name,
|
||||
@ -1298,6 +1446,19 @@ print_futex(const struct syscallname *name,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_NR_kill
|
||||
static void
|
||||
print_kill(const struct syscallname *name,
|
||||
abi_long arg0, abi_long arg1, abi_long arg2,
|
||||
abi_long arg3, abi_long arg4, abi_long arg5)
|
||||
{
|
||||
print_syscall_prologue(name);
|
||||
print_raw_param("%d", arg0, 0);
|
||||
print_signal(arg1, 1);
|
||||
print_syscall_epilogue(name);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* An array of all of the syscalls we know about
|
||||
*/
|
||||
|
@ -85,7 +85,7 @@
|
||||
{ TARGET_NR_clock_settime, "clock_settime" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_clone
|
||||
{ TARGET_NR_clone, "clone" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_clone, "clone" , NULL, print_clone, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_close
|
||||
{ TARGET_NR_close, "close" , "%s(%d)", NULL, NULL },
|
||||
@ -292,7 +292,7 @@
|
||||
{ TARGET_NR_getpgrp, "getpgrp" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_getpid
|
||||
{ TARGET_NR_getpid, "getpid" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_getpid, "getpid" , "%s()", NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_getpmsg
|
||||
{ TARGET_NR_getpmsg, "getpmsg" , NULL, NULL, NULL },
|
||||
@ -418,7 +418,7 @@
|
||||
{ TARGET_NR_keyctl, "keyctl" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_kill
|
||||
{ TARGET_NR_kill, "kill" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_kill, "kill", NULL, print_kill, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_lchown
|
||||
{ TARGET_NR_lchown, "lchown" , NULL, NULL, NULL },
|
||||
@ -448,7 +448,7 @@
|
||||
{ TARGET_NR_llistxattr, "llistxattr" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR__llseek
|
||||
{ TARGET_NR__llseek, "_llseek" , NULL, NULL, NULL },
|
||||
{ TARGET_NR__llseek, "_llseek" , NULL, print__llseek, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_lock
|
||||
{ TARGET_NR_lock, "lock" , NULL, NULL, NULL },
|
||||
@ -1063,13 +1063,13 @@
|
||||
{ TARGET_NR_rmdir, "rmdir" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_rt_sigaction
|
||||
{ TARGET_NR_rt_sigaction, "rt_sigaction" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_rt_sigaction, "rt_sigaction" , NULL, print_rt_sigaction, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_rt_sigpending
|
||||
{ TARGET_NR_rt_sigpending, "rt_sigpending" , NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_rt_sigprocmask
|
||||
{ TARGET_NR_rt_sigprocmask, "rt_sigprocmask" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_rt_sigprocmask, "rt_sigprocmask" , NULL, print_rt_sigprocmask, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_rt_sigqueueinfo
|
||||
{ TARGET_NR_rt_sigqueueinfo, "rt_sigqueueinfo" , NULL, NULL, NULL },
|
||||
|
@ -59,6 +59,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
|
||||
//#include <sys/user.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <qemu-common.h>
|
||||
#ifdef TARGET_GPROF
|
||||
#include <sys/gmon.h>
|
||||
@ -196,7 +197,8 @@ static type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, \
|
||||
#define __NR_sys_inotify_add_watch __NR_inotify_add_watch
|
||||
#define __NR_sys_inotify_rm_watch __NR_inotify_rm_watch
|
||||
|
||||
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
|
||||
#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) || \
|
||||
defined(__s390x__)
|
||||
#define __NR__llseek __NR_lseek
|
||||
#endif
|
||||
|
||||
@ -326,7 +328,7 @@ static int sys_fchmodat(int dirfd, const char *pathname, mode_t mode)
|
||||
return (fchmodat(dirfd, pathname, mode, 0));
|
||||
}
|
||||
#endif
|
||||
#if defined(TARGET_NR_fchownat) && defined(USE_UID16)
|
||||
#if defined(TARGET_NR_fchownat)
|
||||
static int sys_fchownat(int dirfd, const char *pathname, uid_t owner,
|
||||
gid_t group, int flags)
|
||||
{
|
||||
@ -435,7 +437,7 @@ _syscall3(int,sys_faccessat,int,dirfd,const char *,pathname,int,mode)
|
||||
#if defined(TARGET_NR_fchmodat) && defined(__NR_fchmodat)
|
||||
_syscall3(int,sys_fchmodat,int,dirfd,const char *,pathname, mode_t,mode)
|
||||
#endif
|
||||
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat) && defined(USE_UID16)
|
||||
#if defined(TARGET_NR_fchownat) && defined(__NR_fchownat)
|
||||
_syscall5(int,sys_fchownat,int,dirfd,const char *,pathname,
|
||||
uid_t,owner,gid_t,group,int,flags)
|
||||
#endif
|
||||
@ -2970,7 +2972,6 @@ static abi_long do_ipc(unsigned int call, int first,
|
||||
#endif
|
||||
|
||||
/* kernel structure types definitions */
|
||||
#define IFNAMSIZ 16
|
||||
|
||||
#define STRUCT(name, ...) STRUCT_ ## name,
|
||||
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
|
||||
@ -3095,6 +3096,100 @@ static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
|
||||
}
|
||||
#endif
|
||||
|
||||
static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
|
||||
int fd, abi_long cmd, abi_long arg)
|
||||
{
|
||||
const argtype *arg_type = ie->arg_type;
|
||||
int target_size;
|
||||
void *argptr;
|
||||
int ret;
|
||||
struct ifconf *host_ifconf;
|
||||
uint32_t outbufsz;
|
||||
const argtype ifreq_arg_type[] = { MK_STRUCT(STRUCT_sockaddr_ifreq) };
|
||||
int target_ifreq_size;
|
||||
int nb_ifreq;
|
||||
int free_buf = 0;
|
||||
int i;
|
||||
int target_ifc_len;
|
||||
abi_long target_ifc_buf;
|
||||
int host_ifc_len;
|
||||
char *host_ifc_buf;
|
||||
|
||||
assert(arg_type[0] == TYPE_PTR);
|
||||
assert(ie->access == IOC_RW);
|
||||
|
||||
arg_type++;
|
||||
target_size = thunk_type_size(arg_type, 0);
|
||||
|
||||
argptr = lock_user(VERIFY_READ, arg, target_size, 1);
|
||||
if (!argptr)
|
||||
return -TARGET_EFAULT;
|
||||
thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
|
||||
unlock_user(argptr, arg, 0);
|
||||
|
||||
host_ifconf = (struct ifconf *)(unsigned long)buf_temp;
|
||||
target_ifc_len = host_ifconf->ifc_len;
|
||||
target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf;
|
||||
|
||||
target_ifreq_size = thunk_type_size(ifreq_arg_type, 0);
|
||||
nb_ifreq = target_ifc_len / target_ifreq_size;
|
||||
host_ifc_len = nb_ifreq * sizeof(struct ifreq);
|
||||
|
||||
outbufsz = sizeof(*host_ifconf) + host_ifc_len;
|
||||
if (outbufsz > MAX_STRUCT_SIZE) {
|
||||
/* We can't fit all the extents into the fixed size buffer.
|
||||
* Allocate one that is large enough and use it instead.
|
||||
*/
|
||||
host_ifconf = malloc(outbufsz);
|
||||
if (!host_ifconf) {
|
||||
return -TARGET_ENOMEM;
|
||||
}
|
||||
memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf));
|
||||
free_buf = 1;
|
||||
}
|
||||
host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf);
|
||||
|
||||
host_ifconf->ifc_len = host_ifc_len;
|
||||
host_ifconf->ifc_buf = host_ifc_buf;
|
||||
|
||||
ret = get_errno(ioctl(fd, ie->host_cmd, host_ifconf));
|
||||
if (!is_error(ret)) {
|
||||
/* convert host ifc_len to target ifc_len */
|
||||
|
||||
nb_ifreq = host_ifconf->ifc_len / sizeof(struct ifreq);
|
||||
target_ifc_len = nb_ifreq * target_ifreq_size;
|
||||
host_ifconf->ifc_len = target_ifc_len;
|
||||
|
||||
/* restore target ifc_buf */
|
||||
|
||||
host_ifconf->ifc_buf = (char *)(unsigned long)target_ifc_buf;
|
||||
|
||||
/* copy struct ifconf to target user */
|
||||
|
||||
argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
|
||||
if (!argptr)
|
||||
return -TARGET_EFAULT;
|
||||
thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET);
|
||||
unlock_user(argptr, arg, target_size);
|
||||
|
||||
/* copy ifreq[] to target user */
|
||||
|
||||
argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0);
|
||||
for (i = 0; i < nb_ifreq ; i++) {
|
||||
thunk_convert(argptr + i * target_ifreq_size,
|
||||
host_ifc_buf + i * sizeof(struct ifreq),
|
||||
ifreq_arg_type, THUNK_TARGET);
|
||||
}
|
||||
unlock_user(argptr, target_ifc_buf, target_ifc_len);
|
||||
}
|
||||
|
||||
if (free_buf) {
|
||||
free(host_ifconf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static IOCTLEntry ioctl_entries[] = {
|
||||
#define IOCTL(cmd, access, ...) \
|
||||
{ TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
|
||||
@ -3690,9 +3785,9 @@ static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
|
||||
|
||||
#endif /* defined(TARGET_I386) */
|
||||
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
#define NEW_STACK_SIZE 0x40000
|
||||
|
||||
#define NEW_STACK_SIZE PTHREAD_STACK_MIN
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
|
||||
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
typedef struct {
|
||||
@ -3736,9 +3831,6 @@ static void *clone_func(void *arg)
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
/* this stack is the equivalent of the kernel stack associated with a
|
||||
thread/process */
|
||||
#define NEW_STACK_SIZE 8192
|
||||
|
||||
static int clone_func(void *arg)
|
||||
{
|
||||
@ -4072,7 +4164,31 @@ static inline int low2highgid(int gid)
|
||||
else
|
||||
return gid;
|
||||
}
|
||||
|
||||
static inline int tswapid(int id)
|
||||
{
|
||||
return tswap16(id);
|
||||
}
|
||||
#else /* !USE_UID16 */
|
||||
static inline int high2lowuid(int uid)
|
||||
{
|
||||
return uid;
|
||||
}
|
||||
static inline int high2lowgid(int gid)
|
||||
{
|
||||
return gid;
|
||||
}
|
||||
static inline int low2highuid(int uid)
|
||||
{
|
||||
return uid;
|
||||
}
|
||||
static inline int low2highgid(int gid)
|
||||
{
|
||||
return gid;
|
||||
}
|
||||
static inline int tswapid(int id)
|
||||
{
|
||||
return tswap32(id);
|
||||
}
|
||||
#endif /* USE_UID16 */
|
||||
|
||||
void syscall_init(void)
|
||||
@ -6673,25 +6789,32 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
ret = host_to_target_stat64(cpu_env, arg3, &st);
|
||||
break;
|
||||
#endif
|
||||
#ifdef USE_UID16
|
||||
case TARGET_NR_lchown:
|
||||
if (!(p = lock_user_string(arg1)))
|
||||
goto efault;
|
||||
ret = get_errno(lchown(p, low2highuid(arg2), low2highgid(arg3)));
|
||||
unlock_user(p, arg1, 0);
|
||||
break;
|
||||
#ifdef TARGET_NR_getuid
|
||||
case TARGET_NR_getuid:
|
||||
ret = get_errno(high2lowuid(getuid()));
|
||||
break;
|
||||
#endif
|
||||
#ifdef TARGET_NR_getgid
|
||||
case TARGET_NR_getgid:
|
||||
ret = get_errno(high2lowgid(getgid()));
|
||||
break;
|
||||
#endif
|
||||
#ifdef TARGET_NR_geteuid
|
||||
case TARGET_NR_geteuid:
|
||||
ret = get_errno(high2lowuid(geteuid()));
|
||||
break;
|
||||
#endif
|
||||
#ifdef TARGET_NR_getegid
|
||||
case TARGET_NR_getegid:
|
||||
ret = get_errno(high2lowgid(getegid()));
|
||||
break;
|
||||
#endif
|
||||
case TARGET_NR_setreuid:
|
||||
ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
|
||||
break;
|
||||
@ -6701,7 +6824,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
case TARGET_NR_getgroups:
|
||||
{
|
||||
int gidsetsize = arg1;
|
||||
uint16_t *target_grouplist;
|
||||
target_id *target_grouplist;
|
||||
gid_t *grouplist;
|
||||
int i;
|
||||
|
||||
@ -6714,7 +6837,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
if (!target_grouplist)
|
||||
goto efault;
|
||||
for(i = 0;i < ret; i++)
|
||||
target_grouplist[i] = tswap16(grouplist[i]);
|
||||
target_grouplist[i] = tswapid(high2lowgid(grouplist[i]));
|
||||
unlock_user(target_grouplist, arg2, gidsetsize * 2);
|
||||
}
|
||||
}
|
||||
@ -6722,7 +6845,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
case TARGET_NR_setgroups:
|
||||
{
|
||||
int gidsetsize = arg1;
|
||||
uint16_t *target_grouplist;
|
||||
target_id *target_grouplist;
|
||||
gid_t *grouplist;
|
||||
int i;
|
||||
|
||||
@ -6733,7 +6856,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
goto fail;
|
||||
}
|
||||
for(i = 0;i < gidsetsize; i++)
|
||||
grouplist[i] = tswap16(target_grouplist[i]);
|
||||
grouplist[i] = low2highgid(tswapid(target_grouplist[i]));
|
||||
unlock_user(target_grouplist, arg2, 0);
|
||||
ret = get_errno(setgroups(gidsetsize, grouplist));
|
||||
}
|
||||
@ -6809,7 +6932,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
case TARGET_NR_setfsgid:
|
||||
ret = get_errno(setfsgid(arg1));
|
||||
break;
|
||||
#endif /* USE_UID16 */
|
||||
|
||||
#ifdef TARGET_NR_lchown32
|
||||
case TARGET_NR_lchown32:
|
||||
|
@ -49,9 +49,12 @@
|
||||
#define TARGET_IOC_TYPEBITS 8
|
||||
|
||||
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \
|
||||
|| defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS) || defined(TARGET_PPC) || defined(TARGET_MIPS)
|
||||
|| defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS)
|
||||
/* 16 bit uid wrappers emulation */
|
||||
#define USE_UID16
|
||||
#define target_id uint16_t
|
||||
#else
|
||||
#define target_id uint32_t
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \
|
||||
@ -765,6 +768,9 @@ struct target_pollfd {
|
||||
#define TARGET_SIOCADDDLCI 0x8980 /* Create new DLCI device */
|
||||
#define TARGET_SIOCDELDLCI 0x8981 /* Delete DLCI device */
|
||||
|
||||
/* From <linux/wireless.h> */
|
||||
|
||||
#define TARGET_SIOCGIWNAME 0x8B01 /* get name == wireless protocol */
|
||||
|
||||
/* From <linux/fs.h> */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user