Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* stuff needed for libgcc on win32.
  2.  *
  3.  *   Copyright (C) 1996-2015 Free Software Foundation, Inc.
  4.  *   Written By Steve Chamberlain
  5.  *
  6.  * This file is free software; you can redistribute it and/or modify it
  7.  * under the terms of the GNU General Public License as published by the
  8.  * Free Software Foundation; either version 3, or (at your option) any
  9.  * later version.
  10.  *
  11.  * This file is distributed in the hope that it will be useful, but
  12.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * General Public License for more details.
  15.  *
  16.  * Under Section 7 of GPL version 3, you are granted additional
  17.  * permissions described in the GCC Runtime Library Exception, version
  18.  * 3.1, as published by the Free Software Foundation.
  19.  *
  20.  * You should have received a copy of the GNU General Public License and
  21.  * a copy of the GCC Runtime Library Exception along with this program;
  22.  * see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
  23.  * <http://www.gnu.org/licenses/>.
  24.  */
  25.  
  26. #include "auto-host.h"
  27.  
  28. #ifdef HAVE_GAS_CFI_SECTIONS_DIRECTIVE
  29.         .cfi_sections   .debug_frame
  30. # define cfi_startproc()                .cfi_startproc
  31. # define cfi_endproc()                  .cfi_endproc
  32. # define cfi_adjust_cfa_offset(X)       .cfi_adjust_cfa_offset X
  33. # define cfi_def_cfa_register(X)        .cfi_def_cfa_register X
  34. # define cfi_register(D,S)              .cfi_register D, S
  35. # ifdef __x86_64__
  36. #  define cfi_push(X)           .cfi_adjust_cfa_offset 8; .cfi_rel_offset X, 0
  37. #  define cfi_pop(X)            .cfi_adjust_cfa_offset -8; .cfi_restore X
  38. # else
  39. #  define cfi_push(X)           .cfi_adjust_cfa_offset 4; .cfi_rel_offset X, 0
  40. #  define cfi_pop(X)            .cfi_adjust_cfa_offset -4; .cfi_restore X
  41. # endif
  42. #else
  43. # define cfi_startproc()
  44. # define cfi_endproc()
  45. # define cfi_adjust_cfa_offset(X)
  46. # define cfi_def_cfa_register(X)
  47. # define cfi_register(D,S)
  48. # define cfi_push(X)
  49. # define cfi_pop(X)
  50. #endif /* HAVE_GAS_CFI_SECTIONS_DIRECTIVE */
  51.  
  52. #ifdef L_chkstk
  53. /* Function prologue calls __chkstk to probe the stack when allocating more
  54.    than CHECK_STACK_LIMIT bytes in one go.  Touching the stack at 4K
  55.    increments is necessary to ensure that the guard pages used
  56.    by the OS virtual memory manger are allocated in correct sequence.  */
  57.  
  58.         .global ___chkstk
  59.         .global __alloca
  60. #ifdef __x86_64__
  61. /* __alloca is a normal function call, which uses %rcx as the argument.  */
  62.         cfi_startproc()
  63. __alloca:
  64.         movq    %rcx, %rax
  65.         /* FALLTHRU */
  66.  
  67. /* ___chkstk is a *special* function call, which uses %rax as the argument.
  68.    We avoid clobbering the 4 integer argument registers, %rcx, %rdx,
  69.    %r8 and %r9, which leaves us with %rax, %r10, and %r11 to use.  */
  70.         .align  4
  71. ___chkstk:
  72.         popq    %r11                    /* pop return address */
  73.         cfi_adjust_cfa_offset(-8)       /* indicate return address in r11 */
  74.         cfi_register(%rip, %r11)
  75.         movq    %rsp, %r10
  76.         cmpq    $0x1000, %rax           /* > 4k ?*/
  77.         jb      2f
  78.  
  79. 1:      subq    $0x1000, %r10           /* yes, move pointer down 4k*/
  80.         orl     $0x0, (%r10)            /* probe there */
  81.         subq    $0x1000, %rax           /* decrement count */
  82.         cmpq    $0x1000, %rax
  83.         ja      1b                      /* and do it again */
  84.  
  85. 2:      subq    %rax, %r10
  86.         movq    %rsp, %rax              /* hold CFA until return */
  87.         cfi_def_cfa_register(%rax)
  88.         orl     $0x0, (%r10)            /* less than 4k, just peek here */
  89.         movq    %r10, %rsp              /* decrement stack */
  90.  
  91.         /* Push the return value back.  Doing this instead of just
  92.            jumping to %r11 preserves the cached call-return stack
  93.            used by most modern processors.  */
  94.         pushq   %r11
  95.         ret
  96.         cfi_endproc()
  97. #else
  98.         cfi_startproc()
  99. ___chkstk:
  100. __alloca:
  101.         pushl   %ecx                    /* save temp */
  102.         cfi_push(%eax)
  103.         leal    8(%esp), %ecx           /* point past return addr */
  104.         cmpl    $0x1000, %eax           /* > 4k ?*/
  105.         jb      2f
  106.  
  107. 1:      subl    $0x1000, %ecx           /* yes, move pointer down 4k*/
  108.         orl     $0x0, (%ecx)            /* probe there */
  109.         subl    $0x1000, %eax           /* decrement count */
  110.         cmpl    $0x1000, %eax
  111.         ja      1b                      /* and do it again */
  112.  
  113. 2:      subl    %eax, %ecx         
  114.         orl     $0x0, (%ecx)            /* less than 4k, just peek here */
  115.         movl    %esp, %eax              /* save current stack pointer */
  116.         cfi_def_cfa_register(%eax)
  117.         movl    %ecx, %esp              /* decrement stack */
  118.         movl    (%eax), %ecx            /* recover saved temp */
  119.  
  120.         /* Copy the return register.  Doing this instead of just jumping to
  121.            the address preserves the cached call-return stack used by most
  122.            modern processors.  */
  123.         pushl   4(%eax)
  124.         ret
  125.         cfi_endproc()
  126. #endif /* __x86_64__ */
  127. #endif /* L_chkstk */
  128.  
  129. #ifdef L_chkstk_ms
  130. /* ___chkstk_ms is a *special* function call, which uses %rax as the argument.
  131.    We avoid clobbering any registers.  Unlike ___chkstk, it just probes the
  132.    stack and does no stack allocation.  */
  133.         .global ___chkstk_ms
  134. #ifdef __x86_64__
  135.         cfi_startproc()
  136. ___chkstk_ms:
  137.         pushq   %rcx                    /* save temps */
  138.         cfi_push(%rcx)
  139.         pushq   %rax
  140.         cfi_push(%rax)
  141.         cmpq    $0x1000, %rax           /* > 4k ?*/
  142.         leaq    24(%rsp), %rcx          /* point past return addr */
  143.         jb      2f
  144.  
  145. 1:      subq    $0x1000, %rcx           /* yes, move pointer down 4k */
  146.         orq     $0x0, (%rcx)            /* probe there */
  147.         subq    $0x1000, %rax           /* decrement count */
  148.         cmpq    $0x1000, %rax
  149.         ja      1b                      /* and do it again */
  150.  
  151. 2:      subq    %rax, %rcx
  152.         orq     $0x0, (%rcx)            /* less than 4k, just peek here */
  153.  
  154.         popq    %rax
  155.         cfi_pop(%rax)
  156.         popq    %rcx
  157.         cfi_pop(%rcx)
  158.         ret
  159.         cfi_endproc()
  160. #else
  161.         cfi_startproc()
  162. ___chkstk_ms:
  163.         pushl   %ecx                    /* save temp */
  164.         cfi_push(%ecx)
  165.         pushl   %eax
  166.         cfi_push(%eax)
  167.         cmpl    $0x1000, %eax           /* > 4k ?*/
  168.         leal    12(%esp), %ecx          /* point past return addr */
  169.         jb      2f
  170.  
  171. 1:      subl    $0x1000, %ecx           /* yes, move pointer down 4k*/
  172.         orl     $0x0, (%ecx)            /* probe there */
  173.         subl    $0x1000, %eax           /* decrement count */
  174.         cmpl    $0x1000, %eax
  175.         ja      1b                      /* and do it again */
  176.  
  177. 2:      subl    %eax, %ecx
  178.         orl     $0x0, (%ecx)            /* less than 4k, just peek here */
  179.  
  180.         popl    %eax
  181.         cfi_pop(%eax)
  182.         popl    %ecx
  183.         cfi_pop(%ecx)
  184.         ret
  185.         cfi_endproc()
  186. #endif /* __x86_64__ */
  187. #endif /* L_chkstk_ms */
  188.