Skip to content

Commit 3f7685e

Browse files
rth7680vivier
authored andcommitted
linux-user/sparc: Implement setup_sigtramp
Create and record the two signal trampolines. Use them when the guest does not use SA_RESTORER. Acked-by: Mark Cave-Ayland <[email protected]> Reviewed-by: Peter Maydell <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Signed-off-by: Richard Henderson <[email protected]> Message-Id: <[email protected]> Signed-off-by: Laurent Vivier <[email protected]>
1 parent b9188f9 commit 3f7685e

File tree

2 files changed

+30
-14
lines changed

2 files changed

+30
-14
lines changed

linux-user/sparc/signal.c

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,12 @@ static void restore_fpu(struct target_siginfo_fpu *fpu, CPUSPARCState *env)
242242
}
243243

244244
#ifdef TARGET_ARCH_HAS_SETUP_FRAME
245+
static void install_sigtramp(uint32_t *tramp, int syscall)
246+
{
247+
__put_user(0x82102000u + syscall, &tramp[0]); /* mov syscall, %g1 */
248+
__put_user(0x91d02010u, &tramp[1]); /* t 0x10 */
249+
}
250+
245251
void setup_frame(int sig, struct target_sigaction *ka,
246252
target_sigset_t *set, CPUSPARCState *env)
247253
{
@@ -291,13 +297,9 @@ void setup_frame(int sig, struct target_sigaction *ka,
291297
if (ka->ka_restorer) {
292298
env->regwptr[WREG_O7] = ka->ka_restorer;
293299
} else {
294-
env->regwptr[WREG_O7] = sf_addr +
295-
offsetof(struct target_signal_frame, insns) - 2 * 4;
296-
297-
/* mov __NR_sigreturn, %g1 */
298-
__put_user(0x821020d8u, &sf->insns[0]);
299-
/* t 0x10 */
300-
__put_user(0x91d02010u, &sf->insns[1]);
300+
/* Not used, but retain for ABI compatibility. */
301+
install_sigtramp(sf->insns, TARGET_NR_sigreturn);
302+
env->regwptr[WREG_O7] = default_sigreturn;
301303
}
302304
unlock_user(sf, sf_addr, sf_size);
303305
}
@@ -358,13 +360,9 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
358360
if (ka->ka_restorer) {
359361
env->regwptr[WREG_O7] = ka->ka_restorer;
360362
} else {
361-
env->regwptr[WREG_O7] =
362-
sf_addr + offsetof(struct target_rt_signal_frame, insns) - 2 * 4;
363-
364-
/* mov __NR_rt_sigreturn, %g1 */
365-
__put_user(0x82102065u, &sf->insns[0]);
366-
/* t 0x10 */
367-
__put_user(0x91d02010u, &sf->insns[1]);
363+
/* Not used, but retain for ABI compatibility. */
364+
install_sigtramp(sf->insns, TARGET_NR_rt_sigreturn);
365+
env->regwptr[WREG_O7] = default_rt_sigreturn;
368366
}
369367
#else
370368
env->regwptr[WREG_O7] = ka->ka_restorer;
@@ -775,4 +773,18 @@ void sparc64_get_context(CPUSPARCState *env)
775773
unlock_user_struct(ucp, ucp_addr, 1);
776774
force_sig(TARGET_SIGSEGV);
777775
}
776+
#else
777+
void setup_sigtramp(abi_ulong sigtramp_page)
778+
{
779+
uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 2 * 8, 0);
780+
assert(tramp != NULL);
781+
782+
default_sigreturn = sigtramp_page;
783+
install_sigtramp(tramp, TARGET_NR_sigreturn);
784+
785+
default_rt_sigreturn = sigtramp_page + 8;
786+
install_sigtramp(tramp + 2, TARGET_NR_rt_sigreturn);
787+
788+
unlock_user(tramp, sigtramp_page, 2 * 8);
789+
}
778790
#endif

linux-user/sparc/target_signal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ typedef struct target_sigaltstack {
6969

7070
#ifdef TARGET_ABI32
7171
#define TARGET_ARCH_HAS_SETUP_FRAME
72+
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
73+
#else
74+
/* For sparc64, use of KA_RESTORER is mandatory. */
75+
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
7276
#endif
7377

7478
/* bit-flags */

0 commit comments

Comments
 (0)