This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/35124] New: Method _alloca is defined different by MSVCRT as by gcc.
- From: "ktietz at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 7 Feb 2008 12:33:48 -0000
- Subject: [Bug target/35124] New: Method _alloca is defined different by MSVCRT as by gcc.
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
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