Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler-rt/lib/builtins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ if (NOT MSVC)
set(i386_SOURCES
${i386_SOURCES}
i386/chkstk.S
i386/chkstk2.S
)
endif()
else () # MSVC
Expand Down
27 changes: 14 additions & 13 deletions compiler-rt/lib/builtins/i386/chkstk.S
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,24 @@

#include "../assembly.h"

#ifdef __i386__

// _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments,
// then decrement %esp by %eax. Preserves all registers except %esp and flags.
// _chkstk routine
// This routine is windows specific
// http://msdn.microsoft.com/en-us/library/ms648426.aspx
//
// This function does not decrement %esp at the end.

// GCC after 4.6 generates calls to "___chkstk_ms". For other variants of
// this function, which do decrement %esp, see chkstk2.S.

#ifdef __i386__

.text
.balign 4
DEFINE_COMPILERRT_FUNCTION(_alloca) // _chkstk and _alloca are the same function
DEFINE_COMPILERRT_FUNCTION(__chkstk_ms)
push %ecx
push %eax
cmp $0x1000,%eax
lea 8(%esp),%ecx // esp before calling this routine -> ecx
lea 12(%esp),%ecx
jb 1f
2:
sub $0x1000,%ecx
Expand All @@ -27,13 +32,9 @@ DEFINE_COMPILERRT_FUNCTION(_alloca) // _chkstk and _alloca are the same function
1:
sub %eax,%ecx
test %ecx,(%ecx)

lea 4(%esp),%eax // load pointer to the return address into eax
mov %ecx,%esp // install the new top of stack pointer into esp
mov -4(%eax),%ecx // restore ecx
push (%eax) // push return address onto the stack
sub %esp,%eax // restore the original value in eax
pop %eax
pop %ecx
ret
END_COMPILERRT_FUNCTION(_alloca)
END_COMPILERRT_FUNCTION(__chkstk_ms)

#endif // __i386__
57 changes: 57 additions & 0 deletions compiler-rt/lib/builtins/i386/chkstk2.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "../assembly.h"

#ifdef __i386__

// _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments,
// then decrement %esp by %eax. Preserves all registers except %esp and flags.
// This routine is windows specific
// http://msdn.microsoft.com/en-us/library/ms648426.aspx

// Clang on i386 mingw generates calls to "_alloca" (which gets decorated to
// "__alloca").
//
// GCC before 4.6 generated calls a symbol which after decoration is named
// "___chkstk", with three leading underscores. We provide that here as well.
//
// MSVC produces calls to the symbol "__chkstk", with two leading underscores.
// That one has the same signature as this one - but we don't provide that
// symbol here. (If we'd do that, we should do it in a separate object file
// to avoid potential symbol collisions - see
// commit 248aeac1ad2cf4f583490dd1312a5b448d2bb8cc for details.)
//
// GCC after 4.6 generates calls to "___chkstk_ms", which does not decrement
// %esp - that function is defined in chkstk.S.

.text
.balign 4
DEFINE_COMPILERRT_FUNCTION(_alloca) // _chkstk and _alloca are the same function
// This gets decorated into "___chkstk"; GCC < 4.6 references this symbol.
DEFINE_COMPILERRT_FUNCTION(__chkstk)
push %ecx
cmp $0x1000,%eax
lea 8(%esp),%ecx // esp before calling this routine -> ecx
jb 1f
2:
sub $0x1000,%ecx
test %ecx,(%ecx)
sub $0x1000,%eax
cmp $0x1000,%eax
ja 2b
1:
sub %eax,%ecx
test %ecx,(%ecx)

lea 4(%esp),%eax // load pointer to the return address into eax
mov %ecx,%esp // install the new top of stack pointer into esp
mov -4(%eax),%ecx // restore ecx
push (%eax) // push return address onto the stack
sub %esp,%eax // restore the original value in eax
ret
END_COMPILERRT_FUNCTION(__chkstk)
END_COMPILERRT_FUNCTION(_alloca)

#endif // __i386__
Loading