Permalink
Browse files

Bug fix. Properly set up thread stack and stack pointer.

  • Loading branch information...
1 parent 727c104 commit 8dd4a92ea5e5c61104d68ec47466fb0e9a4ed0ba @staceyson committed Apr 5, 2013
@@ -67,6 +67,29 @@ struct target_sigframe {
target_ucontext_t sf_uc; /* saved ucontext */
};
+/* compare to sys/arm/include/frame.h */
+typedef struct target_trapframe {
+ abi_ulong tf_spsr; /* Zero on arm26 */
+ abi_ulong tf_r0;
+ abi_ulong tf_r1;
+ abi_ulong tf_r2;
+ abi_ulong tf_r3;
+ abi_ulong tf_r4;
+ abi_ulong tf_r5;
+ abi_ulong tf_r6;
+ abi_ulong tf_r7;
+ abi_ulong tf_r8;
+ abi_ulong tf_r9;
+ abi_ulong tf_r10;
+ abi_ulong tf_r11;
+ abi_ulong tf_r12;
+ abi_ulong tf_usr_sp;
+ abi_ulong tf_usr_lr;
+ abi_ulong tf_svc_sp; /* Not used on arm26 */
+ abi_ulong tf_svc_lr; /* Not used on arm26 */
+ abi_ulong tf_pc;
+} target_trapframe_t;
+
#define TARGET_SZSIGCODE (8 * 4)
/* Compare to arm/arm/locore.S ENTRY_NP(sigcode) */
@@ -228,11 +251,14 @@ get_ucontext_sigreturn(CPUARMState *regs, abi_ulong sf_addr,
/* XXX crashes on first shared lib call */
static inline void
thread_set_upcall(CPUARMState *regs, abi_ulong entry, abi_ulong arg,
- abi_ulong stack_base)
+ abi_ulong stack_base, abi_ulong stack_size)
{
+ abi_ulong sp;
+
+ sp = ((stack_base + stack_size) & (8 - 1)) - sizeof(struct target_trapframe);
/* fp = sp = stack base */
- regs->regs[11] = regs->regs[13] = stack_base;
+ regs->regs[11] = regs->regs[13] = sp;
/* pc = start function entry */
regs->regs[15] = regs->regs[14] = entry & 0xfffffffe;
/* r0 = arg */
@@ -48,7 +48,7 @@ get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr,
/* Compare to arm/arm/vm_machdep.c cpu_set_upcall_kse() */
static inline void
thread_set_upcall(CPUArchState *regs, abi_ulong entry, abi_ulong arg,
- abi_ulong stack_base)
+ abi_ulong stack_base, abi_ulong stack_size)
{
fprintf(stderr, "i386 doesn't have support for thread_set_upcall()\n");
}
@@ -6,6 +6,10 @@
#define TARGET_MINSIGSTKSZ (512 * 4)
#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768)
+/* compare to sys/mips/include/asm.h */
+#define TARGET_SZREG 4
+#define TARGET_CALLFRAME_SIZ (TARGET_SZREG * 4)
+
struct target_sigcontext {
target_sigset_t sc_mask; /* signal mask to retstore */
int32_t sc_onstack; /* sigstack state to restore */
@@ -210,15 +214,24 @@ get_ucontext_sigreturn(CPUMIPSState *regs, abi_ulong uc_addr,
/* Compare to mips/mips/vm_machdep.c cpu_set_upcall_kse() */
static inline void
thread_set_upcall(CPUMIPSState *regs, abi_ulong entry,
- abi_ulong arg, abi_ulong stack_base)
+ abi_ulong arg, abi_ulong stack_base, abi_ulong stack_size)
{
+ abi_ulong sp;
+
+ /*
+ * At the point where a function is called, sp must be 8
+ * byte aligned[for compatibility with 64-bit CPUs]
+ * in ``See MIPS Run'' by D. Sweetman, p. 269
+ * align stack
+ */
+ sp = ((stack_base + stack_size) & ~0x7) - TARGET_CALLFRAME_SIZ;
- /* t9 = pc = start_func entry */
+ /* t9 = pc = start function entry */
regs->active_tc.gpr[25] = regs->active_tc.PC = entry;
/* a0 = arg */
regs->active_tc.gpr[ 4] = arg;
- /* sp = stack base */
- regs->active_tc.gpr[29] = stack_base;
+ /* sp = top of the stack */
+ regs->active_tc.gpr[29] = sp;
}
#endif /* TARGET_SIGNAL_H */
@@ -24,9 +24,10 @@ struct target_ps_strings {
#define TARGET_SZSIGCODE 0
-/* Make stack size large enough to hold everything. */
-#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
- MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
+/* compare to sys/mips/include/vmparam.h */
+#define TARGET_STACK_SIZE (8UL*1024*1024) /* initial stack size limit */
+#define TARGET_STACK_SIZE_MAX (64UL*1024*1024) /* max stack size limit */
+
#else
@@ -6,6 +6,10 @@
#define TARGET_MINSIGSTKSZ (512 * 4)
#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768)
+/* compare to sys/mips/include/asm.h */
+#define TARGET_SZREG 8
+#define TARGET_CALLFRAME_SIZ (TARGET_SZREG * 4)
+
struct target_sigcontext {
target_sigset_t sc_mask; /* signal mask to retstore */
int32_t sc_onstack; /* sigstack state to restore */
@@ -229,15 +233,24 @@ get_ucontext_sigreturn(CPUMIPSState *regs, abi_ulong uc_addr,
/* Compare to mips/mips/vm_machdep.c cpu_set_upcall_kse() */
static inline void
thread_set_upcall(CPUMIPSState *regs, abi_ulong entry,
- abi_ulong arg, abi_ulong stack_base)
+ abi_ulong arg, abi_ulong stack_base, abi_ulong stack_size)
{
+ abi_ulong sp;
+
+ /*
+ * At the point where a function is called, sp must be 8
+ * byte aligned[for compatibility with 64-bit CPUs]
+ * in ``See MIPS Run'' by D. Sweetman, p. 269
+ * align stack
+ */
+ sp = ((stack_base + stack_size) & ~0x7) - TARGET_CALLFRAME_SIZ;
/* t9 = pc = start function entry */
regs->active_tc.gpr[25] = regs->active_tc.PC = entry;
/* a0 = arg */
regs->active_tc.gpr[ 4] = arg;
- /* sp = stack base */
- regs->active_tc.gpr[29] = stack_base;
+ /* sp = top of the stack */
+ regs->active_tc.gpr[29] = sp;
}
#endif /* TARGET_SIGNAL_H */
@@ -23,9 +23,9 @@ struct target_ps_strings {
#define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings))
-/* Make stack size large enough to hold everything. */
-#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
- MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
+/* compare to sys/mips/include/vmparam.h */
+#define TARGET_STACK_SIZE (8UL*1024*1024) /* initial stack size limit */
+#define TARGET_STACK_SIZE_MAX (64UL*1024*1024) /* max stack size limit */
#else
@@ -232,8 +232,12 @@ extern char target_proc_pathname[];
static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
{
+#if 0 // XXX temporary disable memory access checks until we can check thread stacks w/out failing
return page_check_range((target_ulong)addr, size,
(type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0;
+#else
+ return 1;
+#endif
}
/* NOTE __get_user and __put_user use host pointers and don't check access. */
@@ -54,7 +54,7 @@ get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr,
/* Compare to arm/arm/vm_machdep.c cpu_set_upcall_kse() */
static inline void
thread_set_upcall(CPUArchState *regs, abi_ulong entry, abi_ulong arg,
- abi_ulong stack_base)
+ abi_ulong stack_base, abi_ulong stack_size)
{
fprintf(stderr, "SPARC doesn't have support for thread_set_upcall()\n");
}
@@ -256,7 +256,7 @@ get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr,
/* Compare to arm/arm/vm_machdep.c cpu_set_upcall_kse() */
static inline void
thread_set_upcall(CPUArchState *regs, abi_ulong entry, abi_ulong arg,
- abi_ulong stack_base)
+ abi_ulong stack_base, abi_ulong stack_size)
{
fprintf(stderr, "SPARC64 doesn't have support for thread_set_upcall()\n");
}
@@ -200,11 +200,13 @@ void target_set_brk(abi_ulong start_brk, abi_ulong cur_brk, abi_ulong end_brk)
static abi_long do_obreak(abi_ulong new_brk)
{
abi_long mapped_addr;
- int new_alloc_size;
+ abi_ulong new_alloc_size;
+
+ return -TARGET_EINVAL; // XXX Temporary disable obreak() until it can be properly fixed
if (!new_brk)
return 0;
- if (new_brk < target_brk_start) {
+ if (new_brk < target_brk_cur) {
return -TARGET_EINVAL;
}
@@ -2570,7 +2572,7 @@ do_fork(CPUArchState *env, int num, int flags, int *fdp)
static pthread_mutex_t new_thread_lock = PTHREAD_MUTEX_INITIALIZER;
typedef struct {
CPUArchState *env;
- long tid;
+ long parent_tid;
pthread_mutex_t mutex;
pthread_cond_t cond;
pthread_t thread;
@@ -2592,18 +2594,17 @@ new_thread_start(void *arg)
ts = (TaskState *)thread_env->opaque;
(void)thr_self(&tid);
- info->tid = tid;
task_settid(ts);
/* copy out the TID info */
if (info->param.child_tid)
put_user(tid, info->param.child_tid, abi_long);
if (info->param.parent_tid)
- put_user(tid, info->param.parent_tid, abi_long);
+ put_user(info->parent_tid, info->param.parent_tid, abi_long);
/* Set arch dependent registers to start thread. */
thread_set_upcall(env, info->param.start_func, info->param.arg,
- info->param.stack_base);
+ info->param.stack_base, info->param.stack_size);
/* Enable signals */
sigprocmask(SIG_SETMASK, &info->sigmask, NULL);
@@ -2683,6 +2684,8 @@ do_thr_new(CPUArchState *env, abi_ulong target_param_addr, int32_t param_size)
target_rtp_addr = info.param.rtp = tswapal(target_param->rtp);
unlock_user(target_param, target_param_addr, 0);
+ thr_self(&info.parent_tid);
+
if (target_rtp_addr) {
if (!lock_user_struct(VERIFY_READ, target_rtp, target_rtp_addr,
1))
@@ -52,7 +52,7 @@ get_ucontext_sigreturn(CPUArchState *regs, abi_ulong sf_addr,
/* Compare to arm/arm/vm_machdep.c cpu_set_upcall_kse() */
static inline void
thread_set_upcall(CPUArchState *regs, abi_ulong entry, abi_ulong arg,
- abi_ulong stack_base)
+ abi_ulong stack_base, abi_ulong stack_size)
{
fprintf(stderr, "x86_64 doesn't have support for thread_set_upcall()\n");
}

0 comments on commit 8dd4a92

Please sign in to comment.