public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Add support for the Win32 hook prologue (try 8)
@ 2009-10-07 19:27 Stefan Dösinger
  2009-10-09 13:22 ` [Patch ping] " Stefan Dösinger
  2009-10-09 22:38 ` Richard Henderson
  0 siblings, 2 replies; 9+ messages in thread
From: Stefan Dösinger @ 2009-10-07 19:27 UTC (permalink / raw)
  To: gcc-patches; +Cc: Paolo Bonzini

[-- Attachment #1: Type: text/plain, Size: 2722 bytes --]

Here's another version of the ms_hook_prologue patch.

I noticed that the function context isn't set, and the  
current_function_decl isn't updated by the time the attribute  
callbacks execute. Thus I use current_function_decl, not  
decl_function_context(node) to find out if the function is nested or  
not. If this is not correct(I only checked the C frontend so far),  
please suggest a better solution. The only other way I found was to  
check the nestedness during code generation, which doesn't seem right  
to me(and puts the error at the end of the function, not its  
declaration).

The development / test platform for this patch is x86_64-apple- 
darwin10.0.0 on OSX 10.6.1. I have tested older versions of this on  
x86_64-pc-linux-gnu as well, but didn't run the testsuite for this  
patch on Linux yet.

Changes from try 7:
Disallowed ms_hook_prologue on nested functions
Attached the correct patch this time

Changes from try 6:
the ms_hook_prologue attribute applies to the function, rather than  
its type. Changed the attribute lookup accordingly. However, I still  
allow the attribute for nested functions, there's no reason why this  
wouldn't work. (The case of static_chain and ms_hook_prologue can  
potentially be optimized)

Changes from try 5:
Fixed conflicts with static_chain patches, simple handling for
static_chain+ms_hook_prologue cases.
Improved changelog(hopefully correctly)

Changes from try 4:
Use SIMode instead of Pmode for the registers.

Changes from try 3:
Renamed the attribute name to ms_hook_prologue, since its not always  
generated
by msvc

Changes from try 2:
* Use dg-require-effective-target ilp32 instead of dg-options -m32 in  
the test
* More code layout fixes

Changes from the first try:
* Moved testcase to gcc.target/i386
* restructured ix86_handle_abi_attribute
* Changed HAVE_AS_IX86_SWAP handling as suggested by rth
* ix86_function_msvc_prologue returns a bool, removed fntype != NULL  
check
* fixed indentation in ix86_expand_prologue(hopefully correct now)

2009-09-23: Stefan Dösinger <stefan@codeweavers.com
       * config/i386/i386.md: Added vswapmov, a volative DIMode
          register->register mov with the swap suffix set

       * config/i386/i386.c (ix86_expand_prologue): Add a new function
       attribute ms_hook_prologue that starts functions with the same  
opcode
       sequence used in most Win32 API functions

       * config/i386/i386.c (ix86_function_ms_hook_prologue): New
       * config/i386/i386.c (ix86_handle_fndecl_attribute): New

       * gcc.target/i386/ms_hook_prologue.c: New testcase

       * configure.ac: Test for swap suffix support in as



[-- Attachment #2: ms_hook_prologue.diff --]
[-- Type: application/octet-stream, Size: 8033 bytes --]

Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 152535)
+++ gcc/doc/extend.texi	(working copy)
@@ -2679,6 +2679,14 @@ when targeting Windows.  On all other systems, the
 
 Note, This feature is currently sorried out for Windows targets trying to
 
+@item ms_hook_prologue
+@cindex @code{ms_hook_prologue} attribute
+
+On 32 bit i[34567]86-*-* targets, you can use this function attribute to make
+gcc generate the "hot-patching" function prologue used in Win32 API
+functions in Microsoft Windows XP Service Pack 2 and newer. This requires
+support for the swap suffix in the assembler. (GNU Binutils 2.19.51 or later)
+
 @item naked
 @cindex function without a prologue/epilogue code
 Use this attribute on the ARM, AVR, IP2K and SPU ports to indicate that
Index: gcc/configure.ac
===================================================================
--- gcc/configure.ac	(revision 152535)
+++ gcc/configure.ac	(working copy)
@@ -3047,6 +3047,12 @@ foo:	nop
       [AC_DEFINE(HAVE_AS_IX86_SAHF, 1,
         [Define if your assembler supports the sahf mnemonic.])])
 
+    gcc_GAS_CHECK_FEATURE([swap suffix],
+      gcc_cv_as_ix86_swap,,,
+      [movl.s %esp, %ebp],,
+      [AC_DEFINE(HAVE_AS_IX86_SWAP, 1,
+        [Define if your assembler supports the swap suffix.])])
+
     gcc_GAS_CHECK_FEATURE([different section symbol subtraction],
       gcc_cv_as_ix86_diff_sect_delta,,,
       [.section .rodata
Index: gcc/config/i386/i386.md
===================================================================
--- gcc/config/i386/i386.md	(revision 152535)
+++ gcc/config/i386/i386.md	(working copy)
@@ -241,6 +241,7 @@
    (UNSPECV_RDTSC		18)
    (UNSPECV_RDTSCP		19)
    (UNSPECV_RDPMC		20)
+   (UNSPECV_VSWAPMOV	21)
   ])
 
 ;; Constants to represent pcomtrue/pcomfalse variants
@@ -15087,6 +15088,16 @@
    (set_attr "length_immediate" "0")
    (set_attr "modrm" "0")])
 
+(define_insn "vswapmov"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (match_operand:SI 1 "register_operand" "r"))
+   (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
+  ""
+  "movl.s\t{%1, %0|%0, %1}"
+  [(set_attr "length" "2")
+   (set_attr "length_immediate" "0")
+   (set_attr "modrm" "0")])
+
 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
 ;; branch prediction penalty for the third jump in a 16-byte
 ;; block on K8.
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 152535)
+++ gcc/config/i386/i386.c	(working copy)
@@ -4774,6 +4774,19 @@ ix86_function_type_abi (const_tree fntype)
   return ix86_abi;
 }
 
+static bool
+ix86_function_ms_hook_prologue (const_tree fntype)
+{
+  if (!TARGET_64BIT)
+    {
+      if(lookup_attribute ("ms_hook_prologue", DECL_ATTRIBUTES (fntype)))
+        {
+          return true;
+        }
+    }
+  return false;
+}
+
 static enum calling_abi
 ix86_function_abi (const_tree fndecl)
 {
@@ -8295,6 +8308,7 @@ ix86_expand_prologue (void)
   bool pic_reg_used;
   struct ix86_frame frame;
   HOST_WIDE_INT allocate;
+  int gen_frame_pointer = frame_pointer_needed;
 
   ix86_finalize_stack_realign_flags ();
 
@@ -8307,6 +8321,46 @@ ix86_expand_prologue (void)
 
   ix86_compute_frame_layout (&frame);
 
+  if (ix86_function_ms_hook_prologue (current_function_decl))
+    {
+      rtx push, mov;
+
+      /* Make sure the function starts with
+         8b ff     movl.s %edi,%edi
+         55        push   %ebp
+         8b ec     movl.s %esp,%ebp
+
+         This matches the hookable function prologue in Win32 API functions in Microsoft Windows
+         XP Service Pack 2 and newer. Wine uses this to enable Windows apps to hook the Win32 API
+         functions provided by Wine */
+      insn = emit_insn (gen_vswapmov (gen_rtx_REG (SImode, DI_REG), gen_rtx_REG (SImode, DI_REG)));
+      push = emit_insn (gen_push (hard_frame_pointer_rtx));
+      mov = emit_insn (gen_vswapmov (hard_frame_pointer_rtx, stack_pointer_rtx));
+
+      if (frame_pointer_needed && !(crtl->drap_reg && crtl->stack_realign_needed))
+        {
+          /* The push %ebp and movl.s %esp, %ebp already set up the frame pointer. No need to do
+             this again. */
+          gen_frame_pointer = 0;
+          RTX_FRAME_RELATED_P (push) = 1;
+          RTX_FRAME_RELATED_P (mov) = 1;
+          if (ix86_cfa_state->reg == stack_pointer_rtx)
+            {
+              ix86_cfa_state->reg = hard_frame_pointer_rtx;
+            }
+        }
+      else
+        {
+          /* If the frame pointer is not needed, pop %ebp again. This could be optimized for cases where
+             ebp needs to be backed up for some other reason.
+
+             If stack realignment is needed, pop the base pointer again, align the stack, and later
+             regenerate the frame pointer setup. The frame pointer generated by the hook prologue
+             is not aligned, so it can't be used */
+          insn = emit_insn ((*ix86_gen_pop1) (hard_frame_pointer_rtx));
+        }
+    }
+
   /* The first insn of a function that accepts its static chain on the
      stack is to push the register that would be filled in by a direct
      call.  This insn will be skipped by the trampoline.  */
@@ -8378,7 +8432,7 @@ ix86_expand_prologue (void)
   /* Note: AT&T enter does NOT have reversed args.  Enter is probably
      slower on all targets.  Also sdb doesn't like it.  */
 
-  if (frame_pointer_needed)
+  if (gen_frame_pointer)
     {
       insn = emit_insn (gen_push (hard_frame_pointer_rtx));
       RTX_FRAME_RELATED_P (insn) = 1;
@@ -26458,6 +26512,40 @@ ix86_handle_struct_attribute (tree *node, tree nam
   return NULL_TREE;
 }
 
+#include <signal.h>
+
+static tree
+ix86_handle_fndecl_attribute (tree *node, tree name,
+                              tree args ATTRIBUTE_UNUSED,
+                              int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+{
+  if (TREE_CODE (*node) != FUNCTION_DECL)
+    {
+      warning (OPT_Wattributes, "%qE attribute only applies to functions",
+               name);
+      *no_add_attrs = true;
+      return NULL_TREE;
+    }
+
+  if (TARGET_64BIT)
+    {
+      warning (OPT_Wattributes, "%qE attribute only available for 32-bit",
+               name);
+      return NULL_TREE;
+    }
+
+  if(current_function_decl != NULL_TREE)
+    {
+      error("ms_hook_prologue is not compatible with nested functions\n");
+    }
+
+#ifndef HAVE_AS_IX86_SWAP
+  sorry ("ms_hook_prologue attribute needs assembler swap suffix support");
+#endif
+
+    return NULL_TREE;
+}
+
 static bool
 ix86_ms_bitfield_layout_p (const_tree record_type)
 {
@@ -29500,6 +29588,7 @@ static const struct attribute_spec ix86_attribute_
   /* ms_abi and sysv_abi calling convention function attributes.  */
   { "ms_abi", 0, 0, false, true, true, ix86_handle_abi_attribute },
   { "sysv_abi", 0, 0, false, true, true, ix86_handle_abi_attribute },
+  { "ms_hook_prologue", 0, 0, true, false, false, ix86_handle_fndecl_attribute },
   /* End element.  */
   { NULL,        0, 0, false, false, false, NULL }
 };
--- /dev/null	2009-10-07 20:53:54.000000000 +0200
+++ gcc/testsuite/gcc.target/i386/ms_hook_prologue.c	2009-09-23 20:25:31.000000000 +0200
@@ -0,0 +1,29 @@
+/* Test that the ms_hook_prologue attribute generates the correct code.  */
+
+/* { dg-do run } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+
+int __attribute__ ((__ms_hook_prologue__)) foo ()
+{
+  unsigned char *ptr = (unsigned char *) foo;
+
+  /* The NOP mov must not be optimized away by optimizations.
+     The push %ebp, mov %esp, %ebp must not be removed by
+     -fomit-frame-pointer */
+
+  /* movl.s %edi, %edi */
+  if(*ptr++ != 0x8b) return 1;
+  if(*ptr++ != 0xff) return 1;
+  /* push %ebp */
+  if(*ptr++ != 0x55) return 1;
+  /* movl.s %esp, %ebp */
+  if(*ptr++ != 0x8b) return 1;
+  if(*ptr++ != 0xec) return 1;
+  return 0;
+}
+
+int main ()
+{
+  return foo();
+}

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Patch ping] Add support for the Win32 hook prologue (try 8)
  2009-10-07 19:27 Add support for the Win32 hook prologue (try 8) Stefan Dösinger
@ 2009-10-09 13:22 ` Stefan Dösinger
  2009-10-09 13:49   ` Paolo Bonzini
  2009-10-09 14:53   ` Dave Korn
  2009-10-09 22:38 ` Richard Henderson
  1 sibling, 2 replies; 9+ messages in thread
From: Stefan Dösinger @ 2009-10-09 13:22 UTC (permalink / raw)
  To: gcc-patches

Hi,
On Wednesday I sent another version of my Windows hooking prologue  
patch, but so far the patch hasn't been applied, nor have I received  
any comments.

Is this patch still under review? Are there still further suggestions  
for improvement?

Here's a link to the archives: http://gcc.gnu.org/ml/gcc-patches/2009-10/msg00488.html

Thank you in advance,
Stefan

PS: I don't know the usual application delays in the gcc project, I am  
mostly used to how things work in Wine. So if I am too impatient with  
pinging a patch after two days I apologize.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Patch ping] Add support for the Win32 hook prologue (try 8)
  2009-10-09 13:22 ` [Patch ping] " Stefan Dösinger
@ 2009-10-09 13:49   ` Paolo Bonzini
  2009-10-09 14:53   ` Dave Korn
  1 sibling, 0 replies; 9+ messages in thread
From: Paolo Bonzini @ 2009-10-09 13:49 UTC (permalink / raw)
  To: Stefan Dösinger; +Cc: gcc-patches


> PS: I don't know the usual application delays in the gcc project, I am 
> mostly used to how things work in Wine. So if I am too impatient with 
> pinging a patch after two days I apologize.

It's quite different from Wine indeed.  Usually we ping after 1-2 weeks. 
  I understand this is awful for a random contributor; often people 
develop more patches at the same time to ease pipelining.  On the other 
hand it is in general easier to get a patch in, as there is no BDFL and 
it's relatively rare to have disagreements on the fundamental how's and 
why's of a patch (these are more common in Wine).

Thanks for your persistence.  You chose quite a complicated patch for 
your first one. :-) There has been quite some discussion on it, and if 
there is no response next week I'll go ahead and apply it for you.

I would still like to do a quick sanity check on the patch, so can you 
send me offlist a diff from v4 to v8?

Paolo

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Patch ping] Add support for the Win32 hook prologue (try 8)
  2009-10-09 13:22 ` [Patch ping] " Stefan Dösinger
  2009-10-09 13:49   ` Paolo Bonzini
@ 2009-10-09 14:53   ` Dave Korn
  1 sibling, 0 replies; 9+ messages in thread
From: Dave Korn @ 2009-10-09 14:53 UTC (permalink / raw)
  To: Stefan Dösinger; +Cc: gcc-patches

Stefan Dösinger wrote:
> Hi,
> On Wednesday I sent another version of my Windows hooking prologue
> patch, but so far the patch hasn't been applied, nor have I received any
> comments.

  "Thank you" :-)

    cheers,
      DaveK

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Add support for the Win32 hook prologue (try 8)
  2009-10-07 19:27 Add support for the Win32 hook prologue (try 8) Stefan Dösinger
  2009-10-09 13:22 ` [Patch ping] " Stefan Dösinger
@ 2009-10-09 22:38 ` Richard Henderson
  2009-10-11 21:50   ` [PATCH] Add support for the Win32 hook prologue (try 9) Stefan Dösinger
  1 sibling, 1 reply; 9+ messages in thread
From: Richard Henderson @ 2009-10-09 22:38 UTC (permalink / raw)
  To: Stefan Dösinger; +Cc: gcc-patches, Paolo Bonzini

On 10/07/2009 12:08 PM, Stefan Dösinger wrote:
> I noticed that the function context isn't set, and the
> current_function_decl isn't updated by the time the attribute callbacks
> execute. Thus I use current_function_decl, not
> decl_function_context(node) to find out if the function is nested or
> not. If this is not correct(I only checked the C frontend so far),
> please suggest a better solution. The only other way I found was to
> check the nestedness during code generation, which doesn't seem right to
> me(and puts the error at the end of the function, not its declaration).

Ah, I see what you mean here.  Yes, the decl context hasn't been set up 
yet.  However, testing for current_function_decl isn't correct either. 
I think the only thing you'll be able to do is an error during code 
generation.  You can put the error message at the correct line by using 
DECL_SOURCE_LOCATION and the error_at function.

The patch is ok with that fix.


r~

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH] Add support for the Win32 hook prologue (try 9)
  2009-10-09 22:38 ` Richard Henderson
@ 2009-10-11 21:50   ` Stefan Dösinger
  2009-10-12 16:39     ` Richard Henderson
  0 siblings, 1 reply; 9+ messages in thread
From: Stefan Dösinger @ 2009-10-11 21:50 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2627 bytes --]

A number of Windows programs(Steam, Xfire and others) try to hook  
Win32 API
functions by replacing the first 5 bytes in the function. This causes
problems for Wine because the functions generated by gcc usually start  
with a
different opcode sequence than the one expected by these applications.

Starting with Windows XP SP2, Microsoft starts Win32 functions with this
sequence:


8b ff		movl.s %edi, %edi
55		push %ebp
8b ec	movl.s %esp, %ebp


The attached patch implements a function attribute that allows Wine to  
request
the same 5 bytes at the beginning of a function.

Changes from try 8:
moved the nested function check to ix86_function_ms_hook_prologue,  
check the decl context rather than current_function_decl.

Changes from try 7:
Disallowed ms_hook_prologue on nested functions
Attached the correct patch this time

Changes from try 6:
the ms_hook_prologue attribute applies to the function, rather than  
its type. Changed the attribute lookup accordingly. However, I still  
allow the attribute for nested functions, there's no reason why this  
wouldn't work. (The case of static_chain and ms_hook_prologue can  
potentially be optimized)

Changes from try 5:
Fixed conflicts with static_chain patches, simple handling for
static_chain+ms_hook_prologue cases.
Improved changelog(hopefully correctly)

Changes from try 4:
Use SIMode instead of Pmode for the registers.

Changes from try 3:
Renamed the attribute name to ms_hook_prologue, since its not always  
generated
by msvc

Changes from try 2:
* Use dg-require-effective-target ilp32 instead of dg-options -m32 in  
the test
* More code layout fixes

Changes from the first try:
* Moved testcase to gcc.target/i386
* restructured ix86_handle_abi_attribute
* Changed HAVE_AS_IX86_SWAP handling as suggested by rth
* ix86_function_msvc_prologue returns a bool, removed fntype != NULL  
check
* fixed indentation in ix86_expand_prologue(hopefully correct now)

2009-09-23: Stefan Dösinger <stefan@codeweavers.com
      * config/i386/i386.md: Added vswapmov, a volative DIMode
         register->register mov with the swap suffix set

      * config/i386/i386.c (ix86_expand_prologue): Add a new function
      attribute ms_hook_prologue that starts functions with the same  
opcode
      sequence used in most Win32 API functions

      * config/i386/i386.c (ix86_function_ms_hook_prologue): New
      * config/i386/i386.c (ix86_handle_fndecl_attribute): New

      * gcc.target/i386/ms_hook_prologue.c: New testcase

      * configure.ac: Test for swap suffix support in as


[-- Attachment #2: ms_hook_prologue9.diff --]
[-- Type: application/octet-stream, Size: 8119 bytes --]

Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 152649)
+++ gcc/doc/extend.texi	(working copy)
@@ -2679,6 +2679,14 @@ when targeting Windows.  On all other systems, the
 
 Note, This feature is currently sorried out for Windows targets trying to
 
+@item ms_hook_prologue
+@cindex @code{ms_hook_prologue} attribute
+
+On 32 bit i[34567]86-*-* targets, you can use this function attribute to make
+gcc generate the "hot-patching" function prologue used in Win32 API
+functions in Microsoft Windows XP Service Pack 2 and newer. This requires
+support for the swap suffix in the assembler. (GNU Binutils 2.19.51 or later)
+
 @item naked
 @cindex function without a prologue/epilogue code
 Use this attribute on the ARM, AVR, IP2K and SPU ports to indicate that
Index: gcc/configure.ac
===================================================================
--- gcc/configure.ac	(revision 152649)
+++ gcc/configure.ac	(working copy)
@@ -3047,6 +3047,12 @@ foo:	nop
       [AC_DEFINE(HAVE_AS_IX86_SAHF, 1,
         [Define if your assembler supports the sahf mnemonic.])])
 
+    gcc_GAS_CHECK_FEATURE([swap suffix],
+      gcc_cv_as_ix86_swap,,,
+      [movl.s %esp, %ebp],,
+      [AC_DEFINE(HAVE_AS_IX86_SWAP, 1,
+        [Define if your assembler supports the swap suffix.])])
+
     gcc_GAS_CHECK_FEATURE([different section symbol subtraction],
       gcc_cv_as_ix86_diff_sect_delta,,,
       [.section .rodata
Index: gcc/config/i386/i386.md
===================================================================
--- gcc/config/i386/i386.md	(revision 152649)
+++ gcc/config/i386/i386.md	(working copy)
@@ -241,6 +241,7 @@
    (UNSPECV_RDTSC		18)
    (UNSPECV_RDTSCP		19)
    (UNSPECV_RDPMC		20)
+   (UNSPECV_VSWAPMOV	21)
   ])
 
 ;; Constants to represent pcomtrue/pcomfalse variants
@@ -14888,6 +14889,16 @@
    (set_attr "length_immediate" "0")
    (set_attr "modrm" "0")])
 
+(define_insn "vswapmov"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (match_operand:SI 1 "register_operand" "r"))
+   (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
+  ""
+  "movl.s\t{%1, %0|%0, %1}"
+  [(set_attr "length" "2")
+   (set_attr "length_immediate" "0")
+   (set_attr "modrm" "0")])
+
 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
 ;; branch prediction penalty for the third jump in a 16-byte
 ;; block on K8.
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 152649)
+++ gcc/config/i386/i386.c	(working copy)
@@ -4774,6 +4774,25 @@ ix86_function_type_abi (const_tree fntype)
   return ix86_abi;
 }
 
+static bool
+ix86_function_ms_hook_prologue (const_tree fntype)
+{
+  if (!TARGET_64BIT)
+    {
+      if (lookup_attribute ("ms_hook_prologue", DECL_ATTRIBUTES (fntype)))
+        {
+          if (decl_function_context (fntype) != NULL_TREE)
+          {
+            error_at (DECL_SOURCE_LOCATION (fntype),
+                "ms_hook_prologue is not compatible with nested function");
+          }
+
+          return true;
+        }
+    }
+  return false;
+}
+
 static enum calling_abi
 ix86_function_abi (const_tree fndecl)
 {
@@ -8295,6 +8314,7 @@ ix86_expand_prologue (void)
   bool pic_reg_used;
   struct ix86_frame frame;
   HOST_WIDE_INT allocate;
+  int gen_frame_pointer = frame_pointer_needed;
 
   ix86_finalize_stack_realign_flags ();
 
@@ -8307,6 +8327,46 @@ ix86_expand_prologue (void)
 
   ix86_compute_frame_layout (&frame);
 
+  if (ix86_function_ms_hook_prologue (current_function_decl))
+    {
+      rtx push, mov;
+
+      /* Make sure the function starts with
+         8b ff     movl.s %edi,%edi
+         55        push   %ebp
+         8b ec     movl.s %esp,%ebp
+
+         This matches the hookable function prologue in Win32 API functions in Microsoft Windows
+         XP Service Pack 2 and newer. Wine uses this to enable Windows apps to hook the Win32 API
+         functions provided by Wine */
+      insn = emit_insn (gen_vswapmov (gen_rtx_REG (SImode, DI_REG), gen_rtx_REG (SImode, DI_REG)));
+      push = emit_insn (gen_push (hard_frame_pointer_rtx));
+      mov = emit_insn (gen_vswapmov (hard_frame_pointer_rtx, stack_pointer_rtx));
+
+      if (frame_pointer_needed && !(crtl->drap_reg && crtl->stack_realign_needed))
+        {
+          /* The push %ebp and movl.s %esp, %ebp already set up the frame pointer. No need to do
+             this again. */
+          gen_frame_pointer = 0;
+          RTX_FRAME_RELATED_P (push) = 1;
+          RTX_FRAME_RELATED_P (mov) = 1;
+          if (ix86_cfa_state->reg == stack_pointer_rtx)
+            {
+              ix86_cfa_state->reg = hard_frame_pointer_rtx;
+            }
+        }
+      else
+        {
+          /* If the frame pointer is not needed, pop %ebp again. This could be optimized for cases where
+             ebp needs to be backed up for some other reason.
+
+             If stack realignment is needed, pop the base pointer again, align the stack, and later
+             regenerate the frame pointer setup. The frame pointer generated by the hook prologue
+             is not aligned, so it can't be used */
+          insn = emit_insn ((*ix86_gen_pop1) (hard_frame_pointer_rtx));
+        }
+    }
+
   /* The first insn of a function that accepts its static chain on the
      stack is to push the register that would be filled in by a direct
      call.  This insn will be skipped by the trampoline.  */
@@ -8378,7 +8438,7 @@ ix86_expand_prologue (void)
   /* Note: AT&T enter does NOT have reversed args.  Enter is probably
      slower on all targets.  Also sdb doesn't like it.  */
 
-  if (frame_pointer_needed)
+  if (gen_frame_pointer)
     {
       insn = emit_insn (gen_push (hard_frame_pointer_rtx));
       RTX_FRAME_RELATED_P (insn) = 1;
@@ -26469,6 +26529,35 @@ ix86_handle_struct_attribute (tree *node, tree nam
   return NULL_TREE;
 }
 
+#include <signal.h>
+
+static tree
+ix86_handle_fndecl_attribute (tree *node, tree name,
+                              tree args ATTRIBUTE_UNUSED,
+                              int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+{
+  if (TREE_CODE (*node) != FUNCTION_DECL)
+    {
+      warning (OPT_Wattributes, "%qE attribute only applies to functions",
+               name);
+      *no_add_attrs = true;
+      return NULL_TREE;
+    }
+
+  if (TARGET_64BIT)
+    {
+      warning (OPT_Wattributes, "%qE attribute only available for 32-bit",
+               name);
+      return NULL_TREE;
+    }
+
+#ifndef HAVE_AS_IX86_SWAP
+  sorry ("ms_hook_prologue attribute needs assembler swap suffix support");
+#endif
+
+    return NULL_TREE;
+}
+
 static bool
 ix86_ms_bitfield_layout_p (const_tree record_type)
 {
@@ -29511,6 +29600,7 @@ static const struct attribute_spec ix86_attribute_
   /* ms_abi and sysv_abi calling convention function attributes.  */
   { "ms_abi", 0, 0, false, true, true, ix86_handle_abi_attribute },
   { "sysv_abi", 0, 0, false, true, true, ix86_handle_abi_attribute },
+  { "ms_hook_prologue", 0, 0, true, false, false, ix86_handle_fndecl_attribute },
   /* End element.  */
   { NULL,        0, 0, false, false, false, NULL }
 };
--- /dev/null	2009-10-11 23:42:17.000000000 +0200
+++ gcc/testsuite/gcc.target/i386/ms_hook_prologue.c	2009-09-23 20:25:31.000000000 +0200
@@ -0,0 +1,29 @@
+/* Test that the ms_hook_prologue attribute generates the correct code.  */
+
+/* { dg-do run } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -fomit-frame-pointer" } */
+
+int __attribute__ ((__ms_hook_prologue__)) foo ()
+{
+  unsigned char *ptr = (unsigned char *) foo;
+
+  /* The NOP mov must not be optimized away by optimizations.
+     The push %ebp, mov %esp, %ebp must not be removed by
+     -fomit-frame-pointer */
+
+  /* movl.s %edi, %edi */
+  if(*ptr++ != 0x8b) return 1;
+  if(*ptr++ != 0xff) return 1;
+  /* push %ebp */
+  if(*ptr++ != 0x55) return 1;
+  /* movl.s %esp, %ebp */
+  if(*ptr++ != 0x8b) return 1;
+  if(*ptr++ != 0xec) return 1;
+  return 0;
+}
+
+int main ()
+{
+  return foo();
+}

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Add support for the Win32 hook prologue (try 9)
  2009-10-11 21:50   ` [PATCH] Add support for the Win32 hook prologue (try 9) Stefan Dösinger
@ 2009-10-12 16:39     ` Richard Henderson
  2009-10-12 21:12       ` Stefan Dösinger
  0 siblings, 1 reply; 9+ messages in thread
From: Richard Henderson @ 2009-10-12 16:39 UTC (permalink / raw)
  To: Stefan Dösinger; +Cc: gcc-patches

Committed r152670.

r~

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Add support for the Win32 hook prologue (try 9)
  2009-10-12 16:39     ` Richard Henderson
@ 2009-10-12 21:12       ` Stefan Dösinger
  2009-10-12 21:38         ` Richard Henderson
  0 siblings, 1 reply; 9+ messages in thread
From: Stefan Dösinger @ 2009-10-12 21:12 UTC (permalink / raw)
  To: Richard Henderson; +Cc: gcc-patches

Am 12.10.2009 um 18:37 schrieb Richard Henderson:

> Committed r152670.

Thanks!

Unfortunately, something went wrong with the configure update. I'd  
expect gcc/config.in to be regenerated like gcc/configure, but this is  
apparently not the case. And since config.in wasn't updated, the  
configure regeneration didn't pick up the change either. Do you want  
me to send a patch updating gcc/config.in? (Ie, just run autoheader,  
then send the gcc/config.in diff)?

macbookpro:gcc stefan$ svn status configure.ac configure config.in
macbookpro:gcc stefan$ autoheader
macbookpro:gcc stefan$ autoconf

macbookpro:gcc stefan$
macbookpro:gcc stefan$ svn diff config.in configure
Index: config.in
===================================================================
--- config.in	(revision 152686)
+++ config.in	(working copy)
@@ -315,6 +315,12 @@
  #endif


+/* Define if your assembler supports the swap suffix. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_IX86_SWAP
+#endif
+
+
  /* Define if your assembler supports the lituse_jsrdirect  
relocation. */
  #ifndef USED_FOR_TARGET
  #undef HAVE_AS_JSRDIRECT_RELOCS
Index: configure
===================================================================
--- configure	(revision 152686)
+++ configure	(working copy)
@@ -22917,6 +22917,37 @@

  fi

+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for  
swap suffix" >&5
+$as_echo_n "checking assembler for swap suffix... " >&6; }
+if test "${gcc_cv_as_ix86_swap+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcc_cv_as_ix86_swap=no
+  if test x$gcc_cv_as != x; then
+    echo 'movl.s %esp, %ebp' > conftest.s
+    if { ac_try='$gcc_cv_as  -o conftest.o conftest.s >&5'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+    then
+	gcc_cv_as_ix86_swap=yes
+    else
+      echo "configure: failed program was" >&5
+      cat conftest.s >&5
+    fi
+    rm -f conftest.o conftest.s
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result:  
$gcc_cv_as_ix86_swap" >&5
+$as_echo "$gcc_cv_as_ix86_swap" >&6; }
+if test $gcc_cv_as_ix86_swap = yes; then
+
+$as_echo "#define HAVE_AS_IX86_SWAP 1" >>confdefs.h
+
+fi
+
      { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for  
different section symbol subtraction" >&5
  $as_echo_n "checking assembler for different section symbol  
subtraction... " >&6; }
  if test "${gcc_cv_as_ix86_diff_sect_delta+set}" = set; then :


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Add support for the Win32 hook prologue (try 9)
  2009-10-12 21:12       ` Stefan Dösinger
@ 2009-10-12 21:38         ` Richard Henderson
  0 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2009-10-12 21:38 UTC (permalink / raw)
  To: Stefan Dösinger; +Cc: gcc-patches

On 10/12/2009 02:09 PM, Stefan Dösinger wrote:
> Unfortunately, something went wrong with the configure update.

Indeed, sorry about that.  I've regenerated the files and committed.


r~

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2009-10-12 21:30 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-07 19:27 Add support for the Win32 hook prologue (try 8) Stefan Dösinger
2009-10-09 13:22 ` [Patch ping] " Stefan Dösinger
2009-10-09 13:49   ` Paolo Bonzini
2009-10-09 14:53   ` Dave Korn
2009-10-09 22:38 ` Richard Henderson
2009-10-11 21:50   ` [PATCH] Add support for the Win32 hook prologue (try 9) Stefan Dösinger
2009-10-12 16:39     ` Richard Henderson
2009-10-12 21:12       ` Stefan Dösinger
2009-10-12 21:38         ` Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).