Merge tag '20231119-xtensa-1' of https://github.com/OSLL/qemu-xtensa into staging
target/xtensa fixes for v8.2:
- fix signal delivery in FDPIC
# -----BEGIN PGP SIGNATURE-----
#
# iQJHBAABCgAxFiEEK2eFS5jlMn3N6xfYUfnMkfg/oEQFAmVaXU4THGpjbXZia2Jj
# QGdtYWlsLmNvbQAKCRBR+cyR+D+gRF13EACXNP0MPn2iWqxLPvxW9mDXaQu9cSlJ
# BcAlHKbi21CDdqLYpyMoenRONtHMDKjEhR4Atv+DRhc2qQYKNogLgCM1PtGkb6+z
# rNS6HBaUFsAKovS03JGcBDDYWS97bfN1AQRrrEzCV+SKq5Gq8Tr23LSgFHred0hS
# OlGmb7/S+uMh1Uo+rqLKFvSkcWLyaPxOhw1BoaNWdifSotfRwK++PZUvv7slQk+/
# J2ePbjU/ZTBTmumn0tg8BP66UHmGQ+TcvGOdD0m6qlQoq5XaqAYgNb6/Cm16xIPJ
# GQtmB1m74Dl1cQGYXlg3YFGluOJGidkT6In6dYzOEzjvOg9Rku+9bdCxIyRgQK7g
# gXcQJaEdpBiex3c21XWhMfjpM1pQruRgIQ3xqYETBMKXXqvbgYdUT09JpuaoTUkP
# oTymnBVL+9hyrlhPWXzn8M6IPUlyT7Hmnb0uVmHfTi8UNBhiGBRSN4x3CMDNi9oL
# ziE3xKgEkii9WEY+qSCodLMvLJBzShpKTjmUhfJMYdK07uVzazhGhmtQ8qSi3Rm7
# 6hDfnnBwrnX/CBE1IMca280Aax3TMf8Sn1pJqsTHwlNFb3O5vcixRajJw7xNprkP
# 5CcS+G2fRK7JIb18FI2aBf7DXD4kfasF8UAaiyQfkmD1/LITSGiDKfKFvaqjA7Ln
# wVrNbrGvDRvdEw==
# =sZPo
# -----END PGP SIGNATURE-----
# gpg: Signature made Sun 19 Nov 2023 14:09:02 EST
# gpg: using RSA key 2B67854B98E5327DCDEB17D851F9CC91F83FA044
# gpg: issuer "jcmvbkbc@gmail.com"
# gpg: Good signature from "Max Filippov <filippov@cadence.com>" [unknown]
# gpg: aka "Max Filippov <max.filippov@cogentembedded.com>" [unknown]
# gpg: aka "Max Filippov <jcmvbkbc@gmail.com>" [unknown]
# gpg: WARNING: The key's User ID is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 2B67 854B 98E5 327D CDEB 17D8 51F9 CC91 F83F A044
* tag '20231119-xtensa-1' of https://github.com/OSLL/qemu-xtensa:
linux-user: xtensa: fix signal delivery in FDPIC
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
diff --git a/linux-user/xtensa/signal.c b/linux-user/xtensa/signal.c
index f5fb8b5..32dcfa5 100644
--- a/linux-user/xtensa/signal.c
+++ b/linux-user/xtensa/signal.c
@@ -157,6 +157,9 @@
{
abi_ulong frame_addr;
struct target_rt_sigframe *frame;
+ int is_fdpic = info_is_fdpic(((TaskState *)thread_cpu->opaque)->info);
+ abi_ulong handler = 0;
+ abi_ulong handler_fdpic_GOT = 0;
uint32_t ra;
bool abi_call0;
unsigned base;
@@ -165,6 +168,17 @@
frame_addr = get_sigframe(ka, env, sizeof(*frame));
trace_user_setup_rt_frame(env, frame_addr);
+ if (is_fdpic) {
+ abi_ulong funcdesc_ptr = ka->_sa_handler;
+
+ if (get_user_ual(handler, funcdesc_ptr)
+ || get_user_ual(handler_fdpic_GOT, funcdesc_ptr + 4)) {
+ goto give_sigsegv;
+ }
+ } else {
+ handler = ka->_sa_handler;
+ }
+
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
goto give_sigsegv;
}
@@ -185,14 +199,21 @@
}
if (ka->sa_flags & TARGET_SA_RESTORER) {
- ra = ka->sa_restorer;
+ if (is_fdpic) {
+ if (get_user_ual(ra, ka->sa_restorer)) {
+ unlock_user_struct(frame, frame_addr, 0);
+ goto give_sigsegv;
+ }
+ } else {
+ ra = ka->sa_restorer;
+ }
} else {
/* Not used, but retain for ABI compatibility. */
install_sigtramp(frame->retcode);
ra = default_rt_sigreturn;
}
memset(env->regs, 0, sizeof(env->regs));
- env->pc = ka->_sa_handler;
+ env->pc = handler;
env->regs[1] = frame_addr;
env->sregs[WINDOW_BASE] = 0;
env->sregs[WINDOW_START] = 1;
@@ -212,6 +233,9 @@
env->regs[base + 3] = frame_addr + offsetof(struct target_rt_sigframe,
info);
env->regs[base + 4] = frame_addr + offsetof(struct target_rt_sigframe, uc);
+ if (is_fdpic) {
+ env->regs[base + 11] = handler_fdpic_GOT;
+ }
unlock_user_struct(frame, frame_addr, 1);
return;