From: Philippe Waroquiers Date: Thu, 31 Jul 2014 17:55:27 +0000 (+0000) Subject: arm64: fix the conversion from/to VEX fpsr to/from GDB representation X-Git-Tag: svn/VALGRIND_3_10_0~231 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4ab69c6dc72e6c33e4dbae662d594a4f3159f928;p=thirdparty%2Fvalgrind.git arm64: fix the conversion from/to VEX fpsr to/from GDB representation git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14219 --- diff --git a/coregrind/m_gdbserver/valgrind-low-arm64.c b/coregrind/m_gdbserver/valgrind-low-arm64.c index 1b5a539777..5a32ef87ca 100644 --- a/coregrind/m_gdbserver/valgrind-low-arm64.c +++ b/coregrind/m_gdbserver/valgrind-low-arm64.c @@ -218,17 +218,19 @@ void transfer_register (ThreadId tid, int abs_regno, void * buf, case 64: VG_(transfer) (&arm->guest_Q30, buf, dir, size, mod); break; case 65: VG_(transfer) (&arm->guest_Q31, buf, dir, size, mod); break; case 66: { - /* The ARM64 FPSR representation is not the same as the + /* The VEX ARM64 FPSR representation is not the same as the architecturally defined representation. Hence use conversion - functions to convert to/from it. */ + functions to convert to/from it. + VEX FPSR only models QC (bit 27), and uses a 64 bits to store + this FPSR QC bit. So, we need to transfer from/to the lowest part + of the ULong that VEX provides/needs, as GDB expects or + gives only 4 bytes. */ if (dir == valgrind_to_gdbserver) { ULong fpsr = LibVEX_GuestARM64_get_fpsr(arm); - // XXX FIXME what if size != 8 ? Does this still work? - VG_(transfer) (&fpsr, buf, dir, size, mod); + VG_(transfer) ((UInt*)&fpsr + 1, buf, dir, size, mod); } else { - // XXX FIXME what if size != 8 ? Does this still work? ULong fpsr = 0; - VG_(transfer) (&fpsr, buf, dir, size, mod); + VG_(transfer) ((UInt*)&fpsr + 1, buf, dir, size, mod); LibVEX_GuestARM64_set_fpsr(arm, fpsr); } break;