summary refs log tree commit diff stats
path: root/linux-user/signal.c
diff options
context:
space:
mode:
authorMichael Weiser <michael.weiser@gmx.de>2018-01-11 13:25:31 +0000
committerPeter Maydell <peter.maydell@linaro.org>2018-01-11 13:25:31 +0000
commit50f22fa60d95c04a179e2cbf4b5f58d1f6068b61 (patch)
tree54ae7629bae9584746411b592bf970bd8c60dc1e /linux-user/signal.c
parentcb3aa5fea19cdc108baf6c3aff2e768bf9475b50 (diff)
downloadfocaccia-qemu-50f22fa60d95c04a179e2cbf4b5f58d1f6068b61.tar.gz
focaccia-qemu-50f22fa60d95c04a179e2cbf4b5f58d1f6068b61.zip
linux-user: Fix endianess of aarch64 signal trampoline
Since for aarch64 the signal trampoline is synthesized directly into the
signal frame we need to make sure the instructions end up little-endian.
Otherwise the wrong endianness will cause a SIGILL upon return from the
signal handler on big-endian targets.

Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20171220212308.12614-4-michael.weiser@gmx.de
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'linux-user/signal.c')
-rw-r--r--linux-user/signal.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 74fa03f96d..f85f0dd780 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -1599,9 +1599,13 @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
     if (ka->sa_flags & TARGET_SA_RESTORER) {
         return_addr = ka->sa_restorer;
     } else {
-        /* mov x8,#__NR_rt_sigreturn; svc #0 */
-        __put_user(0xd2801168, &frame->tramp[0]);
-        __put_user(0xd4000001, &frame->tramp[1]);
+        /*
+         * mov x8,#__NR_rt_sigreturn; svc #0
+         * Since these are instructions they need to be put as little-endian
+         * regardless of target default or current CPU endianness.
+         */
+        __put_user_e(0xd2801168, &frame->tramp[0], le);
+        __put_user_e(0xd4000001, &frame->tramp[1], le);
         return_addr = frame_addr + offsetof(struct target_rt_sigframe, tramp);
     }
     env->xregs[0] = usig;