http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57003
--- Comment #11 from Kirill Smirnov <kirill.k.smirnov at math dot spbu.ru> 2013-04-23 21:33:10 UTC --- I'm sorry I cannot reproduce invalid behaviour within a refined test case. Instead I can provide commented asm dump from wine. This block of code works: the returned value (rax register) is used as a pointer to destination buffer. // memcpy( buffer, DIR_Windows, len * sizeof(WCHAR) ); mov rsi,QWORD PTR [rip+0x3e80aa] # 455c30 <DIR_Windows> mov rdx,rbx mov rdi,rax call 26000 <memcpy@plt> // HERE rax points to destination buffer and rdi is corrupted by memcpy mov rcx,rax // memcpy( buffer + len, default_syswow64W, sizeof(default_syswow64W) ); mov rax,QWORD PTR [rip+0x33d95] # a1930 <default_syswow64W.21831> xor edx,edx mov QWORD PTR [rcx+rbx*1],rax mov rax,QWORD PTR [rip+0x33d90] # a1938<default_syswow64W.21831+0x8> mov QWORD PTR [rip+0x3e8071],rcx # 455c20 <DIR_SysWow64> mov QWORD PTR [rcx+rbx*1+0x8],rax This block of code does not work: the returned value (rax) is immediately overwritten and rdi (corrupted by memcpy()) is used as a destination buffer. // memcpy( buffer, DIR_Windows, len * sizeof(WCHAR) ); mov rsi,QWORD PTR [rip+0x3e296a] # 455d10 <DIR_Windows> mov rdi,rax mov rdx,rbx call 26060 <memcpy@plt> // memcpy( buffer + len, default_syswow64W, sizeof(default_syswow64W) ); // HERE rdi is corrupted my GLIBC memcpy and rax is going to be overwritten mov rax,QWORD PTR [rip+0x2e698] # a1a50 <default_syswow64W.21831> xor edx,edx mov rcx,rdi mov QWORD PTR [rdi+rbx*1],rax I'm not sure whether registers with arguments must be kept intact after function returns, but it seems the bug is found - in gcc or glibc.