GCC produced wrong code in gvfs-1.14.2-3.fc18.x86_64

Stephan Bergmann sbergman at redhat.com
Fri Mar 15 15:23:32 UTC 2013


I happened to run across a problem with current gvfsd-sftp in x86_64 
Fedora 18 that is apparently due to bad code generated by GCC.

The function

> void
> g_vfs_read_channel_send_seek_offset (GVfsReadChannel *read_channel,
>                                      goffset offset)
> {
>   GVfsDaemonSocketProtocolReply reply;
>   GVfsChannel *channel;
>
>   channel = G_VFS_CHANNEL (read_channel);
>
>   reply.type = g_htonl (G_VFS_DAEMON_SOCKET_PROTOCOL_REPLY_SEEK_POS);
>   reply.seq_nr = g_htonl (g_vfs_channel_get_current_seq_nr (channel));
>   reply.arg1 = g_htonl (offset & 0xffffffff);
>   reply.arg2 = g_htonl (offset >> 32);
>
>   g_vfs_channel_send_reply (channel, &reply, NULL, 0);
> }

in /usr/src/debug/gvfs-1.14.2/daemon/gvfsreadchannel.c shall split the 
signed 64 bit goffset offset into reply.arg1 and reply.arg2.  What 
happens though is that reply.arg2 erroneously contains the same 
(byte-swapped, due to g_htonl) low-order 32 bits as reply.arg1.  The 
generated code is

> 0x0000000000421c90 <+0>:  push  %rbp
> 0x0000000000421c91 <+1>:  mov   %rsi,%rbp
> 0x0000000000421c94 <+4>:  push  %rbx
> 0x0000000000421c95 <+5>:  mov   %rdi,%rbx
> 0x0000000000421c98 <+8>:  sub   $0x18,%rsp
> 0x0000000000421c9c <+12>: callq 0x415cf0 <g_vfs_channel_get_type>
> 0x0000000000421ca1 <+17>: mov   %rbx,%rdi
> 0x0000000000421ca4 <+20>: mov   %rax,%rsi
> 0x0000000000421ca7 <+23>: callq 0x4093b0 <g_type_check_instance_cast at plt>
> 0x0000000000421cac <+28>: mov   %rax,%rdi
> 0x0000000000421caf <+31>: mov   %rax,%rbx
> 0x0000000000421cb2 <+34>: movl  $0x2000000,(%rsp)
> 0x0000000000421cb9 <+41>: callq 0x416ab0 <g_vfs_channel_get_current_seq_nr>
> 0x0000000000421cbe <+46>: mov   %ebp,%esi
> 0x0000000000421cc0 <+48>: mov   $0x20,%ecx
> 0x0000000000421cc5 <+53>: bswap %eax
> 0x0000000000421cc7 <+55>: sar   %cl,%esi
                             ^^^^^^^^^^^^^^
> 0x0000000000421cc9 <+57>: mov   %eax,0x4(%rsp)
> 0x0000000000421ccd <+61>: mov   %ebp,%eax
> 0x0000000000421ccf <+63>: bswap %esi
> 0x0000000000421cd1 <+65>: bswap %eax
> 0x0000000000421cd3 <+67>: mov   %rbx,%rdi
> 0x0000000000421cd6 <+70>: mov   %esi,0xc(%rsp)
> 0x0000000000421cda <+74>: xor   %ecx,%ecx
> 0x0000000000421cdc <+76>: mov   %rsp,%rsi
> 0x0000000000421cdf <+79>: xor   %edx,%edx
> 0x0000000000421ce1 <+81>: mov   %eax,0x8(%rsp)
> 0x0000000000421ce5 <+85>: callq 0x416210 <g_vfs_channel_send_reply>
> 0x0000000000421cea <+90>: add   $0x18,%rsp
> 0x0000000000421cee <+94>: pop   %rbx
> 0x0000000000421cef <+95>: pop   %rbp
> 0x0000000000421cf0 <+96>: retq

where sar %cl,%esi with %ecx=$0x20 is a nop, as the "processor masks the 
upper three bits of the [%cl] count operand" [AMD64 Architecture 
Programmer’s Manual Volume 3: General Purpose and System Instructions].

Is this a known problem with (Fedora 18's) GCC?

Stephan


More information about the devel mailing list