From: Dmitry V. L. <ld...@al...> - 2014-02-26 22:38:55
|
On Wed, Feb 26, 2014 at 02:01:51PM -0800, enh wrote: > i notice that the decoding of sigaltstack's struct stack_t is wrong on > arm64 for a 32-bit process. looking at print_stack_t in strace, i > don't understand how this works for x86/x86_64 --- the first field is > a void*. so i'm a bit confused about how i should go about fixing this > for arm/arm64. anyone have a clue to spare? This is a demonstration why current multiarch approach is unreliable: every structure containing members whose size differs between personalities has to be open-coded. In case of stack_t, the fix is likely to be this: --- a/signal.c +++ b/signal.c @@ -1084,10 +1084,33 @@ static void print_stack_t(struct tcb *tcp, unsigned long addr) { stack_t ss; + int r; if (!addr) { tprints("NULL"); - } else if (umove(tcp, addr, &ss) < 0) { + return; + } + +#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 + if (current_wordsize != sizeof(ss.ss_sp) && current_wordsize == 4) { + struct { + uint32_t ss_sp; + int32_t ss_flags; + uint32_t ss_size; + } ss32; + r = umove(tcp, addr, &ss32); + if (r >= 0) { + memset(&ss, 0, sizeof(ss)); + ss.ss_sp = (void*)(unsigned long) ss32.ss_sp; + ss.ss_flags = ss32.ss_flags; + ss.ss_size = (unsigned long) ss32.ss_size; + } + } else +#endif + { + r = umove(tcp, addr, &ss); + } + if (r < 0) { tprintf("%#lx", addr); } else { tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp); -- ldv |