[Bug inline-asm/82926] New: x86_64 inline assembly with push/pop produces buggy code

2017-11-09 Thread EoD at xmw dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82926

Bug ID: 82926
   Summary: x86_64 inline assembly with push/pop produces buggy
code
   Product: gcc
   Version: unknown
   URL: https://bugs.freedesktop.org/show_bug.cgi?id=99066
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: inline-asm
  Assignee: unassigned at gcc dot gnu.org
  Reporter: EoD at xmw dot de
  Target Milestone: ---

Created attachment 42569
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42569&action=edit
C++ program showing the issue

Currently, pulseaudio fails compiling with "-O0" due to a crash in its
get_cpuid() function (see URL above for further details).

I attached a simple C++ program to show the issue.


When compiling the program with "-O0" a segfault is caused
  g++ -mx32 -O0 get_cpuid_crash.cpp


When compiling the program with either "-O1" or "-m64", the program does not
segfault:
  g++ -mx32 -O1 get_cpuid_crash.cpp
  g++ -m64 -O0 get_cpuid_crash.cpp

Also using clang does not cause a segfault
  clang++ -mx32 -O0 get_cpuid_crash.cpp


I would also like to quote tanuk from
https://bugs.freedesktop.org/show_bug.cgi?id=99066#c14
> I was asked for more information about the cpuid crash, so here we go:
> 
> This is the code that GCC generates for get_cpuid() on x32:
> 
> 0xf7b6a270   push   %rbp
> 0xf7b6a271 mov%esp,%ebp
> 0xf7b6a273 mov%edi,-0x4(%ebp)
> 0xf7b6a277 mov%rcx,%rax
> 0xf7b6a27amov%r8,%rcx
> 0xf7b6a27dmov%esi,-0x8(%ebp)
> 0xf7b6a281mov%edx,-0xc(%ebp)
> 0xf7b6a285mov%eax,-0x10(%ebp)
> 0xf7b6a289mov%ecx,-0x14(%ebp)
> 0xf7b6a28dmov-0x4(%ebp),%eax  [breakpoint]
> 0xf7b6a291push   %rbx
> 0xf7b6a292cpuid
> 0xf7b6a294mov%ebx,%esi
> 0xf7b6a296pop%rbx
> 0xf7b6a297mov-0x8(%ebp),%edi
> 0xf7b6a29bmov%eax,(%edi)  [segfault]
> 0xf7b6a29emov-0xc(%ebp),%eax
> 0xf7b6a2a2mov%esi,(%eax)
> 0xf7b6a2a5mov-0x10(%ebp),%eax
> 0xf7b6a2a9mov%ecx,(%eax)
> 0xf7b6a2acmov-0x14(%ebp),%eax
> 
> "[breakpoint]" marks the place where the execution stops if you set a
> breakpoint with "break get_cpuid". "[segfault]" marks the place where the
> crash happens.
> 
> Before the breakpoint there's the code that copies the function parameters
> to the stack as follows:
> 
> %edi is the "op" parameter. It's saved to -0x4(%ebp).
> %rcx is the "c" parameter. It's moved to %rax and from %rax to -0x10(%ebp).
> %r8 is the "d" parameter. It's moved to %rcx and from %rcx to -0x14(%ebp).
> %esi is the "a" parameter. It's saved to -0x8(%ebp).
> %edx is the "b" parameter. It's saved to -0xc(%ebp).
> 
> The stack pointer is not updated when the parameters are saved to the stack.
> Since the stack pointer points to the beginning of the frame, the push
> instruction overwrites 8 bytes from the beginning of the frame, overwriting
> the "op" and "a" parameters.
> 
> I think the push is done, because the %rbx register is special in that it
> must always have the same value when returning from a function as it had
> when the function started. The cpuid instruction modifies the %rbx register,
> so that's why we need to save and restore the %rbx register.
> 
> After the pop, this happens:
> 
> 0xf7b6a297mov-0x8(%ebp),%edi
> 
> This reads the stack from the position where the "a" parameter was saved.
> The compiler seems to assume that it has the same value that was written
> there in the beginning of the function, but the push instruction has written
> some random garbage there.
> 
> 0xf7b6a29bmov%eax,(%edi)  [segfault]
> 
> This is supposed to save the return value (well, one part of the return
> value) of the cpuid instruction to the address stored in %edi, but we just
> wrote garbage to %edi, so we end up dereferencing using garbage as the
> pointer (in my tests the value in %edi was 1).

[Bug target/82926] x86_64 inline assembly with push/pop produces buggy code

2017-11-09 Thread EoD at xmw dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82926

--- Comment #3 from EoD  ---
(In reply to Uroš Bizjak from comment #1)
> The testcase violates redzone.
> 
> Either add rsp to the list of clobbered registers, or compile with
> -fno-red-zone.
> 
> OTOH, you should just include  and use __cpuid.

(In reply to Jakub Jelinek from comment #2)
> If it is __x86_64__ only, then the push/pop is totally useless, %rbx is like
> any other reg (for __i386__ too if not pic or when using a recent gcc).
> So just asm ("cpuid" : "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d) : "0"
> (op));
> Or you could e.g. xchg %%ebx, %%esi and back for __i386__ instead of the
> push/pop, or, if for whatever weird reason you don't want to clobber %rbx
> for __x86_64__, you could e.g. subtract the red zone size from %rsp first,
> then push and after poping add back.

Thanks for your fast replies! I have forwarded the issues to the pulseaudio
team: https://bugs.freedesktop.org/show_bug.cgi?id=103656

[Bug c++/70528] [5 Regression] bogus error: constructor required before non-static data member

2017-11-09 Thread EoD at xmw dot de
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70528

EoD  changed:

   What|Removed |Added

 CC||EoD at xmw dot de

--- Comment #20 from EoD  ---
(In reply to Jakub Jelinek from comment #19)
> GCC 5 branch has been closed, should be fixed in GCC 6 and later.

Is this part of GCC 5.5.0?