This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/35124] New: Method _alloca is defined different by MSVCRT as by gcc.


The method _alloca assemble implementation is written that way, that it does
not return the stack pointer. I just reserves and probes the stack space.
The MSVCRT variant declares it as a synonym for POSIX alloca().
Here are three problems by the gcc variant:
1) The stack pointer isn't returned in (eax/rax).
2) If the _alloca function is called by a value not equal to the stack
boundary,
  the stack pointer (esp/rsp) gets unaligned and OS will raise an exception for
  the next instruction pushing to the stack.
3) For target x86_64-pc-mingw32 the calling convention is treated correctly.
  For ms abi, the argument gets reserved room on stack, too. Like for the 32
  bit variant.

For the x86_64-pc-mingw32 target I attached a patch for this.
Index: gcc/gcc/config/i386/cygwin.asm
===================================================================
--- gcc.orig/gcc/config/i386/cygwin.asm
+++ gcc/gcc/config/i386/cygwin.asm
@@ -72,15 +72,44 @@ Ldone:
        pushl   %eax
        ret
 #else
-/* __alloca is a normal function call, which uses %rcx as the argument.  */
+/* __alloca is a normal function call, which uses %rcx as the argument.  And
stack space
+   for the argument is saved.  */
 __alloca:
        movq    %rcx, %rax
-       /* FALLTHRU */
+       addq    $0x7, %rax
+       andq    $0xfffffffffffffff8, %rax
+       popq    %rcx            /* pop return address */
+       popq    %r10            /* Pop the reserved stack space.  */
+       movq    %rsp, %r10      /* get sp */
+       cmpq    $0x1000, %rax   /* > 4k ?*/
+       jb      Ldone_alloca
+
+Lprobe_alloca:
+       subq    $0x1000, %r10           /* yes, move pointer down 4k*/
+       orq     $0x0, (%r10)            /* probe there */
+       subq    $0x1000, %rax           /* decrement count */
+       cmpq    $0x1000, %rax
+       ja      Lprobe_alloca                   /* and do it again */
+
+Ldone_alloca:
+       subq    %rax, %r10
+       orq     $0x0, (%r10)    /* less than 4k, just peek here */
+       movq    %r10, %rax
+       subq    $0x8, %r10      /* Reserve argument stack space.  */
+       movq    %r10, %rsp      /* decrement stack */
+
+       /* Push the return value back.  Doing this instead of just
+          jumping to %rcx preserves the cached call-return stack
+          used by most modern processors.  */
+       pushq   %rcx
+       ret

 /* ___chkstk is a *special* function call, which uses %rax as the argument.
    We avoid clobbering the 4 integer argument registers, %rcx, %rdx, 
    %r8 and %r9, which leaves us with %rax, %r10, and %r11 to use.  */
 ___chkstk:
+       addq    $0x7, %rax      /* Make sure stack is on alignment of 8.  */
+       andq    $0xfffffffffffffff8, %rax
        popq    %r11            /* pop return address */
        movq    %rsp, %r10      /* get sp */
        cmpq    $0x1000, %rax   /* > 4k ?*/


-- 
           Summary: Method _alloca is defined different by MSVCRT as by gcc.
           Product: gcc
           Version: 4.3.0
            Status: UNCONFIRMED
          Severity: critical
          Priority: P3
         Component: target
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: ktietz at gcc dot gnu dot org
 GCC build triplet: *-*-mingw32
  GCC host triplet: *-*-mingw32
GCC target triplet: *-*-mingw32


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35124


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]