[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-ppc] [PULL 08/52] linux-user: Handle PPC64 ELFv2 Function Pointers
From: |
Alexander Graf |
Subject: |
[Qemu-ppc] [PULL 08/52] linux-user: Handle PPC64 ELFv2 Function Pointers |
Date: |
Thu, 4 Sep 2014 19:19:56 +0200 |
From: Tom Musta <address@hidden>
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>
Signed-off-by: Alexander Graf <address@hidden>
---
linux-user/signal.c | 40 ++++++++++++++++++++++++++++++----------
1 file changed, 30 insertions(+), 10 deletions(-)
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 91a03c7..24eb42d 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -4681,6 +4681,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))
@@ -4725,11 +4728,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
@@ -4756,6 +4766,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))
@@ -4814,11 +4827,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.8.1.4
- [Qemu-ppc] [PULL 00/52] ppc patch queue 2014-09-04, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 09/52] hw/ppc/spapr_hcall.c: Fix typo in function names, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 03/52] linux-user: Fix Stack Pointer Bug in PPC setup_rt_frame, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 12/52] spapr: fix possible memory leak, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 13/52] spapr: Move DT memory node rendering to a helper, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 04/52] linux-user: Split PPC Trampoline Encoding from Register Save, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 07/52] linux-user: Implement do_setcontext for PPC64, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 15/52] spapr: Refactor spapr_populate_memory() to allow memoryless nodes, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 17/52] spapr: Add a helper for node0_size calculation, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 08/52] linux-user: Handle PPC64 ELFv2 Function Pointers,
Alexander Graf <=
- [Qemu-ppc] [PULL 16/52] spapr: Split memory nodes to power-of-two blocks, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 01/52] PPC: KVM: Fix g3beige and mac99 when HV is loaded, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 18/52] spapr: Fix ibm, associativity for memory nodes, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 10/52] spapr: add uuid/host details to device tree, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 14/52] spapr: Use DT memory node rendering helper for other nodes, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 02/52] ppc: spapr-rtas - implement os-term rtas call, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 19/52] loader: Add load_image_size() to replace load_image(), Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 21/52] ppc: debug stub: Get trap instruction opcode from KVM, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 23/52] ppc: Add software breakpoint support, Alexander Graf, 2014/09/04
- [Qemu-ppc] [PULL 05/52] linux-user: Enable Signal Handlers on PPC64, Alexander Graf, 2014/09/04