X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=libgcc%2Fconfig%2Fi386%2Fmorestack.S;h=9528431f7e67d1647f6d60b25620f26a5b20843e;hp=62f7ce1c0f7f58ccff5666bdf6b2198d03ef86c8;hb=431d4e10e6f2a31b9beb0b572140495cc5e74f35;hpb=d68bb4d5f0b91523ac545d3106327a53b30eaefe diff --git a/libgcc/config/i386/morestack.S b/libgcc/config/i386/morestack.S index 62f7ce1c0f7..9528431f7e6 100644 --- a/libgcc/config/i386/morestack.S +++ b/libgcc/config/i386/morestack.S @@ -1,5 +1,5 @@ # x86/x86_64 support for -fsplit-stack. -# Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc. +# Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc. # Contributed by Ian Lance Taylor . # This file is part of GCC. @@ -83,6 +83,9 @@ #endif +# The amount of space we ask for when calling non-split-stack code. +#define NON_SPLIT_STACK 0x100000 + # This entry point is for split-stack code which calls non-split-stack # code. When the linker sees this case, it converts the call to # __morestack to call __morestack_non_split instead. We just bump the @@ -109,7 +112,7 @@ __morestack_non_split: movl %esp,%eax # Current stack, subl 8(%esp),%eax # less required stack frame size, - subl $0x4000,%eax # less space for non-split code. + subl $NON_SPLIT_STACK,%eax # less space for non-split code. cmpl %gs:0x30,%eax # See if we have enough space. jb 2f # Get more space if we need it. @@ -138,6 +141,24 @@ __morestack_non_split: je 1f # see above. addl $2,%eax 1: inc %eax + + # If the instruction that we return to is + # leal 20(%ebp),{%eax,%ecx,%edx} + # then we have been called by a varargs function that expects + # %ebp to hold a real value. That can only work if we do the + # full stack split routine. FIXME: This is fragile. + cmpb $0x8d,(%eax) + jne 3f + cmpb $0x14,2(%eax) + jne 3f + cmpb $0x45,1(%eax) + je 2f + cmpb $0x4d,1(%eax) + je 2f + cmpb $0x55,1(%eax) + je 2f + +3: movl %eax,4(%esp) # Update return address. popl %eax # Restore %eax and stack. @@ -153,7 +174,8 @@ __morestack_non_split: .cfi_adjust_cfa_offset -4 # Account for popped register. - addl $0x5000+BACKOFF,4(%esp) # Increment space we request. + # Increment space we request. + addl $NON_SPLIT_STACK+0x1000+BACKOFF,4(%esp) # Fall through into morestack. @@ -168,26 +190,41 @@ __morestack_non_split: movq %rsp,%rax # Current stack, subq %r10,%rax # less required stack frame size, - subq $0x4000,%rax # less space for non-split code. + subq $NON_SPLIT_STACK,%rax # less space for non-split code. #ifdef __LP64__ cmpq %fs:0x70,%rax # See if we have enough space. #else cmpl %fs:0x40,%eax #endif - popq %rax # Restore register. - - .cfi_adjust_cfa_offset -8 # Adjust for popped register. jb 2f # Get more space if we need it. # This breaks call/return prediction, as described above. - incq (%rsp) # Increment the return address. + incq 8(%rsp) # Increment the return address. + + # If the instruction that we return to is + # leaq 24(%rbp), %r11n + # then we have been called by a varargs function that expects + # %ebp to hold a real value. That can only work if we do the + # full stack split routine. FIXME: This is fragile. + movq 8(%rsp),%rax + cmpl $0x185d8d4c,(%rax) + je 2f + + popq %rax # Restore register. + + .cfi_adjust_cfa_offset -8 # Adjust for popped register. ret # Return to caller. 2: - addq $0x5000+BACKOFF,%r10 # Increment space we request. + popq %rax # Restore register. + + .cfi_adjust_cfa_offset -8 # Adjust for popped register. + + # Increment space we request. + addq $NON_SPLIT_STACK+0x1000+BACKOFF,%r10 # Fall through into morestack.