1# s390 support for -fsplit-stack. 2# Copyright (C) 2015-2022 Free Software Foundation, Inc. 3# Contributed by Marcin Kościelnicki <koriakin@0x04.net>. 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# Excess space needed to call ld.so resolver for lazy plt 27# resolution. Go uses sigaltstack so this doesn't need to 28# also cover signal frame size. 29#define BACKOFF 0x1000 30 31#include <auto-host.h> 32 33# The __morestack function. 34 35 .global __morestack 36 .hidden __morestack 37 38 .type __morestack,@function 39 40__morestack: 41.LFB1: 42 .cfi_startproc 43 44 45#ifndef __s390x__ 46 47 48# The 31-bit __morestack function. 49 50 # We use a cleanup to restore the stack guard if an exception 51 # is thrown through this code. 52#ifndef __PIC__ 53 .cfi_personality 0,__gcc_personality_v0 54 .cfi_lsda 0,.LLSDA1 55#else 56 .cfi_personality 0x9b,DW.ref.__gcc_personality_v0 57 .cfi_lsda 0x1b,.LLSDA1 58#endif 59 60 stm %r2, %r15, 0x8(%r15) # Save %r2-%r15. 61 .cfi_offset %r6, -0x48 62 .cfi_offset %r7, -0x44 63 .cfi_offset %r8, -0x40 64 .cfi_offset %r9, -0x3c 65 .cfi_offset %r10, -0x38 66 .cfi_offset %r11, -0x34 67 .cfi_offset %r12, -0x30 68 .cfi_offset %r13, -0x2c 69 .cfi_offset %r14, -0x28 70 .cfi_offset %r15, -0x24 71 lr %r11, %r15 # Make frame pointer for vararg. 72 .cfi_def_cfa_register %r11 73 ahi %r15, -0x60 # 0x60 for standard frame. 74 st %r11, 0(%r15) # Save back chain. 75 lr %r8, %r0 # Save %r0 (static chain). 76 lr %r10, %r1 # Save %r1 (address of parameter block). 77 78 l %r7, 0(%r10) # Required frame size to %r7 79 ear %r1, %a0 # Extract thread pointer. 80 l %r1, 0x20(%r1) # Get stack bounduary 81 ar %r1, %r7 # Stack bounduary + frame size 82 a %r1, 4(%r10) # + stack param size 83 clr %r1, %r15 # Compare with current stack pointer 84 jle .Lnoalloc # guard > sp - frame-size: need alloc 85 86 brasl %r14, __morestack_block_signals 87 88 # We abuse one of caller's fpr save slots (which we don't use for fprs) 89 # as a local variable. Not needed here, but done to be consistent with 90 # the below use. 91 ahi %r7, BACKOFF # Bump requested size a bit. 92 st %r7, 0x40(%r11) # Stuff frame size on stack. 93 la %r2, 0x40(%r11) # Pass its address as parameter. 94 la %r3, 0x60(%r11) # Caller's stack parameters. 95 l %r4, 4(%r10) # Size of stack parameters. 96 brasl %r14, __generic_morestack 97 98 lr %r15, %r2 # Switch to the new stack. 99 ahi %r15, -0x60 # Make a stack frame on it. 100 st %r11, 0(%r15) # Save back chain. 101 102 s %r2, 0x40(%r11) # The end of stack space. 103 ahi %r2, BACKOFF # Back off a bit. 104 ear %r1, %a0 # Extract thread pointer. 105.LEHB0: 106 st %r2, 0x20(%r1) # Save the new stack boundary. 107 108 brasl %r14, __morestack_unblock_signals 109 110 lr %r0, %r8 # Static chain. 111 lm %r2, %r6, 0x8(%r11) # Paremeter registers. 112 113 # Third parameter is address of function meat - address of parameter 114 # block. 115 a %r10, 0x8(%r10) 116 117 # Leave vararg pointer in %r1, in case function uses it 118 la %r1, 0x60(%r11) 119 120 # State of registers: 121 # %r0: Static chain from entry. 122 # %r1: Vararg pointer. 123 # %r2-%r6: Parameters from entry. 124 # %r7-%r10: Indeterminate. 125 # %r11: Frame pointer (%r15 from entry). 126 # %r12-%r13: Indeterminate. 127 # %r14: Return address. 128 # %r15: Stack pointer. 129 basr %r14, %r10 # Call our caller. 130 131 stm %r2, %r3, 0x8(%r11) # Save return registers. 132 133 brasl %r14, __morestack_block_signals 134 135 # We need a stack slot now, but have no good way to get it - the frame 136 # on new stack had to be exactly 0x60 bytes, or stack parameters would 137 # be passed wrong. Abuse fpr save area in caller's frame (we don't 138 # save actual fprs). 139 la %r2, 0x40(%r11) 140 brasl %r14, __generic_releasestack 141 142 s %r2, 0x40(%r11) # Subtract available space. 143 ahi %r2, BACKOFF # Back off a bit. 144 ear %r1, %a0 # Extract thread pointer. 145.LEHE0: 146 st %r2, 0x20(%r1) # Save the new stack boundary. 147 148 # We need to restore the old stack pointer before unblocking signals. 149 # We also need 0x60 bytes for a stack frame. Since we had a stack 150 # frame at this place before the stack switch, there's no need to 151 # write the back chain again. 152 lr %r15, %r11 153 ahi %r15, -0x60 154 155 brasl %r14, __morestack_unblock_signals 156 157 lm %r2, %r15, 0x8(%r11) # Restore all registers. 158 .cfi_remember_state 159 .cfi_restore %r15 160 .cfi_restore %r14 161 .cfi_restore %r13 162 .cfi_restore %r12 163 .cfi_restore %r11 164 .cfi_restore %r10 165 .cfi_restore %r9 166 .cfi_restore %r8 167 .cfi_restore %r7 168 .cfi_restore %r6 169 .cfi_def_cfa_register %r15 170 br %r14 # Return to caller's caller. 171 172# Executed if no new stack allocation is needed. 173 174.Lnoalloc: 175 .cfi_restore_state 176 # We may need to copy stack parameters. 177 l %r9, 0x4(%r10) # Load stack parameter size. 178 ltr %r9, %r9 # And check if it's 0. 179 je .Lnostackparm # Skip the copy if not needed. 180 sr %r15, %r9 # Make space on the stack. 181 la %r8, 0x60(%r15) # Destination. 182 la %r12, 0x60(%r11) # Source. 183 lr %r13, %r9 # Source size. 184.Lcopy: 185 mvcle %r8, %r12, 0 # Copy. 186 jo .Lcopy 187 188.Lnostackparm: 189 # Third parameter is address of function meat - address of parameter 190 # block. 191 a %r10, 0x8(%r10) 192 193 # Leave vararg pointer in %r1, in case function uses it 194 la %r1, 0x60(%r11) 195 196 # OK, no stack allocation needed. We still follow the protocol and 197 # call our caller - it doesn't cost much and makes sure vararg works. 198 # No need to set any registers here - %r0 and %r2-%r6 weren't modified. 199 basr %r14, %r10 # Call our caller. 200 201 lm %r6, %r15, 0x18(%r11) # Restore all callee-saved registers. 202 .cfi_remember_state 203 .cfi_restore %r15 204 .cfi_restore %r14 205 .cfi_restore %r13 206 .cfi_restore %r12 207 .cfi_restore %r11 208 .cfi_restore %r10 209 .cfi_restore %r9 210 .cfi_restore %r8 211 .cfi_restore %r7 212 .cfi_restore %r6 213 .cfi_def_cfa_register %r15 214 br %r14 # Return to caller's caller. 215 216# This is the cleanup code called by the stack unwinder when unwinding 217# through the code between .LEHB0 and .LEHE0 above. 218 219.L1: 220 .cfi_restore_state 221 lr %r2, %r11 # Stack pointer after resume. 222 brasl %r14, __generic_findstack 223 lr %r3, %r11 # Get the stack pointer. 224 sr %r3, %r2 # Subtract available space. 225 ahi %r3, BACKOFF # Back off a bit. 226 ear %r1, %a0 # Extract thread pointer. 227 st %r3, 0x20(%r1) # Save the new stack boundary. 228 229 # We need GOT pointer in %r12 for PLT entry. 230 larl %r12,_GLOBAL_OFFSET_TABLE_ 231 lr %r2, %r6 # Exception header. 232#ifdef __PIC__ 233 brasl %r14, _Unwind_Resume@PLT 234#else 235 brasl %r14, _Unwind_Resume 236#endif 237 238#else /* defined(__s390x__) */ 239 240 241# The 64-bit __morestack function. 242 243 # We use a cleanup to restore the stack guard if an exception 244 # is thrown through this code. 245#ifndef __PIC__ 246 .cfi_personality 0x3,__gcc_personality_v0 247 .cfi_lsda 0x3,.LLSDA1 248#else 249 .cfi_personality 0x9b,DW.ref.__gcc_personality_v0 250 .cfi_lsda 0x1b,.LLSDA1 251#endif 252 253 stmg %r2, %r15, 0x10(%r15) # Save %r2-%r15. 254 .cfi_offset %r6, -0x70 255 .cfi_offset %r7, -0x68 256 .cfi_offset %r8, -0x60 257 .cfi_offset %r9, -0x58 258 .cfi_offset %r10, -0x50 259 .cfi_offset %r11, -0x48 260 .cfi_offset %r12, -0x40 261 .cfi_offset %r13, -0x38 262 .cfi_offset %r14, -0x30 263 .cfi_offset %r15, -0x28 264 lgr %r11, %r15 # Make frame pointer for vararg. 265 .cfi_def_cfa_register %r11 266 aghi %r15, -0xa0 # 0xa0 for standard frame. 267 stg %r11, 0(%r15) # Save back chain. 268 lgr %r8, %r0 # Save %r0 (static chain). 269 lgr %r10, %r1 # Save %r1 (address of parameter block). 270 271 lg %r7, 0(%r10) # Required frame size to %r7 272 ear %r1, %a0 273 sllg %r1, %r1, 32 274 ear %r1, %a1 # Extract thread pointer. 275 lg %r1, 0x38(%r1) # Get stack bounduary 276 agr %r1, %r7 # Stack bounduary + frame size 277 ag %r1, 8(%r10) # + stack param size 278 clgr %r1, %r15 # Compare with current stack pointer 279 jle .Lnoalloc # guard > sp - frame-size: need alloc 280 281 brasl %r14, __morestack_block_signals 282 283 # We abuse one of caller's fpr save slots (which we don't use for fprs) 284 # as a local variable. Not needed here, but done to be consistent with 285 # the below use. 286 aghi %r7, BACKOFF # Bump requested size a bit. 287 stg %r7, 0x80(%r11) # Stuff frame size on stack. 288 la %r2, 0x80(%r11) # Pass its address as parameter. 289 la %r3, 0xa0(%r11) # Caller's stack parameters. 290 lg %r4, 8(%r10) # Size of stack parameters. 291 brasl %r14, __generic_morestack 292 293 lgr %r15, %r2 # Switch to the new stack. 294 aghi %r15, -0xa0 # Make a stack frame on it. 295 stg %r11, 0(%r15) # Save back chain. 296 297 sg %r2, 0x80(%r11) # The end of stack space. 298 aghi %r2, BACKOFF # Back off a bit. 299 ear %r1, %a0 300 sllg %r1, %r1, 32 301 ear %r1, %a1 # Extract thread pointer. 302.LEHB0: 303 stg %r2, 0x38(%r1) # Save the new stack boundary. 304 305 brasl %r14, __morestack_unblock_signals 306 307 lgr %r0, %r8 # Static chain. 308 lmg %r2, %r6, 0x10(%r11) # Paremeter registers. 309 310 # Third parameter is address of function meat - address of parameter 311 # block. 312 ag %r10, 0x10(%r10) 313 314 # Leave vararg pointer in %r1, in case function uses it 315 la %r1, 0xa0(%r11) 316 317 # State of registers: 318 # %r0: Static chain from entry. 319 # %r1: Vararg pointer. 320 # %r2-%r6: Parameters from entry. 321 # %r7-%r10: Indeterminate. 322 # %r11: Frame pointer (%r15 from entry). 323 # %r12-%r13: Indeterminate. 324 # %r14: Return address. 325 # %r15: Stack pointer. 326 basr %r14, %r10 # Call our caller. 327 328 stg %r2, 0x10(%r11) # Save return register. 329 330 brasl %r14, __morestack_block_signals 331 332 # We need a stack slot now, but have no good way to get it - the frame 333 # on new stack had to be exactly 0xa0 bytes, or stack parameters would 334 # be passed wrong. Abuse fpr save area in caller's frame (we don't 335 # save actual fprs). 336 la %r2, 0x80(%r11) 337 brasl %r14, __generic_releasestack 338 339 sg %r2, 0x80(%r11) # Subtract available space. 340 aghi %r2, BACKOFF # Back off a bit. 341 ear %r1, %a0 342 sllg %r1, %r1, 32 343 ear %r1, %a1 # Extract thread pointer. 344.LEHE0: 345 stg %r2, 0x38(%r1) # Save the new stack boundary. 346 347 # We need to restore the old stack pointer before unblocking signals. 348 # We also need 0xa0 bytes for a stack frame. Since we had a stack 349 # frame at this place before the stack switch, there's no need to 350 # write the back chain again. 351 lgr %r15, %r11 352 aghi %r15, -0xa0 353 354 brasl %r14, __morestack_unblock_signals 355 356 lmg %r2, %r15, 0x10(%r11) # Restore all registers. 357 .cfi_remember_state 358 .cfi_restore %r15 359 .cfi_restore %r14 360 .cfi_restore %r13 361 .cfi_restore %r12 362 .cfi_restore %r11 363 .cfi_restore %r10 364 .cfi_restore %r9 365 .cfi_restore %r8 366 .cfi_restore %r7 367 .cfi_restore %r6 368 .cfi_def_cfa_register %r15 369 br %r14 # Return to caller's caller. 370 371# Executed if no new stack allocation is needed. 372 373.Lnoalloc: 374 .cfi_restore_state 375 # We may need to copy stack parameters. 376 lg %r9, 0x8(%r10) # Load stack parameter size. 377 ltgr %r9, %r9 # Check if it's 0. 378 je .Lnostackparm # Skip the copy if not needed. 379 sgr %r15, %r9 # Make space on the stack. 380 la %r8, 0xa0(%r15) # Destination. 381 la %r12, 0xa0(%r11) # Source. 382 lgr %r13, %r9 # Source size. 383.Lcopy: 384 mvcle %r8, %r12, 0 # Copy. 385 jo .Lcopy 386 387.Lnostackparm: 388 # Third parameter is address of function meat - address of parameter 389 # block. 390 ag %r10, 0x10(%r10) 391 392 # Leave vararg pointer in %r1, in case function uses it 393 la %r1, 0xa0(%r11) 394 395 # OK, no stack allocation needed. We still follow the protocol and 396 # call our caller - it doesn't cost much and makes sure vararg works. 397 # No need to set any registers here - %r0 and %r2-%r6 weren't modified. 398 basr %r14, %r10 # Call our caller. 399 400 lmg %r6, %r15, 0x30(%r11) # Restore all callee-saved registers. 401 .cfi_remember_state 402 .cfi_restore %r15 403 .cfi_restore %r14 404 .cfi_restore %r13 405 .cfi_restore %r12 406 .cfi_restore %r11 407 .cfi_restore %r10 408 .cfi_restore %r9 409 .cfi_restore %r8 410 .cfi_restore %r7 411 .cfi_restore %r6 412 .cfi_def_cfa_register %r15 413 br %r14 # Return to caller's caller. 414 415# This is the cleanup code called by the stack unwinder when unwinding 416# through the code between .LEHB0 and .LEHE0 above. 417 418.L1: 419 .cfi_restore_state 420 lgr %r2, %r11 # Stack pointer after resume. 421 brasl %r14, __generic_findstack 422 lgr %r3, %r11 # Get the stack pointer. 423 sgr %r3, %r2 # Subtract available space. 424 aghi %r3, BACKOFF # Back off a bit. 425 ear %r1, %a0 426 sllg %r1, %r1, 32 427 ear %r1, %a1 # Extract thread pointer. 428 stg %r3, 0x38(%r1) # Save the new stack boundary. 429 430 lgr %r2, %r6 # Exception header. 431#ifdef __PIC__ 432 brasl %r14, _Unwind_Resume@PLT 433#else 434 brasl %r14, _Unwind_Resume 435#endif 436 437#endif /* defined(__s390x__) */ 438 439 .cfi_endproc 440 .size __morestack, . - __morestack 441 442 443# The exception table. This tells the personality routine to execute 444# the exception handler. 445 446 .section .gcc_except_table,"a",@progbits 447 .align 4 448.LLSDA1: 449 .byte 0xff # @LPStart format (omit) 450 .byte 0xff # @TType format (omit) 451 .byte 0x1 # call-site format (uleb128) 452 .uleb128 .LLSDACSE1-.LLSDACSB1 # Call-site table length 453.LLSDACSB1: 454 .uleb128 .LEHB0-.LFB1 # region 0 start 455 .uleb128 .LEHE0-.LEHB0 # length 456 .uleb128 .L1-.LFB1 # landing pad 457 .uleb128 0 # action 458.LLSDACSE1: 459 460 461 .global __gcc_personality_v0 462#ifdef __PIC__ 463 # Build a position independent reference to the basic 464 # personality function. 465 .hidden DW.ref.__gcc_personality_v0 466 .weak DW.ref.__gcc_personality_v0 467 .section .data.DW.ref.__gcc_personality_v0,"awG",@progbits,DW.ref.__gcc_personality_v0,comdat 468 .type DW.ref.__gcc_personality_v0, @object 469DW.ref.__gcc_personality_v0: 470#ifndef __LP64__ 471 .align 4 472 .size DW.ref.__gcc_personality_v0, 4 473 .long __gcc_personality_v0 474#else 475 .align 8 476 .size DW.ref.__gcc_personality_v0, 8 477 .quad __gcc_personality_v0 478#endif 479#endif 480 481 482 483# Initialize the stack test value when the program starts or when a 484# new thread starts. We don't know how large the main stack is, so we 485# guess conservatively. We might be able to use getrlimit here. 486 487 .text 488 .global __stack_split_initialize 489 .hidden __stack_split_initialize 490 491 .type __stack_split_initialize, @function 492 493__stack_split_initialize: 494 495#ifndef __s390x__ 496 497 ear %r1, %a0 498 lr %r0, %r15 499 ahi %r0, -0x4000 # We should have at least 16K. 500 st %r0, 0x20(%r1) 501 502 lr %r2, %r15 503 lhi %r3, 0x4000 504#ifdef __PIC__ 505 jg __generic_morestack_set_initial_sp@PLT # Tail call 506#else 507 jg __generic_morestack_set_initial_sp # Tail call 508#endif 509 510#else /* defined(__s390x__) */ 511 512 ear %r1, %a0 513 sllg %r1, %r1, 32 514 ear %r1, %a1 515 lgr %r0, %r15 516 aghi %r0, -0x4000 # We should have at least 16K. 517 stg %r0, 0x38(%r1) 518 519 lgr %r2, %r15 520 lghi %r3, 0x4000 521#ifdef __PIC__ 522 jg __generic_morestack_set_initial_sp@PLT # Tail call 523#else 524 jg __generic_morestack_set_initial_sp # Tail call 525#endif 526 527#endif /* defined(__s390x__) */ 528 529 .size __stack_split_initialize, . - __stack_split_initialize 530 531# Routines to get and set the guard, for __splitstack_getcontext, 532# __splitstack_setcontext, and __splitstack_makecontext. 533 534# void *__morestack_get_guard (void) returns the current stack guard. 535 .text 536 .global __morestack_get_guard 537 .hidden __morestack_get_guard 538 539 .type __morestack_get_guard,@function 540 541__morestack_get_guard: 542 543#ifndef __s390x__ 544 ear %r1, %a0 545 l %r2, 0x20(%r1) 546#else 547 ear %r1, %a0 548 sllg %r1, %r1, 32 549 ear %r1, %a1 550 lg %r2, 0x38(%r1) 551#endif 552 br %r14 553 554 .size __morestack_get_guard, . - __morestack_get_guard 555 556# void __morestack_set_guard (void *) sets the stack guard. 557 .global __morestack_set_guard 558 .hidden __morestack_set_guard 559 560 .type __morestack_set_guard,@function 561 562__morestack_set_guard: 563 564#ifndef __s390x__ 565 ear %r1, %a0 566 st %r2, 0x20(%r1) 567#else 568 ear %r1, %a0 569 sllg %r1, %r1, 32 570 ear %r1, %a1 571 stg %r2, 0x38(%r1) 572#endif 573 br %r14 574 575 .size __morestack_set_guard, . - __morestack_set_guard 576 577# void *__morestack_make_guard (void *, size_t) returns the stack 578# guard value for a stack. 579 .global __morestack_make_guard 580 .hidden __morestack_make_guard 581 582 .type __morestack_make_guard,@function 583 584__morestack_make_guard: 585 586#ifndef __s390x__ 587 sr %r2, %r3 588 ahi %r2, BACKOFF 589#else 590 sgr %r2, %r3 591 aghi %r2, BACKOFF 592#endif 593 br %r14 594 595 .size __morestack_make_guard, . - __morestack_make_guard 596 597# Make __stack_split_initialize a high priority constructor. 598 599#if HAVE_INITFINI_ARRAY_SUPPORT 600 .section .init_array.00000,"aw",@progbits 601#else 602 .section .ctors.65535,"aw",@progbits 603#endif 604 605#ifndef __LP64__ 606 .align 4 607 .long __stack_split_initialize 608 .long __morestack_load_mmap 609#else 610 .align 8 611 .quad __stack_split_initialize 612 .quad __morestack_load_mmap 613#endif 614 615 .section .note.GNU-stack,"",@progbits 616 .section .note.GNU-split-stack,"",@progbits 617 .section .note.GNU-no-split-stack,"",@progbits 618