[3/6] x32: Avoid unsigned long when installing fast tracepoint jump pads

Message ID 1469667685-10848-4-git-send-email-palves@redhat.com
State New, archived
Headers

Commit Message

Pedro Alves July 28, 2016, 1:01 a.m. UTC
  We're casting through unsigned long to write a 64-bit immediate
operand of movabs (the comment said movl, but that was incorrect).
The problem is that unsigned long is 32-bit on x32, so we were writing
fewer bytes than necessary.

Fix this by using an 8 byte memcpy like in other similar places in the
function.

gdb/gdbserver/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	* linux-x86-low.c (amd64_install_fast_tracepoint_jump_pad): Fix
	comment.  Use memcpy instead of casting through unsigned long.
---
 gdb/gdbserver/linux-x86-low.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
  

Comments

Pedro Alves July 28, 2016, 8:51 a.m. UTC | #1
On 07/28/2016 04:07 AM, H.J. Lu wrote:

>> Fix this by using an 8 byte memcpy like in other similar places in the
>> function.

...

>> diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
>> index d6b67c1..1ba98ba 100644
>> --- a/gdb/gdbserver/linux-x86-low.c
>> +++ b/gdb/gdbserver/linux-x86-low.c
>> @@ -1092,10 +1092,10 @@ amd64_install_fast_tracepoint_jump_pad
> (CORE_ADDR tpoint, CORE_ADDR tpaddr,
>>    buf[i++] = 0x41; buf[i++] = 0x51; /* push %r9 */
>>    buf[i++] = 0x41; buf[i++] = 0x50; /* push %r8 */
>>    buf[i++] = 0x9c; /* pushfq */
>> -  buf[i++] = 0x48; /* movl <addr>,%rdi */
>> +  buf[i++] = 0x48; /* movabs <addr>,%rdi */
>>    buf[i++] = 0xbf;
>> -  *((unsigned long *)(buf + i)) = (unsigned long) tpaddr;
>> -  i += sizeof (unsigned long);
>> +  memcpy (buf + i, &tpaddr, 8);
>> +  i += 8;
>>    buf[i++] = 0x57; /* push %rdi */
>>    append_insns (&buildaddr, i, buf);

> 
> Why not use long long here?
> 

My initial fix used uint64_t, which would be even more explicit,
but then I noticed that the the rest of the function uses this
same exact memcpy pattern in other cases where it writes other 64-bit
immediates.  So this makes everything consistent.
Note also that memcpy instead of casting also avoids worrying
about strict aliasing violations.

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c
index d6b67c1..1ba98ba 100644
--- a/gdb/gdbserver/linux-x86-low.c
+++ b/gdb/gdbserver/linux-x86-low.c
@@ -1092,10 +1092,10 @@  amd64_install_fast_tracepoint_jump_pad (CORE_ADDR tpoint, CORE_ADDR tpaddr,
   buf[i++] = 0x41; buf[i++] = 0x51; /* push %r9 */
   buf[i++] = 0x41; buf[i++] = 0x50; /* push %r8 */
   buf[i++] = 0x9c; /* pushfq */
-  buf[i++] = 0x48; /* movl <addr>,%rdi */
+  buf[i++] = 0x48; /* movabs <addr>,%rdi */
   buf[i++] = 0xbf;
-  *((unsigned long *)(buf + i)) = (unsigned long) tpaddr;
-  i += sizeof (unsigned long);
+  memcpy (buf + i, &tpaddr, 8);
+  i += 8;
   buf[i++] = 0x57; /* push %rdi */
   append_insns (&buildaddr, i, buf);