diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2020-11-05 21:23:12 +0000 |
---|---|---|
committer | Laurent Vivier <laurent@vivier.eu> | 2020-11-10 07:52:55 +0100 |
commit | b8ae597f0e6df9d1d80e07083fabf763fcb46013 (patch) | |
tree | 13060470e8c9398d0a68e4c721f0ba4124a986a9 /linux-user | |
parent | 43afbbd9fea1b255cc81f5f4bfd0b6a88826c735 (diff) | |
download | qemu-b8ae597f0e6df9d1d80e07083fabf763fcb46013.zip qemu-b8ae597f0e6df9d1d80e07083fabf763fcb46013.tar.gz qemu-b8ae597f0e6df9d1d80e07083fabf763fcb46013.tar.bz2 |
linux-user/sparc: Fix errors in target_ucontext structures
The various structs that make up the SPARC target_ucontext had some
errors:
* target structures must not include fields which are host pointers,
which might be the wrong size. These should be abi_ulong instead
* because we don't have the 'long double' part of the mcfpu_fregs
union in our version of the target_mc_fpu struct, we need to
manually force it to be 16-aligned
In particular, the lack of 16-alignment caused sparc64_get_context()
and sparc64_set_context() to read and write all the registers at the
wrong offset, which triggered a guest glibc stack check in
siglongjmp:
*** longjmp causes uninitialized stack frame ***: terminated
when trying to run bash.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20201105212314.9628-2-peter.maydell@linaro.org>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/sparc/signal.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/linux-user/sparc/signal.c b/linux-user/sparc/signal.c index d796f50..57ea159 100644 --- a/linux-user/sparc/signal.c +++ b/linux-user/sparc/signal.c @@ -349,10 +349,15 @@ typedef abi_ulong target_mc_greg_t; typedef target_mc_greg_t target_mc_gregset_t[SPARC_MC_NGREG]; struct target_mc_fq { - abi_ulong *mcfq_addr; + abi_ulong mcfq_addr; uint32_t mcfq_insn; }; +/* + * Note the manual 16-alignment; the kernel gets this because it + * includes a "long double qregs[16]" in the mcpu_fregs union, + * which we can't do. + */ struct target_mc_fpu { union { uint32_t sregs[32]; @@ -362,11 +367,11 @@ struct target_mc_fpu { abi_ulong mcfpu_fsr; abi_ulong mcfpu_fprs; abi_ulong mcfpu_gsr; - struct target_mc_fq *mcfpu_fq; + abi_ulong mcfpu_fq; unsigned char mcfpu_qcnt; unsigned char mcfpu_qentsz; unsigned char mcfpu_enab; -}; +} __attribute__((aligned(16))); typedef struct target_mc_fpu target_mc_fpu_t; typedef struct { @@ -377,7 +382,7 @@ typedef struct { } target_mcontext_t; struct target_ucontext { - struct target_ucontext *tuc_link; + abi_ulong tuc_link; abi_ulong tuc_flags; target_sigset_t tuc_sigmask; target_mcontext_t tuc_mcontext; |