Commit bcd47878 authored by Edgar E. Iglesias's avatar Edgar E. Iglesias
Browse files

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: fix mips and ppc to use UID16
  update binfmt conf
  linux-user: fix compiler error on nptl
  ARM: linux-user: Restore iWMMXT state from ucontext on sigreturn
  ARM: linux-user: Expose iWMMXT registers to signal handlers
  ARM: linux-user: Restore VFP state from ucontext on sigreturn
  ARM: linux-user: Expose VFP registers to signal handlers
  ARM: Expose vfp_get_fpscr() and vfp_set_fpscr() to C code
  ARM: linux-user: Correct size of padding in target_ucontext_v2
  target-sparc: remove unused functions cpu_lock(), cpu_unlock()
  ARM: enable XScale/iWMMXT in linux-user mode
  linux-user: Translate getsockopt level option
  linux-user: remove unnecessary local from __get_user(), __put_user()
  linux-user: fix memory leaks with NPTL emulation
  linux-user: mmap_reserve() not controlled by RESERVED_VA
  [PATCH] target-arm: remove unused functions cpu_lock(), cpu_unlock()
parents db1923de b2e7aab2
......@@ -2711,7 +2711,7 @@ int main(int argc, char **argv, char **envp)
struct target_pt_regs regs1, *regs = &regs1;
struct image_info info1, *info = &info1;
struct linux_binprm bprm;
TaskState ts1, *ts = &ts1;
TaskState *ts;
CPUState *env;
int optind;
const char *r;
......@@ -3038,7 +3038,7 @@ int main(int argc, char **argv, char **envp)
}
target_argv[target_argc] = NULL;
memset(ts, 0, sizeof(TaskState));
ts = qemu_mallocz (sizeof(TaskState));
init_task_state(ts);
/* build Task State */
ts->info = info;
......
......@@ -18,15 +18,15 @@
#define TARGET_NR_time (TARGET_NR_Linux + 13)
#define TARGET_NR_mknod (TARGET_NR_Linux + 14)
#define TARGET_NR_chmod (TARGET_NR_Linux + 15)
#define TARGET_NR_lchown32 (TARGET_NR_Linux + 16)
#define TARGET_NR_lchown (TARGET_NR_Linux + 16)
#define TARGET_NR_break (TARGET_NR_Linux + 17)
#define TARGET_NR_unused18 (TARGET_NR_Linux + 18)
#define TARGET_NR_lseek (TARGET_NR_Linux + 19)
#define TARGET_NR_getpid (TARGET_NR_Linux + 20)
#define TARGET_NR_mount (TARGET_NR_Linux + 21)
#define TARGET_NR_umount (TARGET_NR_Linux + 22)
#define TARGET_NR_setuid32 (TARGET_NR_Linux + 23)
#define TARGET_NR_getuid32 (TARGET_NR_Linux + 24)
#define TARGET_NR_setuid (TARGET_NR_Linux + 23)
#define TARGET_NR_getuid (TARGET_NR_Linux + 24)
#define TARGET_NR_stime (TARGET_NR_Linux + 25)
#define TARGET_NR_ptrace (TARGET_NR_Linux + 26)
#define TARGET_NR_alarm (TARGET_NR_Linux + 27)
......@@ -48,11 +48,11 @@
#define TARGET_NR_times (TARGET_NR_Linux + 43)
#define TARGET_NR_prof (TARGET_NR_Linux + 44)
#define TARGET_NR_brk (TARGET_NR_Linux + 45)
#define TARGET_NR_setgid32 (TARGET_NR_Linux + 46)
#define TARGET_NR_getgid32 (TARGET_NR_Linux + 47)
#define TARGET_NR_setgid (TARGET_NR_Linux + 46)
#define TARGET_NR_getgid (TARGET_NR_Linux + 47)
#define TARGET_NR_signal (TARGET_NR_Linux + 48)
#define TARGET_NR_geteuid32 (TARGET_NR_Linux + 49)
#define TARGET_NR_getegid32 (TARGET_NR_Linux + 50)
#define TARGET_NR_geteuid (TARGET_NR_Linux + 49)
#define TARGET_NR_getegid (TARGET_NR_Linux + 50)
#define TARGET_NR_acct (TARGET_NR_Linux + 51)
#define TARGET_NR_umount2 (TARGET_NR_Linux + 52)
#define TARGET_NR_lock (TARGET_NR_Linux + 53)
......@@ -72,8 +72,8 @@
#define TARGET_NR_sigaction (TARGET_NR_Linux + 67)
#define TARGET_NR_sgetmask (TARGET_NR_Linux + 68)
#define TARGET_NR_ssetmask (TARGET_NR_Linux + 69)
#define TARGET_NR_setreuid32 (TARGET_NR_Linux + 70)
#define TARGET_NR_setregid32 (TARGET_NR_Linux + 71)
#define TARGET_NR_setreuid (TARGET_NR_Linux + 70)
#define TARGET_NR_setregid (TARGET_NR_Linux + 71)
#define TARGET_NR_sigsuspend (TARGET_NR_Linux + 72)
#define TARGET_NR_sigpending (TARGET_NR_Linux + 73)
#define TARGET_NR_sethostname (TARGET_NR_Linux + 74)
......@@ -82,8 +82,8 @@
#define TARGET_NR_getrusage (TARGET_NR_Linux + 77)
#define TARGET_NR_gettimeofday (TARGET_NR_Linux + 78)
#define TARGET_NR_settimeofday (TARGET_NR_Linux + 79)
#define TARGET_NR_getgroups32 (TARGET_NR_Linux + 80)
#define TARGET_NR_setgroups32 (TARGET_NR_Linux + 81)
#define TARGET_NR_getgroups (TARGET_NR_Linux + 80)
#define TARGET_NR_setgroups (TARGET_NR_Linux + 81)
#define TARGET_NR_reserved82 (TARGET_NR_Linux + 82)
#define TARGET_NR_symlink (TARGET_NR_Linux + 83)
#define TARGET_NR_unused84 (TARGET_NR_Linux + 84)
......@@ -97,7 +97,7 @@
#define TARGET_NR_truncate (TARGET_NR_Linux + 92)
#define TARGET_NR_ftruncate (TARGET_NR_Linux + 93)
#define TARGET_NR_fchmod (TARGET_NR_Linux + 94)
#define TARGET_NR_fchown32 (TARGET_NR_Linux + 95)
#define TARGET_NR_fchown (TARGET_NR_Linux + 95)
#define TARGET_NR_getpriority (TARGET_NR_Linux + 96)
#define TARGET_NR_setpriority (TARGET_NR_Linux + 97)
#define TARGET_NR_profil (TARGET_NR_Linux + 98)
......@@ -140,8 +140,8 @@
#define TARGET_NR_sysfs (TARGET_NR_Linux + 135)
#define TARGET_NR_personality (TARGET_NR_Linux + 136)
#define TARGET_NR_afs_syscall (TARGET_NR_Linux + 137) /* Syscall for Andrew File System */
#define TARGET_NR_setfsuid32 (TARGET_NR_Linux + 138)
#define TARGET_NR_setfsgid32 (TARGET_NR_Linux + 139)
#define TARGET_NR_setfsuid (TARGET_NR_Linux + 138)
#define TARGET_NR_setfsgid (TARGET_NR_Linux + 139)
#define TARGET_NR__llseek (TARGET_NR_Linux + 140)
#define TARGET_NR_getdents (TARGET_NR_Linux + 141)
#define TARGET_NR__newselect (TARGET_NR_Linux + 142)
......@@ -187,13 +187,13 @@
#define TARGET_NR_shutdown (TARGET_NR_Linux + 182)
#define TARGET_NR_socket (TARGET_NR_Linux + 183)
#define TARGET_NR_socketpair (TARGET_NR_Linux + 184)
#define TARGET_NR_setresuid32 (TARGET_NR_Linux + 185)
#define TARGET_NR_getresuid32 (TARGET_NR_Linux + 186)
#define TARGET_NR_setresuid (TARGET_NR_Linux + 185)
#define TARGET_NR_getresuid (TARGET_NR_Linux + 186)
#define TARGET_NR_query_module (TARGET_NR_Linux + 187)
#define TARGET_NR_poll (TARGET_NR_Linux + 188)
#define TARGET_NR_nfsservctl (TARGET_NR_Linux + 189)
#define TARGET_NR_setresgid32 (TARGET_NR_Linux + 190)
#define TARGET_NR_getresgid32 (TARGET_NR_Linux + 191)
#define TARGET_NR_setresgid (TARGET_NR_Linux + 190)
#define TARGET_NR_getresgid (TARGET_NR_Linux + 191)
#define TARGET_NR_prctl (TARGET_NR_Linux + 192)
#define TARGET_NR_rt_sigreturn (TARGET_NR_Linux + 193)
#define TARGET_NR_rt_sigaction (TARGET_NR_Linux + 194)
......@@ -204,7 +204,7 @@
#define TARGET_NR_rt_sigsuspend (TARGET_NR_Linux + 199)
#define TARGET_NR_pread64 (TARGET_NR_Linux + 200)
#define TARGET_NR_pwrite64 (TARGET_NR_Linux + 201)
#define TARGET_NR_chown32 (TARGET_NR_Linux + 202)
#define TARGET_NR_chown (TARGET_NR_Linux + 202)
#define TARGET_NR_getcwd (TARGET_NR_Linux + 203)
#define TARGET_NR_capget (TARGET_NR_Linux + 204)
#define TARGET_NR_capset (TARGET_NR_Linux + 205)
......
......@@ -697,7 +697,9 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
old_size, new_size,
flags | MREMAP_FIXED,
g2h(mmap_start));
mmap_reserve(old_addr, old_size);
if ( RESERVED_VA ) {
mmap_reserve(old_addr, old_size);
}
}
} else {
int prot = 0;
......
......@@ -17,15 +17,15 @@
#define TARGET_NR_time 13
#define TARGET_NR_mknod 14
#define TARGET_NR_chmod 15
#define TARGET_NR_lchown32 16
#define TARGET_NR_lchown 16
#define TARGET_NR_break 17
#define TARGET_NR_oldstat 18
#define TARGET_NR_lseek 19
#define TARGET_NR_getpid 20
#define TARGET_NR_mount 21
#define TARGET_NR_umount 22
#define TARGET_NR_setuid32 23
#define TARGET_NR_getuid32 24
#define TARGET_NR_setuid 23
#define TARGET_NR_getuid 24
#define TARGET_NR_stime 25
#define TARGET_NR_ptrace 26
#define TARGET_NR_alarm 27
......@@ -47,11 +47,11 @@
#define TARGET_NR_times 43
#define TARGET_NR_prof 44
#define TARGET_NR_brk 45
#define TARGET_NR_setgid32 46
#define TARGET_NR_getgid32 47
#define TARGET_NR_setgid 46
#define TARGET_NR_getgid 47
#define TARGET_NR_signal 48
#define TARGET_NR_geteuid32 49
#define TARGET_NR_getegid32 50
#define TARGET_NR_geteuid 49
#define TARGET_NR_getegid 50
#define TARGET_NR_acct 51
#define TARGET_NR_umount2 52
#define TARGET_NR_lock 53
......@@ -71,8 +71,8 @@
#define TARGET_NR_sigaction 67
#define TARGET_NR_sgetmask 68
#define TARGET_NR_ssetmask 69
#define TARGET_NR_setreuid32 70
#define TARGET_NR_setregid32 71
#define TARGET_NR_setreuid 70
#define TARGET_NR_setregid 71
#define TARGET_NR_sigsuspend 72
#define TARGET_NR_sigpending 73
#define TARGET_NR_sethostname 74
......@@ -81,8 +81,8 @@
#define TARGET_NR_getrusage 77
#define TARGET_NR_gettimeofday 78
#define TARGET_NR_settimeofday 79
#define TARGET_NR_getgroups32 80
#define TARGET_NR_setgroups32 81
#define TARGET_NR_getgroups 80
#define TARGET_NR_setgroups 81
#define TARGET_NR_select 82
#define TARGET_NR_symlink 83
#define TARGET_NR_oldlstat 84
......@@ -96,7 +96,7 @@
#define TARGET_NR_truncate 92
#define TARGET_NR_ftruncate 93
#define TARGET_NR_fchmod 94
#define TARGET_NR_fchown32 95
#define TARGET_NR_fchown 95
#define TARGET_NR_getpriority 96
#define TARGET_NR_setpriority 97
#define TARGET_NR_profil 98
......@@ -139,8 +139,8 @@
#define TARGET_NR_sysfs 135
#define TARGET_NR_personality 136
#define TARGET_NR_afs_syscall 137 /* Syscall for Andrew File System */
#define TARGET_NR_setfsuid32 138
#define TARGET_NR_setfsgid32 139
#define TARGET_NR_setfsuid 138
#define TARGET_NR_setfsgid 139
#define TARGET_NR__llseek 140
#define TARGET_NR_getdents 141
#define TARGET_NR__newselect 142
......@@ -182,7 +182,7 @@
#define TARGET_NR_rt_sigsuspend 178
#define TARGET_NR_pread64 179
#define TARGET_NR_pwrite64 180
#define TARGET_NR_chown32 181
#define TARGET_NR_chown 181
#define TARGET_NR_getcwd 182
#define TARGET_NR_capget 183
#define TARGET_NR_capset 184
......
......@@ -126,8 +126,6 @@ typedef struct TaskState {
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;
extern char *exec_path;
......@@ -266,8 +264,7 @@ static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
*/
#define __put_user(x, hptr)\
({\
int size = sizeof(*hptr);\
switch(size) {\
switch(sizeof(*hptr)) {\
case 1:\
*(uint8_t *)(hptr) = (uint8_t)(typeof(*hptr))(x);\
break;\
......@@ -288,8 +285,7 @@ static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
#define __get_user(x, hptr) \
({\
int size = sizeof(*hptr);\
switch(size) {\
switch(sizeof(*hptr)) {\
case 1:\
x = (typeof(*hptr))*(uint8_t *)(hptr);\
break;\
......
......@@ -1108,10 +1108,44 @@ struct target_ucontext_v2 {
target_stack_t tuc_stack;
struct target_sigcontext tuc_mcontext;
target_sigset_t tuc_sigmask; /* mask last for extensibility */
char __unused[128 - sizeof(sigset_t)];
char __unused[128 - sizeof(target_sigset_t)];
abi_ulong tuc_regspace[128] __attribute__((__aligned__(8)));
};
struct target_user_vfp {
uint64_t fpregs[32];
abi_ulong fpscr;
};
struct target_user_vfp_exc {
abi_ulong fpexc;
abi_ulong fpinst;
abi_ulong fpinst2;
};
struct target_vfp_sigframe {
abi_ulong magic;
abi_ulong size;
struct target_user_vfp ufp;
struct target_user_vfp_exc ufp_exc;
} __attribute__((__aligned__(8)));
struct target_iwmmxt_sigframe {
abi_ulong magic;
abi_ulong size;
uint64_t regs[16];
/* Note that not all the coprocessor control registers are stored here */
uint32_t wcssf;
uint32_t wcasf;
uint32_t wcgr0;
uint32_t wcgr1;
uint32_t wcgr2;
uint32_t wcgr3;
} __attribute__((__aligned__(8)));
#define TARGET_VFP_MAGIC 0x56465001
#define TARGET_IWMMXT_MAGIC 0x12ef842a
struct sigframe_v1
{
struct target_sigcontext sc;
......@@ -1255,11 +1289,48 @@ setup_return(CPUState *env, struct target_sigaction *ka,
return 0;
}
static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUState *env)
{
int i;
struct target_vfp_sigframe *vfpframe;
vfpframe = (struct target_vfp_sigframe *)regspace;
__put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
__put_user(sizeof(*vfpframe), &vfpframe->size);
for (i = 0; i < 32; i++) {
__put_user(env->vfp.regs[i], &vfpframe->ufp.fpregs[i]);
}
__put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
__put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
__put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
__put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
return (abi_ulong*)(vfpframe+1);
}
static abi_ulong *setup_sigframe_v2_iwmmxt(abi_ulong *regspace, CPUState *env)
{
int i;
struct target_iwmmxt_sigframe *iwmmxtframe;
iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
__put_user(TARGET_IWMMXT_MAGIC, &iwmmxtframe->magic);
__put_user(sizeof(*iwmmxtframe), &iwmmxtframe->size);
for (i = 0; i < 16; i++) {
__put_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
}
__put_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
__put_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
__put_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
__put_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
__put_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
__put_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
return (abi_ulong*)(iwmmxtframe+1);
}
static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
target_sigset_t *set, CPUState *env)
{
struct target_sigaltstack stack;
int i;
abi_ulong *regspace;
/* Clear all the bits of the ucontext we don't use. */
memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext));
......@@ -1271,7 +1342,18 @@ static void setup_sigframe_v2(struct target_ucontext_v2 *uc,
memcpy(&uc->tuc_stack, &stack, sizeof(stack));
setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]);
/* FIXME: Save coprocessor signal frame. */
/* Save coprocessor signal frame. */
regspace = uc->tuc_regspace;
if (arm_feature(env, ARM_FEATURE_VFP)) {
regspace = setup_sigframe_v2_vfp(regspace, env);
}
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
regspace = setup_sigframe_v2_iwmmxt(regspace, env);
}
/* Write terminating magic word */
__put_user(0, regspace);
for(i = 0; i < TARGET_NSIG_WORDS; i++) {
__put_user(set->sig[i], &uc->tuc_sigmask.sig[i]);
}
......@@ -1490,10 +1572,65 @@ badframe:
return 0;
}
static abi_ulong *restore_sigframe_v2_vfp(CPUState *env, abi_ulong *regspace)
{
int i;
abi_ulong magic, sz;
uint32_t fpscr, fpexc;
struct target_vfp_sigframe *vfpframe;
vfpframe = (struct target_vfp_sigframe *)regspace;
__get_user(magic, &vfpframe->magic);
__get_user(sz, &vfpframe->size);
if (magic != TARGET_VFP_MAGIC || sz != sizeof(*vfpframe)) {
return 0;
}
for (i = 0; i < 32; i++) {
__get_user(env->vfp.regs[i], &vfpframe->ufp.fpregs[i]);
}
__get_user(fpscr, &vfpframe->ufp.fpscr);
vfp_set_fpscr(env, fpscr);
__get_user(fpexc, &vfpframe->ufp_exc.fpexc);
/* Sanitise FPEXC: ensure VFP is enabled, FPINST2 is invalid
* and the exception flag is cleared
*/
fpexc |= (1 << 30);
fpexc &= ~((1 << 31) | (1 << 28));
env->vfp.xregs[ARM_VFP_FPEXC] = fpexc;
__get_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst);
__get_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2);
return (abi_ulong*)(vfpframe + 1);
}
static abi_ulong *restore_sigframe_v2_iwmmxt(CPUState *env, abi_ulong *regspace)
{
int i;
abi_ulong magic, sz;
struct target_iwmmxt_sigframe *iwmmxtframe;
iwmmxtframe = (struct target_iwmmxt_sigframe *)regspace;
__get_user(magic, &iwmmxtframe->magic);
__get_user(sz, &iwmmxtframe->size);
if (magic != TARGET_IWMMXT_MAGIC || sz != sizeof(*iwmmxtframe)) {
return 0;
}
for (i = 0; i < 16; i++) {
__get_user(env->iwmmxt.regs[i], &iwmmxtframe->regs[i]);
}
__get_user(env->vfp.xregs[ARM_IWMMXT_wCSSF], &iwmmxtframe->wcssf);
__get_user(env->vfp.xregs[ARM_IWMMXT_wCASF], &iwmmxtframe->wcssf);
__get_user(env->vfp.xregs[ARM_IWMMXT_wCGR0], &iwmmxtframe->wcgr0);
__get_user(env->vfp.xregs[ARM_IWMMXT_wCGR1], &iwmmxtframe->wcgr1);
__get_user(env->vfp.xregs[ARM_IWMMXT_wCGR2], &iwmmxtframe->wcgr2);
__get_user(env->vfp.xregs[ARM_IWMMXT_wCGR3], &iwmmxtframe->wcgr3);
return (abi_ulong*)(iwmmxtframe + 1);
}
static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
struct target_ucontext_v2 *uc)
{
sigset_t host_set;
abi_ulong *regspace;
target_to_host_sigset(&host_set, &uc->tuc_sigmask);
sigprocmask(SIG_SETMASK, &host_set, NULL);
......@@ -1501,6 +1638,21 @@ static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,
if (restore_sigcontext(env, &uc->tuc_mcontext))
return 1;
/* Restore coprocessor signal frame */
regspace = uc->tuc_regspace;
if (arm_feature(env, ARM_FEATURE_VFP)) {
regspace = restore_sigframe_v2_vfp(env, regspace);
if (!regspace) {
return 1;
}
}
if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
regspace = restore_sigframe_v2_iwmmxt(env, regspace);
if (!regspace) {
return 1;
}
}
if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
return 1;
......
......@@ -1374,15 +1374,66 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
switch(level) {
case TARGET_SOL_SOCKET:
level = SOL_SOCKET;
switch (optname) {
case TARGET_SO_LINGER:
case TARGET_SO_RCVTIMEO:
case TARGET_SO_SNDTIMEO:
case TARGET_SO_PEERCRED:
case TARGET_SO_PEERNAME:
/* These don't just return a single integer */
goto unimplemented;
level = SOL_SOCKET;
switch (optname) {
/* These don't just return a single integer */
case TARGET_SO_LINGER:
case TARGET_SO_RCVTIMEO:
case TARGET_SO_SNDTIMEO:
case TARGET_SO_PEERCRED:
case TARGET_SO_PEERNAME:
goto unimplemented;
/* Options with 'int' argument. */
case TARGET_SO_DEBUG:
optname = SO_DEBUG;
goto int_case;
case TARGET_SO_REUSEADDR:
optname = SO_REUSEADDR;
goto int_case;
case TARGET_SO_TYPE:
optname = SO_TYPE;
goto int_case;
case TARGET_SO_ERROR:
optname = SO_ERROR;
goto int_case;
case TARGET_SO_DONTROUTE:
optname = SO_DONTROUTE;
goto int_case;
case TARGET_SO_BROADCAST:
optname = SO_BROADCAST;
goto int_case;
case TARGET_SO_SNDBUF:
optname = SO_SNDBUF;
goto int_case;
case TARGET_SO_RCVBUF:
optname = SO_RCVBUF;
goto int_case;
case TARGET_SO_KEEPALIVE:
optname = SO_KEEPALIVE;
goto int_case;
case TARGET_SO_OOBINLINE:
optname = SO_OOBINLINE;
goto int_case;
case TARGET_SO_NO_CHECK:
optname = SO_NO_CHECK;
goto int_case;
case TARGET_SO_PRIORITY:
optname = SO_PRIORITY;
goto int_case;
#ifdef SO_BSDCOMPAT
case TARGET_SO_BSDCOMPAT:
optname = SO_BSDCOMPAT;
goto int_case;
#endif
case TARGET_SO_PASSCRED:
optname = SO_PASSCRED;
goto int_case;
case TARGET_SO_TIMESTAMP:
optname = SO_TIMESTAMP;
goto int_case;
case TARGET_SO_RCVLOWAT:
optname = SO_RCVLOWAT;
goto int_case;
default:
goto int_case;
}
......@@ -1406,7 +1457,7 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
} else {
if (put_user_u8(val, optval_addr))
return -TARGET_EFAULT;
}
}
if (put_user_u32(len, optlen))
return -TARGET_EFAULT;
break;
......@@ -3584,11 +3635,12 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
{
int ret;
TaskState *ts;
uint8_t *new_stack;
CPUState *new_env;
#if defined(CONFIG_USE_NPTL)
unsigned int nptl_flags;
sigset_t sigmask;
#else
uint8_t *new_stack;
#endif
/* Emulate vfork() with fork() */
......@@ -3601,9 +3653,8 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
new_thread_info info;
pthread_attr_t attr;
#endif
ts = qemu_mallocz(sizeof(TaskState) + NEW_STACK_SIZE);
ts = qemu_mallocz(sizeof(TaskState));
init_task_state(ts);
new_stack = ts->stack;
/* we create a new CPU instance. */
new_env = cpu_copy(env);
#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
......@@ -3639,7 +3690,8 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
info.parent_tidptr = parent_tidptr;
ret = pthread_attr_init(&attr);
ret = pthread_attr_setstack(&attr, new_stack, NEW_STACK_SIZE);
ret = pthread_attr_setstacksize(&attr, NEW_STACK_SIZE);
ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
/* It is not safe to deliver signals until the child has finished
initializing, so temporarily block all signals. */
sigfillset(&sigmask);
......@@ -3667,6 +3719,7 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
if (flags & CLONE_NPTL_FLAGS2)
return -EINVAL;
/* This is probably going to die very quickly, but do it anyway. */
new_stack = qemu_mallocz (NEW_STACK_SIZE);
#ifdef __ia64__
ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env);
#else
......@@ -4240,7 +4293,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
sys_futex(g2h(ts->child_tidptr), FUTEX_WAKE, INT_MAX,
NULL, NULL, 0);
}
/* TODO: Free CPU state. */
thread_env = NULL;
qemu_free(cpu_env);
qemu_free(ts);
pthread_exit(NULL);
}
#endif
......
......@@ -49,7 +49,7 @@
#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_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS) || defined(TARGET_PPC) || defined(TARGET_MIPS)
/* 16 bit uid wrappers emulation */
#define USE_UID16
#endif
......
......@@ -12,7 +12,7 @@ fi
# probe cpu type
cpu=`uname -m`
case "$cpu" in
i386|i486|i586|i686|i86pc|BePC)
i386|i486|i586|i686|i86pc|BePC|x86_64)
cpu="i386"
;;
m68k)
......@@ -24,7 +24,7 @@ case "$cpu" in
"Power Macintosh"|ppc|ppc64)
cpu="ppc"
;;
armv4l)
armv[4-9]*)
cpu="arm"
;;
esac
......@@ -60,3 +60,7 @@ if [ $cpu != "mips" ] ; then
echo ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register
echo ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "sh" ] ; then
echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register
echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register
fi
......@@ -227,8 +227,6 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw,
int mmu_idx, int is_softmuu);
#define cpu_handle_mmu_fault cpu_arm_handle_mmu_fault
void cpu_lock(void);
void cpu_unlock(void);
static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
{