[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 7/7] linux-user: Handle PPC64 ELFv2 Function Pointer
From: |
Tom Musta |
Subject: |
[Qemu-devel] [PATCH 7/7] linux-user: Handle PPC64 ELFv2 Function Pointers |
Date: |
Mon, 30 Jun 2014 08:13:42 -0500 |
Function pointers in the 64-bit ELFv2 PowerPC ABI are actual (internal)
entry point addresses. However, when invoking a function via a function
pointer, GPR 12 must also be set to this address so that the TOC may be
handled properly.
Add this support to the invocation of a signal handler.
Signed-off-by: Tom Musta <address@hidden>
---
linux-user/signal.c | 40 ++++++++++++++++++++++++++++++----------
1 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 9f04a20..770e7f7 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -4670,6 +4670,9 @@ static void setup_frame(int sig, struct target_sigaction
*ka,
target_ulong frame_addr, newsp;
int err = 0;
int signal;
+#if defined(TARGET_PPC64)
+ struct image_info *image = ((TaskState *)thread_cpu->opaque)->info;
+#endif
frame_addr = get_sigframe(ka, env, sizeof(*frame));
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))
@@ -4714,11 +4717,18 @@ static void setup_frame(int sig, struct
target_sigaction *ka,
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);
+ if (get_ppc64_abi(image) < 2) {
+ /* ELFv1 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 {
+ /* ELFv2 PPC64 function pointers are entry points, but R12
+ * must also be set */
+ env->nip = tswapl((target_ulong) ka->_sa_handler);
+ env->gpr[12] = env->nip;
+ }
#else
env->nip = (target_ulong) ka->_sa_handler;
#endif
@@ -4745,6 +4755,9 @@ static void setup_rt_frame(int sig, struct
target_sigaction *ka,
target_ulong rt_sf_addr, newsp = 0;
int i, err = 0;
int signal;
+#if defined(TARGET_PPC64)
+ struct image_info *image = ((TaskState *)thread_cpu->opaque)->info;
+#endif
rt_sf_addr = get_sigframe(ka, env, sizeof(*rt_sf));
if (!lock_user_struct(VERIFY_WRITE, rt_sf, rt_sf_addr, 1))
@@ -4803,11 +4816,18 @@ static void setup_rt_frame(int sig, struct
target_sigaction *ka,
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);
+ if (get_ppc64_abi(image) < 2) {
+ /* ELFv1 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 {
+ /* ELFv2 PPC64 function pointers are entry points, but R12
+ * must also be set */
+ env->nip = tswapl((target_ulong) ka->_sa_handler);
+ env->gpr[12] = env->nip;
+ }
#else
env->nip = (target_ulong) ka->_sa_handler;
#endif
--
1.7.1
- [Qemu-devel] [PATCH 0/7] linux-user: Support for Signal Handlers on PPC64, Tom Musta, 2014/06/30
- [Qemu-devel] [PATCH 1/7] linux-user: Fix Stack Pointer Bug in PPC setup_rt_frame, Tom Musta, 2014/06/30
- [Qemu-devel] [PATCH 3/7] linux-user: Enable Signal Handlers on PPC64, Tom Musta, 2014/06/30
- [Qemu-devel] [PATCH 2/7] linux-user: Split PPC Trampoline Encoding from Register Save, Tom Musta, 2014/06/30
- [Qemu-devel] [PATCH 4/7] linux-user: Properly Dereference PPC64 ELFv1 Signal Handler Pointer, Tom Musta, 2014/06/30
- [Qemu-devel] [PATCH 6/7] linux-user: Move get_ppc64_abi, Tom Musta, 2014/06/30
- [Qemu-devel] [PATCH 5/7] linux-user: Implement do_setcontext for PPC64, Tom Musta, 2014/06/30
- [Qemu-devel] [PATCH 7/7] linux-user: Handle PPC64 ELFv2 Function Pointers,
Tom Musta <=