Skip to content

Commit 55e83c2

Browse files
rth7680vivier
authored andcommitted
linux-user/xtensa: Implement setup_sigtramp
Create and record the rt signal trampoline. Use it when the guest does not use SA_RESTORER. Reviewed-by: Max Filippov <[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 3f7685e commit 55e83c2

File tree

2 files changed

+38
-20
lines changed

2 files changed

+38
-20
lines changed

linux-user/xtensa/signal.c

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,29 @@ static int setup_sigcontext(struct target_rt_sigframe *frame,
128128
return 1;
129129
}
130130

131+
static void install_sigtramp(uint8_t *tramp)
132+
{
133+
#ifdef TARGET_WORDS_BIGENDIAN
134+
/* Generate instruction: MOVI a2, __NR_rt_sigreturn */
135+
__put_user(0x22, &tramp[0]);
136+
__put_user(0x0a, &tramp[1]);
137+
__put_user(TARGET_NR_rt_sigreturn, &tramp[2]);
138+
/* Generate instruction: SYSCALL */
139+
__put_user(0x00, &tramp[3]);
140+
__put_user(0x05, &tramp[4]);
141+
__put_user(0x00, &tramp[5]);
142+
#else
143+
/* Generate instruction: MOVI a2, __NR_rt_sigreturn */
144+
__put_user(0x22, &tramp[0]);
145+
__put_user(0xa0, &tramp[1]);
146+
__put_user(TARGET_NR_rt_sigreturn, &tramp[2]);
147+
/* Generate instruction: SYSCALL */
148+
__put_user(0x00, &tramp[3]);
149+
__put_user(0x50, &tramp[4]);
150+
__put_user(0x00, &tramp[5]);
151+
#endif
152+
}
153+
131154
void setup_rt_frame(int sig, struct target_sigaction *ka,
132155
target_siginfo_t *info,
133156
target_sigset_t *set, CPUXtensaState *env)
@@ -164,26 +187,9 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
164187
if (ka->sa_flags & TARGET_SA_RESTORER) {
165188
ra = ka->sa_restorer;
166189
} else {
167-
ra = frame_addr + offsetof(struct target_rt_sigframe, retcode);
168-
#ifdef TARGET_WORDS_BIGENDIAN
169-
/* Generate instruction: MOVI a2, __NR_rt_sigreturn */
170-
__put_user(0x22, &frame->retcode[0]);
171-
__put_user(0x0a, &frame->retcode[1]);
172-
__put_user(TARGET_NR_rt_sigreturn, &frame->retcode[2]);
173-
/* Generate instruction: SYSCALL */
174-
__put_user(0x00, &frame->retcode[3]);
175-
__put_user(0x05, &frame->retcode[4]);
176-
__put_user(0x00, &frame->retcode[5]);
177-
#else
178-
/* Generate instruction: MOVI a2, __NR_rt_sigreturn */
179-
__put_user(0x22, &frame->retcode[0]);
180-
__put_user(0xa0, &frame->retcode[1]);
181-
__put_user(TARGET_NR_rt_sigreturn, &frame->retcode[2]);
182-
/* Generate instruction: SYSCALL */
183-
__put_user(0x00, &frame->retcode[3]);
184-
__put_user(0x50, &frame->retcode[4]);
185-
__put_user(0x00, &frame->retcode[5]);
186-
#endif
190+
/* Not used, but retain for ABI compatibility. */
191+
install_sigtramp(frame->retcode);
192+
ra = default_rt_sigreturn;
187193
}
188194
memset(env->regs, 0, sizeof(env->regs));
189195
env->pc = ka->_sa_handler;
@@ -264,3 +270,13 @@ long do_rt_sigreturn(CPUXtensaState *env)
264270
force_sig(TARGET_SIGSEGV);
265271
return -TARGET_QEMU_ESIGRETURN;
266272
}
273+
274+
void setup_sigtramp(abi_ulong sigtramp_page)
275+
{
276+
uint8_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 6, 0);
277+
assert(tramp != NULL);
278+
279+
default_rt_sigreturn = sigtramp_page;
280+
install_sigtramp(tramp);
281+
unlock_user(tramp, sigtramp_page, 6);
282+
}

linux-user/xtensa/target_signal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@ typedef struct target_sigaltstack {
2020

2121
#include "../generic/signal.h"
2222

23+
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
24+
2325
#endif

0 commit comments

Comments
 (0)