summaryrefslogtreecommitdiff
path: root/linux-user
diff options
context:
space:
mode:
authorTom Musta <tommusta@gmail.com>2014-06-30 08:13:37 -0500
committerAlexander Graf <agraf@suse.de>2014-09-08 12:50:46 +0200
commit7678108b134fc14d0a94fd13c0dd1129525c12d7 (patch)
treedf186cd85b337c6f9d1b964fa8a80282274ca128 /linux-user
parentfbdc200ac2d0d29e88ee6af9b77810c0f84265a6 (diff)
downloadqemu-7678108b134fc14d0a94fd13c0dd1129525c12d7.tar.gz
linux-user: Split PPC Trampoline Encoding from Register Save
Split the encoding of the PowerPC sigreturn trampoline from the saving of register state onto the signal handler stack. This will make it easier in subsequent patches to deal with variations in the stack frame layouts between 32 and 64 bit PowerPC. Signed-off-by: Tom Musta <tommusta@gmail.com> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/signal.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 29529563ea..7365d5ddbf 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -4491,8 +4491,7 @@ static target_ulong get_sigframe(struct target_sigaction *ka,
return newsp;
}
-static void save_user_regs(CPUPPCState *env, struct target_mcontext *frame,
- int sigret)
+static void save_user_regs(CPUPPCState *env, struct target_mcontext *frame)
{
target_ulong msr = env->msr;
int i;
@@ -4559,11 +4558,14 @@ static void save_user_regs(CPUPPCState *env, struct target_mcontext *frame,
/* Store MSR. */
__put_user(msr, &frame->mc_gregs[TARGET_PT_MSR]);
+}
+static void encode_trampoline(int sigret, uint32_t *tramp)
+{
/* Set up the sigreturn trampoline: li r0,sigret; sc. */
if (sigret) {
- __put_user(0x38000000UL | sigret, &frame->tramp[0]);
- __put_user(0x44000002UL, &frame->tramp[1]);
+ __put_user(0x38000000 | sigret, &tramp[0]);
+ __put_user(0x44000002, &tramp[1]);
}
}
@@ -4674,7 +4676,10 @@ static void setup_frame(int sig, struct target_sigaction *ka,
__put_user(sig, &sc->signal);
/* Save user regs. */
- save_user_regs(env, &frame->mctx, TARGET_NR_sigreturn);
+ save_user_regs(env, &frame->mctx);
+
+ /* Construct the trampoline code on the stack. */
+ encode_trampoline(TARGET_NR_sigreturn, (uint32_t *)&frame->mctx.tramp);
/* The kernel checks for the presence of a VDSO here. We don't
emulate a vdso, so use a sigreturn system call. */
@@ -4740,7 +4745,8 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
}
frame = &rt_sf->uc.tuc_mcontext;
- save_user_regs(env, frame, TARGET_NR_rt_sigreturn);
+ save_user_regs(env, frame);
+ encode_trampoline(TARGET_NR_rt_sigreturn, (uint32_t *)&frame->tramp);
/* The kernel checks for the presence of a VDSO here. We don't
emulate a vdso, so use a sigreturn system call. */