diff options
author | Dmitry V. Levin <ldv@altlinux.org> | 2017-09-20 00:15:02 +0000 |
---|---|---|
committer | Dmitry V. Levin <ldv@altlinux.org> | 2017-09-20 00:15:02 +0000 |
commit | 55b097b50674d934ac98747c967dcceaac5c4d46 (patch) | |
tree | f405d74cb10852a409594aef3edd87cf8dff2bbb /linux/powerpc | |
parent | c8a294a585c72e5df5b701806c20cbe96b21c12b (diff) | |
download | strace-55b097b50674d934ac98747c967dcceaac5c4d46.tar.gz |
ppc64: truncate syscall args for 32-bit personality tracees
* linux/powerpc/get_syscall_args.c (get_syscall_args): Clear upper
32 bits of syscall args for 32-bit personality tracees.
* NEWS: Mention this fix.
Diffstat (limited to 'linux/powerpc')
-rw-r--r-- | linux/powerpc/get_syscall_args.c | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/linux/powerpc/get_syscall_args.c b/linux/powerpc/get_syscall_args.c index 66bcae31f..b54377efc 100644 --- a/linux/powerpc/get_syscall_args.c +++ b/linux/powerpc/get_syscall_args.c @@ -2,11 +2,26 @@ static int get_syscall_args(struct tcb *tcp) { - tcp->u_arg[0] = ppc_regs.orig_gpr3; - tcp->u_arg[1] = ppc_regs.gpr[4]; - tcp->u_arg[2] = ppc_regs.gpr[5]; - tcp->u_arg[3] = ppc_regs.gpr[6]; - tcp->u_arg[4] = ppc_regs.gpr[7]; - tcp->u_arg[5] = ppc_regs.gpr[8]; + if (current_personality != 0) { + /* + * Zero-extend from 32 bits. + * Use truncate_klong_to_current_wordsize(tcp->u_arg[N]) + * in syscall handlers + * if you need to use *sign-extended* parameter. + */ + tcp->u_arg[0] = (uint32_t) ppc_regs.orig_gpr3; + tcp->u_arg[1] = (uint32_t) ppc_regs.gpr[4]; + tcp->u_arg[2] = (uint32_t) ppc_regs.gpr[5]; + tcp->u_arg[3] = (uint32_t) ppc_regs.gpr[6]; + tcp->u_arg[4] = (uint32_t) ppc_regs.gpr[7]; + tcp->u_arg[5] = (uint32_t) ppc_regs.gpr[8]; + } else { + tcp->u_arg[0] = ppc_regs.orig_gpr3; + tcp->u_arg[1] = ppc_regs.gpr[4]; + tcp->u_arg[2] = ppc_regs.gpr[5]; + tcp->u_arg[3] = ppc_regs.gpr[6]; + tcp->u_arg[4] = ppc_regs.gpr[7]; + tcp->u_arg[5] = ppc_regs.gpr[8]; + } return 1; } |