From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50421) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X1bPR-0008D7-UM for qemu-devel@nongnu.org; Mon, 30 Jun 2014 09:14:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X1bPH-0007Y3-5l for qemu-devel@nongnu.org; Mon, 30 Jun 2014 09:14:13 -0400 From: Tom Musta Date: Mon, 30 Jun 2014 08:13:39 -0500 Message-Id: <1404134022-17946-5-git-send-email-tommusta@gmail.com> In-Reply-To: <1404134022-17946-1-git-send-email-tommusta@gmail.com> References: <1404134022-17946-1-git-send-email-tommusta@gmail.com> Subject: [Qemu-devel] [PATCH 4/7] linux-user: Properly Dereference PPC64 ELFv1 Signal Handler Pointer List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org Cc: Tom Musta , riku.voipio@linaro.org, agraf@suse.de Properly dereference 64-bit PPC ELF V1 ABIT function pointers to signal handlers. On this platform, function pointers are pointers to structures and the first 64 bits of such a structure contains the function's entry point. The second 64 bits contains the TOC pointer, which must be placed into GPR 2. Signed-off-by: Tom Musta --- linux-user/signal.c | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-) diff --git a/linux-user/signal.c b/linux-user/signal.c index 83bfcd6..7bd9a43 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -4472,6 +4472,15 @@ struct target_rt_sigframe { #endif +#if defined(TARGET_PPC64) + +struct target_func_ptr { + target_ulong entry; + target_ulong toc; +}; + +#endif + /* We use the mc_pad field for the signal return trampoline. */ #define tramp mc_pad @@ -4703,7 +4712,17 @@ static void setup_frame(int sig, struct target_sigaction *ka, env->gpr[1] = newsp; env->gpr[3] = signal; env->gpr[4] = frame_addr + offsetof(struct target_sigframe, sctx); + +#if defined(TARGET_PPC64) + /* PPC64 function pointers are pointers to OPD entries. */ + struct target_func_ptr *handler = + (struct target_func_ptr *)g2h(ka->_sa_handler); + env->nip = tswapl(handler->entry); + env->gpr[2] = tswapl(handler->toc); +#else env->nip = (target_ulong) ka->_sa_handler; +#endif + /* Signal handlers are entered in big-endian mode. */ env->msr &= ~MSR_LE; @@ -4782,7 +4801,17 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka, env->gpr[4] = (target_ulong) h2g(&rt_sf->info); env->gpr[5] = (target_ulong) h2g(&rt_sf->uc); env->gpr[6] = (target_ulong) h2g(rt_sf); + +#if defined(TARGET_PPC64) + /* PPC64 function pointers are pointers to OPD entries. */ + struct target_func_ptr *handler = + (struct target_func_ptr *)g2h(ka->_sa_handler); + env->nip = tswapl(handler->entry); + env->gpr[2] = tswapl(handler->toc); +#else env->nip = (target_ulong) ka->_sa_handler; +#endif + /* Signal handlers are entered in big-endian mode. */ env->msr &= ~MSR_LE; -- 1.7.1