Skip to content

Commit

Permalink
target/ppc: don't byte swap ELFv2 signal handler
Browse files Browse the repository at this point in the history
Previously, the signal handler would be byte swapped if the target and
host CPU used different endianness. This would cause a SIGSEGV when
attempting to translate the opcode pointed to by the swapped address.

 Thread 1 "qemu-ppc64" received signal SIGSEGV, Segmentation fault.
 0x00000000600a9257 in ldl_he_p (ptr=0x4c2c061000000000) at qemu/include/qemu/bswap.h:351
 351        __builtin_memcpy(&r, ptr, sizeof(r));

 #0  0x00000000600a9257 in ldl_he_p (ptr=0x4c2c061000000000) at qemu/include/qemu/bswap.h:351
 #1  0x00000000600a92fe in ldl_be_p (ptr=0x4c2c061000000000) at qemu/include/qemu/bswap.h:449
 #2  0x00000000600c0790 in translator_ldl_swap at qemu/include/exec/translator.h:201
 #3  0x000000006011c1ab in ppc_tr_translate_insn at qemu/target/ppc/translate.c:7856
 #4  0x000000006005ae70 in translator_loop at qemu/accel/tcg/translator.c:102

The signal handler will be byte swapped as a result of the __get_user()
call in sigaction() if it is necessary, no additional swap is required.

Signed-off-by: Vincent Fazio <[email protected]>
Reviewed-by: Laurent Vivier <[email protected]>
Reviewed-by: Richard Henderson <[email protected]>
Message-Id: <[email protected]>
Signed-off-by: David Gibson <[email protected]>
  • Loading branch information
vfazio authored and dgibson committed Mar 24, 2020
1 parent 0418bf7 commit feb39b6
Showing 1 changed file with 2 additions and 4 deletions.
6 changes: 2 additions & 4 deletions linux-user/ppc/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,10 +567,8 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
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;
/* ELFv2 PPC64 function pointers are entry points. R12 must also be set. */
env->gpr[12] = env->nip = ka->_sa_handler;
}
#else
env->nip = (target_ulong) ka->_sa_handler;
Expand Down

0 comments on commit feb39b6

Please sign in to comment.