Home | History | Annotate | Line # | Download | only in i386
morestack.S revision 1.10
      1 # x86/x86_64 support for -fsplit-stack.
      2 # Copyright (C) 2009-2022 Free Software Foundation, Inc.
      3 # Contributed by Ian Lance Taylor <iant@google.com>.
      4 
      5 # This file is part of GCC.
      6 
      7 # GCC is free software; you can redistribute it and/or modify it under
      8 # the terms of the GNU General Public License as published by the Free
      9 # Software Foundation; either version 3, or (at your option) any later
     10 # version.
     11 
     12 # GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15 # for more details.
     16 
     17 # Under Section 7 of GPL version 3, you are granted additional
     18 # permissions described in the GCC Runtime Library Exception, version
     19 # 3.1, as published by the Free Software Foundation.
     20 
     21 # You should have received a copy of the GNU General Public License and
     22 # a copy of the GCC Runtime Library Exception along with this program;
     23 # see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24 # <http://www.gnu.org/licenses/>.
     25 
     26 #include "auto-host.h"
     27 
     28 # Support for allocating more stack space when using -fsplit-stack.
     29 # When a function discovers that it needs more stack space, it will
     30 # call __morestack with the size of the stack frame and the size of
     31 # the parameters to copy from the old stack frame to the new one.
     32 # The __morestack function preserves the parameter registers and
     33 # calls __generic_morestack to actually allocate the stack space.
     34 
     35 # When this is called stack space is very low, but we ensure that
     36 # there is enough space to push the parameter registers and to call
     37 # __generic_morestack.
     38 
     39 # When calling __generic_morestack, FRAME_SIZE points to the size of
     40 # the desired frame when the function is called, and the function
     41 # sets it to the size of the allocated stack.  OLD_STACK points to
     42 # the parameters on the old stack and PARAM_SIZE is the number of
     43 # bytes of parameters to copy to the new stack.  These are the
     44 # parameters of the function that called __morestack.  The
     45 # __generic_morestack function returns the new stack pointer,
     46 # pointing to the address of the first copied parameter.  The return
     47 # value minus the returned *FRAME_SIZE will be the first address on
     48 # the stack which we should not use.
     49 
     50 # void *__generic_morestack (size_t *frame_size, void *old_stack,
     51 #			     size_t param_size);
     52 
     53 # The __morestack routine has to arrange for the caller to return to a
     54 # stub on the new stack.  The stub is responsible for restoring the
     55 # old stack pointer and returning to the caller's caller.  This calls
     56 # __generic_releasestack to retrieve the old stack pointer and release
     57 # the newly allocated stack.
     58 
     59 # void *__generic_releasestack (size_t *available);
     60 
     61 # We do a little dance so that the processor's call/return return
     62 # address prediction works out.  The compiler arranges for the caller
     63 # to look like this:
     64 #   call __generic_morestack
     65 #   ret
     66 #  L:
     67 #   // carry on with function
     68 # After we allocate more stack, we call L, which is in our caller.
     69 # When that returns (to the predicted instruction), we release the
     70 # stack segment and reset the stack pointer.  We then return to the
     71 # predicted instruction, namely the ret instruction immediately after
     72 # the call to __generic_morestack.  That then returns to the caller of
     73 # the original caller.
     74 
     75 
     76 # The amount of extra space we ask for.  In general this has to be
     77 # enough for the dynamic loader to find a symbol and for a signal
     78 # handler to run.
     79 
     80 #ifndef __x86_64__
     81 #define BACKOFF (1024)
     82 #else
     83 #define BACKOFF (3584)
     84 #endif
     85 
     86 
     87 # The amount of space we ask for when calling non-split-stack code.
     88 #define NON_SPLIT_STACK 0x100000
     89 
     90 # This entry point is for split-stack code which calls non-split-stack
     91 # code.  When the linker sees this case, it converts the call to
     92 # __morestack to call __morestack_non_split instead.  We just bump the
     93 # requested stack space by 16K.
     94 
     95 #include <cet.h>
     96 
     97 	.global __morestack_non_split
     98 	.hidden	__morestack_non_split
     99 
    100 #ifdef __ELF__
    101        .type	__morestack_non_split,@function
    102 #endif
    103 
    104 __morestack_non_split:
    105 	.cfi_startproc
    106 
    107 #ifndef __x86_64__
    108 
    109 	# See below for an extended explanation of this.
    110 	.cfi_def_cfa %esp,16
    111 
    112 	pushl	%eax			# Save %eax in case it is a parameter.
    113 
    114 	.cfi_adjust_cfa_offset 4	# Account for pushed register.
    115 
    116 	movl	%esp,%eax		# Current stack,
    117 	subl	8(%esp),%eax		# less required stack frame size,
    118 	subl	$NON_SPLIT_STACK,%eax	# less space for non-split code.
    119 	cmpl	%gs:0x30,%eax		# See if we have enough space.
    120 	jb	2f			# Get more space if we need it.
    121 
    122 	# Here the stack is
    123 	#	%esp + 20:	stack pointer after two returns
    124 	#	%esp + 16:	return address of morestack caller's caller
    125 	#	%esp + 12:	size of parameters
    126 	#	%esp + 8:	new stack frame size
    127 	#	%esp + 4:	return address of this function
    128 	#	%esp:		saved %eax
    129 	#
    130 	# Since we aren't doing a full split stack, we don't need to
    131 	# do anything when our caller returns.  So we return to our
    132 	# caller rather than calling it, and let it return as usual.
    133 	# To make that work we adjust the return address.
    134 
    135 	# This breaks call/return address prediction for the call to
    136 	# this function.  I can't figure out a way to make it work
    137 	# short of copying the parameters down the stack, which will
    138 	# probably take more clock cycles than we will lose breaking
    139 	# call/return address prediction.  We will only break
    140 	# prediction for this call, not for our caller.
    141 
    142 	movl	4(%esp),%eax		# Increment the return address
    143 	cmpb	$0xc3,(%eax)		# to skip the ret instruction;
    144 	je	1f			# see above.
    145 	addl	$2,%eax
    146 1:	inc	%eax
    147 
    148 	# If the instruction that we return to is
    149 	#   leal  20(%ebp),{%eax,%ecx,%edx}
    150 	# then we have been called by a varargs function that expects
    151 	# %ebp to hold a real value.  That can only work if we do the
    152 	# full stack split routine.  FIXME: This is fragile.
    153 	cmpb	$0x8d,(%eax)
    154 	jne	3f
    155 	cmpb	$0x14,2(%eax)
    156 	jne	3f
    157 	cmpb	$0x45,1(%eax)
    158 	je	2f
    159 	cmpb	$0x4d,1(%eax)
    160 	je	2f
    161 	cmpb	$0x55,1(%eax)
    162 	je	2f
    163 
    164 3:
    165 	movl	%eax,4(%esp)		# Update return address.
    166 
    167 	popl	%eax			# Restore %eax and stack.
    168 
    169 	.cfi_adjust_cfa_offset -4	# Account for popped register.
    170 
    171 	ret	$8			# Return to caller, popping args.
    172 
    173 2:
    174 	.cfi_adjust_cfa_offset 4	# Back to where we were.
    175 
    176 	popl	%eax			# Restore %eax and stack.
    177 
    178 	.cfi_adjust_cfa_offset -4	# Account for popped register.
    179 
    180 	# Increment space we request.
    181 	addl	$NON_SPLIT_STACK+0x1000+BACKOFF,4(%esp)
    182 
    183 	# Fall through into morestack.
    184 
    185 #else
    186 
    187 	# See below for an extended explanation of this.
    188 	.cfi_def_cfa %rsp,16
    189 
    190 	pushq	%rax			# Save %rax in case caller is using
    191 					# it to preserve original %r10.
    192 	.cfi_adjust_cfa_offset 8	# Adjust for pushed register.
    193 
    194 	movq	%rsp,%rax		# Current stack,
    195 	subq	%r10,%rax		# less required stack frame size,
    196 	subq	$NON_SPLIT_STACK,%rax	# less space for non-split code.
    197 
    198 #ifdef __LP64__
    199 	cmpq	%fs:0x70,%rax		# See if we have enough space.
    200 #else
    201 	cmpl	%fs:0x40,%eax
    202 #endif
    203 
    204 	jb	2f			# Get more space if we need it.
    205 
    206 	# If the instruction that we return to is
    207 	#   leaq  24(%rbp), %r11n
    208 	# then we have been called by a varargs function that expects
    209 	# %ebp to hold a real value.  That can only work if we do the
    210 	# full stack split routine.  FIXME: This is fragile.
    211 	movq	8(%rsp),%rax
    212 	incq	%rax			# Skip ret instruction in caller.
    213 	cmpl	$0x185d8d4c,(%rax)
    214 	je	2f
    215 
    216 	# This breaks call/return prediction, as described above.
    217 	incq	8(%rsp)			# Increment the return address.
    218 
    219 	popq	%rax			# Restore register.
    220 
    221 	.cfi_adjust_cfa_offset -8	# Adjust for popped register.
    222 
    223 	ret				# Return to caller.
    224 
    225 2:
    226 	popq	%rax			# Restore register.
    227 
    228 	.cfi_adjust_cfa_offset -8	# Adjust for popped register.
    229 
    230 	# Increment space we request.
    231 	addq	$NON_SPLIT_STACK+0x1000+BACKOFF,%r10
    232 
    233 	# Fall through into morestack.
    234 
    235 #endif
    236 
    237 	.cfi_endproc
    238 #ifdef __ELF__
    239 	.size	__morestack_non_split, . - __morestack_non_split
    240 #endif
    241 
    242 # __morestack_non_split falls through into __morestack.
    243 
    244 
    245 # The __morestack function.
    246 
    247 	.global	__morestack
    248 	.hidden	__morestack
    249 
    250 #ifdef __ELF__
    251 	.type	__morestack,@function
    252 #endif
    253 
    254 __morestack:
    255 .LFB1:
    256 	.cfi_startproc
    257 
    258 
    259 #ifndef __x86_64__
    260 
    261 
    262 # The 32-bit __morestack function.
    263 
    264 	# We use a cleanup to restore the stack guard if an exception
    265 	# is thrown through this code.
    266 #ifndef __PIC__
    267 	.cfi_personality 0,__gcc_personality_v0
    268 	.cfi_lsda 0,.LLSDA1
    269 #else
    270 	.cfi_personality 0x9b,DW.ref.__gcc_personality_v0
    271 	.cfi_lsda 0x1b,.LLSDA1
    272 #endif
    273 
    274 	# We return below with a ret $8.  We will return to a single
    275 	# return instruction, which will return to the caller of our
    276 	# caller.  We let the unwinder skip that single return
    277 	# instruction, and just return to the real caller.
    278 
    279 	# Here CFA points just past the return address on the stack,
    280 	# e.g., on function entry it is %esp + 4.  The stack looks
    281 	# like this:
    282 	#	CFA + 12:	stack pointer after two returns
    283 	#	CFA + 8:	return address of morestack caller's caller
    284 	#	CFA + 4:	size of parameters
    285 	#	CFA:		new stack frame size
    286 	#	CFA - 4:	return address of this function
    287 	#	CFA - 8:	previous value of %ebp; %ebp points here
    288 	# Setting the new CFA to be the current CFA + 12 (i.e., %esp +
    289 	# 16) will make the unwinder pick up the right return address.
    290 
    291 	.cfi_def_cfa %esp,16
    292 
    293 	pushl	%ebp
    294 	.cfi_adjust_cfa_offset 4
    295 	.cfi_offset %ebp, -20
    296 	movl	%esp,%ebp
    297 	.cfi_def_cfa_register %ebp
    298 
    299 	# In 32-bit mode the parameters are pushed on the stack.  The
    300 	# argument size is pushed then the new stack frame size is
    301 	# pushed.
    302 
    303 	# In the body of a non-leaf function, the stack pointer will
    304 	# be aligned to a 16-byte boundary.  That is CFA + 12 in the
    305 	# stack picture above: (CFA + 12) % 16 == 0.  At this point we
    306 	# have %esp == CFA - 8, so %esp % 16 == 12.  We need some
    307 	# space for saving registers and passing parameters, and we
    308 	# need to wind up with %esp % 16 == 0.
    309 	subl	$44,%esp
    310 
    311 	# Because our cleanup code may need to clobber %ebx, we need
    312 	# to save it here so the unwinder can restore the value used
    313 	# by the caller.  Note that we don't have to restore the
    314 	# register, since we don't change it, we just have to save it
    315 	# for the unwinder.
    316 	movl	%ebx,-4(%ebp)
    317 	.cfi_offset %ebx, -24
    318 
    319 	# In 32-bit mode the registers %eax, %edx, and %ecx may be
    320 	# used for parameters, depending on the regparm and fastcall
    321 	# attributes.
    322 
    323 	movl	%eax,-8(%ebp)
    324 	movl	%edx,-12(%ebp)
    325 	movl	%ecx,-16(%ebp)
    326 
    327 	call	__morestack_block_signals
    328 
    329 	movl	12(%ebp),%eax		# The size of the parameters.
    330 	movl	%eax,8(%esp)
    331 	leal	20(%ebp),%eax		# Address of caller's parameters.
    332 	movl	%eax,4(%esp)
    333 	addl	$BACKOFF,8(%ebp)	# Ask for backoff bytes.
    334 	leal	8(%ebp),%eax		# The address of the new frame size.
    335 	movl	%eax,(%esp)
    336 
    337 	call	__generic_morestack
    338 
    339 	movl	%eax,%esp		# Switch to the new stack.
    340 	subl	8(%ebp),%eax		# The end of the stack space.
    341 	addl	$BACKOFF,%eax		# Back off 512 bytes.
    342 
    343 .LEHB0:
    344 	# FIXME: The offset must match
    345 	# TARGET_THREAD_SPLIT_STACK_OFFSET in
    346 	# gcc/config/i386/linux.h.
    347 	movl	%eax,%gs:0x30		# Save the new stack boundary.
    348 
    349 	call	__morestack_unblock_signals
    350 
    351 	movl	-12(%ebp),%edx		# Restore registers.
    352 	movl	-16(%ebp),%ecx
    353 
    354 	movl	4(%ebp),%eax		# Increment the return address
    355 	cmpb	$0xc3,(%eax)		# to skip the ret instruction;
    356 	je	1f			# see above.
    357 	addl	$2,%eax
    358 1:	inc	%eax
    359 
    360 	movl	%eax,-12(%ebp)		# Store return address in an
    361 					# unused slot.
    362 
    363 	movl	-8(%ebp),%eax		# Restore the last register.
    364 
    365 	call	*-12(%ebp)		# Call our caller!
    366 
    367 	# The caller will return here, as predicted.
    368 
    369 	# Save the registers which may hold a return value.  We
    370 	# assume that __generic_releasestack does not touch any
    371 	# floating point or vector registers.
    372 	pushl	%eax
    373 	pushl	%edx
    374 
    375 	# Push the arguments to __generic_releasestack now so that the
    376 	# stack is at a 16-byte boundary for
    377 	# __morestack_block_signals.
    378 	pushl	$0			# Where the available space is returned.
    379 	leal	0(%esp),%eax		# Push its address.
    380 	push	%eax
    381 
    382 	call	__morestack_block_signals
    383 
    384 	call	__generic_releasestack
    385 
    386 	subl	4(%esp),%eax		# Subtract available space.
    387 	addl	$BACKOFF,%eax		# Back off 512 bytes.
    388 .LEHE0:
    389 	movl	%eax,%gs:0x30		# Save the new stack boundary.
    390 
    391 	addl	$8,%esp			# Remove values from stack.
    392 
    393 	# We need to restore the old stack pointer, which is in %rbp,
    394 	# before we unblock signals.  We also need to restore %eax and
    395 	# %edx after we unblock signals but before we return.  Do this
    396 	# by moving %eax and %edx from the current stack to the old
    397 	# stack.
    398 
    399 	popl	%edx			# Pop return value from current stack.
    400 	popl	%eax
    401 
    402 	movl	%ebp,%esp		# Restore stack pointer.
    403 
    404 	# As before, we now have %esp % 16 == 12.
    405 
    406 	pushl	%eax			# Push return value on old stack.
    407 	pushl	%edx
    408 	subl	$4,%esp			# Align stack to 16-byte boundary.
    409 
    410 	call	__morestack_unblock_signals
    411 
    412 	addl	$4,%esp
    413 	popl	%edx			# Restore return value.
    414 	popl	%eax
    415 
    416 	.cfi_remember_state
    417 
    418 	# We never changed %ebx, so we don't have to actually restore it.
    419 	.cfi_restore %ebx
    420 
    421 	popl	%ebp
    422 	.cfi_restore %ebp
    423 	.cfi_def_cfa %esp, 16
    424 	ret	$8			# Return to caller, which will
    425 					# immediately return.  Pop
    426 					# arguments as we go.
    427 
    428 # This is the cleanup code called by the stack unwinder when unwinding
    429 # through the code between .LEHB0 and .LEHE0 above.
    430 
    431 .L1:
    432 	.cfi_restore_state
    433 	subl	$16,%esp		# Maintain 16 byte alignment.
    434 	movl	%eax,4(%esp)		# Save exception header.
    435 	movl	%ebp,(%esp)		# Stack pointer after resume.
    436 	call	__generic_findstack
    437 	movl	%ebp,%ecx		# Get the stack pointer.
    438 	subl	%eax,%ecx		# Subtract available space.
    439 	addl	$BACKOFF,%ecx		# Back off 512 bytes.
    440 	movl	%ecx,%gs:0x30		# Save new stack boundary.
    441 	movl	4(%esp),%eax		# Function argument.
    442 	movl	%eax,(%esp)
    443 #ifdef __PIC__
    444 	call	__x86.get_pc_thunk.bx	# %ebx may not be set up for us.
    445 	addl	$_GLOBAL_OFFSET_TABLE_, %ebx
    446 	call	_Unwind_Resume@PLT	# Resume unwinding.
    447 #else
    448 	call	_Unwind_Resume
    449 #endif
    450 
    451 #else /* defined(__x86_64__) */
    452 
    453 
    454 # The 64-bit __morestack function.
    455 
    456 	# We use a cleanup to restore the stack guard if an exception
    457 	# is thrown through this code.
    458 #ifndef __PIC__
    459 	.cfi_personality 0x3,__gcc_personality_v0
    460 	.cfi_lsda 0x3,.LLSDA1
    461 #else
    462 	.cfi_personality 0x9b,DW.ref.__gcc_personality_v0
    463 	.cfi_lsda 0x1b,.LLSDA1
    464 #endif
    465 
    466 	# We will return a single return instruction, which will
    467 	# return to the caller of our caller.  Let the unwinder skip
    468 	# that single return instruction, and just return to the real
    469 	# caller.
    470 	.cfi_def_cfa %rsp,16
    471 
    472 	# Set up a normal backtrace.
    473 	pushq	%rbp
    474 	.cfi_adjust_cfa_offset 8
    475 	.cfi_offset %rbp, -24
    476 	movq	%rsp, %rbp
    477 	.cfi_def_cfa_register %rbp
    478 
    479 	# In 64-bit mode the new stack frame size is passed in r10
    480         # and the argument size is passed in r11.
    481 
    482 	addq	$BACKOFF,%r10		# Ask for backoff bytes.
    483 	pushq	%r10			# Save new frame size.
    484 
    485 	# In 64-bit mode the registers %rdi, %rsi, %rdx, %rcx, %r8,
    486 	# and %r9 may be used for parameters.  We also preserve %rax
    487 	# which the caller may use to hold %r10.
    488 
    489 	pushq	%rax
    490 	pushq	%rdi
    491 	pushq	%rsi
    492 	pushq	%rdx
    493 	pushq	%rcx
    494 	pushq	%r8
    495 	pushq	%r9
    496 
    497 	pushq	%r11
    498 
    499 	# We entered morestack with the stack pointer aligned to a
    500 	# 16-byte boundary (the call to morestack's caller used 8
    501 	# bytes, and the call to morestack used 8 bytes).  We have now
    502 	# pushed 10 registers, so we are still aligned to a 16-byte
    503 	# boundary.
    504 
    505 	call	__morestack_block_signals
    506 
    507 	leaq	-8(%rbp),%rdi		# Address of new frame size.
    508 	leaq	24(%rbp),%rsi		# The caller's parameters.
    509 	popq	%rdx			# The size of the parameters.
    510 
    511 	subq	$8,%rsp			# Align stack.
    512 
    513 	call	__generic_morestack
    514 
    515 	movq	-8(%rbp),%r10		# Reload modified frame size
    516 	movq	%rax,%rsp		# Switch to the new stack.
    517 	subq	%r10,%rax		# The end of the stack space.
    518 	addq	$BACKOFF,%rax		# Back off 1024 bytes.
    519 
    520 .LEHB0:
    521 	# FIXME: The offset must match
    522 	# TARGET_THREAD_SPLIT_STACK_OFFSET in
    523 	# gcc/config/i386/linux64.h.
    524 	# Macro to save the new stack boundary.
    525 #ifdef __LP64__
    526 #define X86_64_SAVE_NEW_STACK_BOUNDARY(reg)	movq	%r##reg,%fs:0x70
    527 #else
    528 #define X86_64_SAVE_NEW_STACK_BOUNDARY(reg)	movl	%e##reg,%fs:0x40
    529 #endif
    530 	X86_64_SAVE_NEW_STACK_BOUNDARY (ax)
    531 
    532 	call	__morestack_unblock_signals
    533 
    534 	movq	-24(%rbp),%rdi		# Restore registers.
    535 	movq	-32(%rbp),%rsi
    536 	movq	-40(%rbp),%rdx
    537 	movq	-48(%rbp),%rcx
    538 	movq	-56(%rbp),%r8
    539 	movq	-64(%rbp),%r9
    540 
    541 	movq	8(%rbp),%r10		# Increment the return address
    542 	incq	%r10			# to skip the ret instruction;
    543 					# see above.
    544 
    545 	movq	-16(%rbp),%rax		# Restore caller's %rax.
    546 
    547 	call	*%r10			# Call our caller!
    548 
    549 	# The caller will return here, as predicted.
    550 
    551 	# Save the registers which may hold a return value.  We
    552 	# assume that __generic_releasestack does not touch any
    553 	# floating point or vector registers.
    554 	pushq	%rax
    555 	pushq	%rdx
    556 
    557 	call	__morestack_block_signals
    558 
    559 	pushq	$0			# For alignment.
    560 	pushq	$0			# Where the available space is returned.
    561 	leaq	0(%rsp),%rdi		# Pass its address.
    562 
    563 	call	__generic_releasestack
    564 
    565 	subq	0(%rsp),%rax		# Subtract available space.
    566 	addq	$BACKOFF,%rax		# Back off 1024 bytes.
    567 .LEHE0:
    568 	X86_64_SAVE_NEW_STACK_BOUNDARY (ax)
    569 
    570 	addq	$16,%rsp		# Remove values from stack.
    571 
    572 	# We need to restore the old stack pointer, which is in %rbp,
    573 	# before we unblock signals.  We also need to restore %rax and
    574 	# %rdx after we unblock signals but before we return.  Do this
    575 	# by moving %rax and %rdx from the current stack to the old
    576 	# stack.
    577 
    578 	popq	%rdx			# Pop return value from current stack.
    579 	popq	%rax
    580 
    581 	movq	%rbp,%rsp		# Restore stack pointer.
    582 
    583 	# Now (%rsp & 16) == 8.
    584 
    585 	subq	$8,%rsp			# For alignment.
    586 	pushq	%rax			# Push return value on old stack.
    587 	pushq	%rdx
    588 
    589 	call	__morestack_unblock_signals
    590 
    591 	popq	%rdx			# Restore return value.
    592 	popq	%rax
    593 	addq	$8,%rsp
    594 
    595 	.cfi_remember_state
    596 	popq	%rbp
    597 	.cfi_restore %rbp
    598 	.cfi_def_cfa %rsp, 16
    599 	ret				# Return to caller, which will
    600 					# immediately return.
    601 
    602 # This is the cleanup code called by the stack unwinder when unwinding
    603 # through the code between .LEHB0 and .LEHE0 above.
    604 
    605 .L1:
    606 	.cfi_restore_state
    607 	subq	$16,%rsp		# Maintain 16 byte alignment.
    608 	movq	%rax,(%rsp)		# Save exception header.
    609 	movq	%rbp,%rdi		# Stack pointer after resume.
    610 	call	__generic_findstack
    611 	movq	%rbp,%rcx		# Get the stack pointer.
    612 	subq	%rax,%rcx		# Subtract available space.
    613 	addq	$BACKOFF,%rcx		# Back off 1024 bytes.
    614 	X86_64_SAVE_NEW_STACK_BOUNDARY (cx)
    615 	movq	(%rsp),%rdi		# Restore exception data for call.
    616 #ifdef __PIC__
    617 	call	_Unwind_Resume@PLT	# Resume unwinding.
    618 #else
    619 	call	_Unwind_Resume		# Resume unwinding.
    620 #endif
    621 
    622 #endif /* defined(__x86_64__) */
    623 
    624 	.cfi_endproc
    625 #ifdef __ELF__
    626 	.size	__morestack, . - __morestack
    627 #endif
    628 
    629 #if !defined(__x86_64__) && defined(__PIC__)
    630 # Output the thunk to get PC into bx, since we use it above.
    631 	.section	.text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
    632 	.globl	__x86.get_pc_thunk.bx
    633 	.hidden	__x86.get_pc_thunk.bx
    634 #ifdef __ELF__
    635 	.type	__x86.get_pc_thunk.bx, @function
    636 #endif
    637 __x86.get_pc_thunk.bx:
    638 	.cfi_startproc
    639 	movl	(%esp), %ebx
    640 	ret
    641 	.cfi_endproc
    642 #ifdef __ELF__
    643 	.size	__x86.get_pc_thunk.bx, . - __x86.get_pc_thunk.bx
    644 #endif
    645 #endif
    646 
    647 # The exception table.  This tells the personality routine to execute
    648 # the exception handler.
    649 
    650 	.section	.gcc_except_table,"a",@progbits
    651 	.align	4
    652 .LLSDA1:
    653 	.byte	0xff	# @LPStart format (omit)
    654 	.byte	0xff	# @TType format (omit)
    655 	.byte	0x1	# call-site format (uleb128)
    656 	.uleb128 .LLSDACSE1-.LLSDACSB1	# Call-site table length
    657 .LLSDACSB1:
    658 	.uleb128 .LEHB0-.LFB1	# region 0 start
    659 	.uleb128 .LEHE0-.LEHB0	# length
    660 	.uleb128 .L1-.LFB1	# landing pad
    661 	.uleb128 0		# action
    662 .LLSDACSE1:
    663 
    664 
    665 	.global __gcc_personality_v0
    666 #ifdef __PIC__
    667 	# Build a position independent reference to the basic
    668         # personality function.
    669 	.hidden DW.ref.__gcc_personality_v0
    670 	.weak   DW.ref.__gcc_personality_v0
    671 	.section .data.DW.ref.__gcc_personality_v0,"awG",@progbits,DW.ref.__gcc_personality_v0,comdat
    672 	.type	DW.ref.__gcc_personality_v0, @object
    673 DW.ref.__gcc_personality_v0:
    674 #ifndef __LP64__
    675 	.align 4
    676 	.size	DW.ref.__gcc_personality_v0, 4
    677 	.long	__gcc_personality_v0
    678 #else
    679 	.align 8
    680 	.size	DW.ref.__gcc_personality_v0, 8
    681 	.quad	__gcc_personality_v0
    682 #endif
    683 #endif
    684 
    685 #if defined __x86_64__ && defined __LP64__
    686 
    687 # This entry point is used for the large model.  With this entry point
    688 # the upper 32 bits of %r10 hold the argument size and the lower 32
    689 # bits hold the new stack frame size.  There doesn't seem to be a way
    690 # to know in the assembler code that we are assembling for the large
    691 # model, and there doesn't seem to be a large model multilib anyhow.
    692 # If one is developed, then the non-PIC code is probably OK since we
    693 # will probably be close to the morestack code, but the PIC code
    694 # almost certainly needs to be changed.  FIXME.
    695 
    696 	.text
    697 	.global	__morestack_large_model
    698 	.hidden	__morestack_large_model
    699 
    700 #ifdef __ELF__
    701 	.type	__morestack_large_model,@function
    702 #endif
    703 
    704 __morestack_large_model:
    705 
    706 	.cfi_startproc
    707 	_CET_ENDBR
    708 
    709 	movq	%r10, %r11
    710 	andl	$0xffffffff, %r10d
    711 	sarq	$32, %r11
    712 	jmp	__morestack
    713 
    714 	.cfi_endproc
    715 #ifdef __ELF__
    716        .size	__morestack_large_model, . - __morestack_large_model
    717 #endif
    718 
    719 #endif /* __x86_64__ && __LP64__ */
    720 
    721 # Initialize the stack test value when the program starts or when a
    722 # new thread starts.  We don't know how large the main stack is, so we
    723 # guess conservatively.  We might be able to use getrlimit here.
    724 
    725 	.text
    726 	.global	__stack_split_initialize
    727 	.hidden	__stack_split_initialize
    728 
    729 #ifdef __ELF__
    730 	.type	__stack_split_initialize, @function
    731 #endif
    732 
    733 __stack_split_initialize:
    734 	_CET_ENDBR
    735 
    736 #ifndef __x86_64__
    737 
    738 	leal	-16000(%esp),%eax	# We should have at least 16K.
    739 	movl	%eax,%gs:0x30
    740 	subl	$4,%esp			# Align stack.
    741 	pushl	$16000
    742 	pushl	%esp
    743 #ifdef __PIC__
    744 	call	__generic_morestack_set_initial_sp@PLT
    745 #else
    746 	call	__generic_morestack_set_initial_sp
    747 #endif
    748 	addl	$12,%esp
    749 	ret
    750 
    751 #else /* defined(__x86_64__) */
    752 
    753 	leaq	-16000(%rsp),%rax	# We should have at least 16K.
    754 	X86_64_SAVE_NEW_STACK_BOUNDARY (ax)
    755 	subq	$8,%rsp			# Align stack.
    756 	movq	%rsp,%rdi
    757 	movq	$16000,%rsi
    758 #ifdef __PIC__
    759 	call	__generic_morestack_set_initial_sp@PLT
    760 #else
    761 	call	__generic_morestack_set_initial_sp
    762 #endif
    763 	addq	$8,%rsp
    764 	ret
    765 
    766 #endif /* defined(__x86_64__) */
    767 
    768 #ifdef __ELF__
    769 	.size	__stack_split_initialize, . - __stack_split_initialize
    770 #endif
    771 
    772 # Routines to get and set the guard, for __splitstack_getcontext,
    773 # __splitstack_setcontext, and __splitstack_makecontext.
    774 
    775 # void *__morestack_get_guard (void) returns the current stack guard.
    776 	.text
    777 	.global	__morestack_get_guard
    778 	.hidden	__morestack_get_guard
    779 
    780 #ifdef __ELF__
    781 	.type	__morestack_get_guard,@function
    782 #endif
    783 
    784 __morestack_get_guard:
    785 
    786 #ifndef __x86_64__
    787 	movl	%gs:0x30,%eax
    788 #else
    789 #ifdef __LP64__
    790 	movq	%fs:0x70,%rax
    791 #else
    792 	movl	%fs:0x40,%eax
    793 #endif
    794 #endif
    795 	ret
    796 
    797 #ifdef __ELF__
    798 	.size	__morestack_get_guard, . - __morestack_get_guard
    799 #endif
    800 
    801 # void __morestack_set_guard (void *) sets the stack guard.
    802 	.global	__morestack_set_guard
    803 	.hidden	__morestack_set_guard
    804 
    805 #ifdef __ELF__
    806 	.type	__morestack_set_guard,@function
    807 #endif
    808 
    809 __morestack_set_guard:
    810 
    811 #ifndef __x86_64__
    812 	movl	4(%esp),%eax
    813 	movl	%eax,%gs:0x30
    814 #else
    815 	X86_64_SAVE_NEW_STACK_BOUNDARY (di)
    816 #endif
    817 	ret
    818 
    819 #ifdef __ELF__
    820 	.size	__morestack_set_guard, . - __morestack_set_guard
    821 #endif
    822 
    823 # void *__morestack_make_guard (void *, size_t) returns the stack
    824 # guard value for a stack.
    825 	.global	__morestack_make_guard
    826 	.hidden	__morestack_make_guard
    827 
    828 #ifdef __ELF__
    829 	.type	__morestack_make_guard,@function
    830 #endif
    831 
    832 __morestack_make_guard:
    833 
    834 #ifndef __x86_64__
    835 	movl	4(%esp),%eax
    836 	subl	8(%esp),%eax
    837 	addl	$BACKOFF,%eax
    838 #else
    839 	subq	%rsi,%rdi
    840 	addq	$BACKOFF,%rdi
    841 	movq	%rdi,%rax
    842 #endif
    843 	ret
    844 
    845 #ifdef __ELF__
    846 	.size	__morestack_make_guard, . - __morestack_make_guard
    847 #endif
    848 
    849 # Make __stack_split_initialize a high priority constructor.  FIXME:
    850 # This is ELF specific.
    851 
    852 #if HAVE_INITFINI_ARRAY_SUPPORT
    853 	.section	.init_array.00000,"aw",@progbits
    854 #else
    855 	.section	.ctors.65535,"aw",@progbits
    856 #endif
    857 
    858 #ifndef __LP64__
    859 	.align	4
    860 	.long	__stack_split_initialize
    861 	.long	__morestack_load_mmap
    862 #else
    863 	.align	8
    864 	.quad	__stack_split_initialize
    865 	.quad	__morestack_load_mmap
    866 #endif
    867 
    868 #if defined(__ELF__) && defined(__linux__)
    869 	.section	.note.GNU-stack,"",@progbits
    870 	.section	.note.GNU-split-stack,"",@progbits
    871 	.section	.note.GNU-no-split-stack,"",@progbits
    872 #endif
    873