mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 09:43:56 -06:00
Merge remote-tracking branch 'riku/linux-user-for-upstream' into staging
* riku/linux-user-for-upstream: (21 commits) linux-user: Handle compressed ISA encodings when processing MIPS exceptions linux-user: Unlock mmap_lock when resuming guest from page_unprotect linux-user: Reset copied CPUs in cpu_copy() always linux-user: Fix epoll on ARM hosts linux-user: fix segmentation fault passing with h2g(x) != x linux-user: Fix pipe syscall return for SPARC linux-user: Fix target_stat and target_stat64 for OpenRISC linux-user: Avoid conditional cpu_reset() configure: Make NPTL non-optional linux-user: Enable NPTL for x86-64 linux-user: Add i386 TLS setter linux-user: Clean up handling of clone() argument order linux-user: Add missing 'break' in i386 get_thread_area syscall linux-user: Enable NPTL for m68k linux-user: Enable NPTL for SPARC targets linux-user: Enable NPTL for OpenRISC linux-user: Move includes of target-specific headers to end of qemu.h configure: Enable threading for unicore32-linux-user configure: Enable threading on all ppc and mips linux-user targets configure: Don't say target_nptl="no" if there is no linux-user target ... Conflicts: linux-user/main.c Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
commit
874ec3c5b3
25 changed files with 220 additions and 190 deletions
|
@ -40,3 +40,5 @@ struct target_pt_regs {
|
|||
#else
|
||||
#define UNAME_MACHINE "armv5tel"
|
||||
#endif
|
||||
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
|
|
@ -38,4 +38,6 @@ struct target_pt_regs {
|
|||
unsigned long eda;
|
||||
};
|
||||
|
||||
#define TARGET_CLONE_BACKWARDS2
|
||||
|
||||
#endif
|
||||
|
|
|
@ -144,3 +144,5 @@ struct target_vm86plus_struct {
|
|||
};
|
||||
|
||||
#define UNAME_MACHINE "i686"
|
||||
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
|
|
@ -28,6 +28,21 @@ static inline void cpu_clone_regs(CPUX86State *env, target_ulong newsp)
|
|||
env->regs[R_EAX] = 0;
|
||||
}
|
||||
|
||||
/* TODO: need to implement cpu_set_tls() */
|
||||
#if defined(TARGET_ABI32)
|
||||
abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr);
|
||||
|
||||
#endif
|
||||
static inline void cpu_set_tls(CPUX86State *env, target_ulong newtls)
|
||||
{
|
||||
do_set_thread_area(env, newtls);
|
||||
cpu_x86_load_seg(env, R_GS, env->segs[R_GS].selector);
|
||||
}
|
||||
#else
|
||||
abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr);
|
||||
|
||||
static inline void cpu_set_tls(CPUX86State *env, target_ulong newtls)
|
||||
{
|
||||
do_arch_prctl(env, TARGET_ARCH_SET_FS, newtls);
|
||||
}
|
||||
#endif /* defined(TARGET_ABI32) */
|
||||
|
||||
#endif /* !defined(TARGET_CPU_H) */
|
||||
|
|
|
@ -29,6 +29,10 @@ static inline void cpu_clone_regs(CPUM68KState *env, target_ulong newsp)
|
|||
env->dregs[0] = 0;
|
||||
}
|
||||
|
||||
/* TODO: need to implement cpu_set_tls() */
|
||||
static inline void cpu_set_tls(CPUM68KState *env, target_ulong newtls)
|
||||
{
|
||||
TaskState *ts = env->opaque;
|
||||
ts->tp_value = newtls;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -92,7 +92,6 @@ int cpu_get_pic_interrupt(CPUX86State *env)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
/***********************************************************/
|
||||
/* Helper routines for implementing atomic operations. */
|
||||
|
||||
|
@ -207,43 +206,6 @@ void cpu_list_unlock(void)
|
|||
{
|
||||
pthread_mutex_unlock(&cpu_list_mutex);
|
||||
}
|
||||
#else /* if !CONFIG_USE_NPTL */
|
||||
/* These are no-ops because we are not threadsafe. */
|
||||
static inline void cpu_exec_start(CPUState *cpu)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void cpu_exec_end(CPUState *cpu)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void start_exclusive(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void end_exclusive(void)
|
||||
{
|
||||
}
|
||||
|
||||
void fork_start(void)
|
||||
{
|
||||
}
|
||||
|
||||
void fork_end(int child)
|
||||
{
|
||||
if (child) {
|
||||
gdbserver_fork((CPUArchState *)thread_cpu->env_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void cpu_list_lock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void cpu_list_unlock(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef TARGET_I386
|
||||
|
@ -2349,7 +2311,31 @@ done_syscall:
|
|||
abi_ulong trap_instr;
|
||||
unsigned int code;
|
||||
|
||||
ret = get_user_ual(trap_instr, env->active_tc.PC);
|
||||
if (env->hflags & MIPS_HFLAG_M16) {
|
||||
if (env->insn_flags & ASE_MICROMIPS) {
|
||||
/* microMIPS mode */
|
||||
abi_ulong instr[2];
|
||||
|
||||
ret = get_user_u16(instr[0], env->active_tc.PC) ||
|
||||
get_user_u16(instr[1], env->active_tc.PC + 2);
|
||||
|
||||
trap_instr = (instr[0] << 16) | instr[1];
|
||||
} else {
|
||||
/* MIPS16e mode */
|
||||
ret = get_user_u16(trap_instr, env->active_tc.PC);
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
code = (trap_instr >> 6) & 0x3f;
|
||||
if (do_break(env, &info, code) != 0) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ret = get_user_ual(trap_instr, env->active_tc.PC);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
@ -2373,14 +2359,30 @@ done_syscall:
|
|||
abi_ulong trap_instr;
|
||||
unsigned int code = 0;
|
||||
|
||||
ret = get_user_ual(trap_instr, env->active_tc.PC);
|
||||
if (env->hflags & MIPS_HFLAG_M16) {
|
||||
/* microMIPS mode */
|
||||
abi_ulong instr[2];
|
||||
|
||||
ret = get_user_u16(instr[0], env->active_tc.PC) ||
|
||||
get_user_u16(instr[1], env->active_tc.PC + 2);
|
||||
|
||||
trap_instr = (instr[0] << 16) | instr[1];
|
||||
} else {
|
||||
ret = get_user_ual(trap_instr, env->active_tc.PC);
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* The immediate versions don't provide a code. */
|
||||
if (!(trap_instr & 0xFC000000)) {
|
||||
code = ((trap_instr >> 6) & ((1 << 10) - 1));
|
||||
if (env->hflags & MIPS_HFLAG_M16) {
|
||||
/* microMIPS mode */
|
||||
code = ((trap_instr >> 12) & ((1 << 4) - 1));
|
||||
} else {
|
||||
code = ((trap_instr >> 6) & ((1 << 10) - 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (do_break(env, &info, code) != 0) {
|
||||
|
@ -3157,12 +3159,7 @@ THREAD CPUState *thread_cpu;
|
|||
void task_settid(TaskState *ts)
|
||||
{
|
||||
if (ts->ts_tid == 0) {
|
||||
#ifdef CONFIG_USE_NPTL
|
||||
ts->ts_tid = (pid_t)syscall(SYS_gettid);
|
||||
#else
|
||||
/* when no threads are used, tid becomes pid */
|
||||
ts->ts_tid = getpid();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3640,9 +3637,7 @@ int main(int argc, char **argv, char **envp)
|
|||
exit(1);
|
||||
}
|
||||
cpu = ENV_GET_CPU(env);
|
||||
#if defined(TARGET_SPARC) || defined(TARGET_PPC)
|
||||
cpu_reset(cpu);
|
||||
#endif
|
||||
cpu_reset(ENV_GET_CPU(env));
|
||||
|
||||
thread_cpu = cpu;
|
||||
|
||||
|
|
|
@ -48,4 +48,6 @@ struct target_pt_regs {
|
|||
uint32_t kernel_mode;
|
||||
};
|
||||
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
||||
#endif
|
||||
|
|
|
@ -225,3 +225,5 @@ struct target_pt_regs {
|
|||
#define TARGET_QEMU_ESIGRETURN 255
|
||||
|
||||
#define UNAME_MACHINE "mips"
|
||||
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
|
|
@ -222,3 +222,5 @@ struct target_pt_regs {
|
|||
#define TARGET_QEMU_ESIGRETURN 255
|
||||
|
||||
#define UNAME_MACHINE "mips64"
|
||||
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
|
||||
//#define DEBUG_MMAP
|
||||
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static __thread int mmap_lock_count;
|
||||
|
||||
|
@ -66,16 +65,6 @@ void mmap_fork_end(int child)
|
|||
else
|
||||
pthread_mutex_unlock(&mmap_mutex);
|
||||
}
|
||||
#else
|
||||
/* We aren't threadsafe to start with, so no need to worry about locking. */
|
||||
void mmap_lock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void mmap_unlock(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* NOTE: all the constants are the HOST ones, but addresses are target. */
|
||||
int target_mprotect(abi_ulong start, abi_ulong len, int prot)
|
||||
|
|
|
@ -25,9 +25,14 @@ static inline void cpu_clone_regs(CPUOpenRISCState *env, target_ulong newsp)
|
|||
if (newsp) {
|
||||
env->gpr[1] = newsp;
|
||||
}
|
||||
env->gpr[2] = 0;
|
||||
env->gpr[11] = 0;
|
||||
}
|
||||
|
||||
/* TODO: need to implement cpu_set_tls() */
|
||||
static inline void cpu_set_tls(CPUOpenRISCState *env, target_ulong newtls)
|
||||
{
|
||||
/* Linux kernel 3.10 does not pay any attention to CLONE_SETTLS
|
||||
* in copy_thread(), so QEMU need not do so either.
|
||||
*/
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -62,3 +62,5 @@ struct target_revectored_struct {
|
|||
#else
|
||||
#define UNAME_MACHINE "ppc"
|
||||
#endif
|
||||
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
|
|
@ -16,16 +16,10 @@
|
|||
#include "exec/user/thunk.h"
|
||||
#include "syscall_defs.h"
|
||||
#include "syscall.h"
|
||||
#include "target_cpu.h"
|
||||
#include "target_signal.h"
|
||||
#include "exec/gdbstub.h"
|
||||
#include "qemu/queue.h"
|
||||
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
#define THREAD __thread
|
||||
#else
|
||||
#define THREAD
|
||||
#endif
|
||||
|
||||
/* This struct is used to hold certain information about the image.
|
||||
* Basically, it replicates in user space what would be certain
|
||||
|
@ -118,11 +112,10 @@ typedef struct TaskState {
|
|||
uint32_t v86flags;
|
||||
uint32_t v86mask;
|
||||
#endif
|
||||
#ifdef CONFIG_USE_NPTL
|
||||
abi_ulong child_tidptr;
|
||||
#endif
|
||||
#ifdef TARGET_M68K
|
||||
int sim_syscalls;
|
||||
abi_ulong tp_value;
|
||||
#endif
|
||||
#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
|
||||
/* Extra fields for semihosted binaries. */
|
||||
|
@ -269,10 +262,8 @@ void mmap_unlock(void);
|
|||
abi_ulong mmap_find_vma(abi_ulong, abi_ulong);
|
||||
void cpu_list_lock(void);
|
||||
void cpu_list_unlock(void);
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
void mmap_fork_start(void);
|
||||
void mmap_fork_end(int child);
|
||||
#endif
|
||||
|
||||
/* main.c */
|
||||
extern unsigned long guest_stack_size;
|
||||
|
@ -450,8 +441,13 @@ static inline void *lock_user_string(abi_ulong guest_addr)
|
|||
#define unlock_user_struct(host_ptr, guest_addr, copy) \
|
||||
unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
|
||||
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
/* Include target-specific struct and function definitions;
|
||||
* they may need access to the target-independent structures
|
||||
* above, so include them last.
|
||||
*/
|
||||
#include "target_cpu.h"
|
||||
#include "target_signal.h"
|
||||
|
||||
#endif /* QEMU_H */
|
||||
|
|
|
@ -21,3 +21,5 @@ struct target_pt_regs {
|
|||
};
|
||||
|
||||
#define UNAME_MACHINE "s390x"
|
||||
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
|
|
@ -7,3 +7,10 @@ struct target_pt_regs {
|
|||
};
|
||||
|
||||
#define UNAME_MACHINE "sun4"
|
||||
|
||||
/* SPARC kernels don't define this in their Kconfig, but they have the
|
||||
* same ABI as if they did, implemented by sparc-specific code which fishes
|
||||
* directly in the u_regs() struct for half the parameters in sparc_do_fork()
|
||||
* and copy_thread().
|
||||
*/
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
|
|
@ -25,12 +25,20 @@ static inline void cpu_clone_regs(CPUSPARCState *env, target_ulong newsp)
|
|||
if (newsp) {
|
||||
env->regwptr[22] = newsp;
|
||||
}
|
||||
/* syscall return for clone child: 0, and clear CF since
|
||||
* this counts as a success return value.
|
||||
*/
|
||||
env->regwptr[0] = 0;
|
||||
/* FIXME: Do we also need to clear CF? */
|
||||
/* XXXXX */
|
||||
printf("HELPME: %s:%d\n", __FILE__, __LINE__);
|
||||
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
|
||||
env->xcc &= ~PSR_CARRY;
|
||||
#else
|
||||
env->psr &= ~PSR_CARRY;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* TODO: need to implement cpu_set_tls() */
|
||||
static inline void cpu_set_tls(CPUSPARCState *env, target_ulong newtls)
|
||||
{
|
||||
env->gregs[7] = newtls;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,3 +8,10 @@ struct target_pt_regs {
|
|||
};
|
||||
|
||||
#define UNAME_MACHINE "sun4u"
|
||||
|
||||
/* SPARC kernels don't define this in their Kconfig, but they have the
|
||||
* same ABI as if they did, implemented by sparc-specific code which fishes
|
||||
* directly in the u_regs() struct for half the parameters in sparc_do_fork()
|
||||
* and copy_thread().
|
||||
*/
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
|
|
|
@ -111,13 +111,8 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
|
|||
|
||||
#include "qemu.h"
|
||||
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
|
||||
CLONE_PARENT_SETTID | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID)
|
||||
#else
|
||||
/* XXX: Hardcode the above values. */
|
||||
#define CLONE_NPTL_FLAGS2 0
|
||||
#endif
|
||||
|
||||
//#define DEBUG
|
||||
|
||||
|
@ -234,12 +229,10 @@ _syscall1(int,exit_group,int,error_code)
|
|||
#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
|
||||
_syscall1(int,set_tid_address,int *,tidptr)
|
||||
#endif
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
#if defined(TARGET_NR_futex) && defined(__NR_futex)
|
||||
_syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
|
||||
const struct timespec *,timeout,int *,uaddr2,int,val3)
|
||||
#endif
|
||||
#endif
|
||||
#define __NR_sys_sched_getaffinity __NR_sched_getaffinity
|
||||
_syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned int, len,
|
||||
unsigned long *, user_mask_ptr);
|
||||
|
@ -1039,6 +1032,9 @@ static abi_long do_pipe(void *cpu_env, abi_ulong pipedes,
|
|||
#elif defined(TARGET_SH4)
|
||||
((CPUSH4State*)cpu_env)->gregs[1] = host_pipe[1];
|
||||
return host_pipe[0];
|
||||
#elif defined(TARGET_SPARC)
|
||||
((CPUSPARCState*)cpu_env)->regwptr[1] = host_pipe[1];
|
||||
return host_pipe[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -4055,7 +4051,7 @@ static abi_long do_modify_ldt(CPUX86State *env, int func, abi_ulong ptr,
|
|||
}
|
||||
|
||||
#if defined(TARGET_I386) && defined(TARGET_ABI32)
|
||||
static abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
|
||||
abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr)
|
||||
{
|
||||
uint64_t *gdt_table = g2h(env->gdt.base);
|
||||
struct target_modify_ldt_ldt_s ldt_info;
|
||||
|
@ -4189,7 +4185,7 @@ static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
|
|||
#endif /* TARGET_I386 && TARGET_ABI32 */
|
||||
|
||||
#ifndef TARGET_ABI32
|
||||
static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
|
||||
abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
|
||||
{
|
||||
abi_long ret = 0;
|
||||
abi_ulong val;
|
||||
|
@ -4227,7 +4223,6 @@ static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
|
|||
|
||||
#define NEW_STACK_SIZE 0x40000
|
||||
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
|
||||
static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
typedef struct {
|
||||
|
@ -4272,16 +4267,6 @@ static void *clone_func(void *arg)
|
|||
/* never exits */
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
|
||||
static int clone_func(void *arg)
|
||||
{
|
||||
CPUArchState *env = arg;
|
||||
cpu_loop(env);
|
||||
/* never exits */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* do_fork() Must return host values and target errnos (unlike most
|
||||
do_*() functions). */
|
||||
|
@ -4292,12 +4277,8 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
|
|||
int ret;
|
||||
TaskState *ts;
|
||||
CPUArchState *new_env;
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
unsigned int nptl_flags;
|
||||
sigset_t sigmask;
|
||||
#else
|
||||
uint8_t *new_stack;
|
||||
#endif
|
||||
|
||||
/* Emulate vfork() with fork() */
|
||||
if (flags & CLONE_VFORK)
|
||||
|
@ -4305,23 +4286,18 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
|
|||
|
||||
if (flags & CLONE_VM) {
|
||||
TaskState *parent_ts = (TaskState *)env->opaque;
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
new_thread_info info;
|
||||
pthread_attr_t attr;
|
||||
#endif
|
||||
|
||||
ts = g_malloc0(sizeof(TaskState));
|
||||
init_task_state(ts);
|
||||
/* we create a new CPU instance. */
|
||||
new_env = cpu_copy(env);
|
||||
#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
|
||||
cpu_reset(ENV_GET_CPU(new_env));
|
||||
#endif
|
||||
/* Init regs that differ from the parent. */
|
||||
cpu_clone_regs(new_env, newsp);
|
||||
new_env->opaque = ts;
|
||||
ts->bprm = parent_ts->bprm;
|
||||
ts->info = parent_ts->info;
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
nptl_flags = flags;
|
||||
flags &= ~CLONE_NPTL_FLAGS2;
|
||||
|
||||
|
@ -4371,17 +4347,6 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
|
|||
pthread_cond_destroy(&info.cond);
|
||||
pthread_mutex_destroy(&info.mutex);
|
||||
pthread_mutex_unlock(&clone_lock);
|
||||
#else
|
||||
if (flags & CLONE_NPTL_FLAGS2)
|
||||
return -EINVAL;
|
||||
/* This is probably going to die very quickly, but do it anyway. */
|
||||
new_stack = g_malloc0 (NEW_STACK_SIZE);
|
||||
#ifdef __ia64__
|
||||
ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env);
|
||||
#else
|
||||
ret = clone(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env);
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
/* if no CLONE_VM, we consider it is a fork */
|
||||
if ((flags & ~(CSIGNAL | CLONE_NPTL_FLAGS2)) != 0)
|
||||
|
@ -4392,7 +4357,6 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
|
|||
/* Child Process. */
|
||||
cpu_clone_regs(env, newsp);
|
||||
fork_end(1);
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
/* There is a race condition here. The parent process could
|
||||
theoretically read the TID in the child process before the child
|
||||
tid is set. This would require using either ptrace
|
||||
|
@ -4408,7 +4372,6 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
|
|||
cpu_set_tls (env, newtls);
|
||||
if (flags & CLONE_CHILD_CLEARTID)
|
||||
ts->child_tidptr = child_tidptr;
|
||||
#endif
|
||||
} else {
|
||||
fork_end(0);
|
||||
}
|
||||
|
@ -4834,7 +4797,6 @@ static inline abi_long host_to_target_stat64(void *cpu_env,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
/* ??? Using host futex calls even when target atomic operations
|
||||
are not really atomic probably breaks things. However implementing
|
||||
futexes locally would make futexes shared between multiple processes
|
||||
|
@ -4886,7 +4848,6 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout,
|
|||
return -TARGET_ENOSYS;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Map host to target signal numbers for the wait family of syscalls.
|
||||
Assume all other status bits are the same. */
|
||||
|
@ -5132,9 +5093,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
|||
abi_long arg5, abi_long arg6, abi_long arg7,
|
||||
abi_long arg8)
|
||||
{
|
||||
#ifdef CONFIG_USE_NPTL
|
||||
CPUState *cpu = ENV_GET_CPU(cpu_env);
|
||||
#endif
|
||||
abi_long ret;
|
||||
struct stat st;
|
||||
struct statfs stfs;
|
||||
|
@ -5148,7 +5107,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
|||
|
||||
switch(num) {
|
||||
case TARGET_NR_exit:
|
||||
#ifdef CONFIG_USE_NPTL
|
||||
/* In old applications this may be used to implement _exit(2).
|
||||
However in threaded applictions it is used for thread termination,
|
||||
and _exit_group is used for application termination.
|
||||
|
@ -5186,7 +5144,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
|||
g_free(ts);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
#endif
|
||||
#ifdef TARGET_GPROF
|
||||
_mcleanup();
|
||||
#endif
|
||||
|
@ -6956,16 +6913,20 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
|||
ret = get_errno(fsync(arg1));
|
||||
break;
|
||||
case TARGET_NR_clone:
|
||||
#if defined(TARGET_SH4) || defined(TARGET_ALPHA)
|
||||
ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
|
||||
#elif defined(TARGET_CRIS)
|
||||
ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg4, arg5));
|
||||
#elif defined(TARGET_MICROBLAZE)
|
||||
/* Linux manages to have three different orderings for its
|
||||
* arguments to clone(); the BACKWARDS and BACKWARDS2 defines
|
||||
* match the kernel's CONFIG_CLONE_* settings.
|
||||
* Microblaze is further special in that it uses a sixth
|
||||
* implicit argument to clone for the TLS pointer.
|
||||
*/
|
||||
#if defined(TARGET_MICROBLAZE)
|
||||
ret = get_errno(do_fork(cpu_env, arg1, arg2, arg4, arg6, arg5));
|
||||
#elif defined(TARGET_S390X)
|
||||
#elif defined(TARGET_CLONE_BACKWARDS)
|
||||
ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
|
||||
#elif defined(TARGET_CLONE_BACKWARDS2)
|
||||
ret = get_errno(do_fork(cpu_env, arg2, arg1, arg3, arg5, arg4));
|
||||
#else
|
||||
ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg4, arg5));
|
||||
ret = get_errno(do_fork(cpu_env, arg1, arg2, arg3, arg5, arg4));
|
||||
#endif
|
||||
break;
|
||||
#ifdef __NR_exit_group
|
||||
|
@ -8558,6 +8519,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
|||
#elif defined(TARGET_I386) && defined(TARGET_ABI32)
|
||||
ret = do_set_thread_area(cpu_env, arg1);
|
||||
break;
|
||||
#elif defined(TARGET_M68K)
|
||||
{
|
||||
TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
|
||||
ts->tp_value = arg1;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
goto unimplemented_nowarn;
|
||||
#endif
|
||||
|
@ -8566,6 +8533,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
|||
case TARGET_NR_get_thread_area:
|
||||
#if defined(TARGET_I386) && defined(TARGET_ABI32)
|
||||
ret = do_get_thread_area(cpu_env, arg1);
|
||||
break;
|
||||
#elif defined(TARGET_M68K)
|
||||
{
|
||||
TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
|
||||
ret = ts->tp_value;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
goto unimplemented_nowarn;
|
||||
#endif
|
||||
|
@ -8670,11 +8644,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
|||
}
|
||||
break;
|
||||
#endif
|
||||
#if defined(CONFIG_USE_NPTL)
|
||||
case TARGET_NR_futex:
|
||||
ret = do_futex(arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
break;
|
||||
#endif
|
||||
#if defined(TARGET_NR_inotify_init) && defined(__NR_inotify_init)
|
||||
case TARGET_NR_inotify_init:
|
||||
ret = get_errno(sys_inotify_init());
|
||||
|
|
|
@ -1138,8 +1138,7 @@ struct target_winsize {
|
|||
#endif
|
||||
|
||||
#if (defined(TARGET_I386) && defined(TARGET_ABI32)) || defined(TARGET_ARM) \
|
||||
|| defined(TARGET_CRIS) || defined(TARGET_UNICORE32) \
|
||||
|| defined(TARGET_OPENRISC)
|
||||
|| defined(TARGET_CRIS) || defined(TARGET_UNICORE32)
|
||||
struct target_stat {
|
||||
unsigned short st_dev;
|
||||
unsigned short __pad1;
|
||||
|
@ -1837,29 +1836,55 @@ struct target_stat {
|
|||
abi_ulong __unused[3];
|
||||
};
|
||||
#elif defined(TARGET_OPENRISC)
|
||||
|
||||
/* These are the asm-generic versions of the stat and stat64 structures */
|
||||
|
||||
struct target_stat {
|
||||
abi_ulong st_dev;
|
||||
abi_ulong st_ino;
|
||||
abi_ulong st_nlink;
|
||||
|
||||
unsigned int st_mode;
|
||||
unsigned int st_nlink;
|
||||
unsigned int st_uid;
|
||||
unsigned int st_gid;
|
||||
unsigned int __pad0;
|
||||
abi_ulong st_rdev;
|
||||
abi_ulong __pad1;
|
||||
abi_long st_size;
|
||||
abi_long st_blksize;
|
||||
abi_long st_blocks; /* Number 512-byte blocks allocated. */
|
||||
|
||||
abi_ulong target_st_atime;
|
||||
int st_blksize;
|
||||
int __pad2;
|
||||
abi_long st_blocks;
|
||||
abi_long target_st_atime;
|
||||
abi_ulong target_st_atime_nsec;
|
||||
abi_ulong target_st_mtime;
|
||||
abi_long target_st_mtime;
|
||||
abi_ulong target_st_mtime_nsec;
|
||||
abi_ulong target_st_ctime;
|
||||
abi_long target_st_ctime;
|
||||
abi_ulong target_st_ctime_nsec;
|
||||
|
||||
abi_long __unused[3];
|
||||
unsigned int __unused4;
|
||||
unsigned int __unused5;
|
||||
};
|
||||
|
||||
struct target_stat64 {
|
||||
uint64_t st_dev;
|
||||
uint64_t st_ino;
|
||||
unsigned int st_mode;
|
||||
unsigned int st_nlink;
|
||||
unsigned int st_uid;
|
||||
unsigned int st_gid;
|
||||
uint64_t st_rdev;
|
||||
uint64_t __pad1;
|
||||
int64_t st_size;
|
||||
int st_blksize;
|
||||
int __pad2;
|
||||
int64_t st_blocks;
|
||||
int target_st_atime;
|
||||
unsigned int target_st_atime_nsec;
|
||||
int target_st_mtime;
|
||||
unsigned int target_st_mtime_nsec;
|
||||
int target_st_ctime;
|
||||
unsigned int target_st_ctime_nsec;
|
||||
unsigned int __unused4;
|
||||
unsigned int __unused5;
|
||||
};
|
||||
|
||||
#else
|
||||
#error unsupported CPU
|
||||
#endif
|
||||
|
@ -2434,8 +2459,11 @@ typedef union target_epoll_data {
|
|||
|
||||
struct target_epoll_event {
|
||||
uint32_t events;
|
||||
#ifdef TARGET_ARM
|
||||
uint32_t __pad;
|
||||
#endif
|
||||
target_epoll_data_t data;
|
||||
};
|
||||
} QEMU_PACKED;
|
||||
#endif
|
||||
struct target_rlimit64 {
|
||||
uint64_t rlim_cur;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue