https://sourceware.org/bugzilla/show_bug.cgi?id=34633

            Bug ID: 34633
           Summary: __attribute__((__ms_hook_prologue__)) on an inline C++
                    class function causes the compiled program to crash
                    when compiled for 64-bit Windows
           Product: binutils
           Version: 2.47
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: gas
          Assignee: unassigned at sourceware dot org
          Reporter: alexhenrie24 at gmail dot com
  Target Milestone: ---

Example (compile with x86_64-w64-mingw32-g++):

class Foo
{
public:
    static void __attribute__((__ms_hook_prologue__)) bar()
    {
    }
};

int main()
{
    Foo::bar();
    return 0;
}

Without ms_hook_prologue, the disassembly shows that Foo::bar is called
correctly:

0000000140001580 <main>:
   140001580:   55                      push   %rbp
   140001581:   48 89 e5                mov    %rsp,%rbp
   140001584:   48 83 ec 20             sub    $0x20,%rsp
   140001588:   e8 e3 00 00 00          call   140001670 <__main>
   14000158d:   e8 6e 15 00 00          call   140002b00 <Foo::bar()>

With ms_hook_prologue, the disassembly shows that register_frame_ctor + 0x10 is
called instead:

0000000140001580 <main>:
   140001580:   55                      push   %rbp
   140001581:   48 89 e5                mov    %rsp,%rbp
   140001584:   48 83 ec 20             sub    $0x20,%rsp
   140001588:   e8 e3 00 00 00          call   140001670 <__main>
   14000158d:   e8 ae 15 00 00          call   140002b40
<register_frame_ctor+0x10>

Defining the function outside the class declaration fixes it:

class Foo
{
public:
    static void __attribute__((__ms_hook_prologue__)) bar();
};

void Foo::bar()
{
}

int main()
{
    Foo::bar();
    return 0;
}

It now disassembles to:

00000001400015af <main>:
   1400015af:   55                      push   %rbp
   1400015b0:   48 89 e5                mov    %rsp,%rbp
   1400015b3:   48 83 ec 20             sub    $0x20,%rsp
   1400015b7:   e8 e4 00 00 00          call   1400016a0 <__main>
   1400015bc:   e8 df ff ff ff          call   1400015a0 <Foo::bar()>

And the function still has the hooking prologue (an 8-byte NOP):

00000001400015a0 <Foo::bar()>:
   1400015a0:   48 8d a4 24 00 00 00    lea    0x0(%rsp),%rsp
   1400015a7:   00

The following assembly has a similar problem:

.text
call bar
.section .text$bar,"x"
.linkonce discard
.space 32, 0xcc
.globl bar
bar:
ret

When assembled with `clang --target=x86_64-w64-windows-gnu -c`, it correctly
jumps to the start of the function:

0000000000000000 <.text>:
   0:   e8 00 00 00 00          call   5 <.text+0x5>
                        1: IMAGE_REL_AMD64_REL32        bar

When assembled with `x86_64-w64-mingw32-gcc -c`, it incorrectly jumps 0x20
bytes past the start of the function:

0000000000000000 <.text>:
   0:   e8 20 00 00 00          call   25 <bar+0x5>
                        1: IMAGE_REL_AMD64_REL32        bar

The fact that the bug can be reproduced with assembly alone suggests that it is
a bug in `as`, not GCC or MinGW.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to